From 69608b92d7f7c9c3ee12447be11bafcb0e081f69 Mon Sep 17 00:00:00 2001 From: xuan <1359774872@qq.com> Date: Wed, 4 Nov 2026 15:45:47 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=BB=98=E8=AE=A4=E5=AF=86=E7=A0=81?= =?UTF-8?q?=E6=8F=90=E7=A4=BA=E6=94=B9=E5=AF=86=E5=B9=B6=E5=90=8C=E6=AD=A5?= =?UTF-8?q?latest=E5=8C=85=EF=BC=8C=E5=8D=87=E8=87=B31.1.17?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +- scripts/upload-apk.js | 62 ++++++++++++++++++++++--------- src/manifest.json | 4 +- src/pages/sys/login/index.vue | 46 ++++++++++++++++------- src/pages/sys/workbench/index.vue | 9 ++++- 5 files changed, 89 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index 7139aec..78381f9 100644 --- a/README.md +++ b/README.md @@ -130,8 +130,9 @@ node scripts/upload-apk.js --file D:\path\你的.apk --target test | `--mode` | 默认 `zhoushang`。可选 `zhoushang`、`zhisheng`、`mes`、`cjt` | | `--version` | 可选。不传则用 `src/manifest.json` 的 `versionName` | -场景值取对应 `.env.{mode}` 里的 `VUE_APP_UPGRADE_NAME`。保存路径为 `/version/{场景值}/{版本号}.apk`。本分支默认场景是 `.env.zhoushang` 的 `erp_pda_zhoushang`,上传成功后会打印完整下载地址,例如: +场景值取对应 `.env.{mode}` 里的 `VUE_APP_UPGRADE_NAME`。保存路径为 `/version/{场景值}/{版本号}.apk`。版本包上传成功后,同一份安装包会再传到 `/version/{场景值}/latest.apk`。本分支默认场景是 `.env.zhoushang` 的 `erp_pda_zhoushang`,上传成功后会打印完整下载地址,例如: ``` https://testhcscm.cdn.zzfzyc.com/version/erp_pda_zhoushang/1.1.9.apk +https://testhcscm.cdn.zzfzyc.com/version/erp_pda_zhoushang/latest.apk ``` diff --git a/scripts/upload-apk.js b/scripts/upload-apk.js index b5afc47..c10a4bf 100644 --- a/scripts/upload-apk.js +++ b/scripts/upload-apk.js @@ -13,6 +13,7 @@ * * 版本号取 src/manifest.json 的 versionName。 * 场景值取对应 .env 的 VUE_APP_UPGRADE_NAME,拼成 /version/{upgradeName}/{version}.apk。 + * 版本包上传成功后,再把同一份安装包上传为 /version/{upgradeName}/latest.apk。 * 运行时输入 ERP 手机号和密码获取 token。多个账套时再选择一次。 */ const fs = require('fs'); @@ -217,6 +218,35 @@ async function uploadToUpyun({ bucket, authorization, policy, filePath, fileName return body; } +function toPublicUrl(target, saveKey, uploaded) { + if (uploaded.url && String(uploaded.url).startsWith('http')) return uploaded.url; + return `${CDN_HOST[target]}${saveKey}`; +} + +async function uploadApkFile({ apiBase, token, apkPath, saveKey, fileName, status }) { + console.log(`场景路径: ${saveKey}`); + console.log('正在获取签名...'); + const sign = await getCdnSign({ + apiBase, + token, + saveKey, + status, + }); + if (!sign.bucket || !sign.authorization || !sign.policy) { + throw new Error('签名返回缺少 bucket、authorization 或 policy'); + } + console.log(`正在上传 ${fileName}...`); + const uploaded = await uploadToUpyun({ + bucket: sign.bucket, + authorization: sign.authorization, + policy: sign.policy, + filePath: apkPath, + fileName, + }); + console.log('上传成功'); + return uploaded; +} + async function main() { const args = parseArgs(process.argv.slice(2)); if (!args.file || !args.target) { @@ -253,6 +283,8 @@ async function main() { const status = args.target === 'prod' ? 2 : 1; const fileName = `${version}.apk`; const saveKey = `/version/${upgradeName}/${fileName}`; + const latestFileName = 'latest.apk'; + const latestSaveKey = `/version/${upgradeName}/${latestFileName}`; const apiBase = API_BASE; const token = await login(apiBase, { phone: args.phone, @@ -261,33 +293,27 @@ async function main() { }); console.log(`版本号: ${version}`); - console.log(`场景路径: ${saveKey}`); const cdnLabel = args.target === 'prod' ? '正式 CDN' : '测试 CDN'; console.log(`CDN: ${cdnLabel}(只影响下载地址,生产环境也可以从测试 CDN 安装)`); - console.log('正在获取签名...'); - const sign = await getCdnSign({ + const uploaded = await uploadApkFile({ apiBase, token, + apkPath, saveKey, + fileName, status, }); - if (!sign.bucket || !sign.authorization || !sign.policy) { - throw new Error('签名返回缺少 bucket、authorization 或 policy'); - } + console.log(toPublicUrl(args.target, saveKey, uploaded)); - console.log('正在上传 APK...'); - const uploaded = await uploadToUpyun({ - bucket: sign.bucket, - authorization: sign.authorization, - policy: sign.policy, - filePath: apkPath, - fileName, + const latestUploaded = await uploadApkFile({ + apiBase, + token, + apkPath, + saveKey: latestSaveKey, + fileName: latestFileName, + status, }); - console.log('上传成功'); - const pathUrl = uploaded.url && String(uploaded.url).startsWith('http') - ? uploaded.url - : `${CDN_HOST[args.target]}${saveKey}`; - console.log(pathUrl); + console.log(toPublicUrl(args.target, latestSaveKey, latestUploaded)); } main().catch((error) => { diff --git a/src/manifest.json b/src/manifest.json index 97471cd..f44d8a4 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -2,8 +2,8 @@ "name" : "浩拓ERP", "appid" : "__UNI__F79F300", "description" : "浩拓ERP", - "versionName" : "1.1.16", - "versionCode" : 116, + "versionName" : "1.1.17", + "versionCode" : 117, "transformPx" : false, "app-plus" : { "optimization" : { diff --git a/src/pages/sys/login/index.vue b/src/pages/sys/login/index.vue index 62f36d0..f00ad4d 100644 --- a/src/pages/sys/login/index.vue +++ b/src/pages/sys/login/index.vue @@ -304,6 +304,16 @@ export default { } }); }, + isDefaultPassword(loginData) { + const value = loginData && loginData.is_default_password; + return value === true || value === 1 || value === '1' || value === 'true'; + }, + enterWorkbench(openPasswordPage) { + const url = openPasswordPage + ? '/pages/sys/workbench/index?changePassword=1' + : '/pages/sys/workbench/index'; + uni.reLaunch({ url }); + }, submit(loginType = '1') { uni.showLoading({ title: '登录中...' @@ -363,31 +373,41 @@ export default { console.log('自动匹配扫码设置失败', scanError); } - setTimeout(() => { - uni.reLaunch({ - url: '/pages/sys/workbench/index' - }); - }, 500); - - var that = this - if (that.remember == true) { + if (this.remember == true) { if ((this.login.username.length > 0) && (this.login.password.length > 0)) { uni.setStorage({ key: 'UserInfo', - data: that.login + data: this.login }) } + } + this.$store.dispatch('initNotification'); + uni.hideLoading(); + + if (this.isDefaultPassword(aLoginUserData)) { + uni.showModal({ + title: '提示', + content: '当前使用的是默认密码,请及时修改密码', + confirmText: '去修改', + cancelText: '稍后', + success: (modalRes) => { + this.enterWorkbench(!!(modalRes && modalRes.confirm)); + }, + fail: () => { + this.enterWorkbench(false); + } + }); + return; } uni.showToast({ icon: 'none', title: '登录成功!' }); - this.$store.dispatch('initNotification'); - setTimeout(function () { - uni.hideLoading(); - }, 1000); + setTimeout(() => { + this.enterWorkbench(false); + }, 500); }).catch((error) => { console.log('login error', error) uni.showToast({ diff --git a/src/pages/sys/workbench/index.vue b/src/pages/sys/workbench/index.vue index d901a91..5823642 100644 --- a/src/pages/sys/workbench/index.vue +++ b/src/pages/sys/workbench/index.vue @@ -124,8 +124,15 @@ export default { }; }, - onLoad() { + onLoad(options) { this.registerScanBroadcast(this.handleScanCode); + if (options && String(options.changePassword) === '1') { + setTimeout(() => { + uni.navigateTo({ + url: '/pages/sys/user/pwd' + }); + }, 300); + } }, // onUnload, onHide, onShow 已由 scanMixin 自动处理