Просмотр исходного кода

fix(risk): 作业上报按设计稿改字典 + 删工期列

- 列表/筛选/详情:作业类型 + 审核状态 改读字典 risk_work_type / risk_work_audit_status
  (之前硬编码 '0'/'1'/'2' 但 DB 存的是中文,前后端不一致)
- 加 loadDicts + workTypeOptions / auditStatusOptions + getDictLabel
- 删「工期(天)」列表列 + 详情项 + 表单字段 + 校验规则
  (设计稿没这个字段,改成用户手动选结束时间)
- 修 <style scoped> 缺点的 bug (.work-report-page)
- 兼容老数据:'0'/'1'/'2' 在 getAuditStatusTag 里映射到同样颜色
yangjingjing 1 день назад
Родитель
Сommit
4b58e21eff
1 измененных файлов с 65 добавлено и 69 удалено
  1. 65 69
      src/views/risk/workReport/index.vue

+ 65 - 69
src/views/risk/workReport/index.vue

@@ -12,8 +12,12 @@
         <el-form-item label="作业类型" prop="workType">
           <el-select v-model="queryParams.workType" placeholder="全部类型" style="width: 200px" @change="handleQuery">
             <el-option label="全部类型" value="" />
-            <el-option label="临时施工上报" value="临时施工上报" />
-            <el-option label="改造工程上报" value="改造工程上报" />
+            <el-option
+              v-for="d in workTypeOptions"
+              :key="d.value"
+              :label="d.label"
+              :value="d.value"
+            />
           </el-select>
         </el-form-item>
         <el-form-item label="项目名称" prop="workTitle">
@@ -28,9 +32,12 @@
         <el-form-item label="状态" prop="auditStatus">
           <el-select v-model="queryParams.auditStatus" placeholder="全部状态" style="width: 200px" @change="handleQuery">
             <el-option label="全部状态" value="" />
-            <el-option label="审核通过" value="1" />
-            <el-option label="待审核" value="0" />
-            <el-option label="审核不通过" value="2" />
+            <el-option
+              v-for="d in auditStatusOptions"
+              :key="d.value"
+              :label="d.label"
+              :value="d.value"
+            />
           </el-select>
         </el-form-item>
         <el-form-item>
@@ -51,7 +58,7 @@
         <el-table-column type="index" label="序号" align="center" width="60" />
         <el-table-column label="作业类型" align="center" prop="workType" width="140">
           <template #default="scope">
-            <el-link :underline="false" type="primary">{{ scope.row.workType }}</el-link>
+            <el-link :underline="false" type="primary">{{ getDictLabel(workTypeOptions, scope.row.workType) }}</el-link>
           </template>
         </el-table-column>
         <el-table-column
@@ -61,12 +68,6 @@
           :show-overflow-tooltip="true"
           min-width="180"
         />
-        <el-table-column
-          label="工期(天)"
-          align="center"
-          prop="durationDays"
-          width="90"
-        />
         <el-table-column
           label="施工开始时间"
           align="center"
@@ -88,7 +89,7 @@
         <el-table-column label="状态" align="center" prop="auditStatus" width="110">
           <template #default="scope">
             <el-tag :type="getAuditStatusTag(scope.row.auditStatus)">
-              {{ getAuditStatusLabel(scope.row.auditStatus) }}
+              {{ getDictLabel(auditStatusOptions, scope.row.auditStatus) }}
             </el-tag>
           </template>
         </el-table-column>
@@ -142,24 +143,6 @@
           </el-col>
         </el-row>
 
-        <el-row :gutter="20">
-          <el-col :span="12">
-            <el-form-item label="工期" prop="durationDays">
-              <el-input-number
-                v-model="form.durationDays"
-                :min="1"
-                :max="3650"
-                :step="1"
-                placeholder="请输入工期,如:3天"
-                controls-position="right"
-                style="width: 100%"
-                @change="handleDurationChange"
-              />
-              <span class="form-tip">单位:天,录入工期+开始时间自动算结束时间</span>
-            </el-form-item>
-          </el-col>
-        </el-row>
-
         <el-row :gutter="20">
           <el-col :span="12">
             <el-form-item label="施工开始时间" prop="workStartTime">
@@ -287,14 +270,11 @@
     <el-dialog v-model="viewDialog.visible" title="作业上报详情" width="780px" append-to-body>
       <el-descriptions :column="2" border>
         <el-descriptions-item label="作业类型">
-          {{ viewForm.workType }}
+          {{ getDictLabel(workTypeOptions, viewForm.workType) }}
         </el-descriptions-item>
         <el-descriptions-item label="项目名称">
           {{ viewForm.workTitle }}
         </el-descriptions-item>
-        <el-descriptions-item label="工期(天)">
-          {{ viewForm.durationDays ?? '-' }}
-        </el-descriptions-item>
         <el-descriptions-item label="施工开始时间">
           {{ viewForm.workStartTime }}
         </el-descriptions-item>
@@ -312,7 +292,7 @@
         </el-descriptions-item>
         <el-descriptions-item label="审核状态">
           <el-tag :type="getAuditStatusTag(viewForm.auditStatus)">
-            {{ getAuditStatusLabel(viewForm.auditStatus) }}
+            {{ getDictLabel(auditStatusOptions, viewForm.auditStatus) }}
           </el-tag>
         </el-descriptions-item>
         <el-descriptions-item label="施工说明" :span="2">
@@ -403,6 +383,7 @@ import {
 } from '@/api/risk/workReport';
 import type { RiskWorkReportBo, RiskWorkReportVo } from '@/api/risk/types';
 import { uploadFile } from '@/api/risk/file';
+import { getDicts } from '@/api/system/dict/data';
 import { Plus, UploadFilled, Document, Picture as IconPicture } from '@element-plus/icons-vue';
 import { ElMessage, FormInstance, UploadFile, UploadRawFile, UploadUserFile } from 'element-plus';
 import type { ComponentInternalInstance } from 'vue';
@@ -416,6 +397,10 @@ const photoFileList = ref<UploadUserFile[]>([]);
 const certFileList = ref<UploadUserFile[]>([]);
 const viewPhotoList = ref<string[]>([]);
 
+// 字典
+const workTypeOptions = ref<Array<{ label: string; value: string }>>([]);
+const auditStatusOptions = ref<Array<{ label: string; value: string }>>([]);
+
 const queryFormRef = ref<FormInstance>();
 const formRef = ref<FormInstance>();
 const auditFormRef = ref<FormInstance>();
@@ -443,7 +428,6 @@ const data = reactive<any>({
     workContent: '',
     workStartTime: '',
     workEndTime: '',
-    durationDays: undefined,
     reporterName: '',
     contactPhone: '',
     photoList: [],
@@ -462,21 +446,6 @@ const data = reactive<any>({
   rules: {
     workType: [{ required: true, message: '请选择作业类型', trigger: 'change' }],
     workTitle: [{ required: true, message: '请输入项目名称', trigger: 'blur' }],
-    durationDays: [
-      { required: true, message: '请输入工期', trigger: 'blur' },
-      {
-        validator: (_rule: any, value: any, callback: any) => {
-          if (value === undefined || value === null || value === '') {
-            callback(new Error('请输入工期'));
-          } else if (Number(value) < 1) {
-            callback(new Error('工期必须大于等于1天'));
-          } else {
-            callback();
-          }
-        },
-        trigger: 'blur'
-      }
-    ],
     workStartTime: [{ required: true, message: '请选择施工开始时间', trigger: 'change' }],
     workEndTime: [
       { required: true, message: '请选择施工结束时间', trigger: 'change' },
@@ -696,7 +665,6 @@ const reset = () => {
     workContent: '',
     workStartTime: '',
     workEndTime: '',
-    durationDays: undefined,
     reporterName: '',
     contactPhone: '',
     photoList: [],
@@ -861,27 +829,54 @@ const handleCertRemove = () => {
 
 // ============ 工具方法 ============
 
+const mapDictData = (resOrList: any) => {
+  const list: any[] = Array.isArray(resOrList)
+    ? resOrList
+    : Array.isArray(resOrList?.data)
+      ? resOrList.data
+      : [];
+  return list
+    .filter((d) => d.status === '0' || d.status === undefined)
+    .sort((a, b) => (a.dictSort || 0) - (b.dictSort || 0))
+    .map((d) => ({ label: d.dictLabel, value: d.dictValue }));
+};
+
+const loadDicts = async () => {
+  try {
+    const [typeRes, statusRes] = await Promise.all([
+      getDicts('risk_work_type'),
+      getDicts('risk_work_audit_status')
+    ]);
+    workTypeOptions.value = mapDictData(typeRes);
+    auditStatusOptions.value = mapDictData(statusRes);
+  } catch (e) {
+    console.error('加载作业上报字典失败', e);
+  }
+};
+
+/** 字典 value → 中文 label */
+const getDictLabel = (
+  opts: Array<{ label: string; value: string }>,
+  val: string
+) => {
+  if (!val) return '';
+  return opts.find((o) => o.value === val)?.label || val;
+};
+
+/** 审核状态 tag 颜色(按字典 list_class 映射) */
 const getAuditStatusTag = (status: string): any => {
   const map: Record<string, string> = {
-    '0': 'warning',
-    '1': 'success',
-    '2': 'danger',
     待审核: 'warning',
     审核通过: 'success',
-    审核不通过: 'danger'
+    审核不通过: 'danger',
+    // 兼容老数据(如果还有 '0'/'1'/'2')
+    '0': 'warning',
+    '1': 'success',
+    '2': 'danger'
   };
   return map[status] || 'info';
 };
 
-const getAuditStatusLabel = (status: string) => {
-  const map: Record<string, string> = {
-    '0': '待审核',
-    '1': '审核通过',
-    '2': '审核不通过'
-  };
-  return map[status] || status || '';
-};
-
 const getCertIcon = (url: string) => {
   if (!url) return Document;
   const lower = url.toLowerCase();
@@ -898,13 +893,14 @@ const openFile = (url: string) => {
   window.open(url, '_blank');
 };
 
-onMounted(() => {
-  getList();
+onMounted(async () => {
+  await loadDicts();
+  await getList();
 });
 </script>
 
 <style scoped>
-  work-report-page {
+.work-report-page {
   padding: 16px;
   height: 100%;
   overflow-y: auto;