heli-mes/mes-ui/mes-ui-admin-vue3/src/views/heli/inspectionreport/detail.vue

443 lines
17 KiB
Vue
Raw Normal View History

2025-01-09 18:29:48 +08:00
<template>
<el-card class="hl-card">
<template #header>
<span><span v-html="dialogTitle"></span></span>
</template>
<el-form ref="formRef" label-width="140px" :rules="formRules" :model="formData" v-loading="formLoading">
<!-- 基础信息 横向布局 -->
<el-card class="hl-card-info">
<template #header>
<div class="hl-card-info-icona"></div><span class="hl-card-info-text">基础信息</span>
</template>
<el-row>
<el-col :span="6">
<el-form-item label="项目编号" prop="projectCode">
<el-input class="!w-260px" v-model="formData.projectCode" :disabled="true" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="项目名称" prop="projectName">
<el-input class="!w-260px" v-model="formData.projectName" :disabled="true" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="子项目编号" prop="projectSubCode">
<el-input class="!w-260px" v-model="formData.projectSubCode" :disabled="true" />
</el-form-item>
</el-col>
<el-col :span="6">
<el-form-item label="子项目名称" prop="projectSubName">
<el-input class="!w-260px" v-model="formData.projectSubName" :disabled="true" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="6">
<el-form-item label="客户名称" prop="customerName">
<el-input class="!w-260px" v-model="formData.customerName" :disabled="true" />
</el-form-item>
</el-col>
</el-row>
</el-card>
<!-- 表格类信息 -->
<el-card class="hl-card-info">
<template #header>
<div class="hl-card-info-icona"></div><span class="hl-card-info-text">检验报告</span>
</template>
<el-row>
<el-col>
<el-card class="hl-incard">
<el-col v-if="active != 'detail'">
<el-upload ref="compositionUploadRef" :file-list="compositionUploadFiles" multiple :action="uploadUrl" :headers="{
Authorization: 'Bearer ' + getAccessToken(),
'tenant-id': getTenantId()
}" name="files" :show-file-list="false" :auto-upload="false" :data="compositionUploadData" :on-change="compositionUploadChange" :on-error="handleError" :on-success="handleSuccess" :before-upload="before" class="upload-file-uploader">
<el-button type="primary">
<Icon icon="ep:upload-filled" />上传材质报告
</el-button>
</el-upload>
<el-upload ref="heatUploadRef" :file-list="heatUploadFiles" multiple :action="uploadUrl" :headers="{
Authorization: 'Bearer ' + getAccessToken(),
'tenant-id': getTenantId()
}" name="files" :show-file-list="false" :auto-upload="false" :data="heatUploadData" :on-change="heatUploadChange" :on-error="handleError" :on-success="handleSuccess" :before-upload="before" class="upload-file-uploader">
<el-button type="primary">
<Icon icon="ep:upload-filled" />上传热处理报告
</el-button>
</el-upload>
<el-upload ref="scanUploadRef" :file-list="scanUploadFiles" multiple :action="uploadUrl" :headers="{
Authorization: 'Bearer ' + getAccessToken(),
'tenant-id': getTenantId()
}" name="files" :show-file-list="false" :auto-upload="false" :data="scanUploadData" :on-change="scanUploadChange" :on-error="handleError" :on-success="handleSuccess" :before-upload="before" class="upload-file-uploader">
<el-button type="primary">
<Icon icon="ep:upload-filled" />上传扫描报告
</el-button>
</el-upload>
<el-upload ref="triUploadRef" :file-list="triUploadFiles" multiple :action="uploadUrl" :headers="{
Authorization: 'Bearer ' + getAccessToken(),
'tenant-id': getTenantId()
}" name="files" :show-file-list="false" :auto-upload="false" :data="triUploadData" :on-change="triUploadChange" :on-error="handleError" :on-success="handleSuccess" :before-upload="before" class="upload-file-uploader">
<el-button type="primary">
<Icon icon="ep:upload-filled" />上传三坐标检测报告
</el-button>
</el-upload>
<el-upload ref="certificateUploadRef" :file-list="certificateUploadFiles" multiple :action="uploadUrl" :headers="{
Authorization: 'Bearer ' + getAccessToken(),
'tenant-id': getTenantId()
}" name="files" :show-file-list="false" :auto-upload="false" :data="certificateUploadData" :on-change="certificateUploadChange" :on-error="handleError" :on-success="handleSuccess" :before-upload="before" class="upload-file-uploader">
<el-button type="primary">
<Icon icon="ep:upload-filled" />上传合格证
</el-button>
</el-upload>
</el-col>
<el-table :data="formData.attachments" v-loading.fullscreen.lock="uploading" element-loading-text="附件上传中..." element-loading-background="rgba(122, 122, 122, 0.6)" class="hl-table">
<el-table-column fixed type="index" width="100" label="序号" align="center" />
<el-table-column prop="name" label="文件名称" align="center" />
<el-table-column prop="businessFileType" label="文件类型" align="center">
<template #default="scope">
{{
getDictLabel(DICT_TYPE.HELI_BUSINESS_FILE_TYPE, scope.row.businessFileType)
}}
</template>
</el-table-column>
<el-table-column prop="createTime" align="center" label="上传时间" :formatter="dateFormatter" />
<el-table-column label="操作" align="center">
<template #default="scope">
<el-button v-if="active != 'detail'" link type="danger" size="small" @click="handleDeleteAttachment(scope.$index, scope.row.businessFileType)">
删除
</el-button>
<el-button v-if="!!scope.row.id" link type="primary" size="small" @click="downloadAttachment(scope.row.name, scope.row.url)">
下载
</el-button>
</template>
</el-table-column>
</el-table>
</el-card>
</el-col>
</el-row>
</el-card>
</el-form>
<div class="text-center hl-footer">
<el-button @click="goback" size="large"> </el-button>
<el-button v-if="active != 'detail'" @click="submitForm('SAVE')" type="primary" :disabled="formLoading" size="large"> </el-button>
</div>
</el-card>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import * as InspectionReportApi from '@/api/heli/inspectionreport'
import { inject } from 'vue'
import { useUserStore } from '@/store/modules/user'
import { useCommonStore } from '@/store/modules/common'
import { getAccessToken, getTenantId } from '@/utils/auth'
import { dateFormatter } from '@/utils/formatTime'
import { DICT_TYPE, getDictLabel } from '@/utils/dict'
import { UploadUserFile } from 'element-plus'
import { deleteFileLogic, downloadFile, getFilePage } from '@/api/infra/file'
import download from '@/utils/download'
defineOptions({ name: 'InspectionReportDetail' })
const reload: any = inject('reload')
const { t } = useI18n() // 国际化
const message = useMessage() // 消息弹窗
const commonStore = useCommonStore()
const userStore = useUserStore()
const router = useRouter()
const active = toRef(commonStore.getStore('active'))
const currentId = toRef(commonStore.getStore('id'))
const formLoading = ref(false)
const dialogTitle = ref('')
const detailDisabled = ref(false)
const businessType = 'INSPECTION_REPORT'
const formData: any = ref({
projectId: undefined,
projectSubId: undefined,
attachments: []
})
const formRef = ref() // 表单 Ref
const subFormRef = ref()
const formRules = reactive({})
/** 重置表单 */
const resetForm = () => {
formData.value = {
projectId: undefined,
projectSubId: undefined,
attachments: []
}
formRef.value?.resetFields()
}
const subFormLoading = ref(false) // 子表单的加载中
const subFormRules = reactive({})
const queryData = async (id?: number) => {
resetForm()
// 修改时,设置数据
if (id) {
formLoading.value = true
try {
formData.value = await InspectionReportApi.getInspectionReport(id)
// 附件信息
let attParams = {
pageNo: 1,
pageSize: 99,
businessId: id,
businessType: businessType
}
formData.value.attachments = (await getFilePage(attParams)).list
} finally {
formLoading.value = false
}
}
}
const submitForm = async (operate) => {
// 提交请求
formLoading.value = true
try {
// 上传附件
if (compositionUploadFiles.value.length > 0) {
compositionUploadData.value.businessId = formData.value.projectSubId
await compositionUploadRef.value!.submit()
}
if (heatUploadFiles.value.length > 0) {
heatUploadData.value.businessId = formData.value.projectSubId
await heatUploadRef.value!.submit()
}
if (scanUploadFiles.value.length > 0) {
scanUploadData.value.businessId = formData.value.projectSubId
await scanUploadRef.value!.submit()
}
if (triUploadFiles.value.length > 0) {
triUploadData.value.businessId = formData.value.projectSubId
await triUploadRef.value!.submit()
}
if (certificateUploadFiles.value.length > 0) {
certificateUploadData.value.businessId = formData.value.projectSubId
await certificateUploadRef.value!.submit()
}
message.success(t('common.operationSuccess'))
reload()
} finally {
formLoading.value = false
}
}
const goback = () => {
router.back()
}
// ====================附件信息 开始=======================================
const uploading = ref(false)
const uploadUrl = ref(import.meta.env.VITE_UPLOAD_BATCH_URL)
const compositionUploadRef = ref()
const compositionUploadFiles = ref<UploadUserFile[]>([])
const compositionUploadData = ref({
businessType: businessType,
businessId: formData.value.projectSubId,
businessFileType: 'COMPOSITION_REPORT'
})
const heatUploadRef = ref()
const heatUploadFiles = ref<UploadUserFile[]>([])
const heatUploadData = ref({
businessType: businessType,
businessId: formData.value.projectSubId,
businessFileType: 'HEAT_TREATMENT_REPORT'
})
const scanUploadRef = ref()
const scanUploadFiles = ref<UploadUserFile[]>([])
const scanUploadData = ref({
businessType: businessType,
businessId: formData.value.projectSubId,
businessFileType: 'SCAN_REPORT'
})
const triUploadRef = ref()
const triUploadFiles = ref<UploadUserFile[]>([])
const triUploadData = ref({
businessType: businessType,
businessId: formData.value.projectSubId,
businessFileType: 'TRI_LINEAR_COORDINATES_MEASURING'
})
const certificateUploadRef = ref()
const certificateUploadFiles = ref<UploadUserFile[]>([])
const certificateUploadData = ref({
businessType: businessType,
businessId: formData.value.projectSubId,
businessFileType: 'CERTIFICATE_OF_QUALIFICATION'
})
const compositionUploadChange = (file, files) => {
compositionUploadFiles.value = files
refreshAttachments(files, 'COMPOSITION_REPORT')
}
const heatUploadChange = (file, files) => {
heatUploadFiles.value = files
refreshAttachments(files, 'HEAT_TREATMENT_REPORT')
}
const scanUploadChange = (file, files) => {
scanUploadFiles.value = files
refreshAttachments(files, 'SCAN_REPORT')
}
const triUploadChange = (file, files) => {
triUploadFiles.value = files
refreshAttachments(files, 'TRI_LINEAR_COORDINATES_MEASURING')
}
const certificateUploadChange = (file, files) => {
certificateUploadFiles.value = files
refreshAttachments(files, 'CERTIFICATE_OF_QUALIFICATION')
}
// 记录待上传、成功上传及失败上传的文件数量
const sumbefore = ref(0)
const successfulUploadsCount = ref(0)
const failedUploadsCount = ref(0)
const failedAttachments = ref<UploadUserFile[]>([])
const failedAttachmentsName = ref()
// 处理单个文件上传成功的情况
const handleSuccess = (response: any, file: UploadUserFile) => {
successfulUploadsCount.value++
}
// 处理单个文件上传失败的情况
const handleError = (error: Error, file: UploadUserFile) => {
failedUploadsCount.value++
if (failedUploadsCount.value > 0) {
// 当有上传错误时
// 将失败的附件添加到failedAttachments.value数组中
failedAttachments.value.push(file)
failedAttachmentsName.value = failedAttachments.value.map((value) => value.name)
}
}
// 储存已上传文件的名称唯一标识
const uploadedFiles = ref([]);
// 文件上传前的钩子用于检查文件是否已存在
const before = (file) => {
// console.log('文件名', file.name);
const fileName: any = file.name;
// 检查文件名是否存在并确保操作的原子性
if (!uploadedFiles.value.includes(fileName)) {
uploadedFiles.value.push(fileName);
sumbefore.value++
return true; // 允许上传
}
// console.log('文件已存在!');
return false; // 阻止上传
}
const newfiless: any = ref([])
const filess: any = ref([])
const refreshAttachments = (files, type) => {
files.forEach((file) => {
const hasDuplicate = newfiless.value.filter((item) => {
return file.name == item.name
})
if (hasDuplicate.length > 0) {
// console.log('重复文件', hasDuplicate)
} else {
newfiless.value.push(file)
formData.value.attachments = [
...formData.value.attachments,
{ ...file, businessFileType: type, createTime: new Date() }
]
}
})
// 排序
formData.value.attachments.sort((v1, v2) => v1.createTime - v2.createTime)
// 文件上传一遍 上传总数等于要上传文件时 刷新页面
const sum = successfulUploadsCount.value + failedUploadsCount.value
// console.log('上传总数', sum)
// console.log('要上传文件数量', sumbefore.value)
if (sumbefore.value !== sum && sumbefore.value !== 0 && sum !== 0) {
// console.log('要上传文件数量不等于上传总数时等待',uploading.value)
uploading.value = true
} else if (sum == sumbefore.value && sumbefore.value > 0 && sum > 0) {
// console.log('要上传文件数量等于上传总数 刷新页面并给出提示')
if (failedUploadsCount.value > 0) {
ElMessageBox.alert(
// 使用错误信息作为提示内容
`文件名为:${failedAttachmentsName.value.join(' / ')}上传失败`,
`文件格式不正确或网络问题 请您稍后再试`,
{
dangerouslyUseHTMLString: false, // 由于我们不是使用HTML字符串所以这里设置为false
confirmButtonText: '知道了',
center: true
}
)
}
reload()
uploading.value = false
}
}
// 删除附件
const handleDeleteAttachment = async (index, type) => {
const deletedAttachments = formData.value.attachments.splice(index, 1)
for (let i = 0; i < deletedAttachments.length; i++) {
const attachment = deletedAttachments[i]
if (attachment.id) {
// 清理已上传文件
await deleteFileLogic(attachment.id)
}
// 清理待上传文件
compositionUploadFiles.value = compositionUploadFiles.value.filter((file1) => {
return file1.name != attachment.name || file1.businessFileType != type
})
heatUploadFiles.value = heatUploadFiles.value.filter((file2) => {
return file2.name != attachment.name || file2.businessFileType != type
})
scanUploadFiles.value = scanUploadFiles.value.filter((file3) => {
return file3.name != attachment.name || file3.businessFileType != type
})
triUploadFiles.value = triUploadFiles.value.filter((file4) => {
return file4.name != attachment.name || file4.businessFileType != type
})
certificateUploadFiles.value = certificateUploadFiles.value.filter((file5) => {
return file5.name != attachment.name || file5.businessFileType != type
})
}
}
// 下载文件
const downloadAttachment = async (name, url) => {
const data = await downloadFile(url)
download.any(data, name)
}
onMounted(() => {
dialogTitle.value = t('action.' + active.value)
if ('detail' == active.value) {
detailDisabled.value = true
}
queryData(currentId.value)
})
</script>
<style scoped>
.upload-file-uploader {
margin-bottom: 10px;
display: inline-block;
margin-right: 20px;
}
</style>