| | |
| | | width="60" /> |
| | | <el-table-column label="隐患编号" |
| | | prop="hiddenCode" |
| | | width="180" |
| | | show-overflow-tooltip /> |
| | | width="150" |
| | | align="center" |
| | | show-overflow-tooltip> |
| | | <template #default="scope"> |
| | | <el-button class="hidden-code-link" |
| | | link |
| | | type="primary" |
| | | @click="openForm('detail', scope.row)"> |
| | | {{ scope.row.hiddenCode }} |
| | | </el-button> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="隐患描述" |
| | | prop="hiddenDesc" |
| | | width="150" |
| | | align="center" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="隐患具体位置" |
| | | prop="location" |
| | | width="150" |
| | | align="center" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="上报人" |
| | | prop="createUserName" |
| | | width="180" |
| | | width="150" |
| | | align="center" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="上报时间" |
| | | prop="createTime" |
| | | width="180" |
| | | align="center" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="整改完成期限" |
| | | prop="rectifyTime" |
| | | width="120" |
| | | align="center" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="整改责任人" |
| | | prop="rectifyUserName" |
| | | width="120" |
| | | align="center" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="整改责任人联系方式" |
| | | prop="rectifyUserMobile" |
| | | width="120" |
| | | width="160" |
| | | align="center" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="整改具体措施" |
| | | prop="rectifyMeasures" |
| | | width="120" |
| | | align="center" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="实际整改完成时间" |
| | | prop="rectifyActualTime" |
| | | width="180" |
| | | align="center" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="验收人" |
| | | prop="verifyUserName" |
| | | width="120" |
| | | align="center" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="验收意见" |
| | | prop="verifyRemark" |
| | | width="120" |
| | | align="center" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="验收时间" |
| | | prop="verifyTime" |
| | | width="120" |
| | | align="center" |
| | | show-overflow-tooltip /> |
| | | <el-table-column label="验收结果" |
| | | prop="verifyResult" |
| | | width="120" |
| | | align="center" |
| | | show-overflow-tooltip> |
| | | <template #default="scope"> |
| | | <el-tag v-if="scope.row.verifyResult" |
| | |
| | | <el-button link |
| | | type="primary" |
| | | size="small" |
| | | :disabled="!scope.row.rectifyActualTime || scope.row.verifyTime" |
| | | :disabled="!scope.row.rectifyActualTime || scope.row.verifyTime || scope.row.isVerify" |
| | | @click="openForm('edit3', scope.row)">验收</el-button> |
| | | </template> |
| | | </el-table-column> |
| | |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <div v-if="operationType === 'edit2' || operationType === 'edit3'" |
| | | <div v-if="showHiddenDetail" |
| | | class="classtitle">隐患详情</div> |
| | | <el-descriptions :column="2" |
| | | style="margin-bottom: 20px;" |
| | | v-if="operationType === 'edit2' || operationType === 'edit3'" |
| | | v-if="showHiddenDetail" |
| | | border> |
| | | <el-descriptions-item label="隐患编号"> |
| | | <span class="detail-title">{{ form.hiddenCode }}</span> |
| | |
| | | </el-descriptions-item> |
| | | </el-descriptions> |
| | | <div class="classtitle" |
| | | v-if="operationType === 'edit3'" |
| | | v-if="showRectifyDetail" |
| | | style="margin-top: 40px;">整改详情</div> |
| | | <el-descriptions :column="2" |
| | | style="margin-bottom: 20px;" |
| | | v-if="operationType === 'edit3'" |
| | | v-if="showRectifyDetail" |
| | | border> |
| | | <el-descriptions-item label="整改具体措施" |
| | | :span="2"> |
| | |
| | | type="date" |
| | | placeholder="请选择" |
| | | clearable /> |
| | | </el-form-item> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <el-form-item label="验收人:" |
| | | prop="verifyUserId"> |
| | | <el-select v-model="form2.verifyUserId" |
| | | placeholder="请选择" |
| | | filterable |
| | | clearable> |
| | | <el-option v-for="item in userList" |
| | | :key="item.userId" |
| | | :label="item.nickName" |
| | | :value="item.userId" /> |
| | | </el-select> |
| | | </el-form-item> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | <el-form-item label="验收人:" |
| | | prop="verifyUserId"> |
| | | <el-select v-model="form3.verifyUserId" |
| | | disabled |
| | | :disabled="!!form3.verifyUserId" |
| | | placeholder="请选择" |
| | | filterable |
| | | clearable> |
| | | <el-option v-for="item in userList" |
| | | :key="item.userId" |
| | |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <div class="classtitle" |
| | | v-if="showVerifyDetail" |
| | | style="margin-top: 40px;">验收详情</div> |
| | | <el-descriptions :column="2" |
| | | style="margin-bottom: 20px;" |
| | | v-if="showVerifyDetail" |
| | | border> |
| | | <el-descriptions-item label="验收人"> |
| | | <span class="detail-title">{{ getVerifyUserName() }}</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="验收时间"> |
| | | <span class="detail-title">{{ form3.verifyTime }}</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="验收结果"> |
| | | <el-tag v-if="form3.verifyResult" |
| | | :type="form3.verifyResult === '通过' ? 'success' : 'danger'"> |
| | | {{ form3.verifyResult }} |
| | | </el-tag> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="验收意见" |
| | | :span="2"> |
| | | <span class="detail-title">{{ form3.verifyRemark }}</span> |
| | | </el-descriptions-item> |
| | | </el-descriptions> |
| | | <div class="classtitle" |
| | | v-if="operationType === 'detail'" |
| | | style="margin-top: 40px;">附件</div> |
| | | <div v-if="operationType === 'detail'" |
| | | v-loading="detailAttachmentLoading" |
| | | class="detail-attachment-preview-list"> |
| | | <el-empty v-if="!detailAttachmentLoading && detailAttachmentList.length === 0" |
| | | description="暂无附件" |
| | | :image-size="80" /> |
| | | <div v-for="item in detailAttachmentList" |
| | | :key="item.storageAttachmentId || item.id || getAttachmentPreviewUrl(item)" |
| | | class="detail-attachment-preview-card"> |
| | | <div class="detail-attachment-header"> |
| | | <span class="detail-attachment-name">{{ getAttachmentName(item) }}</span> |
| | | <el-button link |
| | | type="primary" |
| | | size="small" |
| | | @click="downloadDetailAttachment(item)">下载</el-button> |
| | | </div> |
| | | <el-image v-if="isImageAttachment(item)" |
| | | class="detail-attachment-image" |
| | | :src="getAttachmentPreviewUrl(item)" |
| | | :preview-src-list="detailPreviewImageUrls" |
| | | :initial-index="getImagePreviewIndex(item)" |
| | | fit="contain" |
| | | preview-teleported /> |
| | | <iframe v-else-if="isPdfAttachment(item)" |
| | | class="detail-attachment-frame" |
| | | :src="getAttachmentPreviewUrl(item)" /> |
| | | <div v-else |
| | | class="detail-attachment-placeholder"> |
| | | <span>该文件类型暂不支持内嵌预览</span> |
| | | <el-button link |
| | | type="primary" |
| | | @click="downloadDetailAttachment(item)">下载查看</el-button> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </FormDialog> |
| | | <FileListDialog |
| | | v-if="fileListDialogVisible" |
| | |
| | | import { userListNoPage } from "@/api/system/user.js"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | import { getQuotationList } from "@/api/salesManagement/salesQuotation.js"; |
| | | import { attachmentList } from "@/api/basicData/storageAttachment.js"; |
| | | import { |
| | | dangerInvestigationListPage, |
| | | safeHiddenAdd, |
| | |
| | | const selectedRows = ref([]); |
| | | const userList = ref([]); |
| | | const tableLoading = ref(false); |
| | | const detailAttachmentList = ref([]); |
| | | const detailAttachmentLoading = ref(false); |
| | | const currentRecordId = ref(0); |
| | | const page = reactive({ |
| | | current: 1, |
| | |
| | | return "整改页面"; |
| | | } else if (type === "edit3") { |
| | | return "验收页面"; |
| | | } else if (type === "detail") { |
| | | return "隐患详情"; |
| | | } |
| | | }; |
| | | // 获取类型标签类型 |
| | |
| | | const rules2 = { |
| | | rectifyActualTime: [{ required: true, message: "请选择", trigger: "blur" }], |
| | | rectifyMeasures: [{ required: true, message: "请输入", trigger: "blur" }], |
| | | verifyUserId: [{ required: true, message: "请选择", trigger: "change" }], |
| | | }; |
| | | const rules3 = { |
| | | verifyTime: [{ required: true, message: "请选择", trigger: "blur" }], |
| | | verifyRemark: [{ required: true, message: "请输入", trigger: "blur" }], |
| | | verifyResult: [{ required: true, message: "请选择", trigger: "change" }], |
| | | verifyUserId: [{ required: true, message: "请选择", trigger: "change" }], |
| | | acceptDesc: [{ required: true, message: "请输入", trigger: "blur" }], |
| | | }; |
| | | const { hidden_danger_type } = proxy.useDict("hidden_danger_type"); |
| | |
| | | const form2 = ref({ |
| | | rectifyActualTime: "", // 实际整改完成时间 |
| | | rectifyMeasures: "", // 整改具体措施 |
| | | verifyUserId: "", // 验收人 |
| | | }); |
| | | const form3 = ref({ |
| | | verifyTime: "", // 验收时间 |
| | |
| | | verifyUserName: "", |
| | | verifyResult: "", // 验收结果 |
| | | }); |
| | | const showHiddenDetail = computed(() => ["edit2", "edit3", "detail"].includes(operationType.value)); |
| | | const showRectifyDetail = computed( |
| | | () => |
| | | operationType.value === "edit3" || |
| | | (operationType.value === "detail" && (form2.value.rectifyMeasures || form2.value.rectifyActualTime)) |
| | | ); |
| | | const showVerifyDetail = computed( |
| | | () => |
| | | operationType.value === "detail" && |
| | | (form3.value.verifyUserId || |
| | | form3.value.verifyUserName || |
| | | form3.value.verifyRemark || |
| | | form3.value.verifyTime || |
| | | form3.value.verifyResult) |
| | | ); |
| | | const riskLevelList = ref([ |
| | | { |
| | | value: "重大风险", |
| | |
| | | form.value.rectifyUserName = selectedUser.nickName; |
| | | form.value.rectifyUserMobile = selectedUser.phonenumber; |
| | | } |
| | | }; |
| | | |
| | | const hasUserId = userId => userId !== null && userId !== undefined && userId !== "" && userId !== "null"; |
| | | const normalizeUserId = userId => (hasUserId(userId) ? Number(userId) : ""); |
| | | const getVerifyUserName = () => { |
| | | if (form3.value.verifyUserName) { |
| | | return form3.value.verifyUserName; |
| | | } |
| | | const selectedUser = userList.value.find(user => Number(user.userId) === Number(form3.value.verifyUserId)); |
| | | return selectedUser?.nickName || selectedUser?.userName || ""; |
| | | }; |
| | | const getAttachmentName = row => row?.originalFilename || row?.fileName || row?.name || ""; |
| | | const getAttachmentPreviewUrl = row => row?.previewURL || row?.previewUrl || row?.url || row?.downloadURL || row?.downloadUrl || ""; |
| | | const getAttachmentDownloadUrl = row => row?.downloadURL || row?.downloadUrl || row?.previewURL || row?.previewUrl || row?.url || ""; |
| | | const getAttachmentTypeText = row => `${getAttachmentName(row)} ${getAttachmentPreviewUrl(row)}`.toLowerCase().split("?")[0]; |
| | | const isImageAttachment = row => /\.(jpg|jpeg|png|gif|bmp|webp|svg)$/.test(getAttachmentTypeText(row)); |
| | | const isPdfAttachment = row => /\.pdf$/.test(getAttachmentTypeText(row)); |
| | | const isRectifiedRecord = row => |
| | | !!(row?.rectifyActualTime || row?.rectifyMeasures || row?.verifyTime || row?.verifyResult || row?.verifyRemark); |
| | | const detailPreviewImageUrls = computed(() => |
| | | detailAttachmentList.value |
| | | .filter(isImageAttachment) |
| | | .map(getAttachmentPreviewUrl) |
| | | .filter(Boolean) |
| | | ); |
| | | const getImagePreviewIndex = row => { |
| | | const index = detailPreviewImageUrls.value.indexOf(getAttachmentPreviewUrl(row)); |
| | | return index > -1 ? index : 0; |
| | | }; |
| | | const loadDetailAttachments = recordId => { |
| | | detailAttachmentLoading.value = true; |
| | | detailAttachmentList.value = []; |
| | | return attachmentList({ |
| | | recordType: "safe_hidden", |
| | | recordId, |
| | | }) |
| | | .then(res => { |
| | | detailAttachmentList.value = res?.data || []; |
| | | }) |
| | | .catch(() => { |
| | | detailAttachmentList.value = []; |
| | | ElMessage.error("附件加载失败"); |
| | | }) |
| | | .finally(() => { |
| | | detailAttachmentLoading.value = false; |
| | | }); |
| | | }; |
| | | const downloadDetailAttachment = row => { |
| | | const url = getAttachmentDownloadUrl(row); |
| | | if (!url) { |
| | | ElMessage.warning("文件地址无效,无法下载"); |
| | | return; |
| | | } |
| | | window.open(url, "_blank"); |
| | | }; |
| | | |
| | | // 导入相关 |
| | |
| | | } else { |
| | | item.isRectify = false; |
| | | } |
| | | item.isVerify = hasUserId(item.verifyUserId) && Number(item.verifyUserId) != Number(currentUserId.value); |
| | | }); |
| | | return res; |
| | | }) |
| | |
| | | const openForm = async (type, row) => { |
| | | console.log("row", row); |
| | | operationType.value = type; |
| | | detailAttachmentList.value = []; |
| | | form3.value = { |
| | | verifyTime: "", // 验收时间 |
| | | verifyRemark: "", // 验收备注 |
| | | verifyResult: "", // 验收描述 |
| | | verifyUserId: "", // 验收人 |
| | | verifyUserName: "", |
| | | }; |
| | | form2.value = { |
| | | rectifyActualTime: "", // 实际整改完成时间 |
| | | rectifyMeasures: "", // 整改具体措施 |
| | | verifyUserId: "", // 验收人 |
| | | }; |
| | | if (type === "add") { |
| | | form.value = { |
| | |
| | | form2.value = { |
| | | rectifyActualTime: row.rectifyActualTime, // 实际整改完成时间 |
| | | rectifyMeasures: row.rectifyMeasures, // 整改具体措施 |
| | | verifyUserId: normalizeUserId(row.verifyUserId), // 验收人 |
| | | }; |
| | | } else if (type === "edit3") { |
| | | form.value = { |
| | |
| | | verifyTime: row.verifyTime, // 验收时间 |
| | | verifyRemark: row.verifyRemark, // 验收备注 |
| | | verifyResult: row.verifyResult, // 验收描述 |
| | | verifyUserId: row.verifyUserId, // 验收人 |
| | | verifyUserId: normalizeUserId(row.verifyUserId), // 验收人 |
| | | verifyUserName: row.verifyUserName, |
| | | }; |
| | | console.log("form3.value", form3.value); |
| | | if (!form3.value.verifyUserId || form3.value.verifyUserId === "null") { |
| | | form3.value.verifyUserId = Number(currentUserId.value); // 验收人 |
| | | } |
| | | if (!form3.value.verifyTime || form3.value.verifyTime === "null") { |
| | | form3.value.verifyTime = dayjs().format("YYYY-MM-DD"); // 验收描述 |
| | | } |
| | | } else if (type === "detail") { |
| | | form.value = { |
| | | id: row.id, |
| | | hiddenCode: row.hiddenCode, // 隐患编号 |
| | | location: row.location, // 隐患位置 |
| | | hiddenDesc: row.hiddenDesc, // 隐患描述 |
| | | createUser: row.createUser, // 上报人 |
| | | createUserName: row.createUserName, |
| | | createTime: row.createTime, // 上报时间 |
| | | rectifyUserId: row.rectifyUserId, // 整改责任人 |
| | | rectifyUserName: row.rectifyUserName, |
| | | rectifyTime: row.rectifyTime, // 整改完成期限 |
| | | rectifyUserMobile: row.rectifyUserMobile, // 整改责任人手机号 |
| | | riskLevel: row.riskLevel, // 隐患风险等级 |
| | | type: row.type, // 隐患类型 |
| | | }; |
| | | form2.value = { |
| | | rectifyActualTime: row.rectifyActualTime, // 实际整改完成时间 |
| | | rectifyMeasures: row.rectifyMeasures, // 整改具体措施 |
| | | verifyUserId: normalizeUserId(row.verifyUserId), // 验收人 |
| | | }; |
| | | form3.value = { |
| | | verifyTime: row.verifyTime, // 验收时间 |
| | | verifyRemark: row.verifyRemark, // 验收备注 |
| | | verifyResult: row.verifyResult, // 验收描述 |
| | | verifyUserId: normalizeUserId(row.verifyUserId), // 验收人 |
| | | verifyUserName: row.verifyUserName, |
| | | }; |
| | | loadDetailAttachments(row.id); |
| | | } |
| | | dialogFormVisible.value = true; |
| | | }; |
| | |
| | | proxy.$refs["formRef3"].validate(valid => { |
| | | if (valid) { |
| | | safeHiddenUpdate({ |
| | | ...form3.value, |
| | | ...form2.value, |
| | | ...form.value, |
| | | ...form3.value, |
| | | }).then(res => { |
| | | proxy.$modal.msgSuccess("提交成功"); |
| | | closeDia(); |
| | |
| | | const closeDia = () => { |
| | | proxy.resetForm("formRef"); |
| | | proxy.resetForm("formRef2"); |
| | | proxy.resetForm("formRef3"); |
| | | detailAttachmentList.value = []; |
| | | detailAttachmentLoading.value = false; |
| | | dialogFormVisible.value = false; |
| | | }; |
| | | // 关闭产品弹框 |
| | |
| | | const handleDelete = () => { |
| | | let ids = []; |
| | | if (selectedRows.value.length > 0) { |
| | | const rectifiedRows = selectedRows.value.filter(isRectifiedRecord); |
| | | if (rectifiedRows.length > 0) { |
| | | const hiddenCodes = rectifiedRows.map(item => item.hiddenCode).filter(Boolean).join("、"); |
| | | proxy.$modal.msgWarning(`已整改的隐患不能删除${hiddenCodes ? `:${hiddenCodes}` : ""}`); |
| | | return; |
| | | } |
| | | ids = selectedRows.value.map(item => item.id); |
| | | } else { |
| | | proxy.$modal.msgWarning("请选择数据"); |
| | | return; |
| | | } |
| | | ElMessageBox.confirm("选中的内容将被删除,是否确认删除?", "导出", { |
| | | ElMessageBox.confirm("选中的未整改隐患及其附件将被删除,是否确认删除?", "提示", { |
| | | confirmButtonText: "确认", |
| | | cancelButtonText: "取消", |
| | | type: "warning", |
| | |
| | | return ""; |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getCurrentFactoryName(); |
| | | onMounted(async () => { |
| | | await getCurrentFactoryName(); |
| | | getList(); |
| | | userListNoPage().then(res => { |
| | | userList.value = res.data; |
| | |
| | | justify-content: space-between; |
| | | margin-bottom: 10px; |
| | | } |
| | | .hidden-code-link { |
| | | height: auto; |
| | | padding: 0; |
| | | font-weight: 500; |
| | | } |
| | | .detail-attachment-preview-list { |
| | | min-height: 120px; |
| | | margin-bottom: 20px; |
| | | display: grid; |
| | | grid-template-columns: repeat(auto-fill, minmax(220px, 260px)); |
| | | gap: 12px; |
| | | align-items: start; |
| | | } |
| | | .detail-attachment-preview-card { |
| | | border: 1px solid #e5eaf3; |
| | | border-radius: 6px; |
| | | overflow: hidden; |
| | | background: #fff; |
| | | } |
| | | .detail-attachment-header { |
| | | min-height: 36px; |
| | | padding: 6px 12px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: space-between; |
| | | gap: 12px; |
| | | border-bottom: 1px solid #e5eaf3; |
| | | background: #f7f9fc; |
| | | } |
| | | .detail-attachment-name { |
| | | min-width: 0; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | white-space: nowrap; |
| | | font-weight: 500; |
| | | color: #303133; |
| | | } |
| | | .detail-attachment-image { |
| | | width: 100%; |
| | | height: 160px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | background: #fafafa; |
| | | } |
| | | .detail-attachment-frame { |
| | | width: 100%; |
| | | height: 180px; |
| | | border: 0; |
| | | display: block; |
| | | background: #fafafa; |
| | | } |
| | | .detail-attachment-placeholder { |
| | | min-height: 120px; |
| | | padding: 12px; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | gap: 12px; |
| | | color: #606266; |
| | | background: #fafafa; |
| | | } |
| | | .detail-attachment-preview-list :deep(.el-empty) { |
| | | grid-column: 1 / -1; |
| | | } |
| | | .print-preview-dialog { |
| | | .el-dialog__body { |
| | | padding: 0; |