feat:设备维修逻辑重构

main
黄伟杰 4 hours ago
parent a1b5847161
commit 5980fc8750

@ -33,6 +33,33 @@ export interface DvRepairVO {
status: string // 单据状态
rejectReason?: string // 驳回理由
remark: string // 备注
acceptanceHistoryList?: DvRepairAcceptanceHistoryVO[]
}
export interface DvRepairAcceptanceHistoryVO {
id?: number | string
repairId?: number | string
repairResult?: string | number
finishDate?: Date | string | number
confirmDate?: Date | string | number
confirmBy?: string
status?: string | number
rejectReason?: string
downtimeDuration?: string
faultReason?: string
handlingMeasures?: string
replacementParts?: string
repairContent?: string
repairedImages?: string
createTime?: Date | string | number
}
export interface DvRepairAcceptanceVO {
id: number | string
confirmBy: string
confirmDate?: Date | string | number
status: '1' | '2'
rejectReason?: string
}
// 设备维修记录 API
@ -75,6 +102,10 @@ export const DvRepairApi = {
return await request.put({ url: `/mes/dv-repair/reject`, data })
},
acceptanceDvRepair: async (data: DvRepairAcceptanceVO) => {
return await request.put({ url: `/mes/dv-repair/acceptance`, data })
},
// ==================== 子表(设备维修记录行) ====================
// 获得设备维修记录行列表

@ -2277,6 +2277,9 @@ export default {
// Repair Order
DvRepair: {
reportInfo: 'Repair Request Information',
processingResult: 'Processing Result',
historyRepairResult: 'Historical Processing Result',
repairCode: 'Repair Order No',
repairName: 'Repair Order',
machineryName: 'Device Name',
@ -2332,6 +2335,12 @@ export default {
rejectReasonPrompt: 'Please enter the rejection reason',
rejectReasonRequired: 'Rejection reason cannot be empty',
rejectSuccess: 'Rejected successfully',
acceptance: 'Acceptance',
acceptanceResult: 'Acceptance Result',
acceptancePassed: 'Pass',
acceptanceRejected: 'Reject',
acceptanceSuccess: 'Acceptance submitted successfully',
validatorAcceptanceResultRequired: 'Please select an acceptance result',
creatorName: 'Creator',
createTime: 'Create Time',
operate: 'Operate',

@ -2309,6 +2309,9 @@ export default {
// 维修单
DvRepair: {
all: '全部',
reportInfo: '报修信息',
processingResult: '处理结果',
historyRepairResult: '历史处理结果',
repairCode: '维修单号',
repairName: '维修单',
machineryName: '设备名称',
@ -2364,6 +2367,12 @@ export default {
rejectReasonPrompt: '请输入驳回理由',
rejectReasonRequired: '驳回理由不能为空',
rejectSuccess: '驳回成功',
acceptance: '验收',
acceptanceResult: '验收结果',
acceptancePassed: '通过',
acceptanceRejected: '驳回',
acceptanceSuccess: '验收提交成功',
validatorAcceptanceResultRequired: '请选择验收结果',
creatorName: '创建人',
createTime: '创建时间',
operate: '操作',

@ -259,6 +259,7 @@ export enum DICT_TYPE {
MES_PRODUCE_ITEM_REQUISITION = "mes_produce_item_requisition",
MES_DATA_TYPE = "mes_data_type",
MES_MACHINE_STATUS = "mes_machine_status",
EQUIPMENT_DOCUMENT_STATUS = "equipment_document_status",
MES_MACHINE_TYPE = "mes_machine_type",
MES_FEEDING_TYPE = "mes_feeding_type",
MES_FEEDING_RECORD_STATUS = "mes_feeding_record_status",

@ -9,7 +9,7 @@
<div class="dv-repair-dialog" v-loading="formLoading">
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px">
<section class="dv-repair-section">
<div class="dv-repair-section__title">基本信息</div>
<div class="dv-repair-section__title">{{ t('EquipmentManagement.DvRepair.reportInfo') }}</div>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item :label="t('EquipmentManagement.DvRepair.repairCode')" prop="repairCode">
@ -72,34 +72,6 @@
</el-select>
</el-form-item>
</el-col>
<el-col v-if="formType !== 'create'" :span="8">
<el-form-item :label="t('EquipmentManagement.DvRepair.acceptedBy')" prop="acceptedBy">
<el-select
v-model="formData.acceptedBy"
multiple
filterable
clearable
:placeholder="t('EquipmentManagement.DvRepair.placeholderAcceptedBy')"
class="!w-full"
:disabled="isRepairMetaReadonly"
>
<el-option v-for="item in users" :key="String(item.id)" :label="item.nickname" :value="String(item.id)" />
</el-select>
</el-form-item>
</el-col>
<el-col v-if="formType !== 'create'" :span="8">
<el-form-item :label="t('EquipmentManagement.DvRepair.confirmBy')" prop="confirmBy">
<el-select
v-model="formData.confirmBy"
filterable
clearable
:placeholder="t('EquipmentManagement.DvRepair.placeholderConfirmBy')"
:disabled="isRepairMetaReadonly"
>
<el-option v-for="item in users" :key="String(item.id)" :label="item.nickname" :value="String(item.id)" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item :label="t('EquipmentManagement.DvRepair.status')">
<el-input :model-value="statusLabel" disabled />
@ -232,8 +204,38 @@
</section>
<section v-if="showRepairSection" class="dv-repair-section">
<div class="dv-repair-section__title">处理结果</div>
<div class="dv-repair-section__title-row">
<div class="dv-repair-section__title">{{ t('EquipmentManagement.DvRepair.processingResult') }}</div>
<el-select
v-if="hasRepairHistory"
v-model="selectedRepairHistoryIndex"
class="dv-repair-history-select"
@change="changeRepairHistory"
>
<el-option
v-for="option in repairHistoryOptions"
:key="option.value"
:value="option.value"
:label="option.label"
/>
</el-select>
</div>
<el-row :gutter="20">
<el-col :span="8">
<el-form-item :label="t('EquipmentManagement.DvRepair.acceptedBy')" prop="acceptedBy">
<el-select
v-model="formData.acceptedBy"
multiple
filterable
clearable
:placeholder="t('EquipmentManagement.DvRepair.placeholderAcceptedBy')"
class="!w-full"
:disabled="repairFieldsDisabled"
>
<el-option v-for="item in users" :key="String(item.id)" :label="item.nickname" :value="String(item.id)" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item :label="t('EquipmentManagement.DvRepair.repairResult')" prop="repairStatus">
<template #label>
@ -270,24 +272,6 @@
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item :label="t('EquipmentManagement.DvRepair.confirmDate')" prop="confirmDate">
<template #label>
<span class="dv-repair-label" :class="{ 'is-required': formType === 'repair' }">
{{ t('EquipmentManagement.DvRepair.confirmDate') }}
</span>
</template>
<el-date-picker
v-model="formData.confirmDate"
type="datetime"
format="YYYY-MM-DD HH:mm:ss"
value-format="x"
:placeholder="t('EquipmentManagement.DvRepair.placeholderConfirmDate')"
class="!w-full"
:disabled="repairFieldsDisabled"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="8">
@ -364,13 +348,37 @@
</el-form-item>
</el-col>
</el-row>
</section>
<section v-if="isDetailMode && String(formData.status) === '2'" class="dv-repair-section">
<div class="dv-repair-section__title">{{ t('EquipmentManagement.DvRepair.rejectionInfo') }}</div>
<el-form-item :label="t('EquipmentManagement.DvRepair.rejectReason')">
<el-input :model-value="formData.rejectReason || '-'" type="textarea" :rows="3" disabled />
</el-form-item>
<el-row v-if="hasRepairHistory" :gutter="20">
<el-col :span="8">
<el-form-item :label="t('EquipmentManagement.DvRepair.confirmBy')">
<el-input :model-value="getUserLabel(displayedRepairHistory.confirmBy)" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item :label="t('EquipmentManagement.DvRepair.confirmDate')">
<el-date-picker
:model-value="toTimestamp(displayedRepairHistory.confirmDate)"
type="datetime"
format="YYYY-MM-DD HH:mm:ss"
value-format="x"
class="!w-full"
disabled
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item :label="t('EquipmentManagement.DvRepair.acceptanceResult')">
<el-input :model-value="getDocumentStatusLabel(displayedRepairHistory.status)" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row v-if="hasRepairHistory && String(displayedRepairHistory.status) === '2'" :gutter="20">
<el-col :span="24">
<el-form-item :label="t('EquipmentManagement.DvRepair.rejectReason')">
<el-input :model-value="displayedRepairHistory.rejectReason || '-'" type="textarea" :rows="3" disabled />
</el-form-item>
</el-col>
</el-row>
</section>
<section class="dv-repair-section">
@ -503,7 +511,7 @@
</template>
<script setup lang="ts">
import { DvRepairApi, DvRepairVO } from '@/api/mes/dvrepair'
import { DvRepairAcceptanceHistoryVO, DvRepairApi, DvRepairVO } from '@/api/mes/dvrepair'
import { DeviceLedgerApi, DeviceLedgerVO } from '@/api/mes/deviceledger'
import { DeviceTypeApi, DeviceTypeTreeVO } from '@/api/mes/devicetype'
import { RepairItemsApi } from '@/api/mes/repairItems'
@ -598,10 +606,11 @@ const currentRepairStatusValue = computed(() => {
const showRepairSection = computed(() => {
if (formType.value === 'repair') return true
if (formType.value === 'update') return currentStatusValue.value === '1'
if (formType.value === 'detail') return currentRepairStatusValue.value !== '0'
if (formType.value === 'detail') return hasRepairHistory.value || currentRepairStatusValue.value !== '0'
return false
})
const repairFieldsDisabled = computed(() => formType.value !== 'repair')
const documentStatusOptions = computed(() => getStrDictOptions(DICT_TYPE.EQUIPMENT_DOCUMENT_STATUS))
const submitButtonText = computed(() => {
if (formType.value === 'create') return '保存'
if (formType.value === 'repair') return '保存并提交'
@ -609,15 +618,66 @@ const submitButtonText = computed(() => {
})
const statusLabel = computed(() => {
const status = formData.value.status
if (status === '' || status === null || status === undefined) return t('EquipmentManagement.DvRepair.statusPending')
return String(status) === '1'
? t('EquipmentManagement.DvRepair.statusFinished')
: String(status) === '2'
? t('EquipmentManagement.DvRepair.statusRejected')
: t('EquipmentManagement.DvRepair.statusPending')
return getDocumentStatusLabel(formData.value.status)
})
const repairHistoryList = ref<DvRepairAcceptanceHistoryVO[]>([])
const selectedRepairHistoryIndex = ref<number>()
const hasRepairHistory = computed(() => repairHistoryList.value.length > 0)
const getHistoryTimestamp = (history: DvRepairAcceptanceHistoryVO) => {
const timestamp = toTimestamp(history.createTime ?? history.confirmDate ?? history.finishDate)
return timestamp === undefined ? Number.NEGATIVE_INFINITY : Number(timestamp)
}
const latestRepairHistoryIndex = computed(() => repairHistoryList.value.reduce((latestIndex, history, index) => {
return getHistoryTimestamp(history) >= getHistoryTimestamp(repairHistoryList.value[latestIndex]) ? index : latestIndex
}, 0))
const formatHistoryTime = (history: DvRepairAcceptanceHistoryVO) => {
const timestamp = toTimestamp(history.createTime ?? history.confirmDate ?? history.finishDate)
if (timestamp === undefined) return ''
const date = new Date(timestamp)
const pad = (value: number) => String(value).padStart(2, '0')
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`
}
const repairHistoryOptions = computed(() => repairHistoryList.value.map((item, index) => ({
value: index,
label: `${t('EquipmentManagement.DvRepair.historyRepairResult')} ${index + 1}${formatHistoryTime(item) ? ` · ${formatHistoryTime(item)}` : ''}`
})))
const displayedRepairHistory = computed(() => selectedRepairHistoryIndex.value === undefined
? formData.value
: repairHistoryList.value[selectedRepairHistoryIndex.value] ?? formData.value)
const getDocumentStatusLabel = (value: unknown) => {
const status = value === '' || value === null || value === undefined ? '0' : String(value)
return documentStatusOptions.value.find((item) => String(item.value) === status)?.label ?? status
}
const applyRepairHistory = (source: Record<string, any>) => {
formData.value.repairResult = source.repairResult ?? ''
formData.value.repairStatus = normalizeRepairStatusValue(source.repairStatus ?? source.repairResult)
formData.value.finishDate = toTimestamp(source.finishDate)
formData.value.confirmDate = toTimestamp(source.confirmDate)
formData.value.confirmBy = normalizeUserId(source.confirmBy)
formData.value.rejectReason = source.rejectReason
formData.value.downtimeDuration = source.downtimeDuration
formData.value.faultReason = source.faultReason
formData.value.handlingMeasures = source.handlingMeasures
formData.value.replacementParts = source.replacementParts
formData.value.repairContent = source.repairContent
formData.value.repairedImages = normalizeImageString(source.repairedImages)
}
const changeRepairHistory = () => {
const source = selectedRepairHistoryIndex.value === undefined
? undefined
: repairHistoryList.value[selectedRepairHistoryIndex.value]
if (source) applyRepairHistory(source as Record<string, any>)
}
const showComponentSelect = computed(() => formData.value.machineryTypeId === 2)
const selectedDeviceText = computed(() => {
@ -695,6 +755,12 @@ const normalizeUserId = (value: any) => {
return matched ? String(matched.id) : str
}
const getUserLabel = (value: any) => {
const normalizedValue = normalizeUserId(value)
if (!normalizedValue) return '-'
return users.value.find((user) => String(user.id) === normalizedValue)?.nickname ?? String(value)
}
const splitUserIds = (value: unknown) => {
const values = Array.isArray(value) ? value : String(value ?? '').split(',')
return [...new Set(values.map((item) => normalizeUserId(item)).filter(Boolean) as string[])]
@ -1022,18 +1088,6 @@ const formRules = reactive({
trigger: 'change'
}
],
confirmDate: [
{
validator: (_: any, value: any, callback: any) => {
if (formType.value === 'repair' && !value) {
callback(new Error(t('EquipmentManagement.DvRepair.validatorConfirmDateRequired')))
return
}
callback()
},
trigger: 'change'
}
],
repairStatus: [
{
validator: (_: any, value: any, callback: any) => {
@ -1116,8 +1170,8 @@ const open = async (type: string, id?: number) => {
...createDefaultFormData(),
...detail,
requireDate: toTimestamp(detail?.requireDate) ?? undefined,
finishDate: detail?.finishDate ?? undefined,
confirmDate: detail?.confirmDate ?? undefined,
finishDate: toTimestamp(detail?.finishDate) ?? undefined,
confirmDate: toTimestamp(detail?.confirmDate) ?? undefined,
repairResult: detail?.repairResult ?? '',
repairStatus: detail?.repairStatus === undefined || detail?.repairStatus === null || detail?.repairStatus === ''
? normalizeRepairStatusValue(detail?.repairResult)
@ -1151,6 +1205,9 @@ const open = async (type: string, id?: number) => {
formData.value.componentId = String(formData.value.componentId)
}
}
repairHistoryList.value = Array.isArray(detail?.acceptanceHistoryList) ? detail.acceptanceHistoryList : []
selectedRepairHistoryIndex.value = hasRepairHistory.value ? latestRepairHistoryIndex.value : undefined
changeRepairHistory()
await nextTick()
formRef.value?.clearValidate?.()
} finally {
@ -1206,6 +1263,7 @@ const submitForm = async () => {
data.faultImages = normalizeImageString(data.faultImages)
data.repairedImages = normalizeImageString(data.repairedImages)
data.repairResult = data.repairStatus
delete data.acceptanceHistoryList
const requireDate = toTimestamp(data.requireDate)
if (formType.value === 'repair' && requireDate === undefined) {
@ -1214,7 +1272,7 @@ const submitForm = async () => {
}
if (formType.value === 'repair') {
data.status = '1'
data.status = '3'
}
if (formData.value.deviceId != null && formData.value.deviceId !== '') {
data.machineryId = formData.value.deviceId
@ -1226,11 +1284,10 @@ const submitForm = async () => {
if (formType.value === 'repair') {
await DvRepairApi.updateDvRepairStatus({
id: data.id,
status: '3',
requireDate,
acceptedBy: data.acceptedBy,
confirmBy: data.confirmBy,
finishDate: data.finishDate,
confirmDate: data.confirmDate,
repairStatus: data.repairStatus,
repairResult: data.repairResult,
faultLevel: data.faultLevel,
@ -1267,6 +1324,8 @@ const submitForm = async () => {
const resetForm = () => {
formData.value = createDefaultFormData()
repairHistoryList.value = []
selectedRepairHistoryIndex.value = undefined
deviceOptionsLoaded.value = false
componentOptions.value = []
formRef.value?.resetFields()
@ -1331,6 +1390,22 @@ const resetForm = () => {
}
}
.dv-repair-section__title-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
.dv-repair-section__title {
margin-bottom: 16px;
}
}
.dv-repair-history-select {
width: 260px;
margin-bottom: 16px;
}
.dv-repair-label {
display: inline-flex;
gap: 4px;

@ -189,11 +189,11 @@
<template #default="scope">
<el-button
link type="primary" @click="openForm('repair', scope.row.id)"
v-if="String(scope.row.status) === '0' && !isProcessedRepair(scope.row.repairStatus)" v-hasPermi="['mes:dv-repair:update']">
v-if="canRepair(scope.row.status)" v-hasPermi="['mes:dv-repair:update']">
{{ t('EquipmentManagement.DvRepair.repair') }}
</el-button>
<el-button
v-if="String(scope.row.status) === '0' && !isProcessedRepair(scope.row.repairStatus)"
v-if="String(scope.row.status) === '0'"
link type="primary" @click="openForm('update', scope.row.id)"
v-hasPermi="['mes:dv-repair:update']">
{{ t('action.update') }}
@ -205,10 +205,10 @@
{{ t('action.detail') }}
</el-button>
<el-button
v-if="String(scope.row.status) === '1'"
link type="danger" :loading="String(rejectingId) === String(scope.row.id)" @click="handleReject(scope.row.id)"
v-if="String(scope.row.status) === '3'"
link type="primary" @click="openAcceptance(scope.row)"
v-hasPermi="['mes:dv-repair:update']">
{{ t('EquipmentManagement.DvRepair.reject') }}
{{ t('EquipmentManagement.DvRepair.acceptance') }}
</el-button>
<el-button link type="danger" @click="handleDelete(scope.row.id)" v-hasPermi="['mes:dv-repair:delete']">
{{ t('action.delete') }}
@ -224,14 +224,48 @@
</template>
<DvRepairForm v-else ref="formRef" @success="getList" @closed="formVisible = false" />
<Dialog v-model="acceptanceDialogVisible" :title="t('EquipmentManagement.DvRepair.acceptance')" width="560px" :appendToBody="true">
<el-form ref="acceptanceFormRef" :model="acceptanceForm" :rules="acceptanceRules" label-width="100px">
<el-form-item :label="t('EquipmentManagement.DvRepair.confirmBy')" prop="confirmBy">
<el-select v-model="acceptanceForm.confirmBy" filterable class="!w-full" :placeholder="t('EquipmentManagement.DvRepair.placeholderConfirmBy')">
<el-option v-for="item in users" :key="String(item.id)" :label="item.nickname" :value="String(item.id)" />
</el-select>
</el-form-item>
<el-form-item :label="t('EquipmentManagement.DvRepair.confirmDate')" prop="confirmDate">
<el-date-picker
v-model="acceptanceForm.confirmDate"
type="datetime"
format="YYYY-MM-DD HH:mm:ss"
value-format="x"
class="!w-full"
:placeholder="t('EquipmentManagement.DvRepair.placeholderConfirmDate')"
/>
</el-form-item>
<el-form-item :label="t('EquipmentManagement.DvRepair.acceptanceResult')" prop="status">
<el-radio-group v-model="acceptanceForm.status">
<el-radio label="1">{{ t('EquipmentManagement.DvRepair.acceptancePassed') }}</el-radio>
<el-radio label="2">{{ t('EquipmentManagement.DvRepair.acceptanceRejected') }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="acceptanceForm.status === '2'" :label="t('EquipmentManagement.DvRepair.rejectReason')" prop="rejectReason">
<el-input v-model="acceptanceForm.rejectReason" type="textarea" :rows="3" :placeholder="t('EquipmentManagement.DvRepair.rejectReasonPrompt')" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="acceptanceDialogVisible = false">{{ t('common.cancel') }}</el-button>
<el-button type="primary" :loading="acceptanceLoading" @click="submitAcceptance">{{ t('common.ok') }}</el-button>
</template>
</Dialog>
</div>
</template>
<script setup lang="ts">
import { DICT_TYPE } from '@/utils/dict'
import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
import { dateFormatter, dateFormatter2 } from '@/utils/formatTime'
import download from '@/utils/download'
import { DvRepairApi, DvRepairVO } from '@/api/mes/dvrepair'
import { getSimpleUserList, UserVO } from '@/api/system/user'
import DvRepairForm from './DvRepairForm.vue'
/** 设备维修记录 列表 */
@ -270,17 +304,15 @@ const counters = reactive({
allCount: 0,
pendingCount: 0,
finishedCount: 0,
pendingRepairCount: 0,
passedCount: 0,
failedCount: 0
pendingAcceptanceCount: 0,
rejectedCount: 0
})
const statusCards = computed(() => [
{ key: 'all', label: t('EquipmentManagement.DvRepair.all'), value: counters.allCount, status: undefined, repairStatus: undefined },
{ key: 'pending', label: t('EquipmentManagement.DvRepair.statusPending'), value: counters.pendingCount, status: '0', repairStatus: undefined },
{ key: 'finished', label: t('EquipmentManagement.DvRepair.statusFinished'), value: counters.finishedCount, status: '1', repairStatus: undefined },
{ key: 'pendingRepair', label: t('EquipmentManagement.DvRepair.repairResultPending'), value: counters.pendingRepairCount, status: undefined, repairStatus: '0' },
{ key: 'passed', label: t('EquipmentManagement.DvRepair.repairResultOk'), value: counters.passedCount, status: undefined, repairStatus: '1' },
{ key: 'failed', label: t('EquipmentManagement.DvRepair.repairResultNg'), value: counters.failedCount, status: undefined, repairStatus: '2' }
{ key: 'pending', label: getStatusLabel('0'), value: counters.pendingCount, status: '0', repairStatus: undefined },
{ key: 'pendingAcceptance', label: getStatusLabel('3'), value: counters.pendingAcceptanceCount, status: '3', repairStatus: undefined },
{ key: 'finished', label: getStatusLabel('1'), value: counters.finishedCount, status: '1', repairStatus: undefined },
{ key: 'rejected', label: getStatusLabel('2'), value: counters.rejectedCount, status: '2', repairStatus: undefined }
])
const changeStatus = (key: string, status?: string, repairStatus?: string) => {
currentStatusKey.value = key
@ -297,11 +329,8 @@ const toggleFilters = () => {
updatePlanTableMaxHeight()
}
const statusOptions = [
{ label: t('EquipmentManagement.DvRepair.statusPending'), value: '0' },
{ label: t('EquipmentManagement.DvRepair.statusFinished'), value: '1' },
{ label: t('EquipmentManagement.DvRepair.statusRejected'), value: '2' }
]
const documentStatusOptions = computed(() => getStrDictOptions(DICT_TYPE.EQUIPMENT_DOCUMENT_STATUS))
const statusOptions = computed(() => documentStatusOptions.value)
const repairStatusOptions = [
{ label: t('EquipmentManagement.DvRepair.repairResultPending'), value: '0' },
@ -311,10 +340,7 @@ const repairStatusOptions = [
const getStatusLabel = (value: any) => {
const v = value === '' || value === null || value === undefined ? undefined : String(value)
if (v === '0') return t('EquipmentManagement.DvRepair.statusPending')
if (v === '1') return t('EquipmentManagement.DvRepair.statusFinished')
if (v === '2') return t('EquipmentManagement.DvRepair.statusRejected')
return '-'
return documentStatusOptions.value.find((item) => String(item.value) === v)?.label ?? '-'
}
const getStatusTagType = (value: any) => {
@ -322,6 +348,7 @@ const getStatusTagType = (value: any) => {
if (v === '1') return 'success'
if (v === '0') return 'warning'
if (v === '2') return 'danger'
if (v === '3') return 'primary'
return 'info'
}
@ -341,10 +368,7 @@ const getResultTagType = (value: any) => {
return 'info'
}
const isProcessedRepair = (value: any) => {
const v = value === '' || value === null || value === undefined ? '0' : String(value)
return v !== '0'
}
const canRepair = (status: any) => ['0', '2'].includes(String(status))
const tableRef = ref()
const planTableMaxHeight = ref(520)
@ -359,7 +383,6 @@ const updatePlanTableMaxHeight = async () => {
planTableMaxHeight.value = Math.min(window.innerHeight, Math.max(240, Math.floor(availableHeight)))
}
const selectedIds = ref<number[]>([])
const rejectingId = ref<number | string>()
const handleSelectionChange = (rows: any[]) => {
selectedIds.value = rows?.map((row) => row.id).filter((id) => id !== undefined) ?? []
}
@ -374,9 +397,8 @@ const getList = async () => {
counters.allCount = Number(data?.allCount ?? data?.total ?? 0)
counters.pendingCount = Number(data?.pendingCount ?? 0)
counters.finishedCount = Number(data?.finishedCount ?? 0)
counters.pendingRepairCount = Number(data?.pendingRepairCount ?? 0)
counters.passedCount = Number(data?.passedCount ?? 0)
counters.failedCount = Number(data?.failedCount ?? 0)
counters.pendingAcceptanceCount = Number(data?.pendingAcceptanceCount ?? 0)
counters.rejectedCount = Number(data?.rejectedCount ?? 0)
} finally {
loading.value = false
updatePlanTableMaxHeight()
@ -436,25 +458,61 @@ const handleBatchDelete = async () => {
await handleDelete(selectedIds.value)
}
const handleReject = async (id: number | string) => {
try {
const { value } = await ElMessageBox.prompt(
t('EquipmentManagement.DvRepair.rejectReasonPrompt'),
t('EquipmentManagement.DvRepair.reject'),
{
confirmButtonText: t('common.ok'),
cancelButtonText: t('common.cancel'),
inputPattern: /^[\s\S]*.*\S[\s\S]*$/,
inputErrorMessage: t('EquipmentManagement.DvRepair.rejectReasonRequired')
const users = ref<UserVO[]>([])
const acceptanceDialogVisible = ref(false)
const acceptanceLoading = ref(false)
const acceptanceFormRef = ref()
const acceptanceForm = reactive({
id: undefined as number | string | undefined,
confirmBy: undefined as string | undefined,
confirmDate: Date.now() as number | string,
status: '1' as '1' | '2',
rejectReason: undefined as string | undefined
})
const acceptanceRules = reactive({
confirmBy: [{ required: true, message: t('EquipmentManagement.DvRepair.placeholderConfirmBy'), trigger: 'change' }],
confirmDate: [{ required: true, message: t('EquipmentManagement.DvRepair.validatorConfirmDateRequired'), trigger: 'change' }],
status: [{ required: true, message: t('EquipmentManagement.DvRepair.validatorAcceptanceResultRequired'), trigger: 'change' }],
rejectReason: [{
validator: (_: any, value: any, callback: any) => {
if (acceptanceForm.status === '2' && !String(value ?? '').trim()) {
callback(new Error(t('EquipmentManagement.DvRepair.rejectReasonRequired')))
return
}
)
rejectingId.value = id
await DvRepairApi.rejectDvRepair({ id, rejectReason: value })
message.success(t('EquipmentManagement.DvRepair.rejectSuccess'))
callback()
},
trigger: 'blur'
}]
})
const openAcceptance = async (row: DvRepairVO) => {
if (!users.value.length) users.value = (await getSimpleUserList()) ?? []
acceptanceFormRef.value?.resetFields?.()
acceptanceForm.id = row.id
acceptanceForm.confirmBy = undefined
acceptanceForm.confirmDate = Date.now()
acceptanceForm.status = '1'
acceptanceForm.rejectReason = undefined
acceptanceDialogVisible.value = true
}
const submitAcceptance = async () => {
await acceptanceFormRef.value?.validate()
if (acceptanceForm.id === undefined || acceptanceForm.id === null) return
acceptanceLoading.value = true
try {
await DvRepairApi.acceptanceDvRepair({
id: acceptanceForm.id,
confirmBy: acceptanceForm.confirmBy!,
confirmDate: acceptanceForm.confirmDate,
status: acceptanceForm.status,
rejectReason: acceptanceForm.status === '2' ? acceptanceForm.rejectReason?.trim() : undefined
})
message.success(t('EquipmentManagement.DvRepair.acceptanceSuccess'))
acceptanceDialogVisible.value = false
await getList()
} catch {
} finally {
rejectingId.value = undefined
acceptanceLoading.value = false
}
}

@ -582,7 +582,12 @@ const getHistoryTimestamp = (history: MoldRepairAcceptanceHistoryVO) => {
const toTimestamp = (value: any): any => {
if (value === undefined || value === null || value === '') return undefined
if (typeof value === 'number') return value
const timestamp = new Date(value).getTime()
const text = String(value).trim()
if (/^\d+$/.test(text)) {
const timestamp = Number(text)
return Number.isFinite(timestamp) ? timestamp : undefined
}
const timestamp = new Date(text.replace(/-/g, '/')).getTime()
return Number.isNaN(timestamp) ? undefined : timestamp
}
@ -590,9 +595,17 @@ const latestRepairHistoryIndex = computed(() => repairHistoryList.value.reduce((
return getHistoryTimestamp(history) >= getHistoryTimestamp(repairHistoryList.value[latestIndex]) ? index : latestIndex
}, 0))
const repairHistoryOptions = computed(() => repairHistoryList.value.map((_, index) => ({
const formatHistoryTime = (history: MoldRepairAcceptanceHistoryVO) => {
const timestamp = toTimestamp(history.createTime ?? history.confirmDate ?? history.finishDate)
if (timestamp === undefined) return ''
const date = new Date(timestamp)
const pad = (value: number) => String(value).padStart(2, '0')
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`
}
const repairHistoryOptions = computed(() => repairHistoryList.value.map((item, index) => ({
value: index,
label: `${t('MoldManagement.MoldRepair.historyRepairResult')} ${index + 1}`
label: `${t('MoldManagement.MoldRepair.historyRepairResult')} ${index + 1}${formatHistoryTime(item) ? ` · ${formatHistoryTime(item)}` : ''}`
})))
const displayedRepairHistory = computed(() => {

Loading…
Cancel
Save