| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874 |
- <template>
- <el-alert
- v-if="isRectifyMode && detailReviewRejectReason"
- type="error"
- :title="'不通过原因:' + detailReviewRejectReason"
- show-icon
- class="detail-reject-alert"
- />
- <main class="safety-platform-container__main">
-
- <el-form label-width="150px" :model="ruleFormData" :rules="isViewMode ? undefined : formRules" ref="basicFormRef">
- <el-form-item label="隐患问题类别:" prop="typeId">
- <el-select
- v-model="ruleFormData.typeId"
- placeholder="请选择隐患问题类别"
- clearable
- filterable
- :disabled="isViewMode"
- style="width: 450px"
- >
- <el-option
- v-for="option in ruleFormConfig.find((c) => c.prop === 'typeId')?.selectOptions || []"
- :key="option.value"
- :label="option.label"
- :value="option.value"
- />
- </el-select>
- </el-form-item>
- <el-form-item label="隐患问题:" prop="dangerProblem">
- <el-input
- v-model="ruleFormData.dangerProblem"
- placeholder="请输入隐患问题描述"
- :disabled="isViewMode"
- style="width: 450px"
- />
- </el-form-item>
- <el-form-item label="问题主要原因:" prop="reasonId">
- <el-select
- v-model="ruleFormData.reasonId"
- placeholder="请选择问题主要原因"
- clearable
- filterable
- :disabled="isViewMode"
- style="width: 450px"
- >
- <el-option
- v-for="option in ruleFormConfig.find((c) => c.prop === 'reasonId')?.selectOptions || []"
- :key="option.value"
- :label="option.label"
- :value="option.value"
- />
- </el-select>
- </el-form-item>
- <el-form-item label="任务来源:" prop="taskSource">
- <el-input
- v-model="ruleFormData.taskSource"
- placeholder="如:上级检查、院内自查"
- :disabled="isViewMode"
- style="width: 450px"
- />
- </el-form-item>
- <el-form-item label="整改要求:" prop="rectificationRequirement">
- <el-input
- v-model="ruleFormData.rectificationRequirement"
- placeholder="请输入整改要求"
- :disabled="isViewMode"
- style="width: 450px"
- />
- </el-form-item>
- <el-form-item label="整改责任部门:" prop="rectificationDepartmentId" v-if="ruleFormData.statusId !== 1 && !isCreateMode">
- <el-input
- v-model="ruleFormData.rectificationDepartmentNames"
- placeholder="整改责任部门"
- disabled
- style="width: 450px"
- />
- </el-form-item>
- <el-form-item label="整改负责人:" prop="rectificationResponsibleUserId" v-if="ruleFormData.statusId !== 1 && !isCreateMode">
- <el-input
- v-model="ruleFormData.rectificationResponsiblePerson"
- placeholder="整改负责人"
- disabled
- style="width: 450px"
- />
- </el-form-item>
- <el-form-item label="整改日期:" prop="rectificationDeadline">
- <el-date-picker
- v-model="ruleFormData.rectificationDeadline"
- type="date"
- value-format="YYYY-MM-DD"
- placeholder="请选择整改日期"
- :disabled="isViewMode"
- style="width: 450px"
- />
- </el-form-item>
- <el-form-item label="复查人员所属部门:" prop="reviewDepartmentId">
- <el-cascader
- ref="reviewDeptCascaderRef"
- v-model="ruleFormData.reviewDepartmentId"
- :options="deptTree"
- :props="cascaderDeptProp"
- :show-all-levels="false"
- placeholder="请选择复查人员所属部门"
- filterable
- clearable
- :disabled="isViewMode"
- style="width: 450px"
- />
- </el-form-item>
- <el-form-item label="复查人员:" prop="reviewPersonId">
- <el-select
- v-model="ruleFormData.reviewPersonId"
- placeholder="请选择复查人员"
- clearable
- filterable
- :disabled="isViewMode"
- style="width: 450px"
- @change="onReviewPersonChange"
- >
- <el-option v-for="u in reviewUserList" :key="u.id" :label="u.realname || u.username" :value="u.id" />
- </el-select>
- </el-form-item>
- <el-form-item label="举一反三是否推送:" prop="isDrawLessonsPush">
- <el-radio-group v-model="ruleFormData.isDrawLessonsPush" :disabled="isViewMode" @change="changeDrawLessonsPush">
- <el-radio :value="0">否</el-radio>
- <el-radio :value="1">是</el-radio>
- </el-radio-group>
- </el-form-item>
- <section v-if="ruleFormData.isDrawLessonsPush === 1">
- <el-form-item label="" prop="drawLessonsContent">
- <el-input
- v-model="ruleFormData.drawLessonsContent"
- placeholder="请输入举一反三内容(选填)"
- show-word-limit
- style="width: 450px"
- :disabled="isViewMode"
- />
- </el-form-item>
- <el-form-item label="举一反三责任部门:" prop="drawLessonsDepartmentIds">
- <el-select
- v-model="drawLessonsDeptIdsArray"
- placeholder="请选择举一反三责任部门,可多选"
- clearable
- filterable
- multiple
- collapse-tags
- collapse-tags-tooltip
- :disabled="isViewMode"
- style="width: 450px"
- @change="onDrawLessonsDeptsChange"
- >
- <el-option v-for="d in deptOptions" :key="d.id" :label="d.deptName" :value="d.id" />
- </el-select>
- </el-form-item>
- <el-form-item label="举一反三截止日期:" prop="drawLessonsDeadline">
- <el-date-picker
- v-model="ruleFormData.drawLessonsDeadline"
- type="date"
- value-format="YYYY-MM-DD"
- placeholder="请选择举一反三截止日期(选填)"
- style="width: 450px"
- :disabled="isViewMode"
- />
- </el-form-item>
-
- </section>
- <section v-if="detailStatusOrder>=2&&!isEditMode">
- <el-form-item label="整改完成情况:" prop="rectificationCompletionStatus">
- <el-input
- v-model="ruleFormData.rectificationCompletionStatus"
- placeholder="请输入整改完成情况"
- show-word-limit
- :disabled="!isRectifyMode"
- style="width: 450px"
- />
- </el-form-item>
- <el-form-item label="整改完成时间:" prop="rectificationCompletionTime">
- <el-date-picker
- v-model="ruleFormData.rectificationCompletionTime"
- type="date"
- :disabled="!isRectifyMode"
- value-format="YYYY-MM-DD"
- placeholder="请选择整改完成时间"
- style="width: 450px"
- />
- </el-form-item>
- <el-form-item label="附件上传" prop="attachments">
- <UploadFiles
- label="选择附件"
- :maxCount="1"
- v-if="detailStatusOrder==2"
- :disabled="!isRectifyMode"
- :file-list="attachmentsFileList"
- :allow-all-file-types="true"
- @uploadSuccess="(list: FileItem[]) => handleAttachmentsUploadSuccess(list)"
- @preview="handlePreview"
- />
- <div class="file-list" v-if="detailStatusOrder>=3">
- <div class="file-item" v-for="file in attachmentsFileList" :key="file.fileId">
- <span class="file-item--name">{{ file.fileName }}</span>
- <div class="file-item--footer">
- <el-button link type="primary" @click="previewOnline(file.fileUrl, file.fileType)"
- >预览</el-button
- >
- </div>
- </div>
- </div>
- </el-form-item>
- <el-form-item label="复查意见:" prop="reviewComments" v-if="detailStatusOrder>=3" >
- <el-input
- v-model="ruleFormData.reviewComments"
- type="textarea"
- :rows="3"
- placeholder="请输入复查意见(选填),限300字"
- maxlength="300"
- style="width: 450px"
- show-word-limit
- :disabled="isViewMode && !isReviewMode"
- />
- </el-form-item>
- </section>
- </el-form>
- </main>
- <footer class="safety-platform-container__footer">
- <el-button @click="router.back()">返回</el-button>
- <template v-if="isReviewMode">
- <el-button type="warning" @click="openReviewRejectDialog">审查不通过</el-button>
- <el-button type="primary" @click="handleReviewPass">审查通过</el-button>
- </template>
- <template v-else-if="!isViewMode">
- <el-button type="primary" @click="handleSubmit">
- {{ isCreateMode ? '提交' : '保存' }}
- </el-button>
- </template>
- <template v-else-if="isRectifyMode">
- <el-button type="primary" @click="handleRectifySubmitDirect">整改</el-button>
- </template>
- <!-- 纯查看时仅保留上面的返回,不显示其他按钮 -->
- </footer>
- <!-- 预览 -->
- <PreviewOnline ref="previewOnlineRef" />
- <!-- 复查弹窗 -->
- <el-dialog v-model="showReviewDialog" title="复查隐患" width="520px" destroy-on-close @close="resetReviewForm">
- <el-form ref="reviewFormRef" :model="reviewForm" :rules="reviewRules" label-width="120px">
- <el-form-item label="复查结论" prop="reviewResult">
- <el-radio-group v-model="reviewForm.reviewResult">
- <el-radio :value="1">通过</el-radio>
- <el-radio :value="0">不通过</el-radio>
- </el-radio-group>
- </el-form-item>
- <el-form-item label="复查意见" prop="reviewComments">
- <el-input v-model="reviewForm.reviewComments" type="textarea" :rows="2" placeholder="选填" />
- </el-form-item>
- <el-form-item v-if="reviewForm.reviewResult === 0" label="不通过原因" prop="reviewReason">
- <el-input v-model="reviewForm.reviewReason" type="textarea" :rows="2" placeholder="不通过时必填" />
- </el-form-item>
- <el-form-item label="复查时间" prop="reviewTime">
- <el-date-picker
- v-model="reviewForm.reviewTime"
- type="datetime"
- value-format="YYYY-MM-DDTHH:mm:ss"
- placeholder="选填,默认当前时间"
- style="width: 100%"
- />
- </el-form-item>
- <el-form-item label="附件" prop="attachments">
- <el-input v-model="reviewForm.attachments" placeholder="选填,多个用逗号分隔" />
- </el-form-item>
- </el-form>
- <template #footer>
- <el-button @click="showReviewDialog = false">取消</el-button>
- <el-button type="primary" @click="handleReviewSubmit">提交复查</el-button>
- </template>
- </el-dialog>
- <!-- 审查不通过原因弹窗(复查详情页使用) -->
- <el-dialog
- v-model="showReviewRejectDialog"
- title="审核不通过原因"
- width="560px"
- :close-on-click-modal="false"
- destroy-on-close
- @close="reviewRejectReason = ''"
- >
- <el-input
- v-model="reviewRejectReason"
- type="textarea"
- :rows="6"
- maxlength="300"
- show-word-limit
- placeholder="请填写审核不通过原因(限300字)"
- />
- <template #footer>
- <el-button @click="showReviewRejectDialog = false">取消</el-button>
- <el-button type="primary" @click="handleReviewRejectSubmit">确定</el-button>
- </template>
- </el-dialog>
- <!-- 扣分弹窗 -->
- <el-dialog v-model="showDeductDialog" title="扣分记录" width="400px" destroy-on-close @close="resetDeductForm">
- <el-form ref="deductFormRef" :model="deductForm" :rules="deductRules" label-width="100px">
- <el-form-item label="扣分值" prop="deductionScore">
- <el-input-number
- v-model="deductForm.deductionScore"
- :min="0"
- :max="9999"
- :precision="0"
- placeholder="请输入扣分值(0-9999整数)"
- style="width: 100%"
- />
- </el-form-item>
- <el-form-item label="扣分部门">
- <el-select
- v-model="deductDeptIdsArray"
- placeholder="请选择扣分部门,可多选(复用复查人员所属部门)"
- clearable
- filterable
- multiple
- collapse-tags
- collapse-tags-tooltip
- style="width: 100%"
- >
- <el-option v-for="d in deptOptions" :key="d.id" :label="d.deptName" :value="d.id" />
- </el-select>
- </el-form-item>
- </el-form>
- <template #footer>
- <el-button @click="showDeductDialog = false">取消</el-button>
- <el-button type="primary" @click="handleDeductSubmit">确认扣分</el-button>
- </template>
- </el-dialog>
- </template>
- <script setup lang="ts">
- import { computed, onMounted, ref } from 'vue';
- import { useRoute, useRouter } from 'vue-router';
- import { ElMessage } from 'element-plus';
- import type { FormInstance, FormRules } from 'element-plus';
- import BasicForm from '@/components/BasicForm.vue';
- import UploadFiles from '@/components/UploadFiles/UploadFiles.vue';
- import type { FileItem } from '@/components/UploadFiles/types';
- import { formatAttachmentList } from '@/components/UploadFiles/utils';
- import { useFormConfigHook } from '@/hooks/useFormConfigHook';
- import {
- HIDDEN_DANGER_FORM_CONFIG,
- HIDDEN_DANGER_FORM_DATA,
- HIDDEN_DANGER_FORM_RULES,
- HIDDEN_DANGER_RECTIFY_FORM_CONFIG,
- HIDDEN_DANGER_REVIEW_FORM_CONFIG,
- } from '@/views/production-safety/hiddenTroubleInvestigationAndGovernance/hiddenTroubleAccountManagement/configs/form';
- import {
- getHiddenDangerDetail,
- saveHiddenDanger,
- updateHiddenDanger,
- rectifyHiddenDanger,
- reviewHiddenDanger,
- deductHiddenDangerPoints,
- type SaveHiddenDangerRequest,
- type UpdateHiddenDangerRequest,
- type ReviewHiddenDangerRequest,
- type HiddenDangerDeductPointsRequest,
- } from '@/api/hiddenDanger';
- import type { HiddenDangerItem } from '@/api/hiddenDanger';
- import { getAllDepartments } from '@/api/auth/dept';
- import type { DeptTree } from '@/types/dept/type';
- import { queryAvailableUserList } from '@/api/production-safety/responsibility-implementation';
- import PreviewOnline from '@/views/disaster/components/PreviewOnline.vue';
- import { ru } from 'element-plus/es/locale';
- const router = useRouter();
- const route = useRoute();
- const operate = computed(() => (route.query.operate as string) || 'hidden-trouble-account-create');
- const currentId = computed(() => Number(route.query.id));
- const isCreateMode = computed(() => operate.value === 'hidden-trouble-account-create');
- const isEditMode = computed(() => operate.value === 'hidden-trouble-account-edit');
- const isViewMode = computed(
- () =>
- operate.value === 'hidden-trouble-account-view' ||
- operate.value === 'hidden-trouble-account-rectify' ||
- operate.value === 'hidden-trouble-account-review',
- );
- const isRectifyMode = computed(() => operate.value === 'hidden-trouble-account-rectify');
- const isReviewMode = computed(() => operate.value === 'hidden-trouble-account-review');
- const { ruleFormData, formRules, ruleFormConfig, cloneRuleFormData } = useFormConfigHook(
- HIDDEN_DANGER_FORM_CONFIG,
- HIDDEN_DANGER_FORM_DATA,
- HIDDEN_DANGER_FORM_RULES,
- );
- const previewOnlineRef = ref<InstanceType<typeof PreviewOnline>>();
- /** 查看详情:与复查时字段一致,全部为禁用状态 */
- const viewFormConfig = computed(() =>
- HIDDEN_DANGER_REVIEW_FORM_CONFIG.map((item) => ({
- ...item,
- componentProps: { ...item.componentProps, disabled: true },
- })),
- );
- const computedFormConfig = computed(() => {
- if (isRectifyMode.value) return HIDDEN_DANGER_RECTIFY_FORM_CONFIG;
- if (isReviewMode.value) return HIDDEN_DANGER_REVIEW_FORM_CONFIG;
- if (isViewMode.value) return viewFormConfig.value;
- return ruleFormConfig.value;
- });
- /** 附件:逗号分隔 URL 转 FileItem 列表,供 UploadFiles 使用(复用新增安全考核上传附件) */
- function convertAttachmentsToFileItems(
- attachmentsStr: string,
- ): Array<{ fileId: number; fileName: string; fileType: string; fileSize: string; fileUrl?: string }> {
- if (!attachmentsStr || !String(attachmentsStr).trim()) return [];
- const urls = String(attachmentsStr)
- .split(',')
- .map((u) => u.trim())
- .filter(Boolean);
- return urls.map((url, index) => {
- const parts = url.split('/');
- const fileName = parts[parts.length - 1] || `附件${index + 1}`;
- const ext = fileName.split('.').pop()?.toLowerCase() || '';
- let fileType = 'pdf';
- if (['doc', 'docx'].includes(ext)) fileType = 'word';
- else if (['xls', 'xlsx'].includes(ext)) fileType = 'excel';
- else if (['ppt', 'pptx'].includes(ext)) fileType = 'ppt';
- return { fileId: index + 1, fileName, fileType, fileSize: '0', fileUrl: url };
- });
- }
- // const attachmentsFileList = computed(() => convertAttachmentsToFileItems(ruleFormData.attachments || ''));
- const attachmentsFileList = ref([]) as any
- async function handleAttachmentsUploadSuccess(files: FileItem[]) {
- if (!files?.length) {
- ruleFormData.attachments = '';
- return;
- }
- console.log(files)
- attachmentsFileList.value = files
- ruleFormData.attachments = JSON.stringify(files) || '';
- // try {
- // const list = await formatAttachmentList(files);
- // ruleFormData.attachments = (list || [])
- // .map((r) => r.fileUrl)
- // .filter(Boolean)
- // .join(',');
- // } catch (e) {
- // console.error('附件上传失败:', e);
- // ElMessage.error(e?.message || e?.data || '附件上传失败,请重试');
- // }
- }
- const handlePreview = (url: string) => {
- if (url) {
- // 根据文件扩展名判断文件类型
- const extension = url.split('.').pop()?.toLowerCase() || '';
- let fileType: 'pdf' | 'word' | 'excel' | 'ppt' = 'pdf';
- if (extension === 'doc' || extension === 'docx') {
- fileType = 'word';
- } else if (extension === 'xls' || extension === 'xlsx') {
- fileType = 'excel';
- } else if (extension === 'ppt' || extension === 'pptx') {
- fileType = 'ppt';
- }
- previewOnlineRef.value?.open(url, fileType);
- }
- };
- const previewOnline = (url: string | undefined, type) => {
- if (url) {
- previewOnlineRef.value?.open(url, type);
- }
- };
- const basicFormRef = ref<InstanceType<typeof BasicForm>>();
- /** 部门树,与新增物品领取记录的部门一致(getAllDepartments,取第一级 children) */
- const reviewDeptCascaderRef = ref();
- const deptTree = ref<DeptTree[]>([]);
- const cascaderDeptProp = {
- checkStrictly: true,
- expandTrigger: 'hover' as const,
- value: 'id',
- label: 'deptName',
- emitPath: false,
- };
- /** 部门树扁平化为下拉选项,举一反三责任部门与复查人员所属部门同数据源 */
- function flattenDeptTree(nodes: DeptTree[] | undefined): Array<{ id: number; deptName: string }> {
- if (!nodes?.length) return [];
- const list: Array<{ id: number; deptName: string }> = [];
- const walk = (items: DeptTree[]) => {
- items.forEach((n) => {
- if (n.id != null) list.push({ id: n.id, deptName: n.deptName });
- if (n.children?.length) walk(n.children);
- });
- };
- walk(nodes);
- return list;
- }
- const deptOptions = computed(() => flattenDeptTree(deptTree.value));
- const drawLessonsDeptIdsArray = ref<number[]>([]);
- const reviewUserList = ref<Array<{ id: number; realname?: string; username?: string }>>([]);
- const loadDeptAndUserOptions = async () => {
- try {
- const [deptRes, userRes] = await Promise.all([
- getAllDepartments(),
- queryAvailableUserList({ pageNumber: 1, pageSize: 9999, queryParam: {} }),
- ]);
- const fullTree = (deptRes as DeptTree[]) ?? [];
- deptTree.value = Array.isArray(fullTree) && fullTree[0]?.children ? fullTree[0].children : [];
- reviewUserList.value = (userRes as any)?.records ?? [];
- } catch (e) {
- console.error('获取部门/用户列表失败:', e);
- deptTree.value = [];
- reviewUserList.value = [];
- }
- };
- function onReviewPersonChange() {
- const u = reviewUserList.value.find((x) => x.id === ruleFormData.reviewPersonId);
- ruleFormData.reviewPersonName = u ? u.realname ?? u.username ?? '' : '';
- }
- function onDrawLessonsDeptsChange() {
- ruleFormData.drawLessonsDepartmentIds = drawLessonsDeptIdsArray.value.join(',');
- }
- function changeDrawLessonsPush() {
- if (ruleFormData.isDrawLessonsPush === 1) {
- ruleFormData.drawLessonsContent = '';
- ruleFormData.drawLessonsDepartmentIds = '';
- ruleFormData.drawLessonsDeadline = '';
- drawLessonsDeptIdsArray.value = [];
- }
- }
- /** 状态:1待下发 2待整改 3待复查 4已完成 5待入账(用 statusId,兼容 statusOrder) */
- /** 整改页:详情接口返回的审查不通过原因,供 el-alert 展示 */
- const detailReviewRejectReason = ref('');
- const detailStatusOrder = ref<number>(0);
- const canRectify = computed(() => detailStatusOrder.value === 2);
- const canReview = computed(() => detailStatusOrder.value === 3);
- const getDetail = async () => {
- if (!currentId.value) return;
- try {
- const res = await getHiddenDangerDetail(currentId.value);
- const data = (res as any)?.data ?? res;
- if (data && typeof data === 'object') {
- const d = data as HiddenDangerItem;
- detailStatusOrder.value = d.statusId ?? d.statusOrder ?? 0;
- ruleFormData.dangerProblem = d.dangerProblem ?? '';
- ruleFormData.typeId = d.typeId;
- ruleFormData.reasonId = d.reasonId;
- ruleFormData.taskSource = d.taskSource ?? '';
- ruleFormData.rectificationRequirement = d.rectificationRequirement ?? '';
- ruleFormData.rectificationDeadline = d.rectificationDeadline ?? '';
- ruleFormData.rectificationDepartmentIds = d.rectificationDepartmentIds ?? '';
- ruleFormData.rectificationResponsiblePerson = d.rectificationResponsiblePerson ?? '';
- ruleFormData.reviewDepartmentId = d.reviewDepartmentId;
- ruleFormData.reviewPersonId = d.reviewPersonId;
- ruleFormData.reviewPersonName = d.reviewPersonName ?? '';
- ruleFormData.isDrawLessonsPush = d.isDrawLessonsPush ?? 0;
- ruleFormData.drawLessonsContent = d.drawLessonsContent ?? '';
- ruleFormData.drawLessonsDepartmentIds = d.drawLessonsDepartmentIds ?? '';
- ruleFormData.drawLessonsDeadline = d.drawLessonsDeadline ?? '';
- drawLessonsDeptIdsArray.value = ruleFormData.drawLessonsDepartmentIds
- ? ruleFormData.drawLessonsDepartmentIds
- .split(',')
- .map((s) => Number(s.trim()))
- .filter(Boolean)
- : [];
- ruleFormData.rectificationCompletionStatus = d.rectificationCompletionStatus ?? '';
- ruleFormData.rectificationCompletionTime = d.rectificationCompletionTime ?? '';
- ruleFormData.attachments = d.attachments ?? '';
- attachmentsFileList.value = JSON.parse(d.attachments|| '[]');
- ruleFormData.reviewComments = d.reviewComments?? '';
- ruleFormData.rectificationResponsibleUserId = d.rectificationResponsibleUserId;
- ruleFormData.rectificationDepartmentNames = d.rectificationDepartmentNames ?? '';
- // 整改页:保存审查不通过原因供 el-alert 展示(后端字段 reviewReason)
- if (isRectifyMode.value && d.reviewReason != null && String(d.reviewReason).trim()) {
- detailReviewRejectReason.value = String(d.reviewReason).trim();
- } else {
- detailReviewRejectReason.value = '';
- }
- }
- // if (isReviewMode.value) {
- // ruleFormData.reviewComments = '';
- // }
- cloneRuleFormData();
- } catch (e) {
- console.error('获取隐患详情失败:', e);
- ElMessage.error(e?.message || e?.data || '获取详情失败');
- }
- };
- const handleValidate = async () => {
- if (!basicFormRef.value) return;
- console.log('basicFormRef.value:', basicFormRef.value);
- return await basicFormRef.value.validate();
- };
- const handleSubmit = async () => {
- const ok = await handleValidate();
- if (!ok) return;
- try {
- let rectificationDeadline = ruleFormData.rectificationDeadline;
- if (rectificationDeadline) {
- if (rectificationDeadline.includes('T') || rectificationDeadline.includes(' ')) {
- rectificationDeadline = rectificationDeadline.split('T')[0].split(' ')[0];
- }
- }
- let drawLessonsDeadline = ruleFormData.drawLessonsDeadline;
- if (drawLessonsDeadline) {
- if (drawLessonsDeadline.includes('T') || drawLessonsDeadline.includes(' ')) {
- drawLessonsDeadline = drawLessonsDeadline.split('T')[0].split(' ')[0];
- }
- }
- const payload: SaveHiddenDangerRequest = {
- dangerProblem: ruleFormData.dangerProblem,
- typeId: ruleFormData.typeId!,
- reasonId: ruleFormData.reasonId!,
- taskSource: ruleFormData.taskSource,
- rectificationRequirement: ruleFormData.rectificationRequirement,
- rectificationDeadline: rectificationDeadline,
- rectificationDepartmentId: ruleFormData.rectificationDepartmentId,
- rectificationDepartmentIds: ruleFormData.rectificationDepartmentIds,
- rectificationResponsiblePerson: ruleFormData.rectificationResponsiblePerson,
- reviewDepartmentId: ruleFormData.reviewDepartmentId!,
- reviewPersonId: ruleFormData.reviewPersonId!,
- reviewPersonName: ruleFormData.reviewPersonName,
- isDrawLessonsPush: ruleFormData.isDrawLessonsPush ?? 0,
- drawLessonsContent: ruleFormData.drawLessonsContent || undefined,
- drawLessonsDepartmentIds: ruleFormData.drawLessonsDepartmentIds || undefined,
- drawLessonsDeadline: drawLessonsDeadline || undefined,
- attachments: ruleFormData.attachments || undefined,
- };
- if (isCreateMode.value) {
- await saveHiddenDanger(payload);
- ElMessage.success('创建成功');
- } else if (currentId.value) {
- await updateHiddenDanger({ id: currentId.value, ...payload } as UpdateHiddenDangerRequest);
- ElMessage.success('保存成功');
- }
- router.back();
- } catch (e) {
- console.error('保存隐患台账失败:', e);
- ElMessage.error(e?.message || e?.data || '保存失败,请重试');
- }
- };
- // ---------- 整改(详情页直接提交,无弹窗) ----------
- async function handleRectifySubmitDirect() {
- if (!currentId.value) return;
- try {
- const uploadedFileList = await formatAttachmentList(attachmentsFileList.value);
- await rectifyHiddenDanger({
- dangerId: currentId.value,
- rectificationPlan: '',
- rectificationResponsiblePerson: ruleFormData.rectificationResponsiblePerson || '',
- rectificationStartTime: '',
- rectificationEndTime: '',
- rectificationCompletionStatus: ruleFormData.rectificationCompletionStatus || '',
- rectificationCompletionTime: ruleFormData.rectificationCompletionTime || '',
- attachments: JSON.stringify(uploadedFileList) || undefined,
- isCompleted: 1,
- });
- ElMessage.success('整改提交成功');
- router.back();
- } catch (e) {
- console.error('整改提交失败:', e);
- ElMessage.error(e?.message || e?.data || '整改提交失败,请重试');
- }
- }
- // ---------- 复查 ----------
- const showReviewDialog = ref(false);
- const reviewFormRef = ref<FormInstance>();
- const reviewForm = ref<ReviewHiddenDangerRequest & { reviewResult: number }>({
- dangerId: 0,
- reviewResult: 1,
- reviewComments: '',
- reviewReason: '',
- reviewTime: '',
- attachments: '',
- });
- const reviewRules: FormRules = {
- reviewResult: [{ required: true, message: '请选择复查结论', trigger: 'change' }],
- };
- function resetReviewForm() {
- reviewForm.value = {
- dangerId: currentId.value || 0,
- reviewResult: 1,
- reviewComments: '',
- reviewReason: '',
- reviewTime: '',
- attachments: '',
- };
- }
- function openReviewDialog() {
- resetReviewForm();
- showReviewDialog.value = true;
- }
- async function handleReviewSubmit() {
- if (!currentId.value) return;
- if (reviewForm.value.reviewResult === 0 && !reviewForm.value.reviewReason) {
- ElMessage.warning('不通过时请填写不通过原因');
- return;
- }
- await reviewFormRef.value?.validate?.().catch(() => {});
- try {
- reviewForm.value.dangerId = currentId.value;
- await reviewHiddenDanger(reviewForm.value);
- ElMessage.success('复查提交成功');
- showReviewDialog.value = false;
- getDetail();
- } catch (e) {
- console.error('复查提交失败:', e);
- ElMessage.error(e?.message || e?.data || '复查提交失败,请重试');
- }
- }
- // ---------- 复查详情页:审查通过 / 审查不通过 ----------
- const showReviewRejectDialog = ref(false);
- const reviewRejectReason = ref('');
- function openReviewRejectDialog() {
- reviewRejectReason.value = '';
- showReviewRejectDialog.value = true;
- }
- async function handleReviewPass() {
- if (!currentId.value) return;
- try {
- await reviewHiddenDanger({
- dangerId: currentId.value,
- reviewResult: 1,
- reviewComments: ruleFormData.reviewComments || undefined,
- });
- ElMessage.success('审查通过');
- router.back();
- } catch (e) {
- console.error('审查通过提交失败:', e);
- ElMessage.error(e?.message || e?.data || '提交失败,请重试');
- }
- }
- async function handleReviewRejectSubmit() {
- const reason = (reviewRejectReason.value || '').trim();
- if (!reason) {
- ElMessage.warning('请填写审核不通过原因');
- return;
- }
- if (!currentId.value) return;
- try {
- await reviewHiddenDanger({
- dangerId: currentId.value,
- reviewResult: 0,
- reviewReason: reason,
- });
- ElMessage.success('已提交审查不通过');
- showReviewRejectDialog.value = false;
- router.back();
- } catch (e) {
- console.error('审查不通过提交失败:', e);
- ElMessage.error(e?.message || e?.data || '提交失败,请重试');
- }
- }
- // ---------- 扣分 ----------
- const showDeductDialog = ref(false);
- const deductFormRef = ref<FormInstance>();
- const deductDeptIdsArray = ref<number[]>([]);
- const deductForm = ref<HiddenDangerDeductPointsRequest>({
- dangerId: 0,
- deductionScore: 0,
- });
- const deductRules: FormRules = {
- deductionScore: [
- { required: true, message: '请输入扣分值', trigger: 'blur' },
- { type: 'number', min: 0, max: 9999, message: '扣分值须为0-9999的整数', trigger: 'blur' },
- ],
- };
- function resetDeductForm() {
- deductDeptIdsArray.value = [];
- deductForm.value = {
- dangerId: currentId.value || 0,
- deductionScore: 0,
- };
- }
- function openDeductDialog() {
- resetDeductForm();
- showDeductDialog.value = true;
- }
- async function handleDeductSubmit() {
- if (!currentId.value) return;
- await deductFormRef.value?.validate?.().catch(() => {});
- const score = Number(deductForm.value.deductionScore);
- if (score < 0 || score > 9999 || !Number.isInteger(score)) {
- ElMessage.warning('扣分值须为0-9999的整数');
- return;
- }
- try {
- deductForm.value.dangerId = currentId.value;
- deductForm.value.departmentIds =
- deductDeptIdsArray.value.length > 0 ? deductDeptIdsArray.value.join(',') : undefined;
- await deductHiddenDangerPoints(deductForm.value);
- ElMessage.success('扣分记录成功');
- showDeductDialog.value = false;
- } catch (e) {
- console.error('扣分失败:', e);
- ElMessage.error(e?.message || e?.data || '扣分失败,请重试');
- }
- }
- const issueDeptTree = ref<DeptTree[]>([]);
- const issueUserList = ref<Array<{ id: number; realname?: string; username?: string }>>([]);
- const onIssueDialogOpen = async () => {
- try {
- const [deptRes, userRes] = await Promise.all([
- getAllDepartments(),
- queryAvailableUserList({ pageNumber: 1, pageSize: 9999, queryParam: {} }),
- ]);
- const fullTree = (deptRes as DeptTree[]) ?? [];
- issueDeptTree.value = Array.isArray(fullTree) && fullTree[0]?.children ? fullTree[0].children : [];
- issueUserList.value = (userRes as any)?.records ?? [];
- } catch (e) {
- console.error('获取部门/用户列表失败:', e);
- ElMessage.error(e?.message || e?.data || '加载部门或负责人列表失败');
- issueDeptTree.value = [];
- issueUserList.value = [];
- }
- };
- onMounted(async () => {
- cloneRuleFormData();
- onIssueDialogOpen();
- await loadDeptAndUserOptions();
- if (isEditMode.value || isViewMode.value) {
- await getDetail();
- if (route.query.action === 'review' && isViewMode.value && canReview.value) {
- openReviewDialog();
- }
- }
- });
- </script>
- <style scoped lang="scss">
- @use '@/styles/page-details-layout.scss' as *;
-
- .file-item{
- display: flex;
- justify-content: flex-start;
- gap: 10px;
- }
- </style>
|