diff --git a/src/api/mes/mold.js b/src/api/mes/mold.js
index 12a9cf8..bbf6d52 100644
--- a/src/api/mes/mold.js
+++ b/src/api/mes/mold.js
@@ -80,6 +80,22 @@ export function getBrandList(params = {}) {
})
}
+export function createPressureNetRecord(data) {
+ return request({
+ url: '/admin-api/erp/mold-pressure-net-record/batch-create',
+ method: 'post',
+ data
+ })
+}
+
+export function getPressureNetRecordPage(params = {}) {
+ return request({
+ url: '/admin-api/erp/mold-pressure-net-record/page',
+ method: 'get',
+ params
+ })
+}
+
export function getInTransitMoldAllList() {
return request({
url: '/admin-api/erp/mold/getInTransitMoldAllList',
diff --git a/src/locales/en-US.js b/src/locales/en-US.js
index d3fcb84..097a7f0 100644
--- a/src/locales/en-US.js
+++ b/src/locales/en-US.js
@@ -344,6 +344,7 @@ export default {
validatorOperateTypeRequired: 'Operation type is required',
validatorDeviceRequired: 'Device is required',
validatorMoldRequired: 'Select at least one mold for mounting',
+ validatorOperatorRequired: 'Please select operator',
validatorLowerMoldRequired: 'Select at least one mold for dismounting',
loadEditFailed: 'Failed to load edit data',
confirmDelete: 'Confirm delete this mold operate record?',
@@ -374,7 +375,21 @@ export default {
changeTarget: 'Change Dismount Target',
confirmDismount: 'Confirm Dismount',
clickSelectDeviceFirst: 'Please select a device first',
- noMoldOnDevice: 'No mold on this device'
+ noMoldOnDevice: 'No mold on this device',
+ historySuffix: ' History',
+ historyTitle: 'Mold Operate History',
+ searchPlaceholder: 'Search device/mold name',
+ operator: 'Operator',
+ placeholderOperator: 'Select operator',
+ filterAll: 'All',
+ filterToday: 'Today',
+ filterWeek: 'This Week',
+ historyEmpty: 'No history records',
+ totalPrefix: 'Total: ',
+ totalSuffix: '',
+ confirmDeleteHistory: 'Confirm delete this history record?',
+ operateTime: 'Operate Time',
+ operator: 'Operator'
},
moldInspectionItems: {
moduleName: 'Inspection Items',
@@ -1156,11 +1171,120 @@ export default {
selectTemplateError: 'Please select inspection template',
noItems: 'Please select inspection template first',
noTemplate: 'No templates',
+ resultListTitle: 'Inspection Results',
+ editResult: 'Edit',
+ cancelEdit: 'Cancel Edit',
submit: 'Submit Inspection',
submitSuccess: 'Inspection submitted successfully',
submitFailed: 'Failed to submit inspection',
reInspect: 'Re-inspect'
},
+ moldMaintain: {
+ moduleName: 'Mold Maintenance',
+ addTitle: 'Add Maintenance',
+ detailTitle: 'Maintenance Detail',
+ searchPlaceholder: 'Enter maintenance No.',
+ empty: 'No maintenance records',
+ add: 'Add',
+ moldName: 'Mold Name',
+ moldCode: 'Mold Code',
+ product: 'Product',
+ status: 'Status',
+ taskType: 'Task Type',
+ taskTypeInspect: 'Inspection',
+ taskTypeMaintain: 'Maintenance',
+ planNo: 'Maintenance No.',
+ taskTime: 'Task Time',
+ template: 'Template',
+ operator: 'Operator',
+ jobResultOk: 'OK',
+ jobResultNg: 'NG',
+ progressTitle: 'Progress',
+ noResultData: 'No maintenance result data',
+ requiredText: 'Required',
+ inspectionMethod: 'Maintenance Method',
+ judgmentCriteria: 'Judgment Criteria',
+ textInput: 'Input Value',
+ inputPlaceholder: 'Enter value',
+ images: 'Images',
+ remark: 'Remark',
+ resultText: 'Result',
+ inspectionResultPass: 'Pass',
+ inspectionResultFail: 'Fail',
+ inspectionResultPending: 'Pending',
+ maxUploadCount: 'Max 3 images',
+ selectAllDecisionError: 'Please select all maintenance results',
+ currentMoldInfo: 'Mold Info',
+ moldGroupCode: 'Mold Group Code',
+ moldGroupName: 'Mold Group Name',
+ cavityCount: 'Cavity Count',
+ moldSize: 'Mold Size',
+ currentDevice: 'Current Device',
+ selectMold: 'Select Mold',
+ reSelectMold: 'Re-select Mold',
+ selectMoldError: 'Please select a mold',
+ searchMold: 'Enter mold name',
+ noMoldInfo: 'Please select a mold',
+ noMoldData: 'No molds available',
+ taskName: 'Task Name',
+ taskInfo: 'Task Info',
+ placeholderTaskName: 'Enter task name',
+ templateSelection: 'Template/Task Selection',
+ selectTemplate: 'Select Template',
+ selectTemplateError: 'Please select maintenance template',
+ noItems: 'Please select maintenance template first',
+ noTemplate: 'No templates',
+ resultListTitle: 'Inspection Results',
+ editResult: 'Edit',
+ cancelEdit: 'Cancel Edit',
+ submit: 'Submit Maintenance',
+ submitSuccess: 'Maintenance submitted successfully',
+ submitFailed: 'Failed to submit maintenance',
+ reInspect: 'Re-maintain'
+ },
+ moldPressureNet: {
+ moduleName: 'Replace Pressure Net',
+ recordTitle: 'Pressure Net Replacement',
+ recordDesc: 'Select mold group and sub-mold, then confirm replacement time',
+ history: 'History',
+ historyTitle: 'Pressure Net History',
+ moldGroup: 'Mold Group',
+ selectMoldGroup: 'Select Mold Group',
+ searchMoldGroup: 'Enter mold group name',
+ noMoldGroup: 'No mold groups',
+ moldGroupName: 'Mold Group Name',
+ moldGroupCode: 'Mold Group Code',
+ product: 'Product',
+ subMold: 'Sub-mold',
+ selectSubMold: 'Select Sub-mold',
+ reSelectMoldGroup: 'Re-select Mold Group',
+ reSelectSubMold: 'Re-select Sub-mold',
+ subMoldCode: 'Sub-mold Code',
+ subMoldName: 'Sub-mold Name',
+ searchSubMold: 'Search sub-mold name/code',
+ noSubMold: 'No sub-molds',
+ replaceInfo: 'Replacement Info',
+ replaceTime: 'Replacement Time',
+ pressureNetTime: 'Pressure Net Time',
+ selectReplaceTime: 'Select replacement time',
+ operator: 'Operator',
+ selectOperator: 'Select operator',
+ noOperator: 'No operators',
+ remark: 'Remark',
+ remarkPlaceholder: 'Enter replacement reason or remark',
+ confirmReplace: 'Confirm',
+ selectMoldGroupError: 'Please select a mold group',
+ selectSubMoldError: 'Please select a sub-mold',
+ selectedCount: '{count} sub-mold(s) selected',
+ selectReplaceTimeError: 'Please select replacement time',
+ submitSuccess: 'Saved successfully',
+ submitFailed: 'Save failed',
+ historyMoldIdPlaceholder: 'Enter sub-mold ID, blank for all',
+ searchBrandName: 'Mold Group Name',
+ selectDate: 'Select Date',
+ createTime: 'Create Time',
+ noHistory: 'No pressure net history'
+ },
moldRepair: {
moduleName: 'Mold Repair',
createTitle: 'Create Mold Repair',
diff --git a/src/locales/index.js b/src/locales/index.js
index 1ab9806..449526c 100644
--- a/src/locales/index.js
+++ b/src/locales/index.js
@@ -130,7 +130,12 @@ const literalMap = {
'模具点检': 'moldCheck.moduleName',
'点检详情': 'moldCheck.detailTitle',
'新增点检': 'moldCheck.addTitle',
- '设备运维': 'work.equipmentMaintenance'
+ '设备运维': 'work.equipmentMaintenance',
+ '模具保养': 'moldMaintain.moduleName',
+ '保养详情': 'moldMaintain.detailTitle',
+ '新增保养': 'moldMaintain.addTitle',
+ '更换压网': 'moldPressureNet.moduleName',
+ '压网历史': 'moldPressureNet.historyTitle'
}
export function getCurrentLocale() {
diff --git a/src/locales/zh-CN.js b/src/locales/zh-CN.js
index 08b62df..7b3ff6b 100644
--- a/src/locales/zh-CN.js
+++ b/src/locales/zh-CN.js
@@ -344,6 +344,7 @@ export default {
validatorOperateTypeRequired: '操作类型不能为空',
validatorDeviceRequired: '设备不能为空',
validatorMoldRequired: '请至少选择一个上模模具',
+ validatorOperatorRequired: '请选择操作人',
validatorLowerMoldRequired: '请至少选择一个下模模具',
loadEditFailed: '加载编辑数据失败',
confirmDelete: '确认删除该上下模记录吗?',
@@ -374,7 +375,21 @@ export default {
changeTarget: '更换下模对象',
confirmDismount: '确认下模',
clickSelectDeviceFirst: '请先选择设备',
- noMoldOnDevice: '该设备暂无在机模具'
+ noMoldOnDevice: '该设备暂无在机模具',
+ historySuffix: '历史',
+ historyTitle: '上下模历史',
+ searchPlaceholder: '搜索设备/模具名称',
+ operator: '操作人',
+ placeholderOperator: '请选择操作人',
+ filterAll: '全部',
+ filterToday: '今天',
+ filterWeek: '本周',
+ historyEmpty: '暂无历史记录',
+ totalPrefix: '共 ',
+ totalSuffix: ' 条',
+ confirmDeleteHistory: '确认删除该历史记录吗?',
+ operateTime: '操作时间',
+ operator: '操作人'
},
moldInspectionItems: {
moduleName: '点检项库',
@@ -1159,11 +1174,120 @@ export default {
selectTemplateError: '请选择点检模板',
noItems: '请先选择点检模板',
noTemplate: '暂无模板',
+ resultListTitle: '检验结果',
+ editResult: '编辑',
+ cancelEdit: '取消编辑',
submit: '提交点检',
submitSuccess: '点检提交成功',
submitFailed: '点检提交失败',
reInspect: '再次点检'
},
+ moldMaintain: {
+ moduleName: '模具保养',
+ addTitle: '新增保养',
+ detailTitle: '保养详情',
+ searchPlaceholder: '请输入保养单号',
+ empty: '暂无保养记录',
+ add: '新增',
+ moldName: '模具名称',
+ moldCode: '模具编号',
+ product: '产品',
+ status: '状态',
+ taskType: '任务类型',
+ taskTypeInspect: '点检',
+ taskTypeMaintain: '保养',
+ planNo: '保养单号',
+ taskTime: '执行时间',
+ template: '配置模板',
+ operator: '操作员',
+ jobResultOk: '通过',
+ jobResultNg: '不通过',
+ progressTitle: '进度',
+ noResultData: '暂无保养结果数据',
+ requiredText: '必检',
+ inspectionMethod: '保养方式',
+ judgmentCriteria: '判定基准',
+ textInput: '输入值',
+ inputPlaceholder: '请输入',
+ images: '图片',
+ remark: '备注',
+ resultText: '结果',
+ inspectionResultPass: '通过',
+ inspectionResultFail: '不通过',
+ inspectionResultPending: '待判定',
+ maxUploadCount: '最多上传3张图片',
+ selectAllDecisionError: '请选择所有保养项的判定结果',
+ currentMoldInfo: '模具信息',
+ moldGroupCode: '模具组编码',
+ moldGroupName: '模具组名称',
+ cavityCount: '模穴数',
+ moldSize: '模具尺寸',
+ currentDevice: '当前设备',
+ selectMold: '选择模具',
+ reSelectMold: '重新选择模具',
+ selectMoldError: '请选择模具',
+ searchMold: '请输入模具名称',
+ noMoldInfo: '请选择模具',
+ noMoldData: '暂无可选模具',
+ taskName: '任务名称',
+ taskInfo: '任务信息',
+ placeholderTaskName: '请输入任务名称',
+ templateSelection: '模板/任务选择',
+ selectTemplate: '请选择模板',
+ selectTemplateError: '请选择保养模板',
+ noItems: '请先选择保养模板',
+ noTemplate: '暂无模板',
+ resultListTitle: '检验结果',
+ editResult: '编辑',
+ cancelEdit: '取消编辑',
+ submit: '提交保养',
+ submitSuccess: '保养提交成功',
+ submitFailed: '保养提交失败',
+ reInspect: '再次保养'
+ },
+ moldPressureNet: {
+ moduleName: '更换压网',
+ recordTitle: '压网更换记录',
+ recordDesc: '请选择模具组和子模,确认更换时间',
+ history: '历史数据',
+ historyTitle: '压网历史',
+ moldGroup: '模具组',
+ selectMoldGroup: '选择模具组',
+ searchMoldGroup: '请输入模具组名称',
+ noMoldGroup: '暂无模具组',
+ moldGroupName: '模具组名称',
+ moldGroupCode: '模具组编号',
+ product: '产品',
+ subMold: '子模',
+ selectSubMold: '选择子模',
+ reSelectMoldGroup: '重新选择模具组',
+ reSelectSubMold: '重新选择子模',
+ subMoldCode: '子模编码',
+ subMoldName: '子模名称',
+ searchSubMold: '搜索子模名称/编号',
+ noSubMold: '暂无子模',
+ replaceInfo: '更换信息',
+ replaceTime: '更换时间',
+ pressureNetTime: '压网时间',
+ selectReplaceTime: '请选择更换时间',
+ operator: '操作人',
+ selectOperator: '请选择操作人',
+ noOperator: '暂无操作人',
+ remark: '备注',
+ remarkPlaceholder: '请输入更换原因或备注',
+ confirmReplace: '确认更换',
+ selectMoldGroupError: '请选择模具组',
+ selectSubMoldError: '请选择子模',
+ selectedCount: '已选{count}个子模',
+ selectReplaceTimeError: '请选择更换时间',
+ submitSuccess: '压网更换保存成功',
+ submitFailed: '压网更换保存失败',
+ historyMoldIdPlaceholder: '输入子模ID筛选,不填查全部',
+ searchBrandName: '模具组名称',
+ selectDate: '选择日期',
+ createTime: '创建时间',
+ noHistory: '暂无压网历史记录'
+ },
moldRepair: {
moduleName: '模具维修',
createTitle: '新增模具维修',
diff --git a/src/manifest.json b/src/manifest.json
index e4641a7..069ad36 100644
--- a/src/manifest.json
+++ b/src/manifest.json
@@ -22,7 +22,9 @@
"delay" : 0
},
/* 模块配置 */
- "modules" : {},
+ "modules" : {
+ "Camera" : {}
+ },
/* 应用发布信息 */
"distribute" : {
/* android打包配置 */
diff --git a/src/pages.json b/src/pages.json
index d7a1c5f..5ca6cd6 100644
--- a/src/pages.json
+++ b/src/pages.json
@@ -610,6 +610,13 @@
"navigationStyle": "custom"
}
},
+ {
+ "path": "moldoperate/history",
+ "style": {
+ "navigationBarTitleText": "上下模历史",
+ "navigationStyle": "custom"
+ }
+ },
{
"path": "moldRepair/index",
"style": {
@@ -742,9 +749,44 @@
"navigationBarTitleText": "新增点检",
"navigationStyle": "custom"
}
+ },
+ {
+ "path": "moldMaintain/index",
+ "style": {
+ "navigationBarTitleText": "模具保养",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "moldMaintain/detail",
+ "style": {
+ "navigationBarTitleText": "保养详情",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "moldMaintain/add",
+ "style": {
+ "navigationBarTitleText": "新增保养",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "moldPressureNet/index",
+ "style": {
+ "navigationBarTitleText": "更换压网",
+ "navigationStyle": "custom"
+ }
+ },
+ {
+ "path": "moldPressureNet/history",
+ "style": {
+ "navigationBarTitleText": "压网历史",
+ "navigationStyle": "custom"
+ }
}
]
}
],
"preloadRule": {}
-}
\ No newline at end of file
+}
diff --git a/src/pages_function/pages/moldCheck/add.vue b/src/pages_function/pages/moldCheck/add.vue
index 0ba8050..6907021 100644
--- a/src/pages_function/pages/moldCheck/add.vue
+++ b/src/pages_function/pages/moldCheck/add.vue
@@ -78,8 +78,15 @@
- {{ t('moldCheck.noItems') }}
-
+
+
+ {{ t('moldCheck.resultListTitle') }}
+
+
+ {{ ticketResultEditable ? t('moldCheck.cancelEdit') : t('moldCheck.editResult') }}
+
+
+
@@ -114,6 +122,7 @@
class="form-textarea"
:placeholder="t('moldCheck.inputPlaceholder')"
maxlength="500"
+ :disabled="!ticketResultEditable"
/>
@@ -126,9 +135,9 @@
mode="aspectFill"
@click="previewImage(img, parseImages(item.images))"
/>
- ×
+ ×
-
+
+
@@ -140,19 +149,20 @@
class="form-textarea"
:placeholder="t('moldCheck.inputPlaceholder')"
maxlength="500"
+ :disabled="!ticketResultEditable"
/>
{{ t('moldCheck.resultText') }}
{{ t('moldCheck.inspectionResultPass') }}
{{ t('moldCheck.inspectionResultFail') }}
@@ -164,6 +174,7 @@
+
@@ -247,7 +258,7 @@ import { DICT_TYPE, getDictLabel, initAllDict } from '@/utils/dict'
const { t } = useI18n()
-// 模具信息(从列表页传入或通过选择器选择)
+// Mold info, loaded from route params or picker.
const moldInfo = reactive({
id: '',
code: '',
@@ -268,10 +279,12 @@ const templateFinished = ref(false)
const templatePageNo = ref(1)
const templatePageSize = ref(20)
const inspectionItems = ref([])
+const ticketResultEditable = ref(false)
+const ticketResultBackup = ref(null)
const submitLoading = ref(false)
const statusClass = ref('')
-// 模具选择器
+// Mold picker.
const showMoldPicker = ref(false)
const moldList = ref([])
const moldLoading = ref(false)
@@ -300,7 +313,6 @@ onLoad(async (query) => {
moldInfo.statusLabel = getDictLabel(DICT_TYPE.ERP_MOLD_STATUS, moldInfo.status, moldInfo.status)
updateStatusClass()
} else {
- // 只有ID,加载模具详情
await loadMoldInfo(moldId)
}
}
@@ -327,18 +339,17 @@ async function loadMoldInfo(id) {
function updateStatusClass() {
const status = String(moldInfo.status)
- if (status === '1' || moldInfo.statusLabel.includes('正常') || moldInfo.statusLabel.includes('使用')) {
+ if (status === '1') {
statusClass.value = 'status-success'
- } else if (status === '2' || moldInfo.statusLabel.includes('维修') || moldInfo.statusLabel.includes('警')) {
+ } else if (status === '2') {
statusClass.value = 'status-warning'
- } else if (status === '3' || moldInfo.statusLabel.includes('报废') || moldInfo.statusLabel.includes('停')) {
+ } else if (status === '3') {
statusClass.value = 'status-danger'
} else {
statusClass.value = 'status-default'
}
}
-// 模具选择器
function openMoldPicker() {
showMoldPicker.value = true
if (!moldList.value.length) {
@@ -390,7 +401,6 @@ function selectMold(mold) {
closeMoldPicker()
}
-// 模板选择器
function openTemplatePicker() {
showTemplatePicker.value = true
if (!templateList.value.length) {
@@ -434,6 +444,8 @@ async function loadMoreTemplates() {
function selectTemplate(template) {
selectedTemplate.value = template
+ ticketResultEditable.value = false
+ ticketResultBackup.value = null
loadInspectionItems(template.id)
closeTemplatePicker()
}
@@ -476,7 +488,7 @@ function shouldShowInput(item) {
function isNumericValueType(value) {
const normalized = String(value ?? '')
const label = String(valueTypeText(value) || '').toLowerCase()
- return normalized === '2' || /数值|数字|number|numeric|digit|decimal/.test(label)
+ return normalized === '2' || /鏁板€紎鏁板瓧|number|numeric|digit|decimal/.test(label)
}
function numberInputValue(item) {
@@ -485,6 +497,7 @@ function numberInputValue(item) {
}
function onNumberInputChange(item, value) {
+ if (!ticketResultEditable.value) return
item.textInput = String(value)
}
@@ -513,10 +526,12 @@ function resultOptionClass(item, value) {
}
function setDecision(item, value) {
+ if (!ticketResultEditable.value) return
item.inspectionResult = String(value)
}
async function chooseImages(item) {
+ if (!ticketResultEditable.value) return
try {
const currentCount = parseImages(item.images).length
const remain = Math.max(0, 3 - currentCount)
@@ -546,6 +561,7 @@ async function chooseImages(item) {
}
function removeImage(item, index) {
+ if (!ticketResultEditable.value) return
const next = parseImages(item.images)
next.splice(index, 1)
item.images = next.join(',')
@@ -572,6 +588,19 @@ function goBack() {
uni.navigateBack()
}
+function toggleTicketResultEditable() {
+ if (ticketResultEditable.value) {
+ if (ticketResultBackup.value) {
+ inspectionItems.value = JSON.parse(JSON.stringify(ticketResultBackup.value))
+ ticketResultBackup.value = null
+ }
+ ticketResultEditable.value = false
+ return
+ }
+ ticketResultBackup.value = JSON.parse(JSON.stringify(inspectionItems.value))
+ ticketResultEditable.value = true
+}
+
async function handleSubmit() {
if (submitLoading.value) return
@@ -591,7 +620,7 @@ async function handleSubmit() {
}
const hasUnselected = inspectionItems.value.some((item) => String(item?.inspectionResult || '0') === '0')
- if (inspectionItems.value.length && hasUnselected) {
+ if (ticketResultEditable.value && inspectionItems.value.length && hasUnselected) {
uni.showToast({ title: t('moldCheck.selectAllDecisionError'), icon: 'none' })
return
}
@@ -665,6 +694,11 @@ async function handleSubmit() {
.template-select { display: flex; align-items: center; justify-content: space-between; height: 88rpx; padding: 0 24rpx; background: #f8fafc; border-radius: 14rpx; }
.template-text { font-size: 28rpx; color: #374151; }
.template-text.placeholder { color: #9ca3af; }
+.inspection-section { display: flex; flex-direction: column; gap: 16rpx; }
+.inspection-toolbar { display: flex; align-items: center; justify-content: space-between; gap: 16rpx; padding: 0 4rpx; }
+.inspection-toolbar-title { font-size: 30rpx; font-weight: 700; color: #1f2937; }
+.edit-toggle-btn { height: 60rpx; padding: 0 18rpx; border-radius: 999rpx; border: 1rpx solid #bfdbfe; background: #eff6ff; color: #1f7cff; font-size: 24rpx; font-weight: 600; display: flex; align-items: center; gap: 8rpx; flex-shrink: 0; }
+.edit-toggle-btn.active { border-color: #fecaca; background: #fef2f2; color: #ef4444; }
.inspection-list { display: flex; flex-direction: column; gap: 20rpx; }
.inspection-card { background: #ffffff; border-radius: 24rpx; padding: 24rpx; box-shadow: 0 6rpx 18rpx rgba(15, 23, 42, 0.05); }
.inspection-header { display: flex; align-items: center; gap: 16rpx; }
@@ -681,6 +715,7 @@ async function handleSubmit() {
.result-option { min-width: 160rpx; height: 72rpx; padding: 0 24rpx; border-radius: 14rpx; border: 1rpx solid #d1d5db; color: #6b7280; font-size: 30rpx; display: flex; align-items: center; justify-content: center; background: #ffffff; }
.result-option-active { border-color: #60a5fa; background: #eff6ff; color: #1f7cff; }
.result-option-danger { border-color: #fca5a5; background: #fef2f2; color: #ef4444; }
+.result-option-disabled { opacity: 0.55; }
.pending-tag { padding: 8rpx 14rpx; border-radius: 10rpx; background: #f3f4f6; color: #9ca3af; font-size: 24rpx; }
.form-textarea { width: 100%; min-height: 76rpx; max-height: 108rpx; background: #f8fafc; border-radius: 12rpx; padding: 10rpx 16rpx; font-size: 26rpx; color: #374151; box-sizing: border-box; }
.number-box-wrap { width: 100%; }
@@ -696,10 +731,10 @@ async function handleSubmit() {
.image-upload { width: 140rpx; height: 140rpx; border-radius: 16rpx; border: 2rpx dashed #cbd5e1; background: #f8fafc; display: flex; align-items: center; justify-content: center; }
.image-upload-icon { font-size: 60rpx; color: #94a3b8; line-height: 1; }
.hint { padding: 48rpx 0; text-align: center; color: #9ca3af; font-size: 26rpx; }
-.action-bar { position: fixed; left: 0; right: 0; bottom: 0; display: flex; gap: 20rpx; padding: 20rpx 24rpx calc(20rpx + env(safe-area-inset-bottom)); background: #f5f7fb; }
-.action-btn { flex: 1; height: 88rpx; border-radius: 18rpx; display: flex; align-items: center; justify-content: center; font-size: 30rpx; font-weight: 600; }
-.back-btn { background: #ffffff; color: #1f7cff; border: 1rpx solid #bfdbfe; }
-.submit-btn { background: linear-gradient(135deg, #1f7cff, #3b82f6); color: #ffffff; }
+.action-bar { position: fixed; left: 0; right: 0; bottom: 0; display: flex; gap: 18rpx; padding: 18rpx 24rpx calc(18rpx + env(safe-area-inset-bottom)); background: #ffffff; box-shadow: 0 -8rpx 24rpx rgba(15, 23, 42, 0.06); }
+.action-btn { flex: 1; height: 84rpx; border-radius: 16rpx; display: flex; align-items: center; justify-content: center; font-size: 30rpx; font-weight: 600; }
+.back-btn { background: #eef2f7; color: #475569; }
+.submit-btn { background: #1f4b79; color: #ffffff; }
.action-btn-disabled { background: #94a3b8; }
.picker-mask { position: fixed; left: 0; right: 0; top: 0; bottom: 0; background: rgba(0, 0, 0, 0.5); z-index: 100; display: flex; align-items: flex-end; }
.picker-popup { width: 100%; background: #ffffff; border-radius: 24rpx 24rpx 0 0; padding-bottom: env(safe-area-inset-bottom); }
diff --git a/src/pages_function/pages/moldCheck/detail.vue b/src/pages_function/pages/moldCheck/detail.vue
index e62205f..f5a972a 100644
--- a/src/pages_function/pages/moldCheck/detail.vue
+++ b/src/pages_function/pages/moldCheck/detail.vue
@@ -82,10 +82,10 @@
encodeURI(i)))"
/>
×
@@ -346,6 +346,7 @@ async function handleSave() {
try {
await batchUpdateMoldCheckResults(payload)
detailData.jobStatus = 1
+ uni.setStorageSync('moldCheckListNeedRefresh', '1')
uni.showToast({ title: t('functionCommon.saveSuccess'), icon: 'success' })
await fetchResults()
} catch (error) {
@@ -416,9 +417,9 @@ function normalizeTextInput(value) {
.image-upload { width: 140rpx; height: 140rpx; border-radius: 16rpx; border: 2rpx dashed #cbd5e1; background: #f8fafc; display: flex; align-items: center; justify-content: center; }
.image-upload-icon { font-size: 60rpx; color: #94a3b8; line-height: 1; }
.hint { padding: 48rpx 0; text-align: center; color: #9ca3af; font-size: 26rpx; }
-.action-bar { position: fixed; left: 0; right: 0; bottom: 0; display: flex; gap: 20rpx; padding: 20rpx 24rpx calc(20rpx + env(safe-area-inset-bottom)); background: #f5f7fb; }
-.action-btn { flex: 1; height: 88rpx; border-radius: 18rpx; display: flex; align-items: center; justify-content: center; font-size: 30rpx; font-weight: 600; }
-.back-btn { background: #ffffff; color: #1f7cff; border: 1rpx solid #bfdbfe; }
-.save-btn { background: linear-gradient(135deg, #1f7cff, #3b82f6); color: #ffffff; }
+.action-bar { position: fixed; left: 0; right: 0; bottom: 0; display: flex; gap: 18rpx; padding: 18rpx 24rpx calc(18rpx + env(safe-area-inset-bottom)); background: #ffffff; box-shadow: 0 -8rpx 24rpx rgba(15, 23, 42, 0.06); }
+.action-btn { flex: 1; height: 84rpx; border-radius: 16rpx; display: flex; align-items: center; justify-content: center; font-size: 30rpx; font-weight: 600; }
+.back-btn { background: #eef2f7; color: #475569; }
+.save-btn { background: #1f4b79; color: #ffffff; }
.action-btn-disabled { background: #94a3b8; }
-
\ No newline at end of file
+
diff --git a/src/pages_function/pages/moldLedger/index.vue b/src/pages_function/pages/moldLedger/index.vue
index 078e280..04740c5 100644
--- a/src/pages_function/pages/moldLedger/index.vue
+++ b/src/pages_function/pages/moldLedger/index.vue
@@ -10,7 +10,9 @@
type="text"
:placeholder="t('moldLedger.searchPlaceholder')"
placeholder-class="placeholder"
+ :focus="keywordFocus"
confirm-type="search"
+ @blur="keywordFocus = false"
@confirm="handleSearch"
/>
@@ -19,9 +21,6 @@
{{ t('common.reset') }}
-
-
-
+
+
diff --git a/src/pages_function/pages/moldMaintain/detail.vue b/src/pages_function/pages/moldMaintain/detail.vue
new file mode 100644
index 0000000..3703069
--- /dev/null
+++ b/src/pages_function/pages/moldMaintain/detail.vue
@@ -0,0 +1,425 @@
+
+
+
+
+
+
+
+
+ {{ textValue(detailData.moldName) }}
+
+
+ {{ t('moldMaintain.taskType') }}:
+ {{ planTypeText }}
+
+
+ {{ t('moldMaintain.planNo') }}:
+ {{ textValue(detailData.planNo) }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ t('functionCommon.loading') }}
+ {{ t('moldMaintain.noResultData') }}
+
+
+
+
+
+ {{ t('moldMaintain.inspectionMethod') }}
+ {{ inspectionMethodText(item.inspectionMethod) }}
+
+
+ {{ t('moldMaintain.judgmentCriteria') }}
+ {{ textValue(item.judgmentCriteria) }}
+
+
+
+ {{ t('moldMaintain.textInput') }}
+
+
+
+
+
+ {{ t('moldMaintain.textInput') }}
+
+ {{ textInputDisplay(item) }}
+
+
+
+ {{ t('moldMaintain.images') }}
+
+
+ encodeURI(i)))"
+ />
+ ×
+
+
+ +
+
+
+
+
+
+ {{ t('moldMaintain.remark') }}
+ {{ textValue(item.remark) }}
+
+
+
+ {{ t('moldMaintain.resultText') }}
+
+
+ {{ t('moldMaintain.inspectionResultPass') }}
+
+
+ {{ t('moldMaintain.inspectionResultFail') }}
+
+ {{ t('moldMaintain.inspectionResultPending') }}
+
+
+
+
+
+
+
+
+
+ {{ t('dashboard.back') }}
+ {{ t('functionCommon.save') }}
+
+
+
+
+
+
+
diff --git a/src/pages_function/pages/moldMaintain/index.vue b/src/pages_function/pages/moldMaintain/index.vue
new file mode 100644
index 0000000..9d1eea3
--- /dev/null
+++ b/src/pages_function/pages/moldMaintain/index.vue
@@ -0,0 +1,560 @@
+
+
+
+
+
+
+
+
+
+
+ {{ currentJobStatusLabel }}
+
+
+
+ {{ t('functionCommon.reset') }}
+
+
+
+
+
+
+
+
+ {{ t('moldMaintain.moldName') }}
+ {{ textValue(item.moldName) }}
+
+
+ {{ t('moldMaintain.template') }}
+ {{ textValue(item.configName) }}
+
+
+ {{ t('moldMaintain.operator') }}
+ {{ textValue(item.operatorName) }}
+
+
+ {{ t('moldMaintain.taskTime') }}
+ {{ formatDateTime(item.taskTime) }}
+
+
+
+
+
+ {{ t('functionCommon.loading') }}
+ {{ t('moldMaintain.empty') }}
+ {{ t('functionCommon.loadingMore') }}
+ {{ t('functionCommon.noMoreData') }}
+
+
+
+
+
+
+
+
+ +
+
+
+
+
+
+
+
diff --git a/src/pages_function/pages/moldPressureNet/history.vue b/src/pages_function/pages/moldPressureNet/history.vue
new file mode 100644
index 0000000..9f2dd36
--- /dev/null
+++ b/src/pages_function/pages/moldPressureNet/history.vue
@@ -0,0 +1,233 @@
+
+
+
+
+
+
+
+
+
+ {{ pressureNetTimeFilter || t('moldPressureNet.pressureNetTime') }}
+
+
+ {{ t('functionCommon.search') }}
+ {{ t('functionCommon.reset') }}
+
+
+
+
+
+
+
+
+ {{ t('moldPressureNet.moldGroup') }}
+ {{ item.moldBrandName || '-' }}
+
+
+ {{ t('moldPressureNet.createTime') }}
+ {{ formatDateTime(item.createTime) }}
+
+
+ {{ t('moldPressureNet.remark') }}
+ {{ item.remark || '-' }}
+
+
+
+
+ {{ t('functionCommon.loading') }}
+ {{ t('moldPressureNet.noHistory') }}
+ {{ t('functionCommon.loadingMore') }}
+ {{ t('functionCommon.noMoreData') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages_function/pages/moldPressureNet/index.vue b/src/pages_function/pages/moldPressureNet/index.vue
new file mode 100644
index 0000000..c901f4e
--- /dev/null
+++ b/src/pages_function/pages/moldPressureNet/index.vue
@@ -0,0 +1,432 @@
+
+
+
+
+
+
+ {{ t('moldPressureNet.history') }}
+
+
+
+
+
+
+
+
+
+
+ {{ t('moldPressureNet.selectMoldGroup') }}*
+
+
+ {{ selectedBrand.id ? (selectedBrand.name || selectedBrand.code || '-') : t('moldPressureNet.selectMoldGroup') }}
+ {{ selectedBrand.code || t('moldPressureNet.reSelectMoldGroup') }}
+
+
+
+
+
+
+
+ {{ t('moldPressureNet.moldGroupCode') }}
+ {{ selectedBrand.code || '-' }}
+
+
+ {{ t('moldPressureNet.moldGroupName') }}
+ {{ selectedBrand.name || '-' }}
+
+
+ {{ t('moldPressureNet.product') }}
+ {{ selectedBrand.productName || '-' }}
+
+
+
+
+
+
+
+
+
+ {{ t('moldPressureNet.selectSubMold') }}*
+
+
+ {{ selectedSubMoldIds.length ? t('moldPressureNet.selectedCount', { count: selectedSubMoldIds.length }) : t('moldPressureNet.selectSubMold') }}
+ {{ t('moldPressureNet.reSelectSubMold') }}
+
+
+
+
+
+
+ {{ item.name || item.code || '-' }}
+ ×
+
+
+
+
+
+
+
+
+ {{ t('moldPressureNet.pressureNetTime') }}*
+
+
+
+ {{ t('moldPressureNet.remark') }}
+
+
+
+
+
+
+
+ {{ t('functionCommon.cancel') }}
+
+ {{ t('moldPressureNet.confirmReplace') }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/pages_function/pages/moldRepair/form.vue b/src/pages_function/pages/moldRepair/form.vue
index 8694303..2030709 100644
--- a/src/pages_function/pages/moldRepair/form.vue
+++ b/src/pages_function/pages/moldRepair/form.vue
@@ -927,20 +927,20 @@ function goBack() {
.page-footer {
position: fixed;
- bottom: 0;
left: 0;
right: 0;
+ bottom: 0;
display: flex;
- gap: 20rpx;
- padding: 20rpx 32rpx calc(20rpx + env(safe-area-inset-bottom));
+ gap: 18rpx;
+ padding: 18rpx 24rpx calc(18rpx + env(safe-area-inset-bottom));
background: #ffffff;
- box-shadow: 0 -2rpx 12rpx rgba(0, 0, 0, 0.04);
+ box-shadow: 0 -8rpx 24rpx rgba(15, 23, 42, 0.06);
}
.footer-btn {
flex: 1;
height: 84rpx;
- border-radius: 42rpx;
+ border-radius: 16rpx;
display: flex;
align-items: center;
justify-content: center;
@@ -949,12 +949,12 @@ function goBack() {
}
.footer-btn.cancel {
- background: #f3f4f6;
- color: #4b5563;
+ background: #eef2f7;
+ color: #475569;
}
.footer-btn.confirm {
background: #1f4b79;
color: #ffffff;
}
-
\ No newline at end of file
+
diff --git a/src/pages_function/pages/moldRepair/index.vue b/src/pages_function/pages/moldRepair/index.vue
index 6f9e446..4b9d9b5 100644
--- a/src/pages_function/pages/moldRepair/index.vue
+++ b/src/pages_function/pages/moldRepair/index.vue
@@ -24,9 +24,6 @@
{{ t('functionCommon.reset') }}
-
-
-
{{ t('moldOperate.productionLine') }}
- {{ textValue(device.workshopName) }}
+ {{ getTopLineName(device.deviceLine) }}
{{ t('moldOperate.currentMold') }}
@@ -68,6 +68,7 @@ import { onShow } from '@dcloudio/uni-app'
import { useI18n } from 'vue-i18n'
import NavBar from '@/components/common/NavBar.vue'
import { getDeviceLedgerList } from '@/api/mes/moldoperate'
+import { getDeviceLineTree } from '@/api/mes/deviceLine'
const { t } = useI18n()
@@ -76,6 +77,8 @@ const selectedId = ref(null)
const searchText = ref('')
const loading = ref(false)
+const lineInfoMap = ref(new Map())
+
function textValue(v) {
if (v === 0) return '0'
if (v == null) return '-'
@@ -163,13 +166,64 @@ function getCurrentMold(device) {
return staticMold === '-' ? t('moldOperate.noMoldOnDevice') : staticMold
}
+function flattenLineTree(nodes, parentId) {
+ if (!Array.isArray(nodes)) return
+ for (const node of nodes) {
+ if (node.id != null && node.name != null) {
+ lineInfoMap.value.set(String(node.id), {
+ id: node.id,
+ name: node.name,
+ parentId: node.parentId != null ? node.parentId : (parentId || null),
+ parentChain: node.parentChain || ''
+ })
+ }
+ if (Array.isArray(node.children)) {
+ flattenLineTree(node.children, node.id)
+ }
+ }
+}
+
+function getTopLineName(deviceLineId) {
+ if (deviceLineId == null) return '-'
+ const node = lineInfoMap.value.get(String(deviceLineId))
+ if (!node) return '-'
+ if (node.parentChain) {
+ const firstId = node.parentChain.split(',')[0]?.trim()
+ if (firstId) {
+ const topNode = lineInfoMap.value.get(firstId)
+ if (topNode) return topNode.name
+ }
+ }
+ let current = node
+ const visited = new Set()
+ while (current.parentId != null && current.parentId > 0 && !visited.has(current.id)) {
+ visited.add(current.id)
+ const parent = lineInfoMap.value.get(String(current.parentId))
+ if (!parent) break
+ current = parent
+ }
+ return current.name || '-'
+}
+
+async function loadLineTree() {
+ if (lineInfoMap.value.size > 0) return
+ try {
+ const res = await getDeviceLineTree()
+ const tree = (res && res.data !== undefined) ? res.data : res
+ const nodes = Array.isArray(tree) ? tree : (tree?.list || tree?.children || [])
+ flattenLineTree(nodes)
+ } catch (e) {
+ console.error('load line tree error', e)
+ }
+}
+
const filteredList = computed(() => {
const keyword = searchText.value.trim().toLowerCase()
if (!keyword) return deviceList.value
return deviceList.value.filter((d) => {
return (d.deviceName || '').toLowerCase().includes(keyword) ||
(d.deviceCode || '').toLowerCase().includes(keyword) ||
- (d.workshopName || '').toLowerCase().includes(keyword)
+ (getTopLineName(d.deviceLine) || '').toLowerCase().includes(keyword)
})
})
@@ -203,13 +257,19 @@ function handleConfirm() {
return
}
const device = deviceList.value.find((d) => d.id === selectedId.value)
+ if (device) {
+ const lineName = getTopLineName(device.deviceLine)
+ if (lineName && lineName !== '-') {
+ device.workshopName = lineName
+ }
+ }
// 存入 globalData 后再返回,目标页 onShow 中读取
getApp().globalData._deviceSelectResult = device || null
uni.navigateBack()
}
onShow(async () => {
- await loadDevices()
+ await Promise.allSettled([loadDevices(), loadLineTree()])
})
@@ -343,7 +403,7 @@ onShow(async () => {
left: 0;
right: 0;
bottom: 0;
- padding: 16rpx 24rpx calc(16rpx + env(safe-area-inset-bottom));
+ padding: 18rpx 24rpx calc(18rpx + env(safe-area-inset-bottom));
background: #fff;
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.06);
z-index: 99;
@@ -351,16 +411,16 @@ onShow(async () => {
.bottom-btn {
width: 100%;
- height: 88rpx;
- line-height: 88rpx;
+ height: 84rpx;
+ line-height: 84rpx;
text-align: center;
- border-radius: 12rpx;
+ border-radius: 16rpx;
font-size: 30rpx;
font-weight: 600;
}
.confirm-btn {
- background: #2563eb;
+ background: #1f4b79;
color: #fff;
}
diff --git a/src/pages_function/pages/moldoperate/dismount.vue b/src/pages_function/pages/moldoperate/dismount.vue
index e802b79..ada878e 100644
--- a/src/pages_function/pages/moldoperate/dismount.vue
+++ b/src/pages_function/pages/moldoperate/dismount.vue
@@ -1,6 +1,14 @@
-
+
+
+
+
+
+ {{ t('moldPressureNet.history') }}
+
+
+
@@ -38,7 +46,7 @@
{{ t('moldOperate.productionLine') }}
- {{ textValue(selectedDevice.workshopName) }}
+ {{ getTopLineName(selectedDevice.deviceLine) }}
{{ t('moldOperate.deviceStatus') }}
@@ -98,13 +106,68 @@
-
- + {{ t('moldOperate.clickSelectDeviceFirst') }}
+
+ {{ t('moldOperate.clickSelectDeviceFirst') }}
+
+
+
+
+
+
+
+ {{ t('moldOperate.operator') + ' & ' + t('moldOperate.remark') }}
+
+
+
+
+ *{{ t('moldOperate.operator') }}
+
+
+
+ {{ selectedOperator ? selectedOperator.label : t('moldOperate.placeholderOperator') }}
+
+
+
+
+
+
+ {{ item.label }}
+
+
+ 暂无数据
+
+
+
+
+
+
+
+ {{ t('moldOperate.remark') }}
+
+
+
+ {{ t('functionCommon.cancel') }}
{{ t('moldOperate.confirmDismount') }}
@@ -140,9 +203,71 @@ 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 { getDeviceLineTree } from '@/api/mes/deviceLine'
+import { getSimpleUserList } from '@/api/system/user'
const { t } = useI18n()
+const lineInfoMap = ref(new Map()) // deviceLine id → { name, parentId, parentChain }
+
+// 递归拍平产线树(保存完整节点信息用于向上追溯)
+function flattenLineTree(nodes, parentId) {
+ if (!Array.isArray(nodes)) return
+ for (const node of nodes) {
+ if (node.id != null && node.name != null) {
+ lineInfoMap.value.set(String(node.id), {
+ id: node.id,
+ name: node.name,
+ parentId: node.parentId != null ? node.parentId : (parentId || null),
+ parentChain: node.parentChain || ''
+ })
+ }
+ if (Array.isArray(node.children)) {
+ flattenLineTree(node.children, node.id)
+ }
+ }
+}
+
+// 根据设备产线节点,向上追溯顶层产线名称(参考后端 fillTopCategoryInfo 逻辑)
+function getTopLineName(deviceLineId) {
+ if (deviceLineId == null) return '-'
+ const node = lineInfoMap.value.get(String(deviceLineId))
+ if (!node) return String(deviceLineId)
+
+ // 策略1:通过 parentChain 取第一个 ID(最顶层)
+ if (node.parentChain) {
+ const firstId = node.parentChain.split(',')[0]?.trim()
+ if (firstId) {
+ const topNode = lineInfoMap.value.get(firstId)
+ if (topNode) return topNode.name
+ }
+ }
+
+ // 策略2:通过 parentId 向上遍历直到根节点
+ let current = node
+ const visited = new Set()
+ while (current.parentId != null && current.parentId > 0 && !visited.has(current.id)) {
+ visited.add(current.id)
+ const parent = lineInfoMap.value.get(String(current.parentId))
+ if (!parent) break
+ current = parent
+ }
+ return current.name || String(deviceLineId)
+}
+
+// 加载产线树
+async function loadLineTree() {
+ if (lineInfoMap.value.size > 0) return
+ try {
+ const res = await getDeviceLineTree()
+ const tree = (res && res.data !== undefined) ? res.data : res
+ const nodes = Array.isArray(tree) ? tree : (tree?.list || tree?.children || [])
+ flattenLineTree(nodes)
+ } catch (e) {
+ console.error('load line tree error', e)
+ }
+}
+
// ---- 设备相关 ----
const selectedDevice = ref({})
const deviceOptions = ref([])
@@ -155,6 +280,13 @@ const lowerMoldLoading = ref(false)
const moldsLoaded = ref(false)
const tempSelectedMoldId = ref(null)
+// ---- 操作人与备注 ----
+const remarkText = ref('')
+const operatorOptions = ref([])
+const selectedOperator = ref(null)
+const operatorIndex = ref(-1)
+const showOperatorDropdown = ref(false)
+
// ---- 工具函数 ----
function textValue(v) {
if (v === 0) return '0'
@@ -372,8 +504,40 @@ function confirmLowerMoldSelection() {
function closeLowerMoldPicker() { lowerMoldPickerRef.value?.close() }
-function handleSelectDeviceFirst() {
- openDevicePicker()
+// ---- 操作人列表加载 ----
+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 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' })
+}
+
+function goBack() {
+ uni.navigateBack({ fail: () => uni.switchTab({ url: '/pages/index/index' }) })
}
// ---- 提交 ----
@@ -386,16 +550,30 @@ function validForm() {
uni.showToast({ title: t('moldOperate.validatorLowerMoldRequired'), icon: 'none' })
return false
}
+ if (!selectedOperator.value) {
+ uni.showToast({ title: t('moldOperate.validatorOperatorRequired'), icon: 'none' })
+ return false
+ }
return true
}
async function handleConfirm() {
if (!validForm()) return
try {
+ const device = selectedDevice.value
const payload = {
operateType: '2',
- deviceId: String(selectedDevice.value.id),
- moldId: String(selectedMold.value.id)
+ deviceId: String(device.id),
+ moldId: String(selectedMold.value.id),
+ lineId: device.deviceLine != null ? String(device.deviceLine) : undefined,
+ lineName: device.deviceLine != null ? getTopLineName(device.deviceLine) : (device.lineName || undefined)
+ }
+ // 添加操作人和备注
+ if (selectedOperator.value) {
+ payload.operatorId = selectedOperator.value.value
+ }
+ if (remarkText.value.trim()) {
+ payload.remark = remarkText.value.trim()
}
console.log('[下模] 提交参数 =', JSON.stringify(payload))
await createMoldOperate(payload)
@@ -412,6 +590,9 @@ async function handleConfirm() {
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) || '系统异常'
@@ -419,8 +600,15 @@ async function handleConfirm() {
}
}
+function handleCancel() {
+ // 返回上一页(管理页面)
+ uni.navigateBack({
+ fail: () => uni.switchTab({ url: '/pages/work' })
+ })
+}
+
onShow(async () => {
- await Promise.allSettled([loadDevices()])
+ await Promise.allSettled([loadDevices(), loadLineTree(), loadOperators()])
// 从 globalData 读取设备选择页回传的设备
const device = getApp().globalData._deviceSelectResult
if (device) {
@@ -431,6 +619,23 @@ onShow(async () => {
diff --git a/src/pages_function/pages/moldoperate/index.vue b/src/pages_function/pages/moldoperate/index.vue
index fbf033c..656b25d 100644
--- a/src/pages_function/pages/moldoperate/index.vue
+++ b/src/pages_function/pages/moldoperate/index.vue
@@ -1,13 +1,14 @@
-
-
- <
-
- {{ t('moldOperate.tabUp') }}
-
-
+
+
+
+
+ {{ t('moldPressureNet.history') }}
+
+
+
@@ -104,10 +105,66 @@
+
+
+
+
+ {{ t('moldOperate.operator') + ' & ' + t('moldOperate.remark') }}
+
+
+
+
+ *{{ t('moldOperate.operator') }}
+
+
+
+
+ {{ selectedOperator ? selectedOperator.label : t('moldOperate.placeholderOperator') }}
+
+
+
+
+
+
+
+ {{ item.label }}
+
+
+ 暂无数据
+
+
+
+
+
+
+
+ {{ t('moldOperate.remark') }}
+
+
+
+
+
+
- {{ t('moldOperate.confirmMount') }}
{{ t('functionCommon.cancel') }}
+ {{ t('moldOperate.confirmMount') }}
@@ -117,7 +174,9 @@
import { computed, ref } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import { useI18n } from 'vue-i18n'
+import NavBar from '@/components/common/NavBar.vue'
import { getDeviceLedgerList, createMoldOperate } from '@/api/mes/moldoperate'
+import { getSimpleUserList } from '@/api/system/user'
const { t } = useI18n()
@@ -157,6 +216,10 @@ const selectedDevice = ref({})
const selectedMountMolds = ref([])
const tempSelectedDeviceId = ref(null)
+const remarkText = ref('')
+const operatorOptions = ref([])
+const selectedOperator = ref(null)
+const operatorIndex = ref(-1)
// 设备状态 - 上模
const deviceStatusClass = computed(() => {
@@ -238,6 +301,36 @@ const currentMoldDisplay = computed(() => {
return textValue(selectedDevice.value.currentMold)
})
+// ---- 操作人列表加载 ----
+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)
+ }
+}
+
+const showOperatorDropdown = ref(false)
+
+function toggleOperatorDropdown() {
+ showOperatorDropdown.value = !showOperatorDropdown.value
+}
+
+function closeOperatorDropdown() {
+ showOperatorDropdown.value = false
+}
+
+function handleSelectOperator(item, idx) {
+ selectedOperator.value = item
+ operatorIndex.value = idx
+ closeOperatorDropdown()
+}
+
function selectDevice(device) {
selectedDevice.value = device || {}
tempSelectedDeviceId.value = device ? device.id : null
@@ -269,6 +362,10 @@ function validFormMount() {
uni.showToast({ title: t('moldOperate.validatorMoldRequired'), icon: 'none' })
return false
}
+ if (!selectedOperator.value) {
+ uni.showToast({ title: t('moldOperate.validatorOperatorRequired'), icon: 'none' })
+ return false
+ }
return true
}
@@ -279,7 +376,16 @@ async function handleConfirmMount() {
const payload = {
operateType: '1',
deviceId: String(selectedDevice.value.id),
- moldId: moldIds.length === 1 ? String(moldIds[0]) : moldIds.map(String).join(',')
+ moldId: moldIds.length === 1 ? String(moldIds[0]) : moldIds.map(String).join(','),
+ lineName: selectedDevice.value.workshopName || '',
+ lineId: selectedDevice.value.deviceLine || ''
+ }
+ // 添加操作人和备注
+ if (selectedOperator.value) {
+ payload.operatorId = selectedOperator.value.value
+ }
+ if (remarkText.value.trim()) {
+ payload.remark = remarkText.value.trim()
}
console.log('=== 上模提交参数 ===', JSON.stringify(payload))
console.log('=== deviceId type:', typeof payload.deviceId, 'value:', payload.deviceId)
@@ -342,14 +448,21 @@ function handleScan() {
function handleCancel() {
selectedDevice.value = {}
selectedMountMolds.value = []
+ remarkText.value = ''
+ selectedOperator.value = null
+ operatorIndex.value = -1
+ // 返回上一页(管理页面)
+ uni.navigateBack({
+ fail: () => uni.switchTab({ url: '/pages/work' })
+ })
}
-function goBack() {
- uni.navigateBack({ fail: () => uni.switchTab({ url: '/pages/index/index' }) })
+function goToHistory() {
+ uni.navigateTo({ url: '/pages_function/pages/moldoperate/history?type=up' })
}
onShow(async () => {
- await Promise.allSettled([loadDevices()])
+ await Promise.allSettled([loadDevices(), loadOperators()])
// 从 globalData 读取设备选择页回传的设备
const device = getApp().globalData._deviceSelectResult
if (device) {
@@ -372,37 +485,21 @@ onShow(async () => {
padding-bottom: 140rpx;
}
-/* ====== 自定义导航栏 ====== */
-.custom-nav {
+/* ====== 导航栏右侧按钮 ====== */
+.nav-right-btn {
display: flex;
align-items: center;
- justify-content: space-between;
- height: 88rpx;
- padding: 0 24rpx;
- background: #1a365d;
- color: #fff;
-
- .nav-back {
- width: 60rpx;
- height: 60rpx;
- display: flex;
- align-items: center;
- justify-content: center;
- }
-
- .back-icon {
- font-size: 36rpx;
- font-weight: bold;
- }
-
- .nav-title {
- font-size: 34rpx;
- font-weight: 600;
- }
+ gap: 6rpx;
+ padding: 8rpx 18rpx;
+ background: #ffffff;
+ border-radius: 999rpx;
+ box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.08);
+}
- .nav-placeholder {
- width: 60rpx;
- }
+.nav-right-text {
+ font-size: 24rpx;
+ color: #374151;
+ font-weight: 500;
}
/* ====== 操作按钮区 ====== */
@@ -420,7 +517,7 @@ onShow(async () => {
gap: 12rpx;
height: 96rpx;
border-radius: 12rpx;
- background: #2563eb;
+ background: #1f4b79;
color: #fff;
font-size: 28rpx;
font-weight: 600;
@@ -448,7 +545,6 @@ onShow(async () => {
margin: 16rpx 24rpx;
background: #ffffff;
border-radius: 14rpx;
- overflow: hidden;
}
.section-title-bar {
@@ -567,6 +663,132 @@ onShow(async () => {
.change-text { font-size: 26rpx; color: #666; }
}
+/* ====== 表单行(操作人/备注) ====== */
+.form-row {
+ margin-top: 18rpx;
+
+ &:first-child {
+ margin-top: 0;
+ }
+}
+
+.form-cell {
+ width: 100%;
+
+ .form-label {
+ display: block;
+ font-size: 24rpx;
+ color: #999;
+ margin-bottom: 8rpx;
+
+ .required {
+ color: #dc2626;
+ margin-right: 4rpx;
+ }
+ }
+}
+
+
+
+/* ====== 下拉选择器(操作人) ====== */
+.select-dropdown {
+ position: relative;
+ width: 100%;
+}
+
+.dropdown-input {
+ display: flex;
+ align-items: center;
+ height: 72rpx;
+ padding: 0 20rpx;
+ border: 1rpx solid #e0e0e0;
+ border-radius: 10rpx;
+ font-size: 27rpx;
+ color: #333;
+ background: #f9fafb;
+}
+
+.dropdown-value {
+ flex: 1;
+
+ &.placeholder {
+ color: #bbb;
+ }
+}
+
+.dropdown-arrow {
+ position: absolute;
+ right: 16rpx;
+ top: 50%;
+ transform: translateY(-50%);
+ pointer-events: none;
+}
+
+/* ====== 下拉面板(在输入框下方展开) ====== */
+.dropdown-panel {
+ position: absolute;
+ top: 76rpx;
+ left: 0;
+ right: 0;
+ z-index: 99;
+ background: #ffffff;
+ border: 1rpx solid #e0e0e0;
+ border-radius: 12rpx;
+ box-shadow: 0 8rpx 30rpx rgba(0, 0, 0, 0.1);
+ overflow: hidden;
+}
+
+.dropdown-scroll {
+ max-height: 400rpx;
+}
+
+.dropdown-item {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 22rpx 28rpx;
+ font-size: 27rpx;
+ color: #333;
+ border-bottom: 1rpx solid #f5f5f5;
+
+ &:last-child {
+ border-bottom: none;
+ }
+
+ &:active {
+ background: #f5f7fa;
+ }
+
+ &.active {
+ color: #1f7cff;
+ background: #f0f7ff;
+ }
+}
+
+.dropdown-item-text {
+ flex: 1;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.dropdown-empty {
+ padding: 32rpx;
+ text-align: center;
+ font-size: 26rpx;
+ color: #999;
+}
+
+.form-input {
+ height: 72rpx;
+ padding: 0 20rpx;
+ border: 1rpx solid #e0e0e0;
+ border-radius: 10rpx;
+ font-size: 27rpx;
+ color: #333;
+ background: #f9fafb;
+}
+
/* ====== 空提示 ====== */
.empty-mold-hint {
padding: 40rpx 24rpx;
@@ -593,10 +815,10 @@ onShow(async () => {
right: 0;
bottom: 0;
display: flex;
- gap: 20rpx;
- padding: 16rpx 24rpx calc(16rpx + env(safe-area-inset-bottom));
- background: #fff;
- box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.06);
+ gap: 18rpx;
+ padding: 18rpx 24rpx calc(18rpx + env(safe-area-inset-bottom));
+ background: #ffffff;
+ box-shadow: 0 -8rpx 24rpx rgba(15, 23, 42, 0.06);
z-index: 99;
&.single-btn {
@@ -605,25 +827,23 @@ onShow(async () => {
}
.bottom-btn {
- height: 88rpx;
- line-height: 88rpx;
+ flex: 1;
+ height: 84rpx;
+ line-height: 84rpx;
text-align: center;
- border-radius: 12rpx;
+ border-radius: 16rpx;
font-size: 30rpx;
font-weight: 600;
}
.confirm-btn {
- flex: 1;
- background: #2563eb;
- color: #fff;
+ background: #1f4b79;
+ color: #ffffff;
}
.cancel-btn {
- flex: 1;
- background: #fff;
- color: #666;
- border: 1rpx solid #ddd;
+ background: #eef2f7;
+ color: #475569;
}
diff --git a/src/pages_function/pages/moldoperate/moldSelect.vue b/src/pages_function/pages/moldoperate/moldSelect.vue
index f7692e1..cfe4b3d 100644
--- a/src/pages_function/pages/moldoperate/moldSelect.vue
+++ b/src/pages_function/pages/moldoperate/moldSelect.vue
@@ -328,7 +328,7 @@ onShow(async () => {
left: 0;
right: 0;
bottom: 0;
- padding: 16rpx 24rpx calc(16rpx + env(safe-area-inset-bottom));
+ padding: 18rpx 24rpx calc(18rpx + env(safe-area-inset-bottom));
background: #fff;
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.06);
z-index: 99;
@@ -336,16 +336,16 @@ onShow(async () => {
.bottom-btn {
width: 100%;
- height: 88rpx;
- line-height: 88rpx;
+ height: 84rpx;
+ line-height: 84rpx;
text-align: center;
- border-radius: 12rpx;
+ border-radius: 16rpx;
font-size: 30rpx;
font-weight: 600;
}
.confirm-btn {
- background: #2563eb;
+ background: #1f4b79;
color: #fff;
}
diff --git a/src/utils/permissionMenu.js b/src/utils/permissionMenu.js
index b4a7d31..f61f7e5 100644
--- a/src/utils/permissionMenu.js
+++ b/src/utils/permissionMenu.js
@@ -30,6 +30,15 @@ const MENU_ROUTE_MAP = {
moldtaskconfig: '/pages_function/pages/moldTaskConfiguration/index',
'点检记录': '/pages_function/pages/moldWorkOrderInquiry/index',
moldworkorderinquiry: '/pages_function/pages/moldWorkOrderInquiry/index',
+ '模具保养': '/pages_function/pages/moldMaintain/index',
+ '保养记录': '/pages_function/pages/moldMaintain/index',
+ moldmaintain: '/pages_function/pages/moldMaintain/index',
+ moldmaintenance: '/pages_function/pages/moldMaintain/index',
+ '更换压网': '/pages_function/pages/moldPressureNet/index',
+ '压网更换': '/pages_function/pages/moldPressureNet/index',
+ '压网记录': '/pages_function/pages/moldPressureNet/index',
+ moldpressurenet: '/pages_function/pages/moldPressureNet/index',
+ pressurenet: '/pages_function/pages/moldPressureNet/index',
'产品物料分类': '/pages_function/pages/materialCategory/index',
materialcategory: '/pages_function/pages/materialCategory/index',
'产品物料信息': '/pages_function/pages/materialInfo/index',
diff --git a/static/logo/history.png b/static/logo/history.png
new file mode 100644
index 0000000..13a7873
Binary files /dev/null and b/static/logo/history.png differ