feat:模具维修逻辑重构

main
黄伟杰 1 day ago
parent e02f2d9908
commit 84aa0b90f2

@ -23,6 +23,36 @@ export interface MoldRepairVO {
status: string status: string
rejectReason?: string rejectReason?: string
remark: string remark: string
shutdownDuration?: string
treatmentMeasures?: string
repairSummary?: string
acceptanceHistoryList?: MoldRepairAcceptanceHistoryVO[]
}
export interface MoldRepairAcceptanceHistoryVO {
id?: number | string
repairId?: number | string
repairResult?: string | number
finishDate?: Date | string | number
confirmDate?: Date | string | number
confirmBy?: string
status?: string | number
rejectReason?: string
shutdownDuration?: string
faultReason?: string
treatmentMeasures?: string
replacementParts?: string
repairSummary?: string
repairedImages?: string
createTime?: Date | string | number
}
export interface MoldRepairAcceptanceVO {
id: number | string
confirmBy: string
confirmDate?: Date | string | number
status: '1' | '2'
rejectReason?: string
} }
export type MoldRepairSaveVO = Omit<MoldRepairVO, 'machineryId' | 'machineryCode' | 'machineryName'> export type MoldRepairSaveVO = Omit<MoldRepairVO, 'machineryId' | 'machineryCode' | 'machineryName'>
@ -60,6 +90,10 @@ export const MoldRepairApi = {
return await request.put({ url: `/mes/mold-repair/reject`, data }) return await request.put({ url: `/mes/mold-repair/reject`, data })
}, },
acceptanceMoldRepair: async (data: MoldRepairAcceptanceVO) => {
return await request.put({ url: `/mes/mold-repair/acceptance`, data })
},
getMoldRepairLineListByRepairId: async (repairId) => { getMoldRepairLineListByRepairId: async (repairId) => {
return await request.get({ url: `/mes/mold-repair/mold-repair-line/list-by-repair-id?repairId=` + repairId }) return await request.get({ url: `/mes/mold-repair/mold-repair-line/list-by-repair-id?repairId=` + repairId })
}, },

@ -53,6 +53,16 @@ const uploadBrandingLogo = async (
} }
} }
const removeBrandingLogo = async (field: (typeof brandingLogoItems)[number]['field']) => {
try {
await BrandingLogoApi.updateBrandingLogoConfig({ [field]: '' })
await loadBrandingLogoConfig()
ElMessage.success(t('setting.logoRemoveSuccess'))
} catch {
// The request interceptor displays the server-side error message.
}
}
// //
const systemTheme = ref(appStore.getTheme.elColorPrimary) const systemTheme = ref(appStore.getTheme.elColorPrimary)
@ -248,23 +258,36 @@ const clear = () => {
<div class="grid grid-cols-3 gap-10px"> <div class="grid grid-cols-3 gap-10px">
<div v-for="item in brandingLogoItems" :key="item.field" class="text-center"> <div v-for="item in brandingLogoItems" :key="item.field" class="text-center">
<div class="mb-6px text-12px">{{ t(item.label) }}</div> <div class="mb-6px text-12px">{{ t(item.label) }}</div>
<ElUpload <div class="relative inline-flex">
accept="image/*" <ElUpload
:http-request="(options) => uploadBrandingLogo(item.field, item.path, options)" accept="image/*"
:show-file-list="false" :http-request="(options) => uploadBrandingLogo(item.field, item.path, options)"
> :show-file-list="false"
<img
v-if="brandingLogoConfig[item.field]"
:src="brandingLogoConfig[item.field]"
class="h-72px w-72px rounded-4px border border-solid border-[var(--el-border-color)] object-contain"
/>
<div
v-else
class="h-72px w-72px flex items-center justify-center rounded-4px border border-dashed border-[var(--el-border-color)]"
> >
<Icon icon="ep:plus" /> <img
</div> v-if="brandingLogoConfig[item.field]"
</ElUpload> :src="brandingLogoConfig[item.field]"
class="h-72px w-72px rounded-4px border border-solid border-[var(--el-border-color)] object-contain"
/>
<div
v-else
class="h-72px w-72px flex items-center justify-center rounded-4px border border-dashed border-[var(--el-border-color)]"
>
<Icon icon="ep:plus" />
</div>
</ElUpload>
<ElTooltip v-if="brandingLogoConfig[item.field]" :content="t('action.delete')">
<ElButton
circle
class="absolute right--6px top--6px z-1 !h-20px !w-20px !min-h-0 !p-0"
size="small"
type="danger"
@click.stop="removeBrandingLogo(item.field)"
>
<Icon icon="ep:close" />
</ElButton>
</ElTooltip>
</div>
</div> </div>
</div> </div>

@ -1217,6 +1217,7 @@ export default {
webHeaderLogo: 'Web menu logo', webHeaderLogo: 'Web menu logo',
appLoginLogo: 'App login logo', appLoginLogo: 'App login logo',
logoSaveSuccess: 'Logo settings saved', logoSaveSuccess: 'Logo settings saved',
logoRemoveSuccess: 'Logo removed',
theme: 'Theme', theme: 'Theme',
layout: 'Layout', layout: 'Layout',
systemTheme: 'System theme', systemTheme: 'System theme',
@ -3673,7 +3674,11 @@ export default {
MoldRepair: { MoldRepair: {
moduleName: 'Mold Repair', moduleName: 'Mold Repair',
basicInfo: 'Basic Information', basicInfo: 'Basic Information',
reportInfo: 'Repair Request Information',
faultInfo: 'Fault Information', faultInfo: 'Fault Information',
processingResult: 'Processing Result',
currentRepairResult: 'Current Processing Result',
historyRepairResult: 'Historical Processing Result',
repairCode: 'Repair Order No', repairCode: 'Repair Order No',
repairName: 'Repair Order', repairName: 'Repair Order',
mold: 'Mold', mold: 'Mold',
@ -3700,6 +3705,12 @@ export default {
rejectReasonPrompt: 'Please enter the rejection reason', rejectReasonPrompt: 'Please enter the rejection reason',
rejectReasonRequired: 'Rejection reason cannot be empty', rejectReasonRequired: 'Rejection reason cannot be empty',
rejectSuccess: 'Rejected successfully', rejectSuccess: 'Rejected successfully',
acceptance: 'Acceptance',
acceptanceResult: 'Acceptance Result',
acceptancePassed: 'Pass',
acceptanceRejected: 'Reject',
acceptanceSuccess: 'Acceptance submitted successfully',
validatorAcceptanceResultRequired: 'Please select an acceptance result',
acceptUser: 'Repair User', acceptUser: 'Repair User',
confirmUserShort: 'Acceptance User', confirmUserShort: 'Acceptance User',
creator: 'Creator', creator: 'Creator',

@ -1243,6 +1243,7 @@ export default {
webHeaderLogo: 'Web 菜单 Logo', webHeaderLogo: 'Web 菜单 Logo',
appLoginLogo: 'App Logo', appLoginLogo: 'App Logo',
logoSaveSuccess: 'Logo 配置已保存', logoSaveSuccess: 'Logo 配置已保存',
logoRemoveSuccess: 'Logo 已删除',
theme: '主题', theme: '主题',
layout: '布局', layout: '布局',
systemTheme: '系统主题', systemTheme: '系统主题',
@ -3178,7 +3179,11 @@ export default {
all: '全部', all: '全部',
moduleName: '维修单', moduleName: '维修单',
basicInfo: '基本信息', basicInfo: '基本信息',
reportInfo: '报修信息',
faultInfo: '故障信息', faultInfo: '故障信息',
processingResult: '处理结果',
currentRepairResult: '当前处理结果',
historyRepairResult: '历史处理结果',
repairCode: '维修单号', repairCode: '维修单号',
repairName: '维修单', repairName: '维修单',
mold: '模具', mold: '模具',
@ -3205,6 +3210,12 @@ export default {
rejectReasonPrompt: '请输入驳回理由', rejectReasonPrompt: '请输入驳回理由',
rejectReasonRequired: '驳回理由不能为空', rejectReasonRequired: '驳回理由不能为空',
rejectSuccess: '驳回成功', rejectSuccess: '驳回成功',
acceptance: '验收',
acceptanceResult: '验收结果',
acceptancePassed: '通过',
acceptanceRejected: '驳回',
acceptanceSuccess: '验收提交成功',
validatorAcceptanceResultRequired: '请选择验收结果',
acceptUser: '维修人员', acceptUser: '维修人员',
confirmUserShort: '验收人员', confirmUserShort: '验收人员',
creator: '创建人', creator: '创建人',

@ -271,6 +271,7 @@ export enum DICT_TYPE {
MES_MAINTAIN_TIME_UNIT = "mes_maintain_time_unit", MES_MAINTAIN_TIME_UNIT = "mes_maintain_time_unit",
MES_PROGRESS_TYPE = "mes_progress_type", MES_PROGRESS_TYPE = "mes_progress_type",
MES_MOLD_RECORD_STATUS = "mes_mold_record_status", MES_MOLD_RECORD_STATUS = "mes_mold_record_status",
MOLD_DOCUMENT_STATUS = "mold_document_status",
MES_MOLD_RECORD_TYPE = "mes_mold_record_type", MES_MOLD_RECORD_TYPE = "mes_mold_record_type",
MES_PASS_OR_NOPASS = "mes_pass_or_nopass", MES_PASS_OR_NOPASS = "mes_pass_or_nopass",
MES_MANTAIN_LEVEL = "mes_mantain_level", MES_MANTAIN_LEVEL = "mes_mantain_level",

@ -9,7 +9,7 @@
<div class="dv-repair-dialog" v-loading="formLoading"> <div class="dv-repair-dialog" v-loading="formLoading">
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px"> <el-form ref="formRef" :model="formData" :rules="formRules" label-width="100px">
<section class="dv-repair-section"> <section class="dv-repair-section">
<div class="dv-repair-section__title">基本信息</div> <div class="dv-repair-section__title">{{ t('MoldManagement.MoldRepair.reportInfo') }}</div>
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="8"> <el-col :span="8">
<el-form-item :label="t('MoldManagement.MoldRepair.repairCode')" prop="repairCode"> <el-form-item :label="t('MoldManagement.MoldRepair.repairCode')" prop="repairCode">
@ -70,28 +70,6 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col v-if="formType !== 'create'" :span="8"> <el-col v-if="formType !== 'create'" :span="8">
<el-form-item :label="t('MoldManagement.MoldRepair.repairUser')" prop="acceptedBy">
<el-select
v-model="formData.acceptedBy" multiple filterable clearable
:placeholder="t('MoldManagement.MoldRepair.placeholderAcceptUser')"
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('MoldManagement.MoldRepair.confirmUser')" prop="confirmBy">
<el-select
v-model="formData.confirmBy" filterable clearable
:placeholder="t('MoldManagement.MoldRepair.placeholderConfirmUser')"
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 :span="8">
<el-form-item :label="t('MoldManagement.MoldRepair.status')"> <el-form-item :label="t('MoldManagement.MoldRepair.status')">
<el-input :model-value="statusLabel" disabled /> <el-input :model-value="statusLabel" disabled />
</el-form-item> </el-form-item>
@ -133,9 +111,9 @@
</section> </section>
<section class="dv-repair-section"> <section class="dv-repair-section">
<div class="dv-repair-section__title">维修对象</div> <div class="dv-repair-section__title">{{ t('MoldManagement.MoldRepair.faultInfo') }}</div>
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="8"> <el-col :span="24">
<el-form-item :label="t('MoldManagement.MoldRepair.mold')" prop="moldId"> <el-form-item :label="t('MoldManagement.MoldRepair.mold')" prop="moldId">
<el-input <el-input
:model-value="selectedMoldText" :model-value="selectedMoldText"
@ -154,24 +132,6 @@
</template> </template>
</el-input> </el-input>
</el-form-item> </el-form-item>
</el-col>
<el-col :span="8">
<el-form-item :label="t('MoldManagement.MoldRepair.moldName')" prop="moldName" :required="false">
<el-input v-model="formData.moldName" :placeholder="t('MoldManagement.MoldRepair.placeholderMoldNameAuto')" disabled />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item :label="t('MoldManagement.MoldRepair.moldCode')" prop="moldCode" :required="false">
<el-input v-model="formData.moldCode" :placeholder="t('MoldManagement.MoldRepair.placeholderMoldCodeAuto')" disabled />
</el-form-item>
</el-col>
</el-row>
</section>
<section class="dv-repair-section">
<div class="dv-repair-section__title">故障信息</div>
<el-row :gutter="20">
<el-col :span="24">
<el-form-item :label="t('MoldManagement.MoldRepair.faultPhenomenon')" prop="faultPhenomenon"> <el-form-item :label="t('MoldManagement.MoldRepair.faultPhenomenon')" prop="faultPhenomenon">
<template #label> <template #label>
<span class="dv-repair-label is-required"> <span class="dv-repair-label is-required">
@ -212,8 +172,35 @@
</section> </section>
<section v-if="showRepairFields" class="dv-repair-section"> <section v-if="showRepairFields" 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('MoldManagement.MoldRepair.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-row :gutter="20">
<el-col :span="8">
<el-form-item :label="t('MoldManagement.MoldRepair.repairUser')" prop="acceptedBy">
<el-select
v-model="formData.acceptedBy" multiple filterable clearable
:placeholder="t('MoldManagement.MoldRepair.placeholderAcceptUser')"
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-col :span="8">
<el-form-item :label="t('MoldManagement.MoldRepair.repairResult')" prop="repairStatus"> <el-form-item :label="t('MoldManagement.MoldRepair.repairResult')" prop="repairStatus">
<template #label> <template #label>
@ -246,20 +233,6 @@
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="8">
<el-form-item :label="t('MoldManagement.MoldRepair.confirmDate')" prop="confirmDate">
<template #label>
<span class="dv-repair-label" :class="{ 'is-required': formType === 'repair' }">
{{ t('MoldManagement.MoldRepair.confirmDate') }}
</span>
</template>
<el-date-picker
v-model="formData.confirmDate" type="datetime" format="YYYY-MM-DD HH:mm:ss" value-format="x"
:placeholder="t('MoldManagement.MoldRepair.placeholderConfirmDate')"
class="!w-full" :disabled="repairFieldsDisabled"
/>
</el-form-item>
</el-col>
</el-row> </el-row>
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="8"> <el-col :span="8">
@ -336,13 +309,37 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
</section> <el-row v-if="hasRepairHistory" :gutter="20">
<el-col :span="8">
<section v-if="isDetailMode && String(formData.status) === '2'" class="dv-repair-section"> <el-form-item :label="t('MoldManagement.MoldRepair.confirmUser')">
<div class="dv-repair-section__title">{{ t('MoldManagement.MoldRepair.rejectionInfo') }}</div> <el-input :model-value="getUserLabel(displayedRepairHistory.confirmBy)" disabled />
<el-form-item :label="t('MoldManagement.MoldRepair.rejectReason')"> </el-form-item>
<el-input :model-value="formData.rejectReason || '-'" type="textarea" :rows="3" disabled /> </el-col>
</el-form-item> <el-col :span="8">
<el-form-item :label="t('MoldManagement.MoldRepair.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('MoldManagement.MoldRepair.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('MoldManagement.MoldRepair.rejectReason')">
<el-input :model-value="displayedRepairHistory.rejectReason || '-'" type="textarea" :rows="3" disabled />
</el-form-item>
</el-col>
</el-row>
</section> </section>
<section class="dv-repair-section"> <section class="dv-repair-section">
@ -470,7 +467,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { MoldRepairApi, MoldRepairVO } from '@/api/mold/moldrepair' import { MoldRepairAcceptanceHistoryVO, MoldRepairApi, MoldRepairVO } from '@/api/mold/moldrepair'
import { MoldBrandApi, MoldVO } from '@/api/erp/mold' import { MoldBrandApi, MoldVO } from '@/api/erp/mold'
import { getSimpleUserList, UserVO } from '@/api/system/user' import { getSimpleUserList, UserVO } from '@/api/system/user'
import { DICT_TYPE, getStrDictOptions } from '@/utils/dict' import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
@ -560,24 +557,76 @@ const currentRepairStatusValue = computed(() => {
const showRepairFields = computed(() => { const showRepairFields = computed(() => {
if (formType.value === 'repair') return true if (formType.value === 'repair') return true
if (formType.value === 'update') return currentStatusValue.value === '1' 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 return false
}) })
const repairFieldsDisabled = computed(() => formType.value !== 'repair') const repairFieldsDisabled = computed(() => formType.value !== 'repair')
const failureLevelOptions = computed(() => getStrDictOptions(DICT_TYPE.FAILURE_LEVEL)) const failureLevelOptions = computed(() => getStrDictOptions(DICT_TYPE.FAILURE_LEVEL))
const documentStatusOptions = computed(() => getStrDictOptions(DICT_TYPE.MOLD_DOCUMENT_STATUS))
const statusLabel = computed(() => { const statusLabel = computed(() => {
const status = formData.value.status return getDocumentStatusLabel(formData.value.status)
if (status === '' || status === null || status === undefined) return t('MoldManagement.MoldRepair.statusPending')
return String(status) === '1'
? t('MoldManagement.MoldRepair.statusDone')
: String(status) === '2'
? t('MoldManagement.MoldRepair.statusRejected')
: t('MoldManagement.MoldRepair.statusPending')
}) })
const isHydrating = ref(false) const isHydrating = ref(false)
const openRequestId = ref(0) const openRequestId = ref(0)
const emit = defineEmits(['success', 'closed']) const emit = defineEmits(['success', 'closed'])
const formData = ref<MoldRepairFormData>(createDefaultFormData()) const formData = ref<MoldRepairFormData>(createDefaultFormData())
const repairHistoryList = ref<MoldRepairAcceptanceHistoryVO[]>([])
const selectedRepairHistoryIndex = ref<number>()
const hasRepairHistory = computed(() => repairHistoryList.value.length > 0)
const getHistoryTimestamp = (history: MoldRepairAcceptanceHistoryVO) => {
const timestamp = toTimestamp(history.createTime ?? history.confirmDate ?? history.finishDate)
return timestamp === undefined ? Number.NEGATIVE_INFINITY : Number(timestamp)
}
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()
return Number.isNaN(timestamp) ? undefined : timestamp
}
const latestRepairHistoryIndex = computed(() => repairHistoryList.value.reduce((latestIndex, history, index) => {
return getHistoryTimestamp(history) >= getHistoryTimestamp(repairHistoryList.value[latestIndex]) ? index : latestIndex
}, 0))
const repairHistoryOptions = computed(() => repairHistoryList.value.map((_, index) => ({
value: index,
label: `${t('MoldManagement.MoldRepair.historyRepairResult')} ${index + 1}`
})))
const displayedRepairHistory = computed(() => {
return 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 ?? source.shutdownDuration
formData.value.faultReason = source.faultReason
formData.value.handlingMeasures = source.handlingMeasures ?? source.treatmentMeasures
formData.value.replacementParts = source.replacementParts
formData.value.repairContent = source.repairContent ?? source.repairSummary
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 moldLoading = ref(false) const moldLoading = ref(false)
const moldOptions = ref<{ label: string; value: number; raw?: MoldVO }[]>([]) const moldOptions = ref<{ label: string; value: number; raw?: MoldVO }[]>([])
@ -687,6 +736,12 @@ const resetMoldDialogQuery = () => {
handleMoldDialogQuery() handleMoldDialogQuery()
} }
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 splitUserIds = (value: unknown) => {
const values = Array.isArray(value) ? value : String(value ?? '').split(',') const values = Array.isArray(value) ? value : String(value ?? '').split(',')
return [...new Set(values.map((item) => normalizeUserId(item)).filter(Boolean) as string[])] return [...new Set(values.map((item) => normalizeUserId(item)).filter(Boolean) as string[])]
@ -798,18 +853,6 @@ const formRules = reactive({
trigger: 'change', trigger: 'change',
}, },
], ],
confirmDate: [
{
validator: (_: any, value: any, callback: any) => {
if (formType.value === 'repair' && !value) {
callback(new Error(t('MoldManagement.MoldRepair.validatorConfirmDateRequired')))
return
}
callback()
},
trigger: 'change',
},
],
repairStatus: [ repairStatus: [
{ {
validator: (_: any, value: any, callback: any) => { validator: (_: any, value: any, callback: any) => {
@ -919,9 +962,9 @@ const open = async (type: string, id?: number) => {
if (currentOpenId !== openRequestId.value) return if (currentOpenId !== openRequestId.value) return
;(formData.value as any).requireDate = (formData.value as any).requireDate ?? undefined ;(formData.value as any).requireDate = toTimestamp((formData.value as any).requireDate)
;(formData.value as any).finishDate = (formData.value as any).finishDate ?? (type === 'repair' ? Date.now() : undefined) ;(formData.value as any).finishDate = toTimestamp((formData.value as any).finishDate) ?? (type === 'repair' ? Date.now() : undefined)
;(formData.value as any).confirmDate = (formData.value as any).confirmDate ?? (type === 'repair' ? Date.now() : undefined) ;(formData.value as any).confirmDate = toTimestamp((formData.value as any).confirmDate)
;(formData.value as any).repairResult = (formData.value as any).repairResult ?? '' ;(formData.value as any).repairResult = (formData.value as any).repairResult ?? ''
;(formData.value as any).repairStatus = (formData.value as any).repairStatus === undefined || (formData.value as any).repairStatus === null || (formData.value as any).repairStatus === '' ;(formData.value as any).repairStatus = (formData.value as any).repairStatus === undefined || (formData.value as any).repairStatus === null || (formData.value as any).repairStatus === ''
? normalizeRepairStatusValue((formData.value as any).repairResult) ? normalizeRepairStatusValue((formData.value as any).repairResult)
@ -932,10 +975,10 @@ const open = async (type: string, id?: number) => {
;(formData.value as any).shutdown = (formData.value as any).shutdown ?? undefined ;(formData.value as any).shutdown = (formData.value as any).shutdown ?? undefined
;(formData.value as any).faultImages = normalizeImageString((formData.value as any).faultImages) ;(formData.value as any).faultImages = normalizeImageString((formData.value as any).faultImages)
;(formData.value as any).faultReason = (formData.value as any).faultReason ?? undefined ;(formData.value as any).faultReason = (formData.value as any).faultReason ?? undefined
;(formData.value as any).downtimeDuration = (formData.value as any).downtimeDuration ?? undefined ;(formData.value as any).downtimeDuration = (formData.value as any).downtimeDuration ?? (formData.value as any).shutdownDuration ?? undefined
;(formData.value as any).handlingMeasures = (formData.value as any).handlingMeasures ?? undefined ;(formData.value as any).handlingMeasures = (formData.value as any).handlingMeasures ?? (formData.value as any).treatmentMeasures ?? undefined
;(formData.value as any).replacementParts = (formData.value as any).replacementParts ?? undefined ;(formData.value as any).replacementParts = (formData.value as any).replacementParts ?? undefined
;(formData.value as any).repairContent = (formData.value as any).repairContent ?? undefined ;(formData.value as any).repairContent = (formData.value as any).repairContent ?? (formData.value as any).repairSummary ?? undefined
;(formData.value as any).repairedImages = normalizeImageString((formData.value as any).repairedImages) ;(formData.value as any).repairedImages = normalizeImageString((formData.value as any).repairedImages)
;(formData.value as any).acceptedBy = splitUserIds((formData.value as any).acceptedBy) ;(formData.value as any).acceptedBy = splitUserIds((formData.value as any).acceptedBy)
@ -960,6 +1003,11 @@ const open = async (type: string, id?: number) => {
const label = `${formData.value.moldCode ?? ''} ${formData.value.moldName ?? ''}`.trim() || `ID:${resolvedMoldId}` const label = `${formData.value.moldCode ?? ''} ${formData.value.moldName ?? ''}`.trim() || `ID:${resolvedMoldId}`
moldOptions.value = upsertMoldOption(moldOptions.value, { label, value: resolvedMoldId }) moldOptions.value = upsertMoldOption(moldOptions.value, { label, value: resolvedMoldId })
} }
repairHistoryList.value = Array.isArray((formData.value as any).acceptanceHistoryList)
? (formData.value as any).acceptanceHistoryList
: []
selectedRepairHistoryIndex.value = hasRepairHistory.value ? latestRepairHistoryIndex.value : undefined
changeRepairHistory()
} finally { } finally {
isHydrating.value = false isHydrating.value = false
formLoading.value = false formLoading.value = false
@ -996,11 +1044,20 @@ const submitForm = async () => {
data.faultImages = Array.isArray(data.faultImages) ? data.faultImages.join(',') : (data.faultImages ?? '') data.faultImages = Array.isArray(data.faultImages) ? data.faultImages.join(',') : (data.faultImages ?? '')
data.repairedImages = Array.isArray(data.repairedImages) ? data.repairedImages.join(',') : (data.repairedImages ?? '') data.repairedImages = Array.isArray(data.repairedImages) ? data.repairedImages.join(',') : (data.repairedImages ?? '')
data.repairResult = data.repairStatus data.repairResult = data.repairStatus
data.shutdownDuration = data.downtimeDuration
data.treatmentMeasures = data.handlingMeasures
data.repairSummary = data.repairContent
data.acceptedBy = normalizeAcceptedBy(data.acceptedBy) data.acceptedBy = normalizeAcceptedBy(data.acceptedBy)
data.confirmBy = normalizeUserId(data.confirmBy) data.confirmBy = normalizeUserId(data.confirmBy)
data.repairReporter = normalizeUserId(data.repairReporter) data.repairReporter = normalizeUserId(data.repairReporter)
delete data.acceptanceHistoryList
delete data.downtimeDuration
delete data.handlingMeasures
delete data.repairContent
if (formType.value === 'repair') { if (formType.value === 'repair') {
data.status = '1' data.status = '3'
delete data.confirmBy
delete data.confirmDate
} }
if (formType.value === 'create') { if (formType.value === 'create') {
await MoldRepairApi.createMoldRepair(data) await MoldRepairApi.createMoldRepair(data)
@ -1018,6 +1075,8 @@ const submitForm = async () => {
const resetForm = () => { const resetForm = () => {
formData.value = createDefaultFormData() formData.value = createDefaultFormData()
repairHistoryList.value = []
selectedRepairHistoryIndex.value = undefined
moldOptionsLoaded.value = false moldOptionsLoaded.value = false
formRef.value?.resetFields() formRef.value?.resetFields()
} }
@ -1078,6 +1137,22 @@ const resetForm = () => {
border-left: 3px solid #409eff; border-left: 3px solid #409eff;
} }
.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-code-row { .dv-repair-code-row {
display: flex; display: flex;
gap: 10px; gap: 10px;

@ -178,10 +178,10 @@
<template #default="scope"> <template #default="scope">
<el-button <el-button
link type="primary" @click="openForm('repair', scope.row.id)" 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('MoldManagement.MoldRepair.repair') }}</el-button> >{{ t('MoldManagement.MoldRepair.repair') }}</el-button>
<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)" link type="primary" @click="openForm('update', scope.row.id)"
v-hasPermi="['mes:dv-repair:update']"> v-hasPermi="['mes:dv-repair:update']">
{{ t('MoldManagement.MoldRepair.edit') }} {{ t('MoldManagement.MoldRepair.edit') }}
@ -193,10 +193,10 @@
{{ t('action.detail') }} {{ t('action.detail') }}
</el-button> </el-button>
<el-button <el-button
v-if="String(scope.row.status) === '1'" v-if="String(scope.row.status) === '3'"
link type="danger" :loading="String(rejectingId) === String(scope.row.id)" @click="handleReject(scope.row.id)" link type="primary" @click="openAcceptance(scope.row)"
v-hasPermi="['mes:dv-repair:update']"> v-hasPermi="['mes:dv-repair:update']">
{{ t('MoldManagement.MoldRepair.reject') }} {{ t('MoldManagement.MoldRepair.acceptance') }}
</el-button> </el-button>
<el-button link type="danger" @click="handleDelete(scope.row.id)" v-hasPermi="['mes:dv-repair:delete']"> <el-button link type="danger" @click="handleDelete(scope.row.id)" v-hasPermi="['mes:dv-repair:delete']">
{{ t('MoldManagement.MoldRepair.delete') }} {{ t('MoldManagement.MoldRepair.delete') }}
@ -213,12 +213,47 @@
<div v-if="formVisible"> <div v-if="formVisible">
<MoldRepairForm ref="formRef" @success="handleFormSuccess" @closed="formVisible = false" /> <MoldRepairForm ref="formRef" @success="handleFormSuccess" @closed="formVisible = false" />
</div> </div>
<Dialog v-model="acceptanceDialogVisible" :title="t('MoldManagement.MoldRepair.acceptance')" width="560px" :appendToBody="true">
<el-form ref="acceptanceFormRef" :model="acceptanceForm" :rules="acceptanceRules" label-width="100px">
<el-form-item :label="t('MoldManagement.MoldRepair.confirmUser')" prop="confirmBy">
<el-select v-model="acceptanceForm.confirmBy" filterable class="!w-full" :placeholder="t('MoldManagement.MoldRepair.placeholderConfirmUser')">
<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('MoldManagement.MoldRepair.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('MoldManagement.MoldRepair.placeholderConfirmDate')"
/>
</el-form-item>
<el-form-item :label="t('MoldManagement.MoldRepair.acceptanceResult')" prop="status">
<el-radio-group v-model="acceptanceForm.status">
<el-radio label="1">{{ t('MoldManagement.MoldRepair.acceptancePassed') }}</el-radio>
<el-radio label="2">{{ t('MoldManagement.MoldRepair.acceptanceRejected') }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item v-if="acceptanceForm.status === '2'" :label="t('MoldManagement.MoldRepair.rejectReason')" prop="rejectReason">
<el-input v-model="acceptanceForm.rejectReason" type="textarea" :rows="3" :placeholder="t('MoldManagement.MoldRepair.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>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { dateFormatter, dateFormatter2 } from '@/utils/formatTime' import { dateFormatter, dateFormatter2 } from '@/utils/formatTime'
import download from '@/utils/download' import download from '@/utils/download'
import { MoldRepairApi, MoldRepairVO } from '@/api/mold/moldrepair' import { MoldRepairApi, MoldRepairVO } from '@/api/mold/moldrepair'
import { getSimpleUserList, UserVO } from '@/api/system/user'
import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
import MoldRepairForm from './MoldRepairForm.vue' import MoldRepairForm from './MoldRepairForm.vue'
defineOptions({ name: 'MoldRepair' }) defineOptions({ name: 'MoldRepair' })
@ -264,18 +299,16 @@ const currentStatusKey = ref('all')
const counters = reactive({ const counters = reactive({
allCount: 0, allCount: 0,
pendingCount: 0, pendingCount: 0,
pendingAcceptanceCount: 0,
finishedCount: 0, finishedCount: 0,
pendingRepairCount: 0, rejectedCount: 0
passedCount: 0,
failedCount: 0
}) })
const statusCards = computed(() => [ const statusCards = computed(() => [
{ key: 'all', label: t('MoldManagement.MoldRepair.all'), value: counters.allCount, status: undefined, repairStatus: undefined }, { key: 'all', label: t('MoldManagement.MoldRepair.all'), value: counters.allCount, status: undefined, repairStatus: undefined },
{ key: 'pending', label: t('MoldManagement.MoldRepair.statusPending'), value: counters.pendingCount, status: '0', repairStatus: undefined }, { key: 'pending', label: getStatusLabel('0'), value: counters.pendingCount, status: '0', repairStatus: undefined },
{ key: 'finished', label: t('MoldManagement.MoldRepair.statusDone'), value: counters.finishedCount, status: '1', repairStatus: undefined }, { key: 'pendingAcceptance', label: getStatusLabel('3'), value: counters.pendingAcceptanceCount, status: '3', repairStatus: undefined },
{ key: 'pendingRepair', label: t('MoldManagement.MoldRepair.repairResultPending'), value: counters.pendingRepairCount, status: undefined, repairStatus: '0' }, { key: 'passed', label: getStatusLabel('1'), value: counters.finishedCount, status: '1', repairStatus: undefined },
{ key: 'passed', label: t('MoldManagement.MoldRepair.repairResultOk'), value: counters.passedCount, status: undefined, repairStatus: '1' }, { key: 'rejected', label: getStatusLabel('2'), value: counters.rejectedCount, status: '2', repairStatus: undefined }
{ key: 'failed', label: t('MoldManagement.MoldRepair.repairResultNg'), value: counters.failedCount, status: undefined, repairStatus: '2' }
]) ])
const changeStatus = (key: string, status?: string, repairStatus?: string) => { const changeStatus = (key: string, status?: string, repairStatus?: string) => {
currentStatusKey.value = key currentStatusKey.value = key
@ -285,11 +318,8 @@ const changeStatus = (key: string, status?: string, repairStatus?: string) => {
} }
const exportLoading = ref(false) const exportLoading = ref(false)
const statusOptions = [ const documentStatusOptions = computed(() => getStrDictOptions(DICT_TYPE.MOLD_DOCUMENT_STATUS))
{ label: t('MoldManagement.MoldRepair.statusPending'), value: '0' }, const statusOptions = computed(() => documentStatusOptions.value)
{ label: t('MoldManagement.MoldRepair.statusDone'), value: '1' },
{ label: t('MoldManagement.MoldRepair.statusRejected'), value: '2' }
]
const getResultLabel = (value: any) => { const getResultLabel = (value: any) => {
const v = value === '' || value === null || value === undefined ? undefined : String(value) const v = value === '' || value === null || value === undefined ? undefined : String(value)
@ -309,10 +339,7 @@ const getResultTagType = (value: any) => {
const getStatusLabel = (value: any) => { const getStatusLabel = (value: any) => {
const v = value === '' || value === null || value === undefined ? undefined : String(value) const v = value === '' || value === null || value === undefined ? undefined : String(value)
if (v === '0') return t('MoldManagement.MoldRepair.statusPending') return documentStatusOptions.value.find((item) => String(item.value) === v)?.label ?? '-'
if (v === '1') return t('MoldManagement.MoldRepair.statusDone')
if (v === '2') return t('MoldManagement.MoldRepair.statusRejected')
return '-'
} }
const getStatusTagType = (value: any) => { const getStatusTagType = (value: any) => {
@ -320,13 +347,11 @@ const getStatusTagType = (value: any) => {
if (v === '1') return 'success' if (v === '1') return 'success'
if (v === '0') return 'warning' if (v === '0') return 'warning'
if (v === '2') return 'danger' if (v === '2') return 'danger'
if (v === '3') return 'primary'
return 'info' return 'info'
} }
const isProcessedRepair = (value: any) => { const canRepair = (status: any) => ['0', '2'].includes(String(status))
const v = value === '' || value === null || value === undefined ? '0' : String(value)
return v !== '0'
}
const tableRef = ref() const tableRef = ref()
const planTableMaxHeight = ref(520) const planTableMaxHeight = ref(520)
@ -341,7 +366,6 @@ const updatePlanTableMaxHeight = async () => {
planTableMaxHeight.value = Math.min(window.innerHeight, Math.max(240, Math.floor(availableHeight))) planTableMaxHeight.value = Math.min(window.innerHeight, Math.max(240, Math.floor(availableHeight)))
} }
const selectedIds = ref<number[]>([]) const selectedIds = ref<number[]>([])
const rejectingId = ref<number | string>()
const handleSelectionChange = (rows: any[]) => { const handleSelectionChange = (rows: any[]) => {
selectedIds.value = rows?.map((row) => row.id).filter((id) => id !== undefined) ?? [] selectedIds.value = rows?.map((row) => row.id).filter((id) => id !== undefined) ?? []
} }
@ -361,10 +385,9 @@ const getList = async () => {
total.value = data.total total.value = data.total
counters.allCount = Number(data?.allCount ?? data?.total ?? 0) counters.allCount = Number(data?.allCount ?? data?.total ?? 0)
counters.pendingCount = Number(data?.pendingCount ?? 0) counters.pendingCount = Number(data?.pendingCount ?? 0)
counters.pendingAcceptanceCount = Number(data?.pendingAcceptanceCount ?? 0)
counters.finishedCount = Number(data?.finishedCount ?? 0) counters.finishedCount = Number(data?.finishedCount ?? 0)
counters.pendingRepairCount = Number(data?.pendingRepairCount ?? 0) counters.rejectedCount = Number(data?.rejectedCount ?? 0)
counters.passedCount = Number(data?.passedCount ?? 0)
counters.failedCount = Number(data?.failedCount ?? 0)
} finally { } finally {
loading.value = false loading.value = false
updatePlanTableMaxHeight() updatePlanTableMaxHeight()
@ -422,25 +445,61 @@ const handleBatchDelete = async () => {
await handleDelete(selectedIds.value) await handleDelete(selectedIds.value)
} }
const handleReject = async (id: number | string) => { const users = ref<UserVO[]>([])
try { const acceptanceDialogVisible = ref(false)
const { value } = await ElMessageBox.prompt( const acceptanceLoading = ref(false)
t('MoldManagement.MoldRepair.rejectReasonPrompt'), const acceptanceFormRef = ref()
t('MoldManagement.MoldRepair.reject'), const acceptanceForm = reactive({
{ id: undefined as number | string | undefined,
confirmButtonText: t('common.ok'), confirmBy: undefined as string | undefined,
cancelButtonText: t('common.cancel'), confirmDate: Date.now() as number | string,
inputPattern: /^[\s\S]*.*\S[\s\S]*$/, status: '1' as '1' | '2',
inputErrorMessage: t('MoldManagement.MoldRepair.rejectReasonRequired') rejectReason: undefined as string | undefined
})
const acceptanceRules = reactive({
confirmBy: [{ required: true, message: t('MoldManagement.MoldRepair.placeholderConfirmUser'), trigger: 'change' }],
confirmDate: [{ required: true, message: t('MoldManagement.MoldRepair.validatorConfirmDateRequired'), trigger: 'change' }],
status: [{ required: true, message: t('MoldManagement.MoldRepair.validatorAcceptanceResultRequired'), trigger: 'change' }],
rejectReason: [{
validator: (_: any, value: any, callback: any) => {
if (acceptanceForm.status === '2' && !String(value ?? '').trim()) {
callback(new Error(t('MoldManagement.MoldRepair.rejectReasonRequired')))
return
} }
) callback()
rejectingId.value = id },
await MoldRepairApi.rejectMoldRepair({ id, rejectReason: value }) trigger: 'blur'
message.success(t('MoldManagement.MoldRepair.rejectSuccess')) }]
})
const openAcceptance = async (row: MoldRepairVO) => {
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 MoldRepairApi.acceptanceMoldRepair({
id: acceptanceForm.id,
confirmBy: acceptanceForm.confirmBy!,
confirmDate: acceptanceForm.confirmDate,
status: acceptanceForm.status,
rejectReason: acceptanceForm.status === '2' ? acceptanceForm.rejectReason?.trim() : undefined
})
message.success(t('MoldManagement.MoldRepair.acceptanceSuccess'))
acceptanceDialogVisible.value = false
await getList() await getList()
} catch {
} finally { } finally {
rejectingId.value = undefined acceptanceLoading.value = false
} }
} }

Loading…
Cancel
Save