diff --git a/src/api/system/user.js b/src/api/system/user.js index 2641a5b..94acd63 100644 --- a/src/api/system/user.js +++ b/src/api/system/user.js @@ -22,10 +22,11 @@ export function getUserProfile() { }) } -export function getSimpleUserList() { +export function getSimpleUserList(params) { return request({ url: '/admin-api/system/user/simple-list', - method: 'get' + method: 'get', + params }) } diff --git a/src/locales/en-US.js b/src/locales/en-US.js index cc50a1e..00fa9aa 100644 --- a/src/locales/en-US.js +++ b/src/locales/en-US.js @@ -200,6 +200,7 @@ export default { loadFailed: 'Load failed', deleteSuccess: 'Deleted successfully', deleteFailed: 'Delete failed', + saveSuccess: 'Saved successfully', saveFailed: 'Save failed', createSuccess: 'Created successfully', updateSuccess: 'Updated successfully', @@ -1334,6 +1335,7 @@ export default { placeholderRequireDate: 'Select require date', placeholderAcceptedBy: 'Select repair user', placeholderConfirmBy: 'Select confirm user', + placeholderUserSearch: 'Search by nickname', placeholderMold: 'Select mold', placeholderMoldNameAuto: 'Auto filled', placeholderMoldCodeAuto: 'Auto filled', @@ -1353,6 +1355,7 @@ export default { moldNotFound: 'Mold not found', scanFailed: 'Scan failed', maxUploadCount: 'Max 9 images', + noUserData: 'No user data', saving: 'Saving', saveSuccess: 'Saved successfully', submitSuccess: 'Submitted successfully', @@ -1366,6 +1369,7 @@ export default { validatorFaultLevelRequired: 'Fault level is required', validatorIsShutdownRequired: 'Is shutdown is required', validatorFaultPhenomenonRequired: 'Fault phenomenon is required', + validatorUserRequired: 'Please select a user', validatorRepairStatusRequired: 'Repair result is required', validatorFinishDateRequired: 'Finish date is required', validatorConfirmDateRequired: 'Confirm date is required' diff --git a/src/locales/zh-CN.js b/src/locales/zh-CN.js index 93d6953..b80a5b3 100644 --- a/src/locales/zh-CN.js +++ b/src/locales/zh-CN.js @@ -200,6 +200,7 @@ export default { loadFailed: '加载失败', deleteSuccess: '删除成功', deleteFailed: '删除失败', + saveSuccess: '保存成功', saveFailed: '保存失败', createSuccess: '新增成功', updateSuccess: '更新成功', @@ -355,8 +356,8 @@ export default { productionLine: '所属产线', currentMold: '当前在机模具', deviceStatus: '设备状态', - statusRunning: '运行中', - statusStop: '已停止', + statusRunning: '正常', + statusStop: '停用', statusFault: '故障', selectMountMold: '选择待上模模具', product: '产品', @@ -1337,6 +1338,7 @@ export default { placeholderRequireDate: '请选择报修日期', placeholderAcceptedBy: '请选择维修人员', placeholderConfirmBy: '请选择验收人员', + placeholderUserSearch: '请输入姓名搜索', placeholderMold: '请选择模具', placeholderMoldNameAuto: '自动带出', placeholderMoldCodeAuto: '自动带出', @@ -1356,6 +1358,7 @@ export default { moldNotFound: '未找到对应模具', scanFailed: '扫码失败', maxUploadCount: '最多上传 9 张图片', + noUserData: '暂无人员数据', saving: '保存中', saveSuccess: '保存成功', submitSuccess: '提交成功', @@ -1369,6 +1372,7 @@ export default { validatorFaultLevelRequired: '请选择故障等级', validatorIsShutdownRequired: '请选择是否停机', validatorFaultPhenomenonRequired: '请输入故障现象', + validatorUserRequired: '请选择人员', validatorRepairStatusRequired: '请选择维修结果', validatorFinishDateRequired: '请选择完成日期', validatorConfirmDateRequired: '请选择验收日期' diff --git a/src/pages.json b/src/pages.json index 169b348..59bea2e 100644 --- a/src/pages.json +++ b/src/pages.json @@ -669,6 +669,13 @@ "navigationStyle": "custom" } }, + { + "path": "moldRepair/userSelect", + "style": { + "navigationBarTitleText": "选择人员", + "navigationStyle": "custom" + } + }, { "path": "moldInspectionItems/index", "style": { diff --git a/src/pages_function/pages/moldPressureNet/index.vue b/src/pages_function/pages/moldPressureNet/index.vue index c901f4e..0bc0e87 100644 --- a/src/pages_function/pages/moldPressureNet/index.vue +++ b/src/pages_function/pages/moldPressureNet/index.vue @@ -3,8 +3,7 @@ @@ -83,7 +82,12 @@ {{ t('moldPressureNet.pressureNetTime') }}* - + {{ t('moldPressureNet.remark') }} @@ -317,6 +321,14 @@ function goHistory() { uni.navigateTo({ url: '/pages_function/pages/moldPressureNet/history' }) } +function onPressureNetTimeChange(value) { + const normalizedValue = normalizePressureNetTime(value) + pressureNetTime.value = normalizedValue + setTimeout(() => { + pressureNetTime.value = normalizePressureNetTime(pressureNetTime.value || value) || normalizedValue + }, 0) +} + async function handleSubmit() { if (submitLoading.value) return if (!selectedBrand.id) { @@ -327,7 +339,8 @@ async function handleSubmit() { uni.showToast({ title: t('moldPressureNet.selectSubMoldError'), icon: 'none' }) return } - if (!pressureNetTime.value) { + const normalizedPressureNetTime = normalizePressureNetTime(pressureNetTime.value) + if (!normalizedPressureNetTime) { uni.showToast({ title: t('moldPressureNet.selectReplaceTimeError'), icon: 'none' }) return } @@ -342,12 +355,12 @@ async function handleSubmit() { moldBrandName: selectedBrand.name, moldId: moldId, moldName: selected?.name || '', - pressureNetTime: pressureNetTime.value, + pressureNetTime: normalizedPressureNetTime, remark: remark.value.trim() || undefined } }) await createPressureNetRecord(createReqVOList) - uni.showToast({ title: t('moldPressureNet.submitSuccess'), icon: 'success' }) + uni.showToast({ title: t('functionCommon.saveSuccess'), icon: 'success' }) // 清空表单 selectedBrand.id = '' selectedBrand.name = '' @@ -362,12 +375,31 @@ async function handleSubmit() { submitLoading.value = false } } + +function normalizePressureNetTime(value) { + const text = String(value || '').trim().replace(/\//g, '-') + const dateOnlyMatch = text.match(/^(\d{4}-\d{2}-\d{2})(?:\s+(?:undefined|null|选择时间|select time))?$/i) + if (dateOnlyMatch) { + return `${dateOnlyMatch[1]} ${getCurrentTime()}` + } + const dateTimeMatch = text.match(/^(\d{4}-\d{2}-\d{2})[ T](\d{2}):(\d{2})(?::(\d{2}))?$/) + if (!dateTimeMatch) return '' + const [, date, hour, minute, second = '00'] = dateTimeMatch + return `${date} ${hour}:${minute}:${second}` +} + +function getCurrentTime() { + const date = new Date() + const hour = String(date.getHours()).padStart(2, '0') + const minute = String(date.getMinutes()).padStart(2, '0') + const second = String(date.getSeconds()).padStart(2, '0') + return `${hour}:${minute}:${second}` +} diff --git a/src/pages_function/pages/moldoperate/deviceSelect.vue b/src/pages_function/pages/moldoperate/deviceSelect.vue index 4bbf07c..cac770e 100644 --- a/src/pages_function/pages/moldoperate/deviceSelect.vue +++ b/src/pages_function/pages/moldoperate/deviceSelect.vue @@ -69,6 +69,7 @@ import { useI18n } from 'vue-i18n' import NavBar from '@/components/common/NavBar.vue' import { getDeviceLedgerList } from '@/api/mes/moldoperate' import { getDeviceLineTree } from '@/api/mes/deviceLine' +import { getMoldBrandPage } from '@/api/mes/mold' const { t } = useI18n() @@ -105,65 +106,39 @@ function getStatusLabel(device) { return map[status] || textValue(device.deviceStatus) || '-' } -// 当前在机模具 - 优先从持久化存储读取(实时),否则 fallback 设备台账字段 -function getCurrentMold(device) { - const deviceId = device?.id - const deviceCode = device?.deviceCode +// 设备名 → 在机模具名 映射表 +const deviceMoldMap = ref(new Map()) - // 1. 优先读新版 _mountedMoldInfoMap(按 deviceId 索引,再用 deviceCode fallback) +async function loadDeviceMolds() { try { - const map = uni.getStorageSync('_mountedMoldInfoMap') || {} - // 先按 id 匹配 - const key = String(deviceId) - let info = deviceId != null ? map[key] : null - // 再按 deviceCode 匹配(兼容 id 可能不一致的情况) - if (!info && deviceCode) { - const found = Object.values(map).find((item) => item?.deviceCode === deviceCode) - if (found) info = found - } - - // 调试日志:只在首次加载时输出一次 - if (!getCurrentMold._logged) { - getCurrentMold._logged = true - console.log('[deviceSelect] === 调试信息 ===') - console.log('[deviceSelect] storage map keys:', Object.keys(map)) - console.log('[deviceSelect] storage map values:', map) - console.log('[deviceSelect] 当前设备 deviceId:', deviceId, 'type:', typeof deviceId, 'key:', key) - console.log('[deviceSelect] 当前设备 deviceCode:', deviceCode) - console.log('[deviceSelect] id匹配结果:', info ? '命中' : '未命中') - if (!info) { - console.log('[deviceSelect] 尝试 deviceCode fallback...') - for (const [k, v] of Object.entries(map)) { - console.log('[deviceSelect] storage[', k, '].deviceCode =', v?.deviceCode, 'vs 设备 code =', deviceCode, '匹配:', v?.deviceCode === deviceCode) - } + const res = await getMoldBrandPage({ pageSize: 100 }) + const root = res && res.data !== undefined ? res.data : res + const pageData = root?.pageResult || root + const list = Array.isArray(pageData) ? pageData : (Array.isArray(pageData?.list) ? pageData.list : []) + const map = new Map() + for (const mold of list) { + const deviceName = mold.deviceName + if (deviceName) { + if (!map.has(deviceName)) map.set(deviceName, []) + map.get(deviceName).push(mold.name || '') } - // fallback 检查 - const saved = uni.getStorageSync('_mountedMoldInfo') || null - console.log('[deviceSelect] 旧版 _mountedMoldInfo:', saved) - console.log('[deviceSelect] 设备台账字段 currentMold:', device?.currentMold, 'moldName:', device?.moldName, 'moldId:', device?.moldId) - } - - if (info?.mold) { - return info.mold.name || info.mold.moldName || '-' } + deviceMoldMap.value = map } catch (e) { - console.warn('[deviceSelect] read _mountedMoldInfoMap error', e) + console.error('loadDeviceMolds error', e) } +} - // 2. 兼容旧版 _mountedMoldInfo - let saved = null - try { saved = uni.getStorageSync('_mountedMoldInfo') || null } catch {} - if (saved) { - const idMatch = deviceId != null && String(saved.deviceId) === String(deviceId) - const codeMatch = deviceCode && saved.deviceCode === deviceCode - if (idMatch || codeMatch) { - return saved.mold?.name || saved.mold?.moldName || '-' - } +// 当前在机模具 - 从模具型号接口获取 +function getCurrentMold(device) { + if (!device) return t('moldOperate.noMoldOnDevice') + const deviceName = device.deviceName + if (deviceName && deviceMoldMap.value.has(deviceName)) { + const names = deviceMoldMap.value.get(deviceName) || [] + return names.join(',') } - - // 3. fallback 设备台账静态字段 - const staticMold = textValue(device.currentMold || device.moldName || device.moldId) - return staticMold === '-' ? t('moldOperate.noMoldOnDevice') : staticMold + // fallback 设备台账静态字段 + return textValue(device.currentMold || device.moldName) || t('moldOperate.noMoldOnDevice') } function flattenLineTree(nodes, parentId) { @@ -269,7 +244,7 @@ function handleConfirm() { } onShow(async () => { - await Promise.allSettled([loadDevices(), loadLineTree()]) + await Promise.allSettled([loadDevices(), loadLineTree(), loadDeviceMolds()]) }) diff --git a/src/pages_function/pages/moldoperate/dismount.vue b/src/pages_function/pages/moldoperate/dismount.vue index ada878e..ceffcd5 100644 --- a/src/pages_function/pages/moldoperate/dismount.vue +++ b/src/pages_function/pages/moldoperate/dismount.vue @@ -4,24 +4,24 @@ - - - - - {{ t('moldOperate.scanDevice') }} + + - - - {{ t('moldOperate.selectDevice') }} @@ -80,16 +80,6 @@ {{ t('moldOperate.product') }} {{ textValue(selectedMold.productName) }} - - {{ t('moldOperate.mountTime') }} - {{ textValue(selectedMold.mountTime) }} - - - - - {{ t('moldOperate.useCount') }} - {{ formatUseCount(selectedMold.useCount) }} - @@ -117,40 +107,15 @@ {{ t('moldOperate.operator') + ' & ' + t('moldOperate.remark') }} - - - - *{{ t('moldOperate.operator') }} - - - - {{ selectedOperator ? selectedOperator.label : t('moldOperate.placeholderOperator') }} - - - - - - - {{ item.label }} - - - 暂无数据 - + + + + *{{ t('moldOperate.operator') }} + + {{ currentUserName }} - {{ t('moldOperate.remark') }} @@ -202,11 +167,17 @@ import { computed, reactive, ref } from 'vue' import { onShow } from '@dcloudio/uni-app' import { useI18n } from 'vue-i18n' import NavBar from '@/components/common/NavBar.vue' -import { getLowerMoldList, getDeviceLedgerList, createMoldOperate } from '@/api/mes/moldoperate' +import { getDeviceLedgerList, createMoldOperate } from '@/api/mes/moldoperate' +import { getMoldBrandPage } from '@/api/mes/mold' +import useUserStore from '@/store/modules/user' import { getDeviceLineTree } from '@/api/mes/deviceLine' -import { getSimpleUserList } from '@/api/system/user' const { t } = useI18n() +const userStore = useUserStore() + +// 当前登录用户 +const currentUserName = computed(() => userStore.name || '未知用户') +const currentUserId = computed(() => userStore.userId) const lineInfoMap = ref(new Map()) // deviceLine id → { name, parentId, parentChain } @@ -282,10 +253,8 @@ const tempSelectedMoldId = ref(null) // ---- 操作人与备注 ---- const remarkText = ref('') -const operatorOptions = ref([]) const selectedOperator = ref(null) -const operatorIndex = ref(-1) -const showOperatorDropdown = ref(false) +const scanCodeInput = ref('') // ---- 工具函数 ---- function textValue(v) { @@ -295,12 +264,7 @@ function textValue(v) { return s || '-' } -function formatUseCount(count) { - if (count == null) return '-' - const num = Number(count) - if (isNaN(num)) return String(count) - return num.toLocaleString() + ' ' + t('moldOperate.countUnit') -} + function formatTime(time) { if (!time) return '-' @@ -374,45 +338,20 @@ function findArr(obj, d = 0) { return [] } -async function loadLowerMolds(deviceId) { +async function loadLowerMolds(deviceName) { lowerMoldLoading.value = true try { - // ====== 策略1:优先从持久化存储读取(按设备ID索引,不会互覆盖)====== - let map = {} - try { map = uni.getStorageSync('_mountedMoldInfoMap') || {} } catch {} - const savedInfo = map[String(deviceId)] || null - - console.log('[下模] 持久化在机模具信息 =', savedInfo ? JSON.stringify(savedInfo) : 'null', 'deviceId=', deviceId) - - if (savedInfo && savedInfo.mold) { - console.log('[下模] 命中持久化数据, deviceId=', deviceId) - const m = savedInfo.mold - lowerMoldOptions.value = [{ - id: m.id, - moldId: m.id, - moldName: m.name || m.moldName || '-', - moldCode: m.code || m.moldCode || '-', - productName: m.productName || '-', - mountTime: formatTime(savedInfo.mountTime), - useCount: '-' - }] - console.log('[下模] 使用持久化数据 =', JSON.stringify(lowerMoldOptions.value[0])) - return - } - console.log('[下模] 未命中持久化数据,进入接口查询') - - // ====== 策略2:fallback - 调用在机模具接口 ====== - let list = [] - try { - const res = await getLowerMoldList(deviceId) - const root = (res && res.data !== undefined) ? res.data : res - list = findArr(root) - } catch (apiErr) { - console.warn('[下模] getLowerMoldList 接口异常', apiErr) - } - - lowerMoldOptions.value = list - console.log('[下模] loadLowerMolds 返回 list.length =', list.length) + const res = await getMoldBrandPage({ deviceName, pageSize: 100 }) + const root = (res && res.data !== undefined) ? res.data : res + const pageData = root?.pageResult || root + const list = Array.isArray(pageData) ? pageData : (Array.isArray(pageData?.list) ? pageData.list : []) + lowerMoldOptions.value = list.map(m => ({ + id: m.id, + moldId: m.id, + moldName: m.name || '-', + moldCode: m.code || '-', + productName: m.productName || '-' + })) } catch (e) { console.error('loadLowerMolds error', e) } finally { @@ -420,17 +359,39 @@ async function loadLowerMolds(deviceId) { } } -// ---- 扫描设备码 ---- +// ---- 扫描/输入设备码 ---- +function matchDeviceByCode(code) { + if (!code) return null + let matched = null + if (code.toUpperCase().startsWith('EQUIPMENT-')) { + const idFromQr = code.replace(/EQUIPMENT-/i, '') + matched = deviceOptions.value.find((d) => String(d.raw.id) === idFromQr) + } + if (!matched) { + matched = deviceOptions.value.find((d) => + Object.values(d.raw).some((v) => + typeof v === 'string' && v.trim().toUpperCase() === code.toUpperCase() + ) || d.label.toUpperCase().includes(code.toUpperCase()) + ) + } + if (!matched) { + const idMatch = code.match(/(\d+)$/) + if (idMatch) { + matched = deviceOptions.value.find((d) => String(d.raw.id) === idMatch[1]) + } + } + return matched +} + function handleScan() { uni.scanCode({ onlyFromCamera: false, scanType: ['qrCode', 'barCode'], success(res) { - const code = res.result?.trim() + const code = (res.result || '').trim() if (!code) return - const matched = deviceOptions.value.find((d) => - d.raw.deviceCode === code || String(d.raw.code) === code || d.label.includes(code) - ) + scanCodeInput.value = code + const matched = matchDeviceByCode(code) if (matched) { selectDevice(matched.raw) } else { @@ -445,13 +406,24 @@ function handleScan() { }) } +function onScanInputConfirm() { + const code = scanCodeInput.value.trim() + if (!code) return + const matched = matchDeviceByCode(code) + if (matched) { + selectDevice(matched.raw) + } else { + uni.showToast({ title: t('moldOperate.deviceNotFound'), icon: 'none' }) + } +} + // ---- 设备选择 ---- function selectDevice(device) { selectedDevice.value = device || {} moldsLoaded.value = false selectedMold.value = {} - if (device?.id) { - loadLowerMolds(device.id).then(() => { + if (device?.deviceName) { + loadLowerMolds(device.deviceName).then(() => { moldsLoaded.value = true if (lowerMoldOptions.value.length > 0) { const first = lowerMoldOptions.value[0] @@ -459,9 +431,7 @@ function selectDevice(device) { id: first.id || first.moldId, moldName: first.moldName || first.name, moldCode: first.moldCode || first.code, - productName: first.productName || '-', - mountTime: first.mountTime || '-', - useCount: first.useCount ?? '-' + productName: first.productName || '-' } } }) @@ -475,12 +445,12 @@ function openDevicePicker() { // ---- 在机模具选择(更换下模对象)---- function openLowerMoldPicker() { - if (!selectedDevice.value?.id) { + if (!selectedDevice.value?.deviceName) { uni.showToast({ title: t('moldOperate.validatorDeviceRequired'), icon: 'none' }) return } tempSelectedMoldId.value = selectedMold.value ? String(selectedMold.value.id || selectedMold.value.moldId) : null - loadLowerMolds(selectedDevice.value.id).then(() => { + loadLowerMolds(selectedDevice.value.deviceName).then(() => { lowerMoldPickerRef.value?.open() }) } @@ -494,9 +464,7 @@ function confirmLowerMoldSelection() { id: mold.id || mold.moldId, moldName: mold.moldName || mold.name, moldCode: mold.moldCode || mold.code, - productName: mold.productName || '-', - mountTime: mold.mountTime || '-', - useCount: mold.useCount ?? '-' + productName: mold.productName || '-' } } lowerMoldPickerRef.value?.close() @@ -504,34 +472,16 @@ function confirmLowerMoldSelection() { function closeLowerMoldPicker() { lowerMoldPickerRef.value?.close() } -// ---- 操作人列表加载 ---- -async function loadOperators() { - try { - const res = await getSimpleUserList() - const data = Array.isArray(res) ? res : (Array.isArray(res?.data) ? res.data : []) - operatorOptions.value = data.map((u) => ({ - value: u.id || u.userId, - label: u.nickname || u.userName || u.name || String(u.id || '') - })) - } catch (e) { - console.error('loadOperators error', e) +// ---- 操作人自动设置为当前登录用户 ---- +function autoSetOperator() { + if (currentUserId.value && currentUserName.value) { + selectedOperator.value = { + value: currentUserId.value, + label: currentUserName.value + } } } -function toggleOperatorDropdown() { - showOperatorDropdown.value = !showOperatorDropdown.value -} - -function closeOperatorDropdown() { - showOperatorDropdown.value = false -} - -function handleSelectOperator(item, idx) { - selectedOperator.value = item - operatorIndex.value = idx - closeOperatorDropdown() -} - function goToHistory() { uni.navigateTo({ url: '/pages_function/pages/moldoperate/history?type=down' }) } @@ -578,21 +528,11 @@ async function handleConfirm() { console.log('[下模] 提交参数 =', JSON.stringify(payload)) await createMoldOperate(payload) uni.showToast({ title: t('functionCommon.createSuccess'), icon: 'success' }) - // 下模成功后清除该设备的持久化数据 - if (selectedDevice.value?.id) { - try { - const map = uni.getStorageSync('_mountedMoldInfoMap') || {} - delete map[String(selectedDevice.value.id)] - uni.setStorageSync('_mountedMoldInfoMap', map) - } catch {} - } // 重置表单 selectedDevice.value = {} selectedMold.value = {} lowerMoldOptions.value = [] remarkText.value = '' - selectedOperator.value = null - operatorIndex.value = -1 } catch (e) { console.error('[下模] 保存失败 =', e) const errMsg = e?.msg || (typeof e === 'string' ? e : e?.message) || '系统异常' @@ -608,7 +548,8 @@ function handleCancel() { } onShow(async () => { - await Promise.allSettled([loadDevices(), loadLineTree(), loadOperators()]) + autoSetOperator() + await Promise.allSettled([loadDevices(), loadLineTree()]) // 从 globalData 读取设备选择页回传的设备 const device = getApp().globalData._deviceSelectResult if (device) { @@ -621,21 +562,16 @@ onShow(async () => {