From 818f7737e7396142378dd0c881a4b81950f69a8a Mon Sep 17 00:00:00 2001
From: liutao <790864623@qq.com>
Date: Thu, 4 Jun 2026 14:48:38 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=AE=BE=E5=A4=87=E7=BB=B4?=
=?UTF-8?q?=E4=BF=AE=E5=A2=9E=E5=8A=A0=E6=9D=A1=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/locales/en-US.js | 1 +
src/locales/zh-CN.js | 1 +
.../pages/equipmentMaintenance/index.vue | 299 +++++++++++-------
3 files changed, 195 insertions(+), 106 deletions(-)
diff --git a/src/locales/en-US.js b/src/locales/en-US.js
index bde9954..04f1f87 100644
--- a/src/locales/en-US.js
+++ b/src/locales/en-US.js
@@ -951,6 +951,7 @@ export default {
validatorFaultLevelRequired: 'Please select the failure level',
validatorIsShutdownRequired: 'Please select whether shutdown is required',
validatorFaultPhenomenonRequired: 'Please enter the fault phenomenon',
+ lineFilter: 'Line',
validatorRepairStatusRequired: 'Please select the repair result',
validatorFinishDateRequired: 'Please select the completion date',
validatorConfirmDateRequired: 'Please select the acceptance date'
diff --git a/src/locales/zh-CN.js b/src/locales/zh-CN.js
index d67bf32..91f0e4d 100644
--- a/src/locales/zh-CN.js
+++ b/src/locales/zh-CN.js
@@ -954,6 +954,7 @@ export default {
validatorFaultLevelRequired: '请选择故障等级',
validatorIsShutdownRequired: '请选择是否停机',
validatorFaultPhenomenonRequired: '请输入故障现象',
+ lineFilter: '产线',
validatorRepairStatusRequired: '请选择维修结果',
validatorFinishDateRequired: '请选择完成日期',
validatorConfirmDateRequired: '请选择验收日期'
diff --git a/src/pages_function/pages/equipmentMaintenance/index.vue b/src/pages_function/pages/equipmentMaintenance/index.vue
index 4943ba0..624d7f4 100644
--- a/src/pages_function/pages/equipmentMaintenance/index.vue
+++ b/src/pages_function/pages/equipmentMaintenance/index.vue
@@ -3,6 +3,10 @@
+
+ {{ selectedLineLabel }}
+
+
{{ t('functionCommon.reset') }}
-
-
-
+
+
+
@@ -93,10 +108,16 @@ import {
deleteDvRepair,
getDvRepairPage
} from '@/api/mes/dvrepair'
+import { getDeviceLineTree } from '@/api/mes/deviceLine'
const { t } = useI18n()
const searchKeyword = ref('')
const selectedStatus = ref('')
+const selectedLineId = ref('')
+const lineTree = ref([])
+const lineCascaderShow = ref(false)
+const lineCascaderValue = ref([])
+const lineCascaderKey = ref(0)
const list = ref([])
const loading = ref(false)
const loadingMore = ref(false)
@@ -108,7 +129,6 @@ const initialized = ref(false)
const scrollTop = ref(0)
const showGoTop = ref(false)
const keywordFocus = ref(false)
-const selectedMachineryId = ref('')
const statusOptions = computed(() => [
{ label: t('functionCommon.all'), value: '' },
@@ -127,21 +147,86 @@ const selectedStatusLabel = computed(() => {
return current ? current.label : t('functionCommon.all')
})
-onLoad(async () => {
- initialized.value = true
- activateKeywordFocus()
- await fetchList(true)
+const selectedLineLabel = computed(() => {
+ if (selectedLineId.value === '') return t('equipmentMaintenance.lineFilter')
+ const found = lineOptions.value.find(item => String(item.id) === String(selectedLineId.value))
+ return found?.name || t('equipmentMaintenance.lineFilter')
})
-onShow(async () => {
- activateKeywordFocus()
- if (!initialized.value) return
- await fetchList(true)
+const lineOptions = computed(() => {
+ return flattenLineTree(lineTree.value, 1)
})
-onReachBottom(() => {
- loadMore()
-})
+const lineCascaderOptions = computed(() => [
+ { label: t('functionCommon.all'), value: '' },
+ ...normalizeLineTreeForCascader(lineTree.value)
+])
+
+function flattenLineTree(nodes, level) {
+ const result = []
+ ;(Array.isArray(nodes) ? nodes : []).forEach((node) => {
+ result.push({
+ id: node.id,
+ name: node.name || node.label || String(node.id || ''),
+ level
+ })
+ if (Array.isArray(node.children) && node.children.length) {
+ result.push(...flattenLineTree(node.children, level + 1))
+ }
+ })
+ return result
+}
+
+function normalizeLineTreeForCascader(nodes) {
+ return (Array.isArray(nodes) ? nodes : []).map((node) => {
+ const children = normalizeLineTreeForCascader(node.children)
+ const item = {
+ label: node.name || node.label || String(node.id || ''),
+ value: String(node.id ?? '')
+ }
+ if (children.length) item.children = children
+ return item
+ })
+}
+
+function findLinePath(nodes, id, parents = []) {
+ const target = String(id)
+ for (const node of Array.isArray(nodes) ? nodes : []) {
+ const currentPath = [...parents, String(node.id ?? '')]
+ if (String(node.id) === target) return currentPath
+ const childPath = findLinePath(node.children, id, currentPath)
+ if (childPath.length) return childPath
+ }
+ return []
+}
+
+async function fetchDeviceLineTree() {
+ try {
+ const res = await getDeviceLineTree()
+ const root = res && res.data !== undefined ? res.data : res
+ const treeData = Array.isArray(root) ? root : (Array.isArray(root?.data) ? root.data : [])
+ lineTree.value = normalizeLineTree(treeData)
+ } catch (_) {
+ lineTree.value = []
+ }
+}
+
+function normalizeLineTree(nodes) {
+ return (Array.isArray(nodes) ? nodes : []).map((node) => {
+ const children = normalizeLineTree(node.children)
+ const item = {
+ ...node,
+ id: String(node.id ?? ''),
+ name: node.name || node.label || String(node.id || '')
+ }
+ if (children.length) {
+ item.children = children
+ } else {
+ delete item.children
+ }
+ return item
+ })
+}
async function fetchList(reset) {
if (reset) {
@@ -162,35 +247,50 @@ async function fetchList(reset) {
pageSize: pageSize.value,
repairCode: keyword || undefined,
machineryCode: keyword || undefined,
- machineryId: selectedMachineryId.value || undefined,
+ deviceLine: selectedLineId.value === '' ? undefined : selectedLineId.value,
repairStatus: selectedStatus.value === '' ? undefined : selectedStatus.value
}
const res = await getDvRepairPage(params)
- const page = normalizePageData(res)
- total.value = page.total
- list.value = reset ? page.list : [...list.value, ...page.list]
- finished.value = list.value.length >= total.value || page.list.length < pageSize.value
- } catch (error) {
- if (!reset) {
- pageNo.value = Math.max(1, pageNo.value - 1)
- }
- uni.showToast({ title: t('functionCommon.loadFailed'), icon: 'none' })
+ const root = res && res.data !== undefined ? res.data : res
+ const candidateList = root?.list || root?.rows || root?.records || root?.data?.list || root?.data?.rows || root?.data?.records || []
+ const candidateTotal = root?.total ?? root?.data?.total ?? (Array.isArray(candidateList) ? candidateList.length : 0)
+ onFetchResult({ list: Array.isArray(candidateList) ? candidateList : [], total: Number(candidateTotal || 0) })
+ } catch (e) {
+ onFetchResult({ list: [], total: 0 })
+ if (!reset) pageNo.value = Math.max(1, pageNo.value - 1)
} finally {
loading.value = false
loadingMore.value = false
}
}
-function normalizePageData(res) {
- const root = res && res.data !== undefined ? res.data : res
- const candidateList = root?.list || root?.rows || root?.records || root?.data?.list || root?.data?.rows || root?.data?.records || []
- const candidateTotal = root?.total ?? root?.data?.total ?? (Array.isArray(candidateList) ? candidateList.length : 0)
- return {
- list: Array.isArray(candidateList) ? candidateList : [],
- total: Number(candidateTotal || 0)
+function onFetchResult(result) {
+ const data = result || { list: [], total: 0 }
+ if (pageNo.value === 1) {
+ list.value = data.list
+ } else {
+ list.value = list.value.concat(data.list)
}
+ total.value = data.total
+ const loadedCount = list.value.length
+ finished.value = loadedCount >= total.value || data.list.length < pageSize.value
}
+onLoad(async () => {
+ initialized.value = true
+ await fetchDeviceLineTree()
+ await fetchList(true)
+})
+
+onShow(async () => {
+ if (!initialized.value) return
+ await fetchList(true)
+})
+
+onReachBottom(() => {
+ loadMore()
+})
+
function activateKeywordFocus() {
keywordFocus.value = false
nextTick(() => {
@@ -203,10 +303,25 @@ function handleSearch() {
fetchList(true)
}
+function openLineCascader() {
+ lineCascaderShow.value = true
+}
+
+function onLineCascaderConfirm(values) {
+ const selectedValues = Array.isArray(values) ? values : []
+ const nextValue = selectedValues[selectedValues.length - 1] ?? ''
+ selectedLineId.value = nextValue === '' ? '' : String(nextValue)
+ lineCascaderValue.value = nextValue === '' ? [] : selectedValues.map(item => String(item))
+ fetchList(true)
+}
+
async function resetFilters() {
searchKeyword.value = ''
selectedStatus.value = ''
- selectedMachineryId.value = ''
+ selectedLineId.value = ''
+ lineCascaderValue.value = []
+ lineCascaderShow.value = false
+ lineCascaderKey.value += 1
activateKeywordFocus()
await fetchList(true)
}
@@ -217,51 +332,6 @@ function onStatusFilterChange(event) {
fetchList(true)
}
-async function handleScan() {
- try {
- const res = await uni.scanCode({ scanType: ['qrCode', 'barCode'] })
- const result = String(res?.result || '').trim()
- if (!result) {
- uni.showToast({ title: t('equipmentMaintenance.scanUnrecognized'), icon: 'none' })
- return
- }
- const scan = parseEquipmentScanResult(result)
- if (!scan.id) {
- uni.showToast({ title: t('equipmentMaintenance.scanEquipmentRequired'), icon: 'none' })
- return
- }
- selectedMachineryId.value = scan.id
- searchKeyword.value = ''
- await fetchList(true)
- } catch (error) {
- const message = String(error?.errMsg || '')
- if (message.includes('cancel')) return
- uni.showToast({ title: t('equipmentMaintenance.scanFailed'), icon: 'none' })
- }
-}
-
-function parseEquipmentScanResult(result) {
- const text = String(result || '').trim()
- const directMatch = text.match(/^([A-Z_]+)-(\d+)$/i)
- if (directMatch) {
- return {
- type: directMatch[1].toUpperCase(),
- id: directMatch[1].toUpperCase() === 'EQUIPMENT' ? directMatch[2] : ''
- }
- }
- try {
- const parsed = JSON.parse(text)
- const type = String(parsed?.type || parsed?.bizType || parsed?.codeType || '').toUpperCase()
- const id = String(parsed?.id || parsed?.machineryId || parsed?.deviceId || '').trim()
- return {
- type,
- id: type === 'EQUIPMENT' && id ? id : ''
- }
- } catch {
- return { type: '', id: '' }
- }
-}
-
function canEdit(item) {
return !isProcessedRepair(item?.repairStatus)
}
@@ -410,16 +480,16 @@ function textValue(value) {
.filter-bar {
display: grid;
- grid-template-columns: minmax(0, 1fr) 150rpx 96rpx 64rpx;
+ grid-template-columns: minmax(0, 1fr) 150rpx 110rpx;
align-items: center;
gap: 14rpx;
- padding: 18rpx 4rpx 20rpx;
+ padding: 18rpx 4rpx 16rpx;
}
+.line-filter,
.keyword-box,
.status-box,
-.reset-filter-btn,
-.scan-btn {
+.reset-filter-btn {
height: 66rpx;
background: #ffffff;
border: 1rpx solid #d9dde5;
@@ -428,6 +498,26 @@ function textValue(value) {
align-items: center;
}
+.line-filter {
+ grid-column: 1 / -1;
+ justify-content: space-between;
+ padding: 0 18rpx;
+ border-radius: 8rpx;
+}
+
+.line-filter-text {
+ font-size: 26rpx;
+ color: #374151;
+ max-width: 85%;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.line-filter-text.placeholder {
+ color: #a8adb7;
+}
+
.keyword-box {
padding: 0 20rpx;
}
@@ -456,19 +546,14 @@ function textValue(value) {
color: #a8adb7;
}
-.scan-btn {
- display: flex;
- align-items: center;
- justify-content: center;
- background: #ffffff;
-}
-
.reset-filter-btn {
display: flex;
align-items: center;
justify-content: center;
font-size: 24rpx;
color: #4b5563;
+ border-radius: 8rpx;
+ cursor: pointer;
}
.list-scroll {
@@ -480,15 +565,15 @@ function textValue(value) {
}
.repair-card {
- margin-bottom: 18rpx;
- border-radius: 12rpx;
+ margin-bottom: 20rpx;
+ border-radius: 16rpx;
background: #ffffff;
- box-shadow: none;
+ box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.06);
overflow: hidden;
}
.card-main {
- padding: 24rpx;
+ padding: 28rpx 24rpx;
}
.card-top,
@@ -500,9 +585,9 @@ function textValue(value) {
}
.repair-code {
- max-width: 420rpx;
- font-size: 36rpx;
- line-height: 44rpx;
+ max-width: 460rpx;
+ font-size: 32rpx;
+ line-height: 42rpx;
color: #24456b;
font-weight: 700;
}
@@ -514,9 +599,9 @@ function textValue(value) {
}
.repair-status-tag {
- padding: 8rpx 18rpx;
+ padding: 6rpx 20rpx;
border-radius: 999rpx;
- font-size: 24rpx;
+ font-size: 22rpx;
font-weight: 600;
line-height: 1.2;
}
@@ -537,21 +622,22 @@ function textValue(value) {
align-items: center;
justify-content: space-between;
gap: 20rpx;
- margin-top: 14rpx;
+ margin-top: 16rpx;
}
.equipment-label {
- font-size: 28rpx;
+ font-size: 26rpx;
color: #9ca3af;
- font-weight: 600;
+ font-weight: 500;
flex-shrink: 0;
}
.equipment-value {
flex: 1;
text-align: right;
- font-size: 30rpx;
+ font-size: 28rpx;
color: #9ca3af;
+ font-weight: 500;
}
.text-warning {
@@ -605,8 +691,8 @@ function textValue(value) {
}
.card-actions {
- padding: 18rpx 24rpx;
- border-top: 1rpx solid #f1f5f9;
+ padding: 16rpx 24rpx;
+ border-top: 1rpx solid #f0f2f5;
justify-content: flex-end;
gap: 28rpx;
}
@@ -627,7 +713,7 @@ function textValue(value) {
}
.state-text.empty {
- padding-top: 160rpx;
+ padding-top: 200rpx;
}
.add-btn,
@@ -647,6 +733,7 @@ function textValue(value) {
right: 28rpx;
bottom: calc(56rpx + env(safe-area-inset-bottom));
background: #1f4b79;
+ box-shadow: 0 8rpx 24rpx rgba(31, 75, 121, 0.35);
}
.go-top-btn {
@@ -660,4 +747,4 @@ function textValue(value) {
line-height: 1;
margin-top: -4rpx;
}
-
\ No newline at end of file
+