From 8315222788ee7ec66371414e315c9aac17333dde Mon Sep 17 00:00:00 2001
From: xuan <1359774872@qq.com>
Date: Wed, 4 Nov 2026 14:50:44 +0800
Subject: [PATCH 1/2] =?UTF-8?q?feat:=20=E8=BF=9B=E4=BB=93=E7=AD=89?=
=?UTF-8?q?=E7=BA=A7=E5=8F=AF=E5=A4=9A=E9=80=89=E5=B9=B6=E6=8F=90=E7=A4=BA?=
=?UTF-8?q?=E6=94=B9=E5=AF=86=EF=BC=8C=E5=8D=87=E8=87=B31.1.19?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../storefabric/SearchSelectPopup.vue | 75 +++++++++++++++++--
src/manifest.json | 4 +-
src/pages/storefabric/storeFabricManualIn.vue | 51 ++++++++++---
src/pages/sys/login/index.vue | 14 +++-
src/pages/sys/workbench/index.vue | 19 ++++-
5 files changed, 143 insertions(+), 20 deletions(-)
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 db0eab7..1d4b848 100644
--- a/src/manifest.json
+++ b/src/manifest.json
@@ -2,8 +2,8 @@
"name" : "浩拓织厂",
"appid" : "__UNI__F79F300",
"description" : "周尚-浩拓织厂",
- "versionName" : "1.1.18",
- "versionCode" : 118,
+ "versionName" : "1.1.19",
+ "versionCode" : 119,
"transformPx" : false,
"app-plus" : {
"optimization" : {
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 9154b79..cee5365 100644
--- a/src/pages/sys/login/index.vue
+++ b/src/pages/sys/login/index.vue
@@ -125,6 +125,15 @@ import md5 from '@/common/md5.js';
import manifest from '@/manifest.json';
import { mapState } from 'vuex'
import app_upgrade from '@/uni_modules/app-upgrade/js_sdk/index.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 {
@@ -356,9 +365,12 @@ export default {
getApp().globalData.StoreNameID = aLoginUserData.default_physical_warehouse_id;
getApp().globalData.StoreName = aLoginUserData.default_physical_warehouse_name;
getApp().globalData.StoreTypeNo = '';
+ const workbenchUrl = isDefaultPassword(aLoginUserData)
+ ? '/pages/sys/workbench/index?defaultPassword=1'
+ : '/pages/sys/workbench/index';
setTimeout(() => {
uni.reLaunch({
- url: '/pages/sys/workbench/index'
+ url: workbenchUrl
});
}, 500);
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({
From c390b9f72b2de4555b33e5bde1187de0aaed3d72 Mon Sep 17 00:00:00 2001
From: xuan <1359774872@qq.com>
Date: Wed, 4 Nov 2026 16:15:52 +0800
Subject: [PATCH 2/2] =?UTF-8?q?feat:=20=E6=97=A0=E6=89=AB=E7=A0=81?=
=?UTF-8?q?=E9=85=8D=E7=BD=AE=E6=97=B6=E8=87=AA=E5=8A=A8=E5=8C=B9=E9=85=8D?=
=?UTF-8?q?=E5=B9=B6=E5=8D=87=E8=87=B31.1.20?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/App.vue | 9 ++
src/common/scanAutoConfig.js | 43 ++++++
src/common/scanConfig.js | 257 ++++++++++++++++++++++++++++++++++
src/common/scanMixin.js | 63 +--------
src/manifest.json | 4 +-
src/pages/sys/login/index.vue | 8 +-
6 files changed, 322 insertions(+), 62 deletions(-)
create mode 100644 src/common/scanAutoConfig.js
diff --git a/src/App.vue b/src/App.vue
index 6368c2f..7807a41 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -6,6 +6,7 @@ import { audioManager } from '@/utils/audioManager'
import util from '@/common/util.js';
import md5 from '@/common/md5.js';
+ import { ensureScanConfigAfterLogin } from '@/common/scanAutoConfig.js';
export default {
globalData: {
AppName: '',
@@ -30,6 +31,14 @@ import { audioManager } from '@/utils/audioManager'
audioManager.init();
// 初始化通知系统
this.$store.dispatch('initNotification');
+
+ // 已登录且本地无扫码配置时,自动匹配一次
+ const loginData = uni.getStorageSync('RemoteTokenData');
+ if (loginData && loginData.token && this.$u && this.$u.api) {
+ ensureScanConfigAfterLogin(this.$u.api).catch((error) => {
+ console.log('启动时自动匹配扫码设置失败', error);
+ });
+ }
}
}
diff --git a/src/common/scanAutoConfig.js b/src/common/scanAutoConfig.js
new file mode 100644
index 0000000..db990c0
--- /dev/null
+++ b/src/common/scanAutoConfig.js
@@ -0,0 +1,43 @@
+/**
+ * 登录后 / 冷启动:拉取扫码字典并在本地无配置时自动匹配写入
+ */
+import {
+ DICTIONARY_TYPE_SCANNER,
+ autoConfigureScanSettings,
+} from '@/common/scanConfig.js';
+
+function extractDictionaryList(res) {
+ if (Array.isArray(res)) return res;
+ if (res && Array.isArray(res.list)) return res.list;
+ return [];
+}
+
+/**
+ * @param {object} api - this.$u.api
+ * @returns {Promise<{saved:boolean,skipped:boolean,config:object|null,reason?:string}>}
+ */
+export async function ensureScanConfigAfterLogin(api) {
+ if (!api || !api.dictionary || !api.dictionary.getDetailEnumList) {
+ return autoConfigureScanSettings({ remoteConfigs: [] });
+ }
+
+ let remoteConfigs = [];
+ try {
+ const res = await api.dictionary.getDetailEnumList({
+ dictionary_id: DICTIONARY_TYPE_SCANNER,
+ });
+ remoteConfigs = extractDictionaryList(res);
+ } catch (error) {
+ console.log('拉取扫码字典失败,改用内置配置自动匹配', error);
+ }
+
+ const result = autoConfigureScanSettings({ remoteConfigs });
+ if (result.skipped) {
+ console.log('本地已有扫码设置,跳过自动匹配', result.config && result.config.name);
+ } else if (result.saved) {
+ console.log('已自动写入扫码设置', result.config && result.config.name);
+ } else {
+ console.log('自动匹配扫码设置未写入', result.reason);
+ }
+ return result;
+}
diff --git a/src/common/scanConfig.js b/src/common/scanConfig.js
index fb3eae8..9a23799 100644
--- a/src/common/scanConfig.js
+++ b/src/common/scanConfig.js
@@ -13,6 +13,91 @@ export const PHONE_SCAN_CONFIG = {
isPhoneScan: true,
};
+/** 内置扫码配置:补 needSetup,并在字典拉不到时兜底 */
+export const BUILTIN_SCANNER_CONFIGS = [
+ {
+ 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: 'NONE',
+ },
+ },
+ {
+ brand: 'sunmi',
+ name: '商米',
+ action: 'com.sunmi.scanner.ACTION_DATA_CODE_RECEIVED',
+ dataKey: 'data',
+ needSetup: false,
+ },
+ {
+ brand: 'urovo',
+ name: '优博讯',
+ action: 'android.intent.ACTION_DECODE_DATA',
+ dataKey: 'barcode_string',
+ needSetup: false,
+ },
+ {
+ brand: 'nlscan',
+ name: '新大陆',
+ action: 'nlscan.action.SCANNER_RESULT',
+ dataKey: 'SCAN_BARCODE1',
+ needSetup: false,
+ },
+ { ...PHONE_SCAN_CONFIG },
+];
+
+/** 设备关键词 / 常见扫码相关包名,用于自动识别 */
+const DETECT_RULES = [
+ {
+ matchNames: ['商米'],
+ matchActions: ['com.sunmi.scanner.ACTION_DATA_CODE_RECEIVED'],
+ keywords: ['sunmi'],
+ packages: ['com.sunmi.scanner', 'woyou.aidlservice.jiuiv5'],
+ },
+ {
+ matchNames: ['新大陆'],
+ matchActions: ['nlscan.action.SCANNER_RESULT'],
+ keywords: ['newland', 'nls', 'nlscan'],
+ packages: ['com.nlscan.barcodescanner', 'com.newland'],
+ },
+ {
+ matchNames: ['优博讯'],
+ matchActions: ['android.intent.ACTION_DECODE_DATA'],
+ keywords: ['urovo', 'ubx'],
+ packages: ['com.urovo', 'com.ubx'],
+ },
+ {
+ matchNames: ['盈达'],
+ matchActions: ['android.intent.action.SCANRESULT'],
+ keywords: ['idata', 'yingda'],
+ packages: ['com.idata'],
+ },
+ {
+ matchNames: ['海雅达'],
+ matchActions: ['com.android.scanner.broadcast'],
+ keywords: ['haiyada'],
+ packages: [],
+ },
+ {
+ matchNames: ['东大集成(AUTOID)', '东大集成', '东集'],
+ matchActions: ['com.android.server.scannerservice.broadcast'],
+ keywords: ['seuic', 'autoid', 'eastcom', '东集', '东大'],
+ packages: ['com.seuic.scanner'],
+ },
+];
+
+const PDA_DEVICE_KEYWORDS = [
+ 'newland', 'nls', 'nlscan', 'sunmi', 'urovo', 'ubx', 'zebra', 'honeywell',
+ 'idata', 'seuic', 'autoid', '东集', '东大',
+];
+
const NO_SETUP_HINT_KEY = 'pda_scan_config_hint_shown';
export function isPhoneScanConfig(config) {
@@ -152,3 +237,175 @@ export function markNoConfigHintShown() {
console.log('记录扫码枪提示状态失败', e);
}
}
+
+export function mergeScannerConfigs(remoteConfigs = []) {
+ const configMap = new Map();
+ BUILTIN_SCANNER_CONFIGS.forEach((item) => {
+ if (!isPhoneScanConfig(item)) {
+ configMap.set(item.action || item.brand, item);
+ }
+ });
+ (remoteConfigs || []).forEach((raw) => {
+ const normalized = mapDictionaryToScannerConfig(raw, BUILTIN_SCANNER_CONFIGS);
+ if (!normalized || isPhoneScanConfig(normalized)) return;
+ configMap.set(normalized.action || normalized.brand, normalized);
+ });
+ const list = Array.from(configMap.values());
+ list.push({ ...PHONE_SCAN_CONFIG });
+ return list;
+}
+
+export function getDeviceIdentity() {
+ // #ifdef APP-PLUS
+ try {
+ const Build = plus.android.importClass('android.os.Build');
+ return {
+ manufacturer: String(Build.MANUFACTURER || '').toLowerCase(),
+ model: String(Build.MODEL || '').toLowerCase(),
+ brand: String(Build.BRAND || '').toLowerCase(),
+ };
+ } catch (e) {
+ console.log('读取设备信息失败', e);
+ }
+ // #endif
+ return { manufacturer: '', model: '', brand: '' };
+}
+
+export function isPdaDevice() {
+ const identity = getDeviceIdentity();
+ const text = `${identity.manufacturer} ${identity.model} ${identity.brand}`;
+ return PDA_DEVICE_KEYWORDS.some((keyword) => text.includes(String(keyword).toLowerCase()));
+}
+
+function findDetectRule(config) {
+ return DETECT_RULES.find((rule) => {
+ if (rule.matchNames.includes(config.name)) return true;
+ if (rule.matchActions.includes(config.action)) return true;
+ return false;
+ }) || null;
+}
+
+function isPackageInstalled(packageName) {
+ // #ifdef APP-PLUS
+ try {
+ const main = plus.android.runtimeMainActivity();
+ const pm = main.getPackageManager();
+ plus.android.importClass(pm);
+ pm.getPackageInfo(packageName, 0);
+ return true;
+ } catch (e) {
+ return false;
+ }
+ // #endif
+ return false;
+}
+
+function canResolveBroadcast(action) {
+ if (!action) return false;
+ // #ifdef APP-PLUS
+ try {
+ const main = plus.android.runtimeMainActivity();
+ const Intent = plus.android.importClass('android.content.Intent');
+ const pm = main.getPackageManager();
+ plus.android.importClass(pm);
+ const intent = new Intent(action);
+ const list = pm.queryBroadcastReceivers(intent, 0);
+ return !!(list && list.size && list.size() > 0);
+ } catch (e) {
+ console.log('探测广播接收方失败', action, e);
+ return false;
+ }
+ // #endif
+ return false;
+}
+
+function scoreScannerConfig(config, identity) {
+ if (!config || isPhoneScanConfig(config)) {
+ return 0;
+ }
+
+ let score = 0;
+ const rule = findDetectRule(config);
+ const deviceText = `${identity.manufacturer} ${identity.model} ${identity.brand}`;
+
+ if (canResolveBroadcast(config.action)) {
+ score += 100;
+ }
+
+ if (rule) {
+ if ((rule.packages || []).some((pkg) => isPackageInstalled(pkg))) {
+ score += 60;
+ }
+ if ((rule.keywords || []).some((keyword) => deviceText.includes(String(keyword).toLowerCase()))) {
+ score += 40;
+ }
+ }
+
+ return score;
+}
+
+/**
+ * 在候选配置中选出最匹配当前设备的一项;非 PDA 且无命中则回落手机扫码
+ */
+export function matchBestScanConfig(candidateConfigs = []) {
+ const configs = (candidateConfigs || [])
+ .map((item) => normalizeConfig(item, BUILTIN_SCANNER_CONFIGS))
+ .filter(Boolean);
+ const pdaConfigs = configs.filter((item) => !isPhoneScanConfig(item));
+ const identity = getDeviceIdentity();
+
+ let best = null;
+ let bestScore = 0;
+ pdaConfigs.forEach((config) => {
+ const score = scoreScannerConfig(config, identity);
+ if (score > bestScore) {
+ bestScore = score;
+ best = config;
+ }
+ });
+
+ if (best && bestScore > 0) {
+ return best;
+ }
+
+ if (!isPdaDevice()) {
+ return { ...PHONE_SCAN_CONFIG };
+ }
+
+ return pdaConfigs[0] || { ...PHONE_SCAN_CONFIG };
+}
+
+/**
+ * 仅本地没有有效配置时,自动匹配并写入扫描设置
+ * @returns {{ saved: boolean, config: object|null, skipped: boolean, reason?: string }}
+ */
+export function autoConfigureScanSettings({ remoteConfigs = [] } = {}) {
+ const existing = getScanConfig(BUILTIN_SCANNER_CONFIGS);
+ if (existing) {
+ return {
+ saved: false,
+ skipped: true,
+ config: existing,
+ reason: 'local_exists',
+ };
+ }
+
+ const candidates = mergeScannerConfigs(remoteConfigs);
+ const matched = matchBestScanConfig(candidates);
+ if (!matched) {
+ return {
+ saved: false,
+ skipped: false,
+ config: null,
+ reason: 'no_match',
+ };
+ }
+
+ const saved = saveScanConfig(matched);
+ return {
+ saved,
+ skipped: false,
+ config: matched,
+ reason: saved ? 'saved' : 'save_failed',
+ };
+}
diff --git a/src/common/scanMixin.js b/src/common/scanMixin.js
index 8e42082..1dc2597 100644
--- a/src/common/scanMixin.js
+++ b/src/common/scanMixin.js
@@ -1,19 +1,16 @@
// common/scanMixin.js
// 多厂商PDA扫码器兼容方案 - 策略模式 + 配置表驱动
import {
+ BUILTIN_SCANNER_CONFIGS,
getScanConfig,
hasShownNoConfigHint,
+ isPdaDevice as detectPdaDevice,
isPhoneScanConfig,
markNoConfigHintShown,
normalizeConfig,
PHONE_SCAN_CONFIG,
} from '@/common/scanConfig.js';
-const PDA_DEVICE_KEYWORDS = [
- 'newland', 'nls', 'nlscan', 'sunmi', 'urovo', 'zebra', 'honeywell',
- 'idata', 'seuic', 'autoid', '东集', '东大',
-];
-
export default {
data() {
return {
@@ -28,46 +25,7 @@ export default {
methods: {
getScannerConfigs() {
- return [
- {
- // 东大集成 SEUIC / AUTOID 系列(如 AUTOID9),勿与新大陆 nlscan 混淆
- 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: 'NONE'
- }
- },
- {
- brand: 'sunmi',
- name: '商米',
- action: 'com.sunmi.scanner.ACTION_DATA_CODE_RECEIVED',
- dataKey: 'data',
- needSetup: false
- },
- {
- brand: 'urovo',
- name: '优博讯',
- action: 'android.intent.ACTION_DECODE_DATA',
- dataKey: 'barcode_string',
- needSetup: false
- },
- {
- // 新大陆 Newland,广播为 nlscan.action.SCANNER_RESULT
- brand: 'nlscan',
- name: '新大陆',
- action: 'nlscan.action.SCANNER_RESULT',
- dataKey: 'SCAN_BARCODE1',
- needSetup: false
- },
- { ...PHONE_SCAN_CONFIG },
- ];
+ return BUILTIN_SCANNER_CONFIGS;
},
getPhoneScanConfig() {
@@ -75,20 +33,7 @@ export default {
},
isPdaDevice() {
- // #ifdef APP-PLUS
- try {
- const Build = plus.android.importClass('android.os.Build');
- const manufacturer = String(Build.MANUFACTURER || '').toLowerCase();
- const model = String(Build.MODEL || '').toLowerCase();
- return PDA_DEVICE_KEYWORDS.some((keyword) => {
- return manufacturer.includes(keyword) || model.includes(keyword);
- });
- } catch (error) {
- console.log('检测设备类型失败', error);
- return false;
- }
- // #endif
- return false;
+ return detectPdaDevice();
},
shouldUsePhoneScan() {
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/sys/login/index.vue b/src/pages/sys/login/index.vue
index cee5365..f8415a8 100644
--- a/src/pages/sys/login/index.vue
+++ b/src/pages/sys/login/index.vue
@@ -125,6 +125,7 @@ import md5 from '@/common/md5.js';
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;
@@ -334,7 +335,7 @@ export default {
this.$u.api.pdaLogin({
'phone': this.login.username,
'password': this.login.password,
- }).then((res) => {
+ }).then(async (res) => {
console.log('login res', res)
var aLoginUserData = res;
@@ -365,6 +366,11 @@ 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';