You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

320 lines
9.5 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<Dialog v-model="dialogVisible" :title="dialogTitle" width="1500px" append-to-body>
<el-table
v-loading="loading"
:data="list"
:stripe="true"
:show-overflow-tooltip="true"
:row-key="getRowKey"
>
<el-table-column
:label="t('QualityManagement.TicketResultDialog.index')"
type="index"
align="center"
width="60"
/>
<el-table-column
:label="t('QualityManagement.TicketResultDialog.inspectionItemName')"
align="center"
prop="name"
min-width="160"
/>
<el-table-column
:label="t('QualityManagement.TicketResultDialog.inspectionMethod')"
align="center"
prop="tool"
min-width="120"
/>
<el-table-column
:label="t('QualityManagement.TicketResultDialog.judgmentCriteria')"
align="center"
prop="standardVal"
min-width="100"
/>
<el-table-column
:label="t('QualityManagement.TicketResultDialog.unit')"
align="center"
prop="unitName"
min-width="80"
/>
<el-table-column
:label="t('QualityManagement.TicketResultDialog.upperVal')"
align="center"
prop="upperVal"
min-width="100"
/>
<el-table-column
:label="t('QualityManagement.TicketResultDialog.lowerVal')"
align="center"
prop="lowerVal"
min-width="100"
/>
<el-table-column
:label="t('QualityManagement.TicketResultDialog.images')"
align="center"
prop="images"
width="160"
>
<template #default="scope">
<UploadImg
v-if="String(scope.row.zjResult) === '0'"
v-model="imageMap[String(scope.row.id)]"
:drag="false"
:show-btn-text="false"
width="64px"
height="64px"
/>
<el-image
v-else-if="scope.row.images"
:src="parseFirstImage(scope.row.images)"
:preview-src-list="parseImages(scope.row.images)"
preview-teleported
fit="cover"
style="width: 64px; height: 64px"
/>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="输入值" align="center" min-width="150">
<template #default="scope">
<el-input
v-if="String(scope.row.zjResult) === '0'"
v-model="scope.row.textInput"
clearable
placeholder="请输入"
/>
<span v-else>{{ scope.row.textInput || '-' }}</span>
</template>
</el-table-column>
<el-table-column
:label="t('QualityManagement.TicketResultDialog.remark')"
align="center"
prop="remark"
min-width="160"
/>
<el-table-column
:label="t('QualityManagement.TicketResultDialog.inspectionResult')"
align="center"
prop="zjResult"
width="120"
>
<template #default="scope">
<el-tag v-if="String(scope.row.zjResult) === '0'" type="info">
{{ t('QualityManagement.TicketResultDialog.inspectionResultPending') }}
</el-tag>
<el-tag v-else-if="String(scope.row.zjResult) === '1'" type="success">
{{ t('QualityManagement.TicketResultDialog.inspectionResultPass') }}
</el-tag>
<el-tag v-else-if="String(scope.row.zjResult) === '2'" type="danger">
{{ t('QualityManagement.TicketResultDialog.inspectionResultFail') }}
</el-tag>
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column
:label="t('QualityManagement.TicketResultDialog.operate')"
align="center"
width="200"
fixed="right"
>
<template #default="scope">
<el-radio-group
v-if="String(scope.row.zjResult) === '0'"
v-model="decisionMap[String(scope.row.id)]"
>
<el-radio :label="1">{{ t('QualityManagement.TicketResultDialog.pass') }}</el-radio>
<el-radio :label="2">{{ t('QualityManagement.TicketResultDialog.fail') }}</el-radio>
</el-radio-group>
<span v-else>-</span>
</template>
</el-table-column>
</el-table>
<el-pagination
v-show="total > 0"
v-model:current-page="queryParams.pageNo"
v-model:page-size="queryParams.pageSize"
:background="true"
:page-sizes="[10, 20, 30, 50, 100]"
:pager-count="7"
:total="total"
class="mt-15px mb-15px flex justify-end"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
<div v-if="String(status) === '4'" class="mt-10px text-14px">
<span>{{ t('QualityManagement.ZjTask.status') }}</span>
<DictTag :type="'job_status'" :value="status" />
<span class="ml-20px">取消原因:</span>
<span>{{ cancelReason || '-' }}</span>
</div>
<template #footer>
<el-button @click="dialogVisible = false">
{{ t('QualityManagement.TicketResultDialog.cancel') }}
</el-button>
<el-button
type="primary"
@click="handleSave"
:loading="submitLoading"
:disabled="submitLoading || !isAllSelected()"
>
{{ t('QualityManagement.TicketResultDialog.save') }}
</el-button>
</template>
</Dialog>
</template>
<script setup lang="ts">
import type { ZjTaskResultVO } from '@/api/mes/zjtask'
import { ZjTaskApi } from '@/api/mes/zjtask'
import { DictTag } from '@/components/DictTag'
defineOptions({ name: 'ZjTaskResultDialog' })
const { t } = useI18n()
const dialogVisible = ref(false)
const dialogTitle = ref(t('QualityManagement.TicketResultDialog.moduleName'))
const loading = ref(false)
const submitLoading = ref(false)
const emit = defineEmits(['success'])
const message = useMessage()
const list = ref<ZjTaskResultVO[]>([])
const total = ref(0)
const taskId = ref<number | undefined>(undefined)
const status = ref<string | number | undefined>(undefined)
const cancelReason = ref<string | undefined>(undefined)
const decisionMap = reactive<Record<string, number | undefined>>({})
const imageMap = reactive<Record<string, string>>({})
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
})
const open = async (options: { id: number; status?: string | number; cancelReason?: string }) => {
dialogVisible.value = true
dialogTitle.value = t('QualityManagement.TicketResultDialog.moduleName')
taskId.value = options.id
status.value = options.status
cancelReason.value = options.cancelReason
for (const key of Object.keys(decisionMap)) delete decisionMap[key]
for (const key of Object.keys(imageMap)) delete imageMap[key]
queryParams.pageNo = 1
await getList()
}
defineExpose({ open })
const getList = async () => {
if (!taskId.value) return
loading.value = true
try {
const data = await ZjTaskApi.getZjTaskResultPage({
pageNo: queryParams.pageNo,
pageSize: queryParams.pageSize,
taskId: taskId.value,
})
list.value = data.list
total.value = data.total
for (const row of list.value) {
const id = row?.id
if (!id) continue
if (row.images && !imageMap[String(id)]) {
imageMap[String(id)] = parseFirstImage(row.images)
}
if (row.zjResult !== undefined && row.zjResult !== null && !decisionMap[String(id)]) {
decisionMap[String(id)] = Number(row.zjResult)
}
}
} finally {
loading.value = false
}
}
const handleSizeChange = () => {
queryParams.pageNo = 1
getList()
}
const handleCurrentChange = () => {
getList()
}
const getRowKey = (row: ZjTaskResultVO) => {
return String(row.id ?? '')
}
const handleSave = async () => {
if (!taskId.value) {
message.error('任务标识不存在,无法保存')
return
}
const currentTaskId = taskId.value
const hasUnselected = list.value.some((row) => {
if (!row?.id) return false
const decision = decisionMap[String(row.id)]
return decision !== 1 && decision !== 2
})
if (hasUnselected) {
message.error('请先为所有记录选择通过或不通过')
return
}
const payload: { id: number; taskId: number; images?: string; zjResult: number }[] = []
for (const row of list.value) {
if (!row?.id) continue
const decision = decisionMap[String(row.id)]
if (decision !== 1 && decision !== 2) continue
const img = imageMap[String(row.id)] || row.images
payload.push({ id: row.id, taskId: currentTaskId, images: img, zjResult: decision, textInput: row.textInput })
}
if (!payload.length) {
message.error('暂无需要保存的记录')
return
}
submitLoading.value = true
try {
await ZjTaskApi.batchUpdateZjTaskResults(payload)
message.success('更新成功')
emit('success')
dialogVisible.value = false
} catch {
message.error('更新失败')
} finally {
submitLoading.value = false
}
}
const parseImages = (value: any): string[] => {
if (!value) return []
if (Array.isArray(value)) return value.map(String).filter(Boolean)
return String(value)
.split(',')
.map((v) => v.trim())
.filter(Boolean)
}
const parseFirstImage = (value: any): string => {
return parseImages(value)[0] || ''
}
const isAllSelected = () => {
if (!list.value.length) return false
for (const row of list.value) {
if (!row?.id) continue
const decision = decisionMap[String(row.id)]
if (decision !== 1 && decision !== 2) return false
}
return true
}
</script>
<style scoped lang="scss">
:deep(.el-upload) {
margin: 0 auto;
}
</style>