diff --git a/src/locales/en-US.js b/src/locales/en-US.js index fad32ff..1360bf5 100644 --- a/src/locales/en-US.js +++ b/src/locales/en-US.js @@ -864,13 +864,13 @@ export default { deviceType: 'Device Type', deviceStatus: 'Device Status', lineFilter: 'Line', - allFilter: 'All Filters', - moreFilter: 'More Filters', - categoryStatus: 'Category & Status', - categoryInfo: 'Category Info', - dateFilter: 'Date Filter', - deviceBrand: 'Device Brand', - sn: 'Serial No.', + allFilter: 'All Filters', + moreFilter: 'More Filters', + categoryStatus: 'Category & Status', + categoryInfo: 'Category Info', + dateFilter: 'Date Filter', + deviceBrand: 'Device Brand', + sn: 'Serial No.', scanUnrecognized: 'QR code content not recognized', scanTypeMismatch: 'QR code type does not match', scanFailed: 'Scan failed', @@ -880,7 +880,7 @@ export default { dailyAverageValue: 'Daily Avg Value', dataCollectionCapacity: 'Data Collection Capacity', productionDate: 'Production Date', - outgoingTime: 'Outgoing Date', + outgoingTime: 'Outgoing Date', factoryEntryDate: 'Factory Entry Date', deviceLocation: 'Device Location', deviceManagerName: 'Device Manager', @@ -900,17 +900,17 @@ export default { loadFailed: 'Failed to load equipment detail', placeholderDeviceCode: 'Enter device code', placeholderDeviceName: 'Enter device name', - placeholderDeviceBrand: 'Enter device brand', - placeholderSn: 'Enter serial number', + placeholderDeviceBrand: 'Enter device brand', + placeholderSn: 'Enter serial number', placeholderDeviceType: 'Select device type', placeholderDeviceSpec: 'Enter device spec', placeholderRatedCapacity: 'Enter rated capacity', placeholderDailyAverageValue: 'Enter daily average value', placeholderDataCollectionCapacity: 'Enter data collection capacity', placeholderProductionDate: 'Select production date', - placeholderOutgoingTime: 'Select outgoing date', - placeholderOutgoingStartTime: 'Start date', - placeholderOutgoingEndTime: 'End date', + placeholderOutgoingTime: 'Select outgoing date', + placeholderOutgoingStartTime: 'Start date', + placeholderOutgoingEndTime: 'End date', placeholderFactoryEntryDate: 'Select factory entry date', placeholderDeviceLocation: 'Enter device location', placeholderRemark: 'Enter remark', @@ -993,8 +993,17 @@ export default { statusPending: 'Pending Repair', statusPassed: 'Passed', statusRejected: 'Rejected', - placeholderRepairCode: 'Enter repair order no.', - placeholderRepairName: 'Enter repair order name', + statusDocumentPending: 'Pending', + statusDocumentFinished: 'Finished', + moreFilter: 'More Filters', + statusFilter: 'Status Filters', + dateFilter: 'Date Filters', placeholderRepairCode: 'Enter repair order no.', + placeholderRepairName: 'Enter repair order name', placeholderRequireStartDate: 'Report start date', + placeholderRequireEndDate: 'Report end date', + placeholderFinishStartDate: 'Completion start date', + placeholderFinishEndDate: 'Completion end date', + placeholderConfirmStartDate: 'Acceptance start date', + placeholderConfirmEndDate: 'Acceptance end date', placeholderRequireDate: 'Select report date', placeholderAcceptedBy: 'Select repair technician', placeholderConfirmBy: 'Select inspector', @@ -1747,30 +1756,30 @@ export default { outModeWholePallet: 'Whole Pallet', outModeSplitPallet: 'Split Pallet' }, - productInventory: { - moduleName: 'Product Inventory', - detailTitle: 'Product Inventory Detail', - searchPlaceholder: 'Enter product code or name', - allWarehouse: 'All Warehouses', - warehousePlaceholder: 'Warehouse Filter', - productInfo: 'Product Info', - stockInfo: 'Stock Info', - productName: 'Product Name', - barCode: 'Product Code', - warehouse: 'Warehouse', - area: 'Area', - count: 'Base Qty', - stockDisplay: 'Stock Display', - areaStockDisplay: 'Area Stock Display', - totalPackageCount: 'Total Packages', - totalBaseCount: 'Total Pieces', - unit: 'Unit', - category: 'Product Category', - standard: 'Spec', - packagingRule: 'Packaging/Conversion Rule', - latestInTime: 'Latest Inbound', - latestOutTime: 'Latest Outbound', - remark: 'Remark', - empty: 'No product inventory data', - noDetailId: 'No product inventory ID' - }} + productInventory: { + moduleName: 'Product Inventory', + detailTitle: 'Product Inventory Detail', + searchPlaceholder: 'Enter product code or name', + allWarehouse: 'All Warehouses', + warehousePlaceholder: 'Warehouse Filter', + productInfo: 'Product Info', + stockInfo: 'Stock Info', + productName: 'Product Name', + barCode: 'Product Code', + warehouse: 'Warehouse', + area: 'Area', + count: 'Base Qty', + stockDisplay: 'Stock Display', + areaStockDisplay: 'Area Stock Display', + totalPackageCount: 'Total Packages', + totalBaseCount: 'Total Pieces', + unit: 'Unit', + category: 'Product Category', + standard: 'Spec', + packagingRule: 'Packaging/Conversion Rule', + latestInTime: 'Latest Inbound', + latestOutTime: 'Latest Outbound', + remark: 'Remark', + empty: 'No product inventory data', + noDetailId: 'No product inventory ID' + }} diff --git a/src/locales/zh-CN.js b/src/locales/zh-CN.js index 76fbb2f..7aa2efb 100644 --- a/src/locales/zh-CN.js +++ b/src/locales/zh-CN.js @@ -864,13 +864,13 @@ export default { deviceType: '设备类型', deviceStatus: '设备状态', lineFilter: '产线', - allFilter: '全部筛选', - moreFilter: '更多筛选', - categoryStatus: '分类状态', - categoryInfo: '分类信息', - dateFilter: '日期筛选', - deviceBrand: '设备品牌', - sn: '序列号', + allFilter: '全部筛选', + moreFilter: '更多筛选', + categoryStatus: '分类状态', + categoryInfo: '分类信息', + dateFilter: '日期筛选', + deviceBrand: '设备品牌', + sn: '序列号', scanUnrecognized: '未识别二维码内容', scanTypeMismatch: '二维码类型不匹配', scanFailed: '扫码失败', @@ -900,8 +900,8 @@ export default { loadFailed: '加载设备详情失败', placeholderDeviceCode: '请输入设备编码', placeholderDeviceName: '请输入设备名称', - placeholderDeviceBrand: '请输入设备品牌', - placeholderSn: '请输入序列号', + placeholderDeviceBrand: '请输入设备品牌', + placeholderSn: '请输入序列号', placeholderDeviceType: '请选择设备类型', placeholderDeviceSpec: '请输入设备规格', placeholderRatedCapacity: '请输入额定产能', @@ -909,8 +909,8 @@ export default { placeholderDataCollectionCapacity: '请输入数据采集产能', placeholderProductionDate: '请选择生产日期', placeholderOutgoingTime: '请选择出厂日期', - placeholderOutgoingStartTime: '开始日期', - placeholderOutgoingEndTime: '结束日期', + placeholderOutgoingStartTime: '开始日期', + placeholderOutgoingEndTime: '结束日期', placeholderFactoryEntryDate: '请选择入厂日期', placeholderDeviceLocation: '请输入设备位置', placeholderRemark: '请输入备注', @@ -994,8 +994,17 @@ export default { statusPending: '待维修', statusPassed: '通过', statusRejected: '不通过', - placeholderRepairCode: '请输入维修单编号', - placeholderRepairName: '请输入维修单名称', + statusDocumentPending: '待完成', + statusDocumentFinished: '已完成', + moreFilter: '更多筛选', + statusFilter: '状态筛选', + dateFilter: '日期筛选', placeholderRepairCode: '请输入维修单编号', + placeholderRepairName: '请输入维修单名称', placeholderRequireStartDate: '报修开始日期', + placeholderRequireEndDate: '报修结束日期', + placeholderFinishStartDate: '完成开始日期', + placeholderFinishEndDate: '完成结束日期', + placeholderConfirmStartDate: '验收开始日期', + placeholderConfirmEndDate: '验收结束日期', placeholderRequireDate: '请选择报修日期', placeholderAcceptedBy: '请选择维修人员', placeholderConfirmBy: '请选择验收人员', @@ -1544,7 +1553,7 @@ export default { moduleName: '产品盘点执行', createTitle: '新增产品盘点', executeTitle: '执行盘点', - detailTitle: '产品盘点详情', + detailTitle: '产品盘点详情', selectProductTitle: '选择产品', selectItemTitle: '选择盘点项', selectWarehouseTitle: '选择仓库', @@ -1829,33 +1838,33 @@ export default { empty: '暂无出库单据', createTitle: '新增物料出库' }, - productInventory: { - moduleName: '产品库存查询', - detailTitle: '产品库存详情', - searchPlaceholder: '请输入产品编码或名称', - allWarehouse: '全部仓库', - warehousePlaceholder: '仓库筛选', - productInfo: '产品信息', - stockInfo: '库存信息', - productName: '产品名称', - barCode: '产品编码', - warehouse: '仓库', - area: '库区', - count: '基本数量', - stockDisplay: '库存展示', - areaStockDisplay: '库区库存展示', - totalPackageCount: '总包数', - totalBaseCount: '总个数', - unit: '单位', - category: '产品小类', - standard: '规格', - packagingRule: '包装/换算规则', - latestInTime: '最近入库', - latestOutTime: '最近出库', - remark: '备注', - empty: '暂无产品库存数据', - noDetailId: '暂无产品库存ID' - }, + productInventory: { + moduleName: '产品库存查询', + detailTitle: '产品库存详情', + searchPlaceholder: '请输入产品编码或名称', + allWarehouse: '全部仓库', + warehousePlaceholder: '仓库筛选', + productInfo: '产品信息', + stockInfo: '库存信息', + productName: '产品名称', + barCode: '产品编码', + warehouse: '仓库', + area: '库区', + count: '基本数量', + stockDisplay: '库存展示', + areaStockDisplay: '库区库存展示', + totalPackageCount: '总包数', + totalBaseCount: '总个数', + unit: '单位', + category: '产品小类', + standard: '规格', + packagingRule: '包装/换算规则', + latestInTime: '最近入库', + latestOutTime: '最近出库', + remark: '备注', + empty: '暂无产品库存数据', + noDetailId: '暂无产品库存ID' + }, sparepartInventory: { moduleName: '备件库存查询', searchPlaceholder: '请输入备件编码或名称', diff --git a/src/pages_function/pages/equipmentLedger/index.vue b/src/pages_function/pages/equipmentLedger/index.vue index 215119e..c12655c 100644 --- a/src/pages_function/pages/equipmentLedger/index.vue +++ b/src/pages_function/pages/equipmentLedger/index.vue @@ -75,7 +75,7 @@ - @@ -777,7 +777,8 @@ function formatDateValue(value) { .filter-drawer { width: 630rpx; - height: 100vh; + height: calc(100vh - var(--status-bar-height)); + margin-top: var(--status-bar-height); background: #f5f5f7; display: flex; flex-direction: column; diff --git a/src/pages_function/pages/equipmentMaintenance/index.vue b/src/pages_function/pages/equipmentMaintenance/index.vue index be1046e..3ddaf2e 100644 --- a/src/pages_function/pages/equipmentMaintenance/index.vue +++ b/src/pages_function/pages/equipmentMaintenance/index.vue @@ -3,29 +3,38 @@ - - {{ selectedLineLabel }} - - - - + + + {{ selectedLineLabel }} + + + + + {{ selectedStatusLabel }} + + + - - - {{ selectedStatusLabel }} - + + + - - {{ t('functionCommon.reset') }} + + + + + + + + + + + + {{ t('equipmentMaintenance.moreFilter') }} + + + + + {{ t('equipmentMaintenance.basicInfo') }} + + + + {{ t('equipmentMaintenance.repairName') }} + + + + {{ t('equipmentMaintenance.acceptedBy') }} + + + + + + + + {{ t('equipmentMaintenance.statusFilter') }} + + + {{ t('equipmentMaintenance.status') }} + + + + {{ selectedDocumentStatusLabel }} + + + + + + + + + + {{ t('equipmentMaintenance.dateFilter') }} + + + {{ t('equipmentMaintenance.requireDate') }} + + + + + + {{ t('equipmentMaintenance.finishDate') }} + + + + + + {{ t('equipmentMaintenance.confirmDate') }} + + + + + + + + {{ t('functionCommon.reset') }} + {{ t('functionCommon.confirm') }} + + + + { return current ? current.label : t('functionCommon.all') }) +const documentStatusOptions = computed(() => [ + { label: t('functionCommon.all'), value: '' }, + { label: t('equipmentMaintenance.statusDocumentPending'), value: '0' }, + { label: t('equipmentMaintenance.statusDocumentFinished'), value: '1' } +]) + +const documentStatusLabels = computed(() => documentStatusOptions.value.map((item) => item.label)) +const documentStatusPickerIndex = computed(() => { + const index = documentStatusOptions.value.findIndex((item) => item.value === selectedDocumentStatus.value) + return index >= 0 ? index : 0 +}) +const selectedDocumentStatusLabel = computed(() => { + const current = documentStatusOptions.value.find((item) => item.value === selectedDocumentStatus.value) + return current ? current.label : t('functionCommon.all') +}) + const selectedLineLabel = computed(() => { if (selectedLineId.value === '') return t('equipmentMaintenance.lineFilter') const found = lineOptions.value.find(item => String(item.id) === String(selectedLineId.value)) @@ -244,15 +381,26 @@ async function fetchList(reset) { try { const keyword = searchKeyword.value.trim() - const machineryId = parseMachineryIdKeyword(keyword) + const repairName = repairNameFilter.value.trim() + const acceptedBy = acceptedByFilter.value.trim() + const requireDateRange = Array.isArray(requireDateFilter.value) ? requireDateFilter.value : [] + const finishDateRange = Array.isArray(finishDateFilter.value) ? finishDateFilter.value : [] + const confirmDateRange = Array.isArray(confirmDateFilter.value) ? confirmDateFilter.value : [] const params = { pageNo: pageNo.value, pageSize: pageSize.value, - repairCode: machineryId ? undefined : keyword || undefined, - machineryCode: machineryId ? undefined : keyword || undefined, - machineryId: machineryId || undefined, + keyword: keyword || undefined, + repairName: repairName || undefined, deviceLine: selectedLineId.value === '' ? undefined : selectedLineId.value, - repairStatus: selectedStatus.value === '' ? undefined : selectedStatus.value + repairStatus: selectedStatus.value === '' ? undefined : selectedStatus.value, + acceptedBy: acceptedBy || undefined, + status: selectedDocumentStatus.value === '' ? undefined : selectedDocumentStatus.value, + 'requireDate[0]': formatQueryDate(requireDateRange[0], false), + 'requireDate[1]': formatQueryDate(requireDateRange[1], true), + 'finishDate[0]': formatQueryDate(finishDateRange[0], false), + 'finishDate[1]': formatQueryDate(finishDateRange[1], true), + 'confirmDate[0]': formatQueryDate(confirmDateRange[0], false), + 'confirmDate[1]': formatQueryDate(confirmDateRange[1], true) } const res = await getDvRepairPage(params) const root = res && res.data !== undefined ? res.data : res @@ -268,9 +416,13 @@ async function fetchList(reset) { } } -function parseMachineryIdKeyword(keyword) { - const match = String(keyword || '').trim().match(/-(\d+)$/) - return match ? Number(match[1]) : undefined + +function formatQueryDate(value, isEnd) { + if (!value) return undefined + const text = String(value).trim() + if (!text) return undefined + if (text.includes(':')) return text + return text + ' ' + (isEnd ? '23:59:59' : '00:00:00') } function onFetchResult(result) { @@ -325,6 +477,19 @@ function handleSearch() { fetchList(true) } +function openFilterDrawer() { + filterPopupRef.value?.open() +} + +function closeFilterDrawer() { + filterPopupRef.value?.close() +} + +async function confirmFilterDrawer() { + closeFilterDrawer() + await fetchList(true) +} + function openLineCascader() { lineCascaderShow.value = true } @@ -339,11 +504,18 @@ function onLineCascaderConfirm(values) { async function resetFilters() { searchKeyword.value = '' - selectedStatus.value = '' + selectedStatus.value = DEFAULT_REPAIR_STATUS selectedLineId.value = '' + repairNameFilter.value = '' + acceptedByFilter.value = '' + selectedDocumentStatus.value = '' + requireDateFilter.value = [] + finishDateFilter.value = [] + confirmDateFilter.value = [] lineCascaderValue.value = [] lineCascaderShow.value = false lineCascaderKey.value += 1 + closeFilterDrawer() activateKeywordFocus() await fetchList(true) } @@ -354,6 +526,11 @@ function onStatusFilterChange(event) { fetchList(true) } +function onDocumentStatusChange(event) { + const index = Number(event?.detail?.value || 0) + selectedDocumentStatus.value = documentStatusOptions.value[index]?.value ?? '' +} + function canEdit(item) { return !isProcessedRepair(item?.repairStatus) } @@ -501,81 +678,285 @@ function textValue(value) { } .filter-bar { - display: grid; - grid-template-columns: minmax(0, 1fr) 150rpx 110rpx; + padding: 18rpx 14rpx 20rpx; + background: #f3f4f6; +} + +.filter-row { + display: flex; align-items: center; - gap: 14rpx; - padding: 18rpx 4rpx 16rpx; + gap: 18rpx; +} + +.search-row { + margin-top: 18rpx; +} + +.quick-row > picker { + min-width: 0; + flex: 1; } +.keyword-wrap, +.status-filter, .line-filter, -.keyword-box, -.status-box, -.reset-filter-btn { +.icon-filter-btn { height: 66rpx; - background: #ffffff; border: 1rpx solid #d9dde5; + background: #ffffff; box-sizing: border-box; +} + +.keyword-wrap { + min-width: 0; + flex: 1; display: flex; align-items: center; } +.keyword-input { + width: 100%; + height: 64rpx; + padding: 0 20rpx; + font-size: 26rpx; + color: #374151; +} + +.status-filter, .line-filter { - grid-column: 1 / -1; + min-width: 0; + flex: 1; + display: flex; + align-items: center; justify-content: space-between; - padding: 0 18rpx; - border-radius: 8rpx; + padding: 0 18rpx 0 26rpx; +} + +.icon-filter-btn { + width: 66rpx; + flex: 0 0 66rpx; + display: flex; + align-items: center; + justify-content: center; + border-color: transparent; + background: transparent; } +.status-filter-text, .line-filter-text { - font-size: 26rpx; - color: #374151; - max-width: 85%; + min-width: 0rpx; + flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; + font-size: 26rpx; + color: #374151; } -.line-filter-text.placeholder { +.status-filter-text.placeholder, +.line-filter-text.placeholder, +.placeholder { color: #a8adb7; } -.keyword-box { - padding: 0 20rpx; +.filter-drawer { + width: 630rpx; + height: calc(100vh - var(--status-bar-height)); + margin-top: var(--status-bar-height); + background: #f5f5f7; + display: flex; + flex-direction: column; + overflow: hidden; + border-radius: 28rpx 0 0 28rpx; } -.keyword-input { +:deep(.equipment-filter-popup.right .uni-popup__content-transition) { + transform: none !important; +} + +.drawer-header { + height: 104rpx; + padding: 18rpx 34rpx 0; + background: #ffffff; + display: flex; + align-items: center; + box-sizing: border-box; +} + +.drawer-title { + color: #1f2937; + font-size: 34rpx; + line-height: 1.3; + font-weight: 700; +} + +.drawer-body { + flex: 1; + min-height: 0; + padding-bottom: 40rpx; + box-sizing: border-box; +} + +.drawer-section { + margin-bottom: 18rpx; + padding: 28rpx 28rpx 30rpx; + border-radius: 24rpx; + background: #ffffff; + box-sizing: border-box; +} + +.drawer-section-head { + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 24rpx; +} + +.drawer-section-title { + font-size: 32rpx; + line-height: 1.3; + color: #1f2937; + font-weight: 700; +} + +.drawer-grid { + display: grid; + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 22rpx 20rpx; +} + +.drawer-field { + min-width: 0; +} + +.drawer-field-wide { + grid-column: 1 / -1; +} + +.drawer-field-gap { + margin-top: 22rpx; +} + +.drawer-label { + display: block; + margin-bottom: 12rpx; + font-size: 24rpx; + line-height: 1.3; + color: #4b5563; + font-weight: 500; +} + +.drawer-input, +.drawer-picker, +.drawer-date { width: 100%; + min-height: 74rpx; + border: 0; + border-radius: 8rpx; + background: #f7f8fb; + box-sizing: border-box; +} + +.drawer-input { + height: 74rpx; + padding: 0 18rpx; font-size: 26rpx; - color: #374151; + color: #111827; + text-align: center; } -.status-box { - justify-content: space-between; +.drawer-picker { + display: flex; + align-items: center; + justify-content: center; padding: 0 18rpx; + gap: 8rpx; } -.status-box-text, -.placeholder { +.drawer-picker-text { + min-width: 0; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; font-size: 26rpx; + color: #111827; + text-align: center; } -.status-box-text { - color: #374151; +.drawer-picker-text.placeholder { + color: #9ca3af; } -.placeholder { - color: #a8adb7; +.drawer-date { + display: flex; + align-items: center; + padding: 0 12rpx; +} + +.drawer-date :deep(.uni-date), +.drawer-date :deep(.uni-date-editor), +.drawer-date :deep(.uni-date-editor--x), +.drawer-date :deep(.uni-date-x) { + width: 100%; +} + +.drawer-date :deep(.uni-date-editor), +.drawer-date :deep(.uni-date-editor--x), +.drawer-date :deep(.uni-date-x) { + min-height: 74rpx; +} + +.drawer-date :deep(.uni-date-editor--x), +.drawer-date :deep(.uni-date-x) { + border: 0; + padding: 0; + background: transparent; +} + +.drawer-date :deep(.uni-date-range) { + display: flex; + align-items: center; } -.reset-filter-btn { +.drawer-date :deep(.uni-date__x-input) { + text-align: center; + font-size: 26rpx; + color: #111827; +} + +.drawer-actions { + height: 126rpx; + padding: 18rpx 28rpx 24rpx; + box-sizing: border-box; + display: flex; + align-items: center; + gap: 0; + background: #ffffff; + box-shadow: 0 -8rpx 24rpx rgba(17, 24, 39, 0.06); +} + +.drawer-action { + flex: 1; + height: 72rpx; display: flex; align-items: center; justify-content: center; - font-size: 24rpx; - color: #4b5563; - border-radius: 8rpx; - cursor: pointer; + font-size: 28rpx; + font-weight: 600; + border: 2rpx solid #174b78; + box-sizing: border-box; +} + +.drawer-action.reset { + border-radius: 12rpx 0 0 12rpx; + background: #ffffff; + color: #174b78; +} + +.drawer-action.confirm { + border-radius: 0 12rpx 12rpx 0; + background: #174b78; + color: #ffffff; } .list-scroll {