| | |
| | | </el-table-column> |
| | | <el-table-column fixed="right" |
| | | label="操作" |
| | | min-width="250" |
| | | min-width="150" |
| | | align="center"> |
| | | <template #default="scope"> |
| | | <el-button link |
| | | <!-- <el-button link |
| | | type="primary" |
| | | size="small" |
| | | @click="openForm('edit', scope.row)">编辑</el-button> |
| | | @click="openForm('edit', scope.row)">编辑</el-button> --> |
| | | <el-button link |
| | | type="primary" |
| | | size="small" |
| | |
| | | <el-button link |
| | | type="primary" |
| | | size="small" |
| | | :disabled="scope.row.isRectify || scope.row.rectifyActualTime" |
| | | @click="openForm('edit2', scope.row)">整改</el-button> |
| | | <el-button link |
| | | type="primary" |
| | | size="small" |
| | | :disabled="!scope.row.rectifyActualTime" |
| | | :disabled="!scope.row.rectifyActualTime || scope.row.verifyTime" |
| | | @click="openForm('edit3', scope.row)">验收</el-button> |
| | | </template> |
| | | </el-table-column> |
| | |
| | | </el-col> |
| | | </el-row> |
| | | </el-form> |
| | | <div v-if="operationType === 'edit2' || operationType === 'edit3'" |
| | | class="classtitle">隐患详情</div> |
| | | <el-descriptions :column="2" |
| | | style="margin-bottom: 20px;" |
| | | v-if="operationType === 'edit2' || operationType === 'edit3'" |
| | | title="隐患详情" |
| | | border> |
| | | <el-descriptions-item label="隐患编号"> |
| | | <span class="detail-title">{{ form.hiddenCode }}</span> |
| | |
| | | <span class="detail-title">{{ form.hiddenDesc }}</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="隐患类型"> |
| | | <span class="detail-title">{{ form.type }}</span> |
| | | <span class="detail-title">{{ TypeLabel(form.type) }}</span> |
| | | </el-descriptions-item> |
| | | <el-descriptions-item label="隐患风险等级"> |
| | | <el-tag :type="getTypeTagType(form.riskLevel)"> |
| | |
| | | <span class="detail-title">{{ form.rectifyTime }}</span> |
| | | </el-descriptions-item> |
| | | </el-descriptions> |
| | | <div class="classtitle" |
| | | v-if="operationType === 'edit3'" |
| | | style="margin-top: 40px;">整改详情</div> |
| | | <el-descriptions :column="2" |
| | | style="margin-bottom: 20px;" |
| | | v-if="operationType === 'edit3'" |
| | | title="整改详情" |
| | | border> |
| | | <el-descriptions-item label="整改具体措施" |
| | | :span="2"> |
| | |
| | | <span class="detail-title">{{ form2.rectifyActualTime }}</span> |
| | | </el-descriptions-item> |
| | | </el-descriptions> |
| | | <div class="classtitle" |
| | | v-if="operationType === 'edit2' || operationType === 'edit3'" |
| | | style="margin-top: 40px;margin-bottom: 30px;">验收情况</div> |
| | | <el-form :model="form2" |
| | | v-if="operationType === 'edit2'" |
| | | label-width="140px" |
| | |
| | | </el-row> |
| | | </el-form> |
| | | </FormDialog> |
| | | <!-- 附件列表弹窗 --> |
| | | <FileListDialog ref="fileListRef" |
| | | v-model="fileListDialogVisible" |
| | | :show-upload-button="true" |
| | | :show-delete-button="true" |
| | | :upload-method="handleUpload" |
| | | :delete-method="handleFileDelete" |
| | | title="附件列表" /> |
| | | <FileListDialog |
| | | v-if="fileListDialogVisible" |
| | | :record-id="currentRecordId" |
| | | record-type="safe_hidden" |
| | | v-model:visible="fileListDialogVisible"/> |
| | | |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { getToken } from "@/utils/auth"; |
| | | import pagination from "@/components/PIMTable/Pagination.vue"; |
| | | import { onMounted, ref, getCurrentInstance } from "vue"; |
| | | import { onMounted, ref, getCurrentInstance, computed } from "vue"; |
| | | import { ElMessageBox, ElMessage } from "element-plus"; |
| | | import useUserStore from "@/store/modules/user"; |
| | | import { userListNoPage } from "@/api/system/user.js"; |
| | | import FileListDialog from "@/components/Dialog/FileListDialog.vue"; |
| | | import FormDialog from "@/components/Dialog/FormDialog.vue"; |
| | | import { getQuotationList } from "@/api/salesManagement/salesQuotation.js"; |
| | | import { |
| | |
| | | safeHiddenUpdate, |
| | | safeHiddenDel, |
| | | fileListPage, |
| | | safeHiddenFileAdd, |
| | | safeHiddenFileDel, |
| | | } from "@/api/safeProduction/dangerInvestigation.js"; |
| | | import useFormData from "@/hooks/useFormData.js"; |
| | | import request from "@/utils/request"; |
| | | import dayjs from "dayjs"; |
| | | import { get } from "@vueuse/core"; |
| | | |
| | | const userStore = useUserStore(); |
| | | const { proxy } = getCurrentInstance(); |
| | |
| | | const selectedRows = ref([]); |
| | | const userList = ref([]); |
| | | const tableLoading = ref(false); |
| | | const currentRecordId = ref(0); |
| | | const page = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | |
| | | verifyResult: [{ required: true, message: "请选择", trigger: "change" }], |
| | | acceptDesc: [{ required: true, message: "请输入", trigger: "blur" }], |
| | | }; |
| | | const typeList = ref([ |
| | | { |
| | | value: "设备安全", |
| | | label: "设备安全", |
| | | }, |
| | | { |
| | | value: "人员操作", |
| | | label: "人员操作", |
| | | }, |
| | | { |
| | | value: "环境风险", |
| | | label: "环境风险", |
| | | }, |
| | | { |
| | | value: "物料管控", |
| | | label: "物料管控", |
| | | }, |
| | | { |
| | | value: "其他", |
| | | label: "其他", |
| | | }, |
| | | ]); |
| | | const { hidden_danger_type } = proxy.useDict("hidden_danger_type"); |
| | | const typeList = computed(() => hidden_danger_type?.value || []); |
| | | const TypeLabel = val => { |
| | | const item = typeList.value.find(i => String(i.value) === String(val)); |
| | | return item ? item.label : val; |
| | | }; |
| | | const form2 = ref({ |
| | | rectifyActualTime: "", // 实际整改完成时间 |
| | | rectifyMeasures: "", // 整改具体措施 |
| | |
| | | label: "低风险", |
| | | }, |
| | | ]); |
| | | // 隐患类型选项 |
| | | const { type_qualification } = proxy.useDict("type_qualification"); |
| | | const { form, rules } = toRefs(data); |
| | | const { form: searchForm } = useFormData(data.searchForm); |
| | | // 产品表单弹框数据 |
| | |
| | | tableLoading.value = false; |
| | | tableData.value = res.data.records; |
| | | total.value = res.data.total; |
| | | tableData.value.forEach(item => { |
| | | // console.log(item.rectifyUserId, currentUserId.value, "======="); |
| | | if (Number(item.rectifyUserId) != Number(currentUserId.value)) { |
| | | item.isRectify = true; |
| | | } else { |
| | | item.isRectify = false; |
| | | } |
| | | }); |
| | | return res; |
| | | }) |
| | | .catch(() => { |
| | |
| | | proxy.$modal.msg("已取消"); |
| | | }); |
| | | }; |
| | | const isPeople = rectifyUserId => { |
| | | return Number(rectifyUserId) == Number(currentUserId.value); |
| | | }; |
| | | |
| | | /** |
| | | * 判断是否可以发货 |
| | |
| | | const statusStr = shippingStatus ? String(shippingStatus).trim() : ""; |
| | | return statusStr === "待发货" || statusStr === "审核拒绝"; |
| | | }; |
| | | const filePagination = ref({ |
| | | current: 1, |
| | | size: 10, |
| | | total: 0, |
| | | }); |
| | | |
| | | /** |
| | | * 下载文件 |
| | |
| | | const fileListDialogVisible = ref(false); |
| | | const currentFileRow = ref(null); |
| | | const downLoadFile = row => { |
| | | currentFileRow.value = row; |
| | | fileListPage({ safeHiddenId: row.id }).then(res => { |
| | | if (fileListRef.value) { |
| | | fileListRef.value.open(res.data.records); |
| | | } |
| | | }); |
| | | currentRecordId.value = row.id; |
| | | fileListDialogVisible.value = true; |
| | | }; |
| | | const currentUserId = ref(""); |
| | | const currentUserName = ref(""); |
| | |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getCurrentFactoryName(); |
| | | getList(); |
| | | userListNoPage().then(res => { |
| | | userList.value = res.data; |
| | | }); |
| | | getCurrentFactoryName(); |
| | | }); |
| | | // 上传附件 |
| | | const handleUpload = async () => { |
| | | if (!currentFileRow.value) { |
| | | proxy.$modal.msgWarning("请先选择数据"); |
| | | return null; |
| | | } |
| | | |
| | | return new Promise(resolve => { |
| | | // 创建一个隐藏的文件输入元素 |
| | | const input = document.createElement("input"); |
| | | input.type = "file"; |
| | | input.style.display = "none"; |
| | | input.onchange = async e => { |
| | | const file = e.target.files[0]; |
| | | if (!file) { |
| | | resolve(null); |
| | | return; |
| | | } |
| | | |
| | | try { |
| | | // 使用 FormData 上传文件 |
| | | const formData = new FormData(); |
| | | formData.append("file", file); |
| | | |
| | | const uploadRes = await request({ |
| | | url: "/file/upload", |
| | | method: "post", |
| | | data: formData, |
| | | headers: { |
| | | "Content-Type": "multipart/form-data", |
| | | Authorization: `Bearer ${getToken()}`, |
| | | }, |
| | | }); |
| | | |
| | | if (uploadRes.code === 200) { |
| | | // 保存附件信息 |
| | | const fileData = { |
| | | safeHiddenId: currentFileRow.value.id, |
| | | name: uploadRes.data.originalName || file.name, |
| | | url: uploadRes.data.tempPath || uploadRes.data.url, |
| | | }; |
| | | |
| | | const saveRes = await safeHiddenFileAdd(fileData); |
| | | if (saveRes.code === 200) { |
| | | proxy.$modal.msgSuccess("文件上传成功"); |
| | | // 重新加载文件列表 |
| | | const listRes = await fileListPage({ |
| | | safeHiddenId: currentFileRow.value.id, |
| | | }); |
| | | if (listRes.code === 200 && fileListRef.value) { |
| | | const fileList = (listRes.data?.records || []).map(item => ({ |
| | | name: item.name, |
| | | url: item.url, |
| | | id: item.id, |
| | | ...item, |
| | | })); |
| | | fileListRef.value.setList(fileList); |
| | | } |
| | | // 返回新文件信息 |
| | | resolve({ |
| | | name: fileData.name, |
| | | url: fileData.url, |
| | | id: saveRes.data?.id, |
| | | }); |
| | | } else { |
| | | proxy.$modal.msgError(saveRes.msg || "文件保存失败"); |
| | | resolve(null); |
| | | } |
| | | } else { |
| | | proxy.$modal.msgError(uploadRes.msg || "文件上传失败"); |
| | | resolve(null); |
| | | } |
| | | } catch (error) { |
| | | proxy.$modal.msgError("文件上传失败"); |
| | | resolve(null); |
| | | } finally { |
| | | document.body.removeChild(input); |
| | | } |
| | | }; |
| | | |
| | | document.body.appendChild(input); |
| | | input.click(); |
| | | }); |
| | | }; |
| | | // 删除附件 |
| | | const handleFileDelete = async row => { |
| | | try { |
| | | const res = await safeHiddenFileDel([row.id]); |
| | | if (res.code === 200) { |
| | | proxy.$modal.msgSuccess("删除成功"); |
| | | // 重新加载文件列表 |
| | | if (currentFileRow.value && fileListRef.value) { |
| | | const listRes = await fileListPage({ |
| | | safeHiddenId: currentFileRow.value.id, |
| | | }); |
| | | if (listRes.code === 200) { |
| | | const fileList = (listRes.data?.records || []).map(item => ({ |
| | | name: item.name, |
| | | url: item.url, |
| | | id: item.id, |
| | | ...item, |
| | | })); |
| | | fileListRef.value.setList(fileList); |
| | | } |
| | | } |
| | | return true; // 返回 true 表示删除成功,组件会更新列表 |
| | | } else { |
| | | proxy.$modal.msgError(res.msg || "删除失败"); |
| | | return false; |
| | | } |
| | | } catch (error) { |
| | | proxy.$modal.msgError("删除失败"); |
| | | return false; |
| | | } |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | |
| | | page-break-after: avoid; |
| | | } |
| | | } |
| | | .classtitle { |
| | | font-size: 16px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | border-left: 4px solid #409eff; |
| | | padding-left: 12px; |
| | | margin-bottom: 12px; |
| | | } |
| | | </style> |