From ce78b658757d80f27a106e4af39ca80e8d677567 Mon Sep 17 00:00:00 2001 From: guanj Date: Fri, 24 Apr 2026 09:13:17 +0800 Subject: [PATCH] =?UTF-8?q?=E6=8F=90=E4=BA=A4=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- App.vue | 208 +--- changelog.md | 10 + common/api/user.js | 483 ++++----- common/css/base.scss | 18 +- common/js/request.js | 2 +- common/js/update.js | 227 ++++ components/Cn-device-card/Cn-device-card.vue | 6 +- .../Cn-filterCriteria/Cn-filterCriteria.vue | 60 +- components/Cn-icon-device/Cn-icon-device.vue | 24 +- .../Cn-icon-transient/Cn-icon-transient.vue | 42 +- components/yxt-letterIndex/pinyinUtil.js | 989 ++++++++++++++++++ package-lock.json | 557 ++++++---- package.json | 2 +- pages/device/list.vue | 4 +- pages/device/realTime/index.vue | 28 +- pages/engineering/list.vue | 3 +- pages/home/selectEngineering.vue | 40 +- pages/home/selectEngineering1.vue | 144 +++ pages/index/comp/apply.vue | 13 +- pages/index/comp/steadyState.vue | 4 +- pages/index/comp/transient.vue | 21 +- pages/index/index.vue | 2 +- pages/message1/alarm.vue | 2 +- pages/message1/comp/alarmDetails.vue | 4 +- pages/message1/comp/preview.vue | 12 +- pages/message1/index.scss | 5 +- pages/message1/run.vue | 50 +- pages/message1/steadyState.vue | 4 +- pages/message1/transient.vue | 33 +- pages/project/list.vue | 1 + readme.md | 111 ++ yarn.lock | 503 +++------ 32 files changed, 2470 insertions(+), 1142 deletions(-) create mode 100644 changelog.md create mode 100644 common/js/update.js create mode 100644 components/yxt-letterIndex/pinyinUtil.js create mode 100644 pages/home/selectEngineering1.vue create mode 100644 readme.md diff --git a/App.vue b/App.vue index 7537159..8cca913 100644 --- a/App.vue +++ b/App.vue @@ -1,10 +1,11 @@ diff --git a/changelog.md b/changelog.md new file mode 100644 index 0000000..a7dc2e7 --- /dev/null +++ b/changelog.md @@ -0,0 +1,10 @@ +# 更新日志 + +## 1.0.0 (2025-10-15) +- 初始版本发布 +- 实现字母索引列表功能 +- 支持按拼音首字母分组展示数据 +- 集成右侧快速字母导航功能 +- 添加滚动监听和高亮显示当前字母 +- 支持签到状态显示和补签操作 +- 优化空数据状态展示 diff --git a/common/api/user.js b/common/api/user.js index f62a7e6..33ac8f1 100644 --- a/common/api/user.js +++ b/common/api/user.js @@ -1,238 +1,245 @@ -import request from '../js/request' - -/** - * 发送验证码 - * @param {*} params.type 0:登录 1:注册 2:修改密码 6:忘记密码 4:更换手机号第二步获取验证码 5:更换手机号第一步获取验证码 - * @returns - */ -export function apiGetYms(params) { - return request({ - url: '/user-boot/appUser/authCode', - data: { - phone: params.phone, - devCode: uni.getStorageSync('devCode'), - type: params.type, - }, - method: 'POST', - }) -} - -/** - * 登录 - * @param {*} params.type 0:ysm 1:pwd - * @returns - */ -export function apiLogin(params) { - console.log(uni.getStorageSync('devCode')) - return request({ - url: '/shiningCloud/user/login', - data: { - phone: params.phone, - devCode: uni.getStorageSync('devCode'), - key: params.key.trim(), - type: params.type, - }, - method: 'POST', - }) -} - -/** - * 验证码登录 - * @param {*} params.type 0:ysm 1:pwd - * @returns - */ -export function apiYsmLogin(params) { - uni.setStorageSync('access_token', 'Basic bmpjbmFwcDpuamNucHFz') - return request({ - url: '/pqs-auth/oauth/token', - data: { - grant_type: 'sms_code', - phone: params.phone, - smsCode: params.smsCode.trim(), - }, - method: 'POST', - }) -} - -/** - * 注册 - * @param {*} params - * @returns - */ -export function apiRegister(params) { - return request({ - url: '/user-boot/appUser/register', - data: { - phone: params.phone, - devCode: uni.getStorageSync('devCode'), - code: params.code.trim(), - }, - method: 'POST', - }) -} - -/** - * app用户注册完自动登录 - * @param params - * @returns {*} - */ -export function autoLogin(phone) { - return request({ - url: '/pqs-auth/oauth/autoLogin', - data: { - phone: phone, - }, - method: 'POST', - }) -} - -// 第一次登录设置密码 -export function apiSetPsd(params) { - return request({ - url: '/shiningCloud/user/setPsd', - data: { - userId: uni.getStorageSync('userInfo').userIndex, - devCode: uni.getStorageSync('devCode'), - password: params.password.trim(), - }, - method: 'POST', - }) -} - -// 重置密码 -export function apiReSetPsd(params) { - return request({ - url: '/user-boot/appUser/resetPsd', - data: { - phone: params.phone, - code: params.code.trim(), - devCode: uni.getStorageSync('devCode'), - password: params.password.trim(), - }, - method: 'POST', - }) -} - -// 更换手机号第一步 -export function apiComfirmCode(params) { - return request({ - url: '/user-boot/appUser/confirmCode', - data: { - devCode: uni.getStorageSync('devCode'), - phone: params.phone, - code: params.code.trim(), - }, - method: 'POST', - }) -} - -// 重新绑定手机号 -export function apiRebindPhone(params) { - return request({ - url: '/user-boot/appUser/rebindPhone', - data: { - devCode: uni.getStorageSync('devCode'), - userId: uni.getStorageSync('userInfo').userIndex, - phoneNew: params.phone, - code: params.code.trim(), - }, - method: 'POST', - }) -} - -// 角色升级 -export function roleUpdate({ userId, referralCode }) { - return request({ - url: '/user-boot/appRole/roleUpdate', - method: 'post', - data: { - devCode: uni.getStorageSync('devCode'), - referralCode, - userId, - }, - }) -} - -// 密码登录 -export function apiPwdLogin(params) { - return request({ - url: '/pqs-auth/oauth/token', - header: { - Authorization: 'Basic bmpjbnRlc3Q6bmpjbnBxcw==', // 客户端信息加密摘要认证 - }, - params, - method: 'POST', - }) -} - -//登录获取公钥 -export function gongkey(data) { - console.log(data) - return request({ - url: '/user-boot/user/generateSm2Key', - method: 'get', - data: data, - }) -} - -// 修改手机号 -export function apiModifyPsd(params) { - return request({ - url: '/user-boot/appUser/modifyPsd', - data: { - devCode: uni.getStorageSync('devCode'), - userId: uni.getStorageSync('userInfo').userIndex, - phone: params.phone, - password: params.password.trim(), - code: params.code.trim(), - }, - method: 'POST', - }) -} - -// 更改用户信息 -export function apiUpdateUser(params) { - return request({ - url: '/user-boot/user/updateAppUser', - data: { - ...params, - }, - header: { - 'Content-Type': 'application/json', - }, - method: 'PUT', - }) -} -// 更改用户信息 -export function apiDeleteUser(params) { - return request({ - url: '/user-boot/user/delete', - data: { - id: uni.getStorageSync('userInfo').userIndex, - }, - method: 'DELETE', - }) -} - -// 更新用户推送标识 - -export function apiUpdatePush(params) { - uni.getPushClientId({ - success: (res) => { - console.log('🚀 ~ apiUpdatePush111 ~ res:', res) - let push_clientid = res.cid - console.log(push_clientid, 'push_clientid') - request({ - url: '/user-boot/appUser/updateDevCode', - data: { - devCode: push_clientid, - userId: uni.getStorageSync('userInfo').userIndex, - }, - method: 'POST', - }) - }, - fail(err) { - console.log('🚀 ~ apiUpdatePush222 ~ res:', err) - }, - }) -} +import request from '../js/request' + +/** + * 发送验证码 + * @param {*} params.type 0:登录 1:注册 2:修改密码 6:忘记密码 4:更换手机号第二步获取验证码 5:更换手机号第一步获取验证码 + * @returns + */ +export function apiGetYms(params) { + return request({ + url: '/user-boot/appUser/authCode', + data: { + phone: params.phone, + devCode: uni.getStorageSync('devCode'), + type: params.type, + }, + method: 'POST', + }) +} + +/** + * 登录 + * @param {*} params.type 0:ysm 1:pwd + * @returns + */ +export function apiLogin(params) { + console.log(uni.getStorageSync('devCode')) + return request({ + url: '/shiningCloud/user/login', + data: { + phone: params.phone, + devCode: uni.getStorageSync('devCode'), + key: params.key.trim(), + type: params.type, + }, + method: 'POST', + }) +} + +/** + * 验证码登录 + * @param {*} params.type 0:ysm 1:pwd + * @returns + */ +export function apiYsmLogin(params) { + uni.setStorageSync('access_token', 'Basic bmpjbmFwcDpuamNucHFz') + return request({ + url: '/pqs-auth/oauth/token', + data: { + grant_type: 'sms_code', + phone: params.phone, + smsCode: params.smsCode.trim(), + }, + method: 'POST', + }) +} + +/** + * 注册 + * @param {*} params + * @returns + */ +export function apiRegister(params) { + return request({ + url: '/user-boot/appUser/register', + data: { + phone: params.phone, + devCode: uni.getStorageSync('devCode'), + code: params.code.trim(), + }, + method: 'POST', + }) +} + +/** + * app用户注册完自动登录 + * @param params + * @returns {*} + */ +export function autoLogin(phone) { + return request({ + url: '/pqs-auth/oauth/autoLogin', + data: { + phone: phone, + }, + method: 'POST', + }) +} + +// 第一次登录设置密码 +export function apiSetPsd(params) { + return request({ + url: '/shiningCloud/user/setPsd', + data: { + userId: uni.getStorageSync('userInfo').userIndex, + devCode: uni.getStorageSync('devCode'), + password: params.password.trim(), + }, + method: 'POST', + }) +} + +// 重置密码 +export function apiReSetPsd(params) { + return request({ + url: '/user-boot/appUser/resetPsd', + data: { + phone: params.phone, + code: params.code.trim(), + devCode: uni.getStorageSync('devCode'), + password: params.password.trim(), + }, + method: 'POST', + }) +} + +// 更换手机号第一步 +export function apiComfirmCode(params) { + return request({ + url: '/user-boot/appUser/confirmCode', + data: { + devCode: uni.getStorageSync('devCode'), + phone: params.phone, + code: params.code.trim(), + }, + method: 'POST', + }) +} + +// 重新绑定手机号 +export function apiRebindPhone(params) { + return request({ + url: '/user-boot/appUser/rebindPhone', + data: { + devCode: uni.getStorageSync('devCode'), + userId: uni.getStorageSync('userInfo').userIndex, + phoneNew: params.phone, + code: params.code.trim(), + }, + method: 'POST', + }) +} + +// 角色升级 +export function roleUpdate({ userId, referralCode }) { + return request({ + url: '/user-boot/appRole/roleUpdate', + method: 'post', + data: { + devCode: uni.getStorageSync('devCode'), + referralCode, + userId, + }, + }) +} + +// 密码登录 +export function apiPwdLogin(params) { + return request({ + url: '/pqs-auth/oauth/token', + header: { + Authorization: 'Basic bmpjbnRlc3Q6bmpjbnBxcw==', // 客户端信息加密摘要认证 + }, + params, + method: 'POST', + }) +} + +//登录获取公钥 +export function gongkey(data) { + console.log(data) + return request({ + url: '/user-boot/user/generateSm2Key', + method: 'get', + data: data, + }) +} + +// 修改手机号 +export function apiModifyPsd(params) { + return request({ + url: '/user-boot/appUser/modifyPsd', + data: { + devCode: uni.getStorageSync('devCode'), + userId: uni.getStorageSync('userInfo').userIndex, + phone: params.phone, + password: params.password.trim(), + code: params.code.trim(), + }, + method: 'POST', + }) +} + +// 更改用户信息 +export function apiUpdateUser(params) { + return request({ + url: '/user-boot/user/updateAppUser', + data: { + ...params, + }, + header: { + 'Content-Type': 'application/json', + }, + method: 'PUT', + }) +} +// 更改用户信息 +export function apiDeleteUser(params) { + return request({ + url: '/user-boot/user/delete', + data: { + id: uni.getStorageSync('userInfo').userIndex, + }, + method: 'DELETE', + }) +} + +// 更新用户推送标识 + +export function apiUpdatePush(params) { + uni.getPushClientId({ + success: (res) => { + console.log('🚀 ~ apiUpdatePush111 ~ res:', res) + let push_clientid = res.cid + console.log(push_clientid, 'push_clientid') + request({ + url: '/user-boot/appUser/updateDevCode', + data: { + devCode: push_clientid, + userId: uni.getStorageSync('userInfo').userIndex, + }, + method: 'POST', + }) + }, + fail(err) { + console.log('🚀 ~ apiUpdatePush222 ~ res:', err) + }, + }) +} +// 获取当前版本号 +export function getLastData() { + return request({ + url: '/cs-system-boot/appVersion/getLastData?versionType=APP', + method: 'POST', + }) +} \ No newline at end of file diff --git a/common/css/base.scss b/common/css/base.scss index 5a3bc3d..7d6215c 100644 --- a/common/css/base.scss +++ b/common/css/base.scss @@ -292,6 +292,20 @@ image { font-size: 30rpx; } .boxClick:active { - transform: scale(0.94); - opacity: 0.8; + // transform: scale(0.94); + // opacity: 0.8; + animation: elastic-bounce 0.5s; +} +@keyframes elastic-bounce { + 0% { + transform: scale(1); + } + + 50% { + transform: scale(0.96); + } + + 100% { + transform: scale(1); + } } diff --git a/common/js/request.js b/common/js/request.js index 6d2766f..286df41 100644 --- a/common/js/request.js +++ b/common/js/request.js @@ -27,7 +27,7 @@ export default (options = {}) => { } uni.request({ url, - timeout: 1000 *30, + timeout: 1000 * 60, data: { ...options.data, }, diff --git a/common/js/update.js b/common/js/update.js new file mode 100644 index 0000000..93c20cc --- /dev/null +++ b/common/js/update.js @@ -0,0 +1,227 @@ +import { getLastData } from '../api/user.js' + +export const checkAppUpdate = () => { + // 开发环境跳过检查 + const isDev = process.env.NODE_ENV === 'development' + // if (isDev) { + console.log('开发环境,不执行更新检查') + return + // } + + // 获取当前应用信息 + plus.runtime.getProperty(plus.runtime.appid, (info) => { + const currentVersion = info.version + + getLastData() + .then((res) => { + + // let res = { + // data: { + // versionName: 'v1.6.83', + // forceUpdate: '1', + // androidPath: 'https://app.liuyingyong.cn/build/download/3c26e400-3a33-11f1-8997-a16e76fa35b3', + // // androidPath: 'http://112.4.144.18:8040/shiningCloud/file/canneng_wulian.apk', + // iosPath: 'xxxx', + // }, + // } + if (!res?.data) { + console.log('未获取到版本信息') + return + } + + // 适配新的接口返回格式 + const { versionName, androidPath, iosPath, forceUpdate = '1' } = res.data + + // 版本相同则不需要更新 + if (versionName.includes(currentVersion)) { + console.log('已是最新版本') + return + } + + const isForce = forceUpdate === '1' // 字符串 '1' 表示强制更新 + + const iosUrl = iosPath + + handleUpdate({ version: versionName, androidPath, iosUrl, isForce }) + }) + .catch((err) => { + console.error('获取版本接口失败', err) + }) + }) +} + +/** + * 处理更新逻辑 + */ +const handleUpdate = ({ version, androidPath, iosUrl, isForce }) => { + const isAndroid = plus.os.name === 'Android' + const isIOS = plus.os.name === 'iOS' + + if (isAndroid) { + handleAndroidUpdate({ androidPath, isForce }) + } else if (isIOS) { + handleIOSUpdate({ iosUrl, isForce }) + } else { + console.warn('未知操作系统') + } +} + +/** + * 处理安卓更新 + */ +const handleAndroidUpdate = ({ androidPath, isForce }) => { + if (!androidPath?.length) { + console.error('未找到安卓安装包') + uni.showToast({ + title: '更新包不存在', + icon: 'error', + }) + return + } + + const downloadUrl = androidPath + + uni.showModal({ + title: '更新提示', + content: '发现新版本,是否立即更新?', + showCancel: !isForce, // 强制更新隐藏取消按钮 + confirmText: '去更新', + cancelText: '暂不更新', + success: (modalRes) => { + if (modalRes.confirm) { + downloadAndInstallApk(downloadUrl) + } else if (isForce) { + // 强制更新且用户取消,退出应用 + plus.runtime.quit() + } + }, + }) +} + +/** + * 处理iOS更新 + */ +const handleIOSUpdate = ({ iosUrl, isForce }) => { + if (!iosUrl) { + console.error('未找到iOS下载链接') + uni.showToast({ + title: '更新链接不存在', + icon: 'error', + }) + return + } + + uni.showModal({ + title: '更新提示', + content: '发现新版本,请前往 App Store 更新', + showCancel: !isForce, + confirmText: '去更新', + cancelText: '暂不更新', + success: (modalRes) => { + if (modalRes.confirm) { + plus.runtime.openURL(iosUrl) + } + + // 强制更新时,无论确认还是取消都退出应用 + if (isForce) { + setTimeout(() => { + plus.runtime.quit() + }, 300) // 给跳转留一点时间 + } + }, + }) +} + +/** + * 下载并安装APK(安卓专用) + */ +const downloadAndInstallApk = (url) => { + // 显示原生进度条 + let progressWaiting = plus.nativeUI.showWaiting('正在下载中,请稍等...', { + modal: true, + round: true, + close: false, // 不允许用户关闭 + padlock: true, // 锁定屏幕 + }) + + const options = { + filename: '_doc/update/canneng_wulian.apk', + timeout: 120, + } + + const downloadTask = plus.downloader.createDownload(url, options, (downloadedFile, status) => { + progressWaiting.close() + + if (status === 200) { + installApk(downloadedFile.filename, url) + } else { + handleDownloadError(url) + } + }) + + // // 更新进度 + downloadTask.addEventListener('statechanged', (task) => { + if (task.state === 3 && task.totalSize > 0) { + const percent = ((task.downloadedSize / task.totalSize) * 100).toFixed(0) + console.log("🚀 ~ downloadAndInstallApk ~ percent:", percent) + // 直接更新 waiting 的标题,不会闪烁 + progressWaiting.setTitle(`正在下载更新 ${percent}%`) + } + }) + + downloadTask.start() +} + +/** + * 安装APK + */ +const installApk = (filePath, downloadUrl) => { + console.log('🚀 ~ installApk ~ filePath:', filePath) + plus.runtime.install( + filePath, + { force: true }, + () => { + // 安装成功 + uni.showModal({ + title: '安装成功', + content: '是否立即重启应用?', + showCancel: false, + confirmText: '立即重启', + success: () => { + plus.runtime.restart() + }, + }) + }, + (error) => { + console.error('安装失败', error) + uni.showModal({ + title: '安装失败', + content: `安装失败:${error.message}\n请检查是否已开启安装权限`, + confirmText: '重试', + cancelText: '取消', + success: (res) => { + if (res.confirm) { + downloadAndInstallApk(downloadUrl) + } + }, + }) + }, + ) +} + +/** + * 处理下载错误 + */ +const handleDownloadError = (downloadUrl) => { + uni.showModal({ + title: '下载失败', + content: '网络异常或下载链接失效,是否重试?', + confirmText: '重试', + cancelText: '取消', + success: (res) => { + if (res.confirm) { + downloadAndInstallApk(downloadUrl) + } + }, + }) +} diff --git a/components/Cn-device-card/Cn-device-card.vue b/components/Cn-device-card/Cn-device-card.vue index ac77081..47c00e1 100644 --- a/components/Cn-device-card/Cn-device-card.vue +++ b/components/Cn-device-card/Cn-device-card.vue @@ -233,12 +233,14 @@ export default { color: #909399; } .zl-tag { + // background-color: #007aff20; + // color: #007aff; background-color: #007aff20; color: #007aff; } .jc-tag { - background-color: #3498db20; - color: #3498db; + background-color: #007aff20; + color: #007aff; } .pinToTop { background-color: $uni-theme-color; diff --git a/components/Cn-filterCriteria/Cn-filterCriteria.vue b/components/Cn-filterCriteria/Cn-filterCriteria.vue index 12d7eb8..9198fe3 100644 --- a/components/Cn-filterCriteria/Cn-filterCriteria.vue +++ b/components/Cn-filterCriteria/Cn-filterCriteria.vue @@ -1,13 +1,15 @@