diff --git a/src/common/scanConfig.js b/src/common/scanConfig.js index 619a439..9a23799 100644 --- a/src/common/scanConfig.js +++ b/src/common/scanConfig.js @@ -16,16 +16,17 @@ export const PHONE_SCAN_CONFIG = { /** 内置扫码配置:补 needSetup,并在字典拉不到时兜底 */ export const BUILTIN_SCANNER_CONFIGS = [ { - brand: 'newland', - name: '东大集成', + brand: 'seuic', + name: '东大集成(AUTOID)', action: 'com.android.server.scannerservice.broadcast', dataKey: 'scannerdata', needSetup: true, setupAction: 'com.android.scanner.service_settings', setupParams: { + barcode_send_mode: 'BROADCAST', action_barcode_broadcast: 'com.android.server.scannerservice.broadcast', key_barcode_broadcast: 'scannerdata', - endchar: 'ENTER', + endchar: 'NONE', }, }, { @@ -35,13 +36,6 @@ export const BUILTIN_SCANNER_CONFIGS = [ dataKey: 'data', needSetup: false, }, - { - brand: 'nlscan', - name: '新大陆', - action: 'nlscan.action.SCANNER_RESULT', - dataKey: 'SCAN_BARCODE1', - needSetup: false, - }, { brand: 'urovo', name: '优博讯', @@ -50,17 +44,10 @@ export const BUILTIN_SCANNER_CONFIGS = [ needSetup: false, }, { - brand: 'idata', - name: '盈达', - action: 'android.intent.action.SCANRESULT', - dataKey: 'value', - needSetup: false, - }, - { - brand: 'iData', - name: '海雅达', - action: 'com.android.scanner.broadcast', - dataKey: 'scandata', + brand: 'nlscan', + name: '新大陆', + action: 'nlscan.action.SCANNER_RESULT', + dataKey: 'SCAN_BARCODE1', needSetup: false, }, { ...PHONE_SCAN_CONFIG }, @@ -83,31 +70,32 @@ const DETECT_RULES = [ { matchNames: ['优博讯'], matchActions: ['android.intent.ACTION_DECODE_DATA'], - keywords: ['urovo'], + keywords: ['urovo', 'ubx'], packages: ['com.urovo', 'com.ubx'], }, { matchNames: ['盈达'], matchActions: ['android.intent.action.SCANRESULT'], keywords: ['idata', 'yingda'], - packages: ['com.idata', 'com.android.scanner'], + packages: ['com.idata'], }, { matchNames: ['海雅达'], matchActions: ['com.android.scanner.broadcast'], - keywords: ['iData', 'seui', 'haiyada'], - packages: ['com.android.scanner'], + keywords: ['haiyada'], + packages: [], }, { - matchNames: ['东大集成', '东集'], + matchNames: ['东大集成(AUTOID)', '东大集成', '东集'], matchActions: ['com.android.server.scannerservice.broadcast'], - keywords: ['seuic', 'eastcom', 'newland', 'nls'], - packages: ['com.android.scanner', 'com.seuic.scanner'], + keywords: ['seuic', 'autoid', 'eastcom', '东集', '东大'], + packages: ['com.seuic.scanner'], }, ]; const PDA_DEVICE_KEYWORDS = [ - 'newland', 'nls', 'sunmi', 'urovo', 'honeywell', 'idata', 'seuic', 'zebra', 'ubx', + 'newland', 'nls', 'nlscan', 'sunmi', 'urovo', 'ubx', 'zebra', 'honeywell', + 'idata', 'seuic', 'autoid', '东集', '东大', ]; const NO_SETUP_HINT_KEY = 'pda_scan_config_hint_shown'; @@ -161,13 +149,13 @@ function enrichFromBuiltinConfig(config, builtinConfigs = []) { return { ...config, - needSetup: config.needSetup != null ? config.needSetup : builtin.needSetup, - setupAction: config.setupAction || builtin.setupAction || '', - setupParams: config.setupParams || builtin.setupParams || null, + needSetup: builtin.needSetup, + setupAction: builtin.setupAction || '', + setupParams: builtin.setupParams || null, }; } -export function normalizeConfig(raw, builtinConfigs = BUILTIN_SCANNER_CONFIGS) { +export function normalizeConfig(raw, builtinConfigs = []) { if (!raw || typeof raw !== 'object') return null; const brand = String(raw.brand || raw.id || raw.dictionary_detail_id || raw.name || ''); @@ -197,11 +185,11 @@ export function normalizeConfig(raw, builtinConfigs = BUILTIN_SCANNER_CONFIGS) { return config; } -export function mapDictionaryToScannerConfig(raw, builtinConfigs = BUILTIN_SCANNER_CONFIGS) { +export function mapDictionaryToScannerConfig(raw, builtinConfigs = []) { return normalizeConfig(raw, builtinConfigs); } -export function getScanConfig(builtinConfigs = BUILTIN_SCANNER_CONFIGS) { +export function getScanConfig(builtinConfigs = []) { try { const data = uni.getStorageSync(STORAGE_KEY); const normalized = normalizeConfig(data, builtinConfigs); @@ -220,10 +208,6 @@ export function getScanConfig(builtinConfigs = BUILTIN_SCANNER_CONFIGS) { } } -export function hasLocalScanConfig(builtinConfigs = BUILTIN_SCANNER_CONFIGS) { - return !!getScanConfig(builtinConfigs); -} - export function saveScanConfig(config) { const normalized = normalizeConfig(config); if (!normalized) { @@ -262,7 +246,7 @@ export function mergeScannerConfigs(remoteConfigs = []) { } }); (remoteConfigs || []).forEach((raw) => { - const normalized = mapDictionaryToScannerConfig(raw); + const normalized = mapDictionaryToScannerConfig(raw, BUILTIN_SCANNER_CONFIGS); if (!normalized || isPhoneScanConfig(normalized)) return; configMap.set(normalized.action || normalized.brand, normalized); }); @@ -290,7 +274,7 @@ export function getDeviceIdentity() { export function isPdaDevice() { const identity = getDeviceIdentity(); const text = `${identity.manufacturer} ${identity.model} ${identity.brand}`; - return PDA_DEVICE_KEYWORDS.some((keyword) => text.includes(keyword.toLowerCase())); + return PDA_DEVICE_KEYWORDS.some((keyword) => text.includes(String(keyword).toLowerCase())); } function findDetectRule(config) { @@ -365,7 +349,7 @@ function scoreScannerConfig(config, identity) { */ export function matchBestScanConfig(candidateConfigs = []) { const configs = (candidateConfigs || []) - .map((item) => normalizeConfig(item)) + .map((item) => normalizeConfig(item, BUILTIN_SCANNER_CONFIGS)) .filter(Boolean); const pdaConfigs = configs.filter((item) => !isPhoneScanConfig(item)); const identity = getDeviceIdentity(); @@ -396,7 +380,7 @@ export function matchBestScanConfig(candidateConfigs = []) { * @returns {{ saved: boolean, config: object|null, skipped: boolean, reason?: string }} */ export function autoConfigureScanSettings({ remoteConfigs = [] } = {}) { - const existing = getScanConfig(); + const existing = getScanConfig(BUILTIN_SCANNER_CONFIGS); if (existing) { return { saved: false, diff --git a/src/common/scanMixin.js b/src/common/scanMixin.js index f94dd0e..1dc2597 100644 --- a/src/common/scanMixin.js +++ b/src/common/scanMixin.js @@ -25,7 +25,7 @@ export default { methods: { getScannerConfigs() { - return BUILTIN_SCANNER_CONFIGS.map((item) => ({ ...item })); + return BUILTIN_SCANNER_CONFIGS; }, getPhoneScanConfig() { diff --git a/src/components/storefabric/SearchSelectPopup.vue b/src/components/storefabric/SearchSelectPopup.vue index 93d6a0e..a182685 100644 --- a/src/components/storefabric/SearchSelectPopup.vue +++ b/src/components/storefabric/SearchSelectPopup.vue @@ -19,9 +19,16 @@ v-for="item in filteredList" :key="String(item.value)" class="search-select__item" - @click="confirm(item)" - >{{ item.label }} + :class="{ 'is-selected': multiple && isPicked(item) }" + @click="onItemClick(item)" + > + {{ item.label }} + 已选 + + + 确定 + @@ -33,12 +40,15 @@ export default { title: { type: String, default: '请选择' }, placeholder: { type: String, default: '请输入名称搜索' }, list: { type: Array, default: () => [] }, + multiple: { type: Boolean, default: false }, + selected: { type: Array, default: () => [] }, }, data() { return { keyword: '', panelMaxHeight: 520, listHeight: 360, + picked: [], }; }, computed: { @@ -56,6 +66,7 @@ export default { show(val) { if (val) { this.keyword = ''; + this.picked = (this.selected || []).map((item) => String(item)); this.calcHeight(); } }, @@ -70,16 +81,37 @@ export default { const winH = sys.windowHeight || 600; // 弹层约占屏高 65%,列表为弹层去掉标题+搜索后的剩余高度 this.panelMaxHeight = Math.floor(winH * 0.65); - this.listHeight = Math.max(220, this.panelMaxHeight - 140); + const chrome = this.multiple ? 230 : 140; + this.listHeight = Math.max(220, this.panelMaxHeight - chrome); } catch (e) { this.panelMaxHeight = 520; - this.listHeight = 360; + this.listHeight = this.multiple ? 280 : 360; } }, + isPicked(item) { + return this.picked.includes(String(item.value)); + }, + onItemClick(item) { + if (!this.multiple) { + this.confirm(item); + return; + } + const key = String(item.value); + if (this.picked.includes(key)) { + this.picked = this.picked.filter((value) => value !== key); + return; + } + this.picked = this.picked.concat(key); + }, confirm(item) { this.visible = false; this.$emit('confirm', item); }, + confirmMultiple() { + const selected = (this.list || []).filter((item) => this.isPicked(item)); + this.visible = false; + this.$emit('confirm', selected); + }, }, }; @@ -126,9 +158,42 @@ export default { font-size: $pda-font-popup-sub; } .search-select__item { - padding: 32rpx 30rpx; + display: flex; + align-items: center; + justify-content: space-between; + min-height: $pda-row-min-height; + padding: 20rpx 30rpx; + box-sizing: border-box; font-size: $pda-font-popup-item; color: #202328; border-bottom: 1px solid #f2f2f2; } +.search-select__item-label { + flex: 1; + min-width: 0; + font-size: $pda-font-popup-item; + color: #202328; +} +.search-select__item.is-selected .search-select__item-label { + color: #2f78e6; +} +.search-select__check { + flex-shrink: 0; + margin-left: 16rpx; + font-size: $pda-font-action; + color: #2f78e6; +} +.search-select__footer { + flex-shrink: 0; + padding: 16rpx 30rpx 8rpx; +} +.search-select__ok { + height: $pda-button-height; + line-height: $pda-button-height; + text-align: center; + font-size: $pda-font-button; + color: #fff; + background: #2979ff; + border-radius: 46rpx; +} diff --git a/src/manifest.json b/src/manifest.json index 1d4b848..a20d8a9 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -2,8 +2,8 @@ "name" : "浩拓织厂", "appid" : "__UNI__F79F300", "description" : "周尚-浩拓织厂", - "versionName" : "1.1.19", - "versionCode" : 119, + "versionName" : "1.1.20", + "versionCode" : 120, "transformPx" : false, "app-plus" : { "optimization" : { diff --git a/src/pages/common/aidex.scss b/src/pages/common/aidex.scss index 056a364..776ae3e 100644 --- a/src/pages/common/aidex.scss +++ b/src/pages/common/aidex.scss @@ -58,11 +58,10 @@ } .u-cell_title { - flex: 1; - min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; + min-width: 655rpx; } .u-border-bottom:last-child:after { diff --git a/src/pages/storefabric/storeFabricManualIn.vue b/src/pages/storefabric/storeFabricManualIn.vue index f105baf..ac09fe8 100644 --- a/src/pages/storefabric/storeFabricManualIn.vue +++ b/src/pages/storefabric/storeFabricManualIn.vue @@ -109,6 +109,8 @@ title="选择等级" placeholder="请输入等级名称" :list="levelOptions" + multiple + :selected="detail.grey_fabric_level_id" @confirm="onLevelConfirm" /> { + nameMap[String(item.value)] = item.label; + }); + return ids.map((id) => nameMap[String(id)]).filter(Boolean).join('、'); }, }, onLoad() { @@ -272,10 +281,15 @@ export default { } this.levelPickerShow = true; }, - onLevelConfirm(item) { - if (!item) return; - this.detail.grey_fabric_level_id = [Number(item.value)]; - this.detail.grey_fabric_level_name = item.label || ''; + onLevelConfirm(items) { + const list = Array.isArray(items) ? items : (items ? [items] : []); + this.detail.grey_fabric_level_id = list + .map((item) => Number(item.value)) + .filter((item) => Number.isFinite(item)); + this.detail.grey_fabric_level_name = list + .map((item) => item.label) + .filter(Boolean) + .join('、'); }, async loadInspectorOptions() { try { @@ -338,6 +352,8 @@ export default { this.detail = { ...emptyDetail(), fabric_piece_code: code, + inspector_id: this.detail.inspector_id, + inspector_name: this.detail.inspector_name, }; this.weightKg = ''; } finally { @@ -347,6 +363,8 @@ export default { applyScanDetail(res, fallbackCode) { const data = res || {}; const levelIds = normalizeLevelIds(data.grey_fabric_level_id); + const hasIncomingInspector = data.inspector_id != null && data.inspector_id !== '' + || String(data.inspector_name || '').trim(); this.detail = { ...emptyDetail(), fabric_piece_code: data.fabric_piece_code || fallbackCode || '', @@ -356,9 +374,15 @@ export default { grey_fabric_code: data.grey_fabric_code || '', inspection_weight: formatDisplayWeightKg(data.inspection_weight) ? data.inspection_weight : null, grey_fabric_level_id: levelIds, - grey_fabric_level_name: data.grey_fabric_level_name || '', - inspector_id: data.inspector_id != null ? data.inspector_id : null, - inspector_name: data.inspector_name || '', + grey_fabric_level_name: Array.isArray(data.grey_fabric_level_name) + ? data.grey_fabric_level_name.filter(Boolean).join('、') + : (data.grey_fabric_level_name || ''), + inspector_id: hasIncomingInspector && data.inspector_id != null && data.inspector_id !== '' + ? data.inspector_id + : this.detail.inspector_id, + inspector_name: hasIncomingInspector + ? (data.inspector_name || this.detail.inspector_name || '') + : (this.detail.inspector_name || ''), }; this.weightKg = formatDisplayWeightKg(data.inspection_weight); this.scanCode = this.detail.fabric_piece_code; @@ -421,11 +445,15 @@ export default { } }, resetForNextScan() { + const inspectorId = this.detail.inspector_id; + const inspectorName = this.detail.inspector_name; this.scanCode = ''; - this.detail = emptyDetail(); + this.detail = { + ...emptyDetail(), + inspector_id: inspectorId, + inspector_name: inspectorName, + }; this.weightKg = ''; - this.warehouseBinId = null; - this.warehouseBinName = ''; this.$nextTick(() => { this.scanFocus = false; this.$nextTick(() => { @@ -525,6 +553,7 @@ export default { text-align: right; font-size: $pda-font-body; color: #202328; + word-break: break-all; } .manual-in__unit { diff --git a/src/pages/sys/login/index.vue b/src/pages/sys/login/index.vue index f50bd4a..f8415a8 100644 --- a/src/pages/sys/login/index.vue +++ b/src/pages/sys/login/index.vue @@ -126,6 +126,15 @@ import manifest from '@/manifest.json'; import { mapState } from 'vuex' import app_upgrade from '@/uni_modules/app-upgrade/js_sdk/index.js' import { ensureScanConfigAfterLogin } from '@/common/scanAutoConfig.js' + +function isDefaultPassword(data) { + if (!data || typeof data !== 'object') return false; + const value = data.is_default_password != null + ? data.is_default_password + : (data.user && data.user.is_default_password); + return value === true || value === 1 || value === '1' || value === 'true'; +} + export default { data() { return { @@ -357,12 +366,19 @@ export default { getApp().globalData.StoreNameID = aLoginUserData.default_physical_warehouse_id; getApp().globalData.StoreName = aLoginUserData.default_physical_warehouse_name; getApp().globalData.StoreTypeNo = ''; - try { await ensureScanConfigAfterLogin(this.$u.api); } catch (scanError) { console.log('自动匹配扫码设置失败', scanError); } + const workbenchUrl = isDefaultPassword(aLoginUserData) + ? '/pages/sys/workbench/index?defaultPassword=1' + : '/pages/sys/workbench/index'; + setTimeout(() => { + uni.reLaunch({ + url: workbenchUrl + }); + }, 500); var that = this if (that.remember == true) { @@ -375,40 +391,14 @@ export default { } + uni.showToast({ + icon: 'none', + title: '登录成功!' + }); this.$store.dispatch('initNotification'); setTimeout(function () { uni.hideLoading(); }, 1000); - - const goWorkbench = () => { - uni.reLaunch({ - url: '/pages/sys/workbench/index' - }); - }; - - if (aLoginUserData.is_default_password) { - uni.showModal({ - title: '提示', - content: '检测到当前为默认密码,建议修改后再使用', - confirmText: '去修改', - cancelText: '取消', - success: (modalRes) => { - if (modalRes.confirm) { - uni.reLaunch({ - url: '/pages/sys/user/pwd?from=login' - }); - } else { - goWorkbench(); - } - } - }); - } else { - uni.showToast({ - icon: 'none', - title: '登录成功!' - }); - setTimeout(goWorkbench, 500); - } }).catch((error) => { console.log('login error', error) uni.showToast({ diff --git a/src/pages/sys/user/index.vue b/src/pages/sys/user/index.vue index d79ea94..8917f9b 100644 --- a/src/pages/sys/user/index.vue +++ b/src/pages/sys/user/index.vue @@ -36,19 +36,21 @@ !--> - - - - - - - - - - - - - + + + + + + + + + + + + + + {{ appName }} @@ -144,52 +146,20 @@ export default { }; diff --git a/src/pages/sys/user/pwd.vue b/src/pages/sys/user/pwd.vue index f5bb1e7..732d9c1 100644 --- a/src/pages/sys/user/pwd.vue +++ b/src/pages/sys/user/pwd.vue @@ -30,11 +30,10 @@ import base64 from '@/common/base64.js'; export default { data() { return { - fromLogin: false, model: { oldPassword: '', newPassword: '', - confirmPassword: '' + confirmNewPassword: '' }, rules: { oldPassword: [ @@ -73,31 +72,10 @@ export default { } }; }, - onLoad(options) { - this.fromLogin = options && options.from === 'login'; - }, onReady() { this.$refs.uForm.setRules(this.rules); }, - onBackPress() { - if (this.fromLogin) { - uni.reLaunch({ - url: '/pages/sys/workbench/index' - }); - return true; - } - return false; - }, methods: { - goAfterSuccess() { - if (this.fromLogin) { - uni.reLaunch({ - url: '/pages/sys/workbench/index' - }); - return; - } - uni.navigateBack(); - }, submit() { this.$refs.uForm.validate(valid => { if (valid) { @@ -106,19 +84,12 @@ export default { newPassword: this.model.newPassword }).then(res => { if(res.code == '200'){ - const userInfo = uni.getStorageSync('UserInfo'); - if (userInfo && typeof userInfo === 'object') { - uni.setStorageSync('UserInfo', { - ...userInfo, - password: this.model.newPassword - }); - } uni.showModal({ title: '提示', content: res.msg, showCancel: false, - success: () => { - this.goAfterSuccess(); + success: function () { + uni.navigateBack(); } }); }else{ @@ -135,7 +106,7 @@ export default { }); }, cancel() { - this.goAfterSuccess(); + uni.navigateBack(); } } }; diff --git a/src/pages/sys/workbench/index.vue b/src/pages/sys/workbench/index.vue index fd0896a..b907e85 100644 --- a/src/pages/sys/workbench/index.vue +++ b/src/pages/sys/workbench/index.vue @@ -76,9 +76,12 @@ export default { }; }, - onLoad() { + onLoad(options) { const sys = uni.getSystemInfoSync(); this.statusBarHeight = sys.statusBarHeight || 20; + if (options && String(options.defaultPassword) === '1') { + this.promptChangePassword(); + } // #ifdef APP-PLUS plus.runtime.getProperty(plus.runtime.appid, (inf) => { if (inf && inf.version) { @@ -90,6 +93,20 @@ export default { }, methods: { + promptChangePassword() { + setTimeout(() => { + uni.showModal({ + title: '提示', + content: '当前使用的是默认密码,请修改密码', + confirmText: '去修改', + cancelText: '稍后', + success: (res) => { + if (!res.confirm) return; + uni.navigateTo({ url: '/pages/sys/user/pwd' }); + }, + }); + }, 400); + }, handleScanCode(scanResult) { const cleanResult = scanResult.trim().replace(/[\r\n]/g, ''); uni.navigateTo({