Parcourir la source

报送资料列表样式及接口对接,提交接口对接

shiyanyu il y a 1 mois
Parent
commit
7f46c353f6

+ 19 - 1
src/api/auditTaskProcessing.js

@@ -21,7 +21,25 @@ export function getProjectInformationInfo(projectId) {
 //  根据任务ID获取报送资料要求列表
 export function getTaskRequirementList(taskId) {
   return request({
-    url: url + '/costProjectTaskMaterial/v1/listByTaskId?taskId=' + data.taskId,
+    url: url + '/costProjectTaskMaterial/v1/listByTaskId?taskId=' + taskId,
     method: 'get',
   })
 }
+
+// 新增/更新报送资料要求
+export function addOrUpdateTaskRequirement(data) {
+  return request({
+    url: url + '/costProjectTaskMaterial/v1/save',
+    method: 'post',
+    data: data,
+  })
+}
+
+// 填报任务提交
+export function submitTaskRequirement(data) {
+  return request({
+    url: url + '/api/enterprise/castTask/save',
+    method: 'post',
+    data: data,
+  })
+}

+ 60 - 0
src/mixins/useDict.js

@@ -52,6 +52,66 @@ export const dictMixin = {
         return item ? item.name : key // 找不到对应名称时返回原key
       }
     },
+    // 根据字典 value 获取字典 name
+    getDictNameByValue(typeKey, value) {
+      const dictData = this.dictData[typeKey]
+      if (!dictData || dictData.length === 0) return ''
+      if (value === null || value === undefined || value === '') return ''
+
+      // 辅助函数:在字典数据中根据 value 查找对应的 item
+      const findDictItemByValue = (searchValue) => {
+        if (
+          searchValue === null ||
+          searchValue === undefined ||
+          searchValue === ''
+        )
+          return null
+
+        // 尝试多种类型的匹配
+        const strValue = String(searchValue)
+        const numValue = Number(searchValue)
+
+        // 1. 严格匹配(原始类型)
+        let item = dictData.find((item) => item.value === searchValue)
+        if (item) return item
+
+        // 2. 字符串匹配
+        item = dictData.find((item) => {
+          return String(item.value) === strValue
+        })
+        if (item) return item
+
+        // 3. 数字匹配(如果 value 可以转换为数字)
+        if (!isNaN(numValue) && !isNaN(searchValue)) {
+          item = dictData.find((item) => {
+            const itemNum = Number(item.value)
+            return !isNaN(itemNum) && itemNum === numValue
+          })
+          if (item) return item
+        }
+
+        return null
+      }
+
+      // 检查 value 是否包含逗号分隔的多个值
+      const valueStr = String(value)
+      if (valueStr.includes(',')) {
+        // 处理多个值
+        const values = valueStr
+          .split(',')
+          .map((v) => v.trim())
+          .filter(Boolean)
+        const names = values.map((v) => {
+          const item = findDictItemByValue(v)
+          return item ? item.name : v // 找不到对应名称时返回原 value
+        })
+        return names.join(', ')
+      } else {
+        // 处理单个值
+        const item = findDictItemByValue(value)
+        return item ? item.name : valueStr // 找不到对应名称时返回原 value
+      }
+    },
   },
 }
 

+ 289 - 133
src/views/EntDeclaration/auditTaskManagement/taskFillIn.vue

@@ -340,46 +340,155 @@
           <el-table
             style="margin-top: 20px"
             border
-            :data="formData.dataRequirements"
+            :data="groupedDataRequirements"
             size="mini"
+            :show-header="true"
+            :row-class-name="getRowClassName"
           >
+            <el-table-column prop="seq" label="序号" width="80" align="center">
+              <template slot-scope="scope">
+                <span v-if="!scope.row.isCategoryHeader">
+                  {{ scope.row.seq || scope.row.index }}
+                </span>
+              </template>
+            </el-table-column>
             <el-table-column
-              prop="seq"
-              label="序号"
-              width="80"
-              align="center"
-            ></el-table-column>
-            <el-table-column
-              prop="name"
+              prop="informationName"
               label="报送资料"
               min-width="280"
-            ></el-table-column>
+            >
+              <template slot-scope="scope">
+                <div
+                  v-if="scope.row.isCategoryHeader"
+                  class="category-header-cell"
+                >
+                  {{ scope.row.categoryName }}
+                </div>
+                <span v-else>{{ scope.row.informationName || '-' }}</span>
+              </template>
+            </el-table-column>
             <el-table-column
-              prop="type"
+              prop="informationType"
               label="资料类型"
               width="130"
               align="center"
-            ></el-table-column>
+            >
+              <template slot-scope="scope">
+                <span v-if="!scope.row.isCategoryHeader">
+                  <span
+                    v-if="
+                      scope.row.informationType !== null &&
+                      scope.row.informationType !== undefined
+                    "
+                  >
+                    {{
+                      getDictName(
+                        'materialType',
+                        String(scope.row.informationType)
+                      ) || scope.row.informationType
+                    }}
+                  </span>
+                  <span v-else>-</span>
+                </span>
+              </template>
+            </el-table-column>
             <el-table-column
-              prop="required"
+              prop="isRequired"
               label="是否必填"
               width="110"
               align="center"
-            ></el-table-column>
+            >
+              <template slot-scope="scope">
+                <span v-if="!scope.row.isCategoryHeader">
+                  {{ scope.row.isRequired === '1' ? '是' : '否' }}
+                </span>
+              </template>
+            </el-table-column>
             <el-table-column
-              prop="uploadStatus"
+              prop="isUploaded"
               label="是否上传"
               width="110"
               align="center"
-            ></el-table-column>
+            >
+              <template slot-scope="scope">
+                <span v-if="!scope.row.isCategoryHeader">
+                  <span v-if="scope.row.isUploaded === '1'">已上传</span>
+                  <span v-else class="text-danger">未上传</span>
+                </span>
+              </template>
+            </el-table-column>
             <el-table-column
               prop="operation"
               label="操作"
               width="220"
               align="center"
-            ></el-table-column>
+            >
+              <template slot-scope="scope">
+                <template v-if="!scope.row.isCategoryHeader">
+                  <template v-if="scope.row.isUploaded === '1'">
+                    <el-button
+                      type="text"
+                      size="small"
+                      @click="handleFileView(scope.row)"
+                    >
+                      查看
+                    </el-button>
+                    <el-button
+                      type="text"
+                      size="small"
+                      @click="handleFileDownload(scope.row)"
+                    >
+                      下载
+                    </el-button>
+                    <el-button
+                      type="text"
+                      size="small"
+                      @click="handleFileUpload(scope.row)"
+                    >
+                      上传
+                    </el-button>
+                  </template>
+                  <template v-else>
+                    <template
+                      v-if="
+                        getDictName(
+                          'materialType',
+                          String(scope.row.informationType)
+                        ) === '预置模版' ||
+                        scope.row.informationType === '预置模版'
+                      "
+                    >
+                      <el-button
+                        type="text"
+                        size="small"
+                        @click="handleTemplateDownload(scope.row)"
+                      >
+                        模版下载
+                      </el-button>
+                      <el-button
+                        type="text"
+                        size="small"
+                        @click="handleDataUpload(scope.row)"
+                      >
+                        数据上传
+                      </el-button>
+                    </template>
+                    <template v-else>
+                      <el-button
+                        type="text"
+                        size="small"
+                        @click="handleFileUpload(scope.row)"
+                      >
+                        上传
+                      </el-button>
+                    </template>
+                  </template>
+                </template>
+              </template>
+            </el-table-column>
+          </el-table>
 
-            <template slot="default">
+          <!-- <template slot="default">
               <template
                 v-if="
                   formData.dataRequirements.categories &&
@@ -488,8 +597,7 @@
                   </td>
                 </tr>
               </template>
-            </template>
-          </el-table>
+            </template> -->
         </el-tab-pane>
         <!-- 成本调查表 -->
         <el-tab-pane label="成本调查表" name="costSurvey">
@@ -746,28 +854,28 @@
         :rules="materialRules"
         label-width="100px"
       >
-        <el-form-item label="资料类别" prop="category">
+        <el-form-item label="资料类别" prop="informationType">
           <el-select
-            v-model="materialForm.category"
+            v-model="materialForm.informationType"
             placeholder="请选择资料类别"
             style="width: 100%"
           >
             <el-option
-              v-for="item in materialCategoryOptions"
-              :key="item.value"
-              :label="item.label"
-              :value="item.value"
+              v-for="item in dictData['materialType']"
+              :key="item.key"
+              :label="item.name"
+              :value="item.key"
             ></el-option>
           </el-select>
         </el-form-item>
-        <el-form-item label="资料名称" prop="name">
+        <el-form-item label="资料名称" prop="informationName">
           <el-input
-            v-model="materialForm.name"
+            v-model="materialForm.informationName"
             placeholder="请输入资料名称"
             style="width: 100%"
           ></el-input>
         </el-form-item>
-        <el-form-item label="资料要求" prop="requirement">
+        <el-form-item label="资料要求" prop="informationRequire">
           <el-upload
             class="upload-demo"
             action="#"
@@ -781,7 +889,7 @@
           >
             <el-button size="small" type="primary">选择文件</el-button>
             <div slot="tip" class="el-upload__tip">
-              只能上传jpg/png/pdf文件,且不超过10MB,最多上传5个文件
+              最多上传5个文件,支持所有格式
             </div>
           </el-upload>
         </el-form-item>
@@ -809,6 +917,8 @@
   import {
     getProjectInformationInfo,
     getTaskRequirementList,
+    addOrUpdateTaskRequirement,
+    submitTaskRequirement,
   } from '@/api/auditTaskProcessing'
   import RegionSelector from '@/views/costAudit/projectInfo/auditProjectManage/annualReviewPlan/RegionSelector.vue'
   import CatalogCascader from '@/views/costAudit/projectInfo/auditProjectManage/annualReviewPlan/CatalogCascader.vue'
@@ -836,6 +946,8 @@
           attributionYear: [], // 归属年度
           projectProposal: [], // 立项来源
           auditType: [], //监审形式
+          materialType: [], // 资料类型
+          materialCategory: [], // 资料类别
         },
         // 立项依据文件列表
         accordingFileList: [],
@@ -843,6 +955,7 @@
         otherFileList: [],
         // 页面标题
         pageTitle: '立项信息',
+        projectId: '', // 项目ID
         taskId: '', // 任务ID
         // 当前激活的标签页
         activeTab: 'projectInfo',
@@ -898,84 +1011,7 @@
               zip: 200333,
             },
           ],
-          dataRequirements: {
-            categories: [
-              {
-                categoryId: 'comprehensive',
-                name: '综合性资料',
-                items: [
-                  {
-                    seq: 1,
-                    name: '企业基本情况介绍: 包括企业名称、企业地址、企业员工数量等。',
-                    type: '文档文件',
-                    required: '是',
-                    uploaded: true,
-                  },
-                  {
-                    seq: 2,
-                    name: '组织机构图: 企业组织架构及……',
-                    type: '文档文件',
-                    required: '是',
-                    uploaded: false,
-                  },
-                  {
-                    seq: 3,
-                    name: '营业执照:',
-                    type: '文档文件',
-                    required: '是',
-                    uploaded: true,
-                  },
-                  {
-                    seq: 4,
-                    name: '企业管理制度:',
-                    type: '文档文件',
-                    required: '是',
-                    uploaded: false,
-                  },
-                ],
-              },
-              {
-                categoryId: 'financial',
-                name: '财务会计资料',
-                items: [
-                  {
-                    seq: 1,
-                    name: '财务审计表',
-                    type: 'excel文件',
-                    required: '是',
-                    uploaded: true,
-                  },
-                  {
-                    seq: 2,
-                    name: '资产卡片',
-                    type: '预置模版',
-                    required: '是',
-                    uploaded: true,
-                  },
-                  {
-                    seq: 3,
-                    name: '',
-                    type: '预置模版',
-                    required: '是',
-                    uploaded: false,
-                  },
-                ],
-              },
-              {
-                categoryId: 'other',
-                name: '其他资料',
-                items: [
-                  {
-                    seq: 1,
-                    name: '',
-                    type: '文档文件',
-                    required: '否',
-                    uploaded: false,
-                  },
-                ],
-              },
-            ],
-          },
+          dataRequirements: [],
           costSurveyData: [
             {
               index: 1,
@@ -1140,15 +1176,16 @@
         // 补充材料弹窗相关数据
         materialDialogVisible: false,
         materialForm: {
-          category: '',
-          name: '',
+          informationType: '',
+          informationName: '',
+          informationRequire: '',
           fileList: [],
         },
         materialRules: {
-          category: [
+          informationType: [
             { required: true, message: '请选择资料类别', trigger: 'change' },
           ],
-          name: [
+          informationName: [
             { required: true, message: '请输入资料名称', trigger: 'blur' },
           ],
         },
@@ -1166,13 +1203,91 @@
         currentSurveyData: null,
       }
     },
+    computed: {
+      // 按类别分组的报送资料列表
+      groupedDataRequirements() {
+        if (
+          !this.formData.dataRequirements ||
+          !Array.isArray(this.formData.dataRequirements) ||
+          this.formData.dataRequirements.length === 0
+        ) {
+          return []
+        }
+
+        // 按类别分组
+        const groups = {}
+        this.formData.dataRequirements.forEach((item, index) => {
+          // 获取类别标识,使用 informationType 作为类别 key
+          const categoryKey =
+            item.informationType ||
+            item.category ||
+            item.categoryId ||
+            item.categoryName ||
+            'other'
+          // 优先从字典中获取类别名称
+          let categoryName = ''
+          if (categoryKey) {
+            // 优先使用 getDictNameByValue 根据 value 查找
+            categoryName = this.getDictNameByValue(
+              'materialCategory',
+              categoryKey
+            )
+            // 如果 getDictNameByValue 没找到,尝试使用 getDictName 根据 key 查找
+            if (!categoryName || categoryName === String(categoryKey)) {
+              categoryName = this.getDictName('materialCategory', categoryKey)
+            }
+            // 如果字典中都找不到,使用 item.categoryName 作为后备
+            if (!categoryName || categoryName === String(categoryKey)) {
+              categoryName = item.informationTypeName || categoryKey
+            }
+          }
+
+          if (!groups[categoryKey]) {
+            groups[categoryKey] = {
+              categoryKey,
+              categoryName: categoryName || String(categoryKey),
+              items: [],
+            }
+          }
+          // 添加序号(每个类别内从1开始)
+          const itemWithSeq = {
+            ...item,
+            index: index + 1,
+            seq: groups[categoryKey].items.length + 1,
+          }
+          groups[categoryKey].items.push(itemWithSeq)
+        })
+
+        // 将分组转换为扁平数组,插入类别标题行
+        const result = []
+        Object.keys(groups).forEach((categoryKey) => {
+          const group = groups[categoryKey]
+          // 添加类别标题行
+          result.push({
+            isCategoryHeader: true,
+            categoryName: group.categoryName,
+            categoryKey: group.categoryKey,
+          })
+          // 添加该类别下的所有项目
+          group.items.forEach((item) => {
+            result.push({
+              ...item,
+              isCategoryHeader: false,
+            })
+          })
+        })
+
+        return result
+      },
+    },
     mounted() {
       this.getAllUnitList()
       this.getDefaultDem()
       this.getUser()
       // 从路由参数中获取 formType
       console.log('路由参数', this.$route.query)
-      this.taskId = this.$route.query.info.projectId
+      this.projectId = this.$route.query.info.projectId
+      this.taskId = this.$route.query.info.userTask.id
       this.tabCheck = this.$route.query.info.status
       if (this.tabCheck === 'jtsy') {
         this.tabVisiable = false
@@ -1270,6 +1385,13 @@
         // this.formData.catalogId = value.join(',')
         this.formData.basicInfo.catalogId = value
       },
+      // 表格行样式
+      getRowClassName({ row }) {
+        if (row.isCategoryHeader) {
+          return 'category-header-row'
+        }
+        return ''
+      },
       // 标签页切换
       handleTabClick(tab) {
         console.log(tab, 'qiehuan')
@@ -1284,16 +1406,29 @@
       },
       // 获取立项项目信息
       getProjectInformation() {
-        getProjectInformationInfo(this.taskId).then((res) => {
+        getProjectInformationInfo(this.projectId).then((res) => {
           console.log('立项项目信息', res)
           this.formData.basicInfo = res.value
         })
       },
       // 获取报送资料要求列表
-      getTaskRequirementPage(taskId) {
-        getTaskRequirementList(taskId).then((res) => {
-          console.log('报送资料要求', res)
-        })
+      getTaskRequirementPage() {
+        console.log('送报资料接口', this.taskId)
+        getTaskRequirementList(this.taskId)
+          .then((res) => {
+            console.log('报送资料要求', res)
+            if (res && res.code === 200 && res.value) {
+              this.formData.dataRequirements = Array.isArray(res.value)
+                ? res.value
+                : []
+            } else {
+              this.formData.dataRequirements = []
+            }
+          })
+          .catch((err) => {
+            console.error('获取报送资料失败', err)
+            this.formData.dataRequirements = []
+          })
       },
 
       // 提交
@@ -1301,8 +1436,20 @@
         this.loading.submit = true
         // 保存逻辑
         setTimeout(() => {
-          this.loading.submit = false
-          Message.success('提交成功')
+          submitTaskRequirement({ taskId: this.taskId })
+            .then((res) => {
+              this.loading.submit = false
+              console.log('提交成功', res)
+              if (res && res.code === 200) {
+                Message.success('提交成功')
+              } else {
+                Message.error('提交失败')
+              }
+            })
+            .catch((err) => {
+              console.error('提交失败', err)
+              Message.error('提交失败')
+            })
         }, 500)
       },
 
@@ -1413,8 +1560,9 @@
       // 重置补充材料表单
       resetMaterialForm() {
         this.materialForm = {
-          category: '',
-          name: '',
+          informationType: '',
+          informationName: '',
+          informationRequire: '',
           fileList: [],
         }
         if (this.$refs.materialForm) {
@@ -1455,18 +1603,7 @@
       },
 
       beforeMaterialUpload(file) {
-        const isJPG = file.type === 'image/jpeg' || file.type === 'image/png'
-        const isPDF = file.type === 'application/pdf'
-        const isLt10M = file.size / 1024 / 1024 < 10
-
-        if (!isJPG && !isPDF) {
-          Message.error('只能上传 JPG/PNG/PDF 格式的文件!')
-          return false
-        }
-        if (!isLt10M) {
-          Message.error('上传文件大小不能超过 10MB!')
-          return false
-        }
+        // 允许所有格式的文件上传,不进行格式限制
         return true
       },
 
@@ -1569,4 +1706,23 @@
   .ml10 {
     margin-left: 10px;
   }
+  .text-danger {
+    color: #d9001b;
+  }
+
+  // 类别头行样式
+  ::v-deep .category-header-row {
+    background-color: #f5f7fa !important;
+
+    td {
+      background-color: #f5f7fa !important;
+      padding: 12px 16px !important;
+    }
+  }
+
+  .category-header-cell {
+    font-weight: 700;
+    color: #303133;
+    padding-left: 16px;
+  }
 </style>

+ 6 - 6
src/views/EntDeclaration/auditTaskProcessing/index.vue

@@ -28,7 +28,7 @@
             <el-option label="年度计划外" value="2"></el-option>
           </el-select>
         </el-form-item> -->
-        <el-form-item label="监审形式:">
+        <!-- <el-form-item label="监审形式:">
           <el-select
             v-model="searchForm.auditType"
             placeholder="请选择监审形式"
@@ -41,9 +41,9 @@
               :label="item.name"
               :value="item.key"
             ></el-option>
-          </el-select>
-          <!-- <el-input v-model="searchForm.auditType" placeholder="请输入监审形式" clearable /> -->
-        </el-form-item>
+          </el-select> -->
+        <!-- <el-input v-model="searchForm.auditType" placeholder="请输入监审形式" clearable /> -->
+        <!-- </el-form-item> -->
         <!-- <el-form-item label="立项地区:">
           <el-input v-model="searchForm.areaName" placeholder="请输入立项地区" clearable />
         </el-form-item> -->
@@ -53,7 +53,7 @@
         <!-- <el-form-item label="状态:">
           <el-select v-model="searchForm.status" placeholder="请选择状态">
             <el-option label="提交材料" value="tjcl"></el-option>
-            <el-option label="材料初审" value="clcs"></el-option>
+            <el-option label="材料初审" value="ccls"></el-option>
             <el-option label="实地审核" value="sdsh"></el-option>
             <el-option label="意见告知" value="yigz"></el-option>
             <el-option label="意见反馈" value="yjfk"></el-option>
@@ -155,7 +155,7 @@
       >
         <template slot-scope="scope">
           <div v-if="scope.row.status === 'tjcl'">提交材料</div>
-          <div v-if="scope.row.status === 'clcs'">材料初审</div>
+          <div v-if="scope.row.status === 'ccls'">材料初审</div>
           <div v-if="scope.row.status === 'sdsh'">实地审核</div>
           <div v-if="scope.row.status === 'yigz'">意见告知</div>
           <div v-if="scope.row.status === 'yjfk'">意见反馈</div>