Explorar o código

fix: 跨表查询

shiyanyu hai 1 semana
pai
achega
618ebd67e7

+ 10 - 0
src/api/audit/survey.js

@@ -77,6 +77,16 @@ export function reviewCastTaskInfo(data) {
   })
 }
 
+// 固定表/动态表:跨表引用数据
+// GET /api/surveyTemplate/v1/getCrossTableData?taskId=xxx&surveyTemplateId=yyy&type=1&period=2024
+export function getCrossTableData(params) {
+  return request({
+    url: url + '/api/surveyTemplate/v1/getCrossTableData',
+    method: 'get',
+    params,
+  })
+}
+
 // 数据下载
 export function downloadTemplate(data) {
   return request({

+ 61 - 4
src/views/EntDeclaration/auditTaskManagement/components/CostSurveyTab.vue

@@ -46,6 +46,7 @@
       "
       :catalog-id="catalogId"
       :task-id="taskId"
+      :cross-table-info="crossTableInfo"
       @save="handleFixedTableSave"
       @refresh="handleRefresh"
     />
@@ -71,6 +72,7 @@
           ? currentSurveyRow.surveyTemplateId
           : surveyTemplateId
       "
+      :cross-table-info="crossTableInfo"
       @save="handleDynamicTableSave"
       @refresh="handleRefresh"
     />
@@ -256,6 +258,7 @@
     getDynamicTableData,
     downloadTemplate,
     importData,
+    getCrossTableData,
   } from '@/api/audit/survey'
   import { getListBySurveyTemplateIdAndVersion } from '@/api/costSurveyTemplateHeaders'
 
@@ -332,6 +335,12 @@
         fixedFields: '',
         fixedFieldids: '',
         columnsMeta: [],
+        // 跨表引用数据
+        crossTableInfo: {
+          isCrossTable: false,
+          crossTableName: '',
+          data: {},
+        },
         // 上传相关
         pendingDynamicRow: null,
       }
@@ -388,6 +397,54 @@
         }
         this.auditPeriods = [str]
       },
+      // 加载跨表引用数据(固定表/动态表使用,period 不传=查全部)
+      async loadCrossTableInfo(row) {
+        const surveyTemplateId =
+          (row && (row.surveyTemplateId || row.templateId)) ||
+          this.surveyTemplateId ||
+          ''
+        const taskId = (row && (row.taskId || row.taskID)) || this.taskId || ''
+
+        if (!surveyTemplateId || !taskId) {
+          this.crossTableInfo = {
+            isCrossTable: false,
+            crossTableName: '',
+            data: {},
+          }
+          return
+        }
+
+        try {
+          const res = await getCrossTableData({
+            taskId,
+            surveyTemplateId,
+            type: 1,
+          })
+          // 兼容后端返回 code=0 的格式
+          const payload = res?.data || res?.value || res
+          if (payload && (payload.code === 0 || payload.code === 200)) {
+            const d = payload.data || {}
+            this.crossTableInfo = {
+              isCrossTable: !!d.isCrossTable,
+              crossTableName: d.crossTableName || '',
+              data: d.data || {},
+            }
+          } else {
+            this.crossTableInfo = {
+              isCrossTable: false,
+              crossTableName: '',
+              data: {},
+            }
+          }
+        } catch (e) {
+          console.error('获取跨表引用数据失败:', e)
+          this.crossTableInfo = {
+            isCrossTable: false,
+            crossTableName: '',
+            data: {},
+          }
+        }
+      },
       // 处理在线填报点击
       async handleOnlineFillClick(row) {
         this.currentSurveyRow = row
@@ -433,12 +490,12 @@
           await this.initFormFields()
           // 接口调用完成后会自动打开弹窗(在 initFormFields 中处理)
         } else if (row.tableType === '固定表') {
-          // 如果表格类型是"固定表",弹出固定表填报弹窗
-          // 调用接口获取固定表配置
+          // 固定表:先加载跨表引用数据,再初始化固定表
+          await this.loadCrossTableInfo(row)
           await this.initFixedTableData()
-          // 接口调用完成后会自动打开弹窗(在 initFixedTableData 中处理)
         } else if (row.tableType === '动态表') {
-          // 如果表格类型是"动态表",弹出动态表填报弹窗
+          // 动态表:先加载跨表引用数据,再初始化动态表
+          await this.loadCrossTableInfo(row)
           this.resetDynamicDialogState()
           await this.initDynamicTableData()
         } else {

+ 30 - 3
src/views/EntDeclaration/auditTaskManagement/components/DataRequirementsTab.vue

@@ -214,8 +214,31 @@
         <template slot-scope="scope">
           <template v-if="!scope.row.isCategoryHeader">
             <template v-if="String(scope.row.formatRequired) !== '3'">
+              <!-- 固定表:也支持在线填报(templateType=2) -->
+              <template v-if="String(scope.row.templateType) === '2'">
+                <el-button
+                  v-if="scope.row.isUpload === 1 || scope.row.isUpload === '1'"
+                  type="text"
+                  size="small"
+                  @click="handleViewTemplate(scope.row)"
+                >
+                  查看
+                </el-button>
+                <el-button
+                  type="text"
+                  size="small"
+                  :disabled="isViewMode"
+                  @click="handleOnlineSubmission(scope.row)"
+                >
+                  在线填报
+                </el-button>
+              </template>
+
               <el-button
-                v-if="scope.row.isUpload === 1 || scope.row.isUpload === '1'"
+                v-if="
+                  (scope.row.isUpload === 1 || scope.row.isUpload === '1') &&
+                  String(scope.row.templateType) !== '2'
+                "
                 type="text"
                 size="small"
                 @click="handleFileView(scope.row)"
@@ -223,7 +246,10 @@
                 查看
               </el-button>
               <el-button
-                v-if="scope.row.isUpload === 1 || scope.row.isUpload === '1'"
+                v-if="
+                  (scope.row.isUpload === 1 || scope.row.isUpload === '1') &&
+                  String(scope.row.templateType) !== '2'
+                "
                 type="text"
                 size="small"
                 @click="$emit('handleFileDownload', scope.row)"
@@ -233,7 +259,8 @@
               <el-button
                 v-if="
                   scope.row.auditedStatus !== '1' &&
-                  (currentNode === 'clcs' || currentNode === 'tjcl')
+                  (currentNode === 'clcs' || currentNode === 'tjcl') &&
+                  String(scope.row.templateType) !== '2'
                 "
                 type="text"
                 size="small"

+ 25 - 2
src/views/EntDeclaration/auditTaskManagement/components/FixedTableDialog.vue

@@ -215,6 +215,16 @@
         type: Object,
         default: () => ({}),
       },
+      // 跨表引用数据(来自 getCrossTableData)
+      // 结构:{ isCrossTable: boolean, crossTableName: string, data: { '表名.Q1': '100', ... } }
+      crossTableInfo: {
+        type: Object,
+        default: () => ({
+          isCrossTable: false,
+          crossTableName: '',
+          data: {},
+        }),
+      },
       // 表格数据配置
       // 格式: [
       //   {
@@ -1956,12 +1966,25 @@
       recomputeRowForYear(row, year) {
         if (!row || !row.calculationFormula) return
         const expr = row.calculationFormula.toString()
-        // 替换变量为对应年的数值
-        const replaced = expr.replace(/[A-Z]+\d+/g, (code) => {
+
+        // 1) 先替换跨表引用:形如 “表名.Q1”
+        const replacedCross = expr.replace(
+          /([^+\-*/()\s]+\.[A-Za-z0-9_]+)/g,
+          (token) => {
+            const data = this.crossTableInfo && this.crossTableInfo.data
+            const raw = data && data[token]
+            const num = Number(raw)
+            return !isNaN(num) ? String(num) : '0'
+          }
+        )
+
+        // 2) 再替换本表引用:形如 “Q1”、“C12”(原逻辑)
+        const replaced = replacedCross.replace(/[A-Z]+\d+/g, (code) => {
           const refRow = this.cellCodeIndex[code]
           const v = refRow ? Number(refRow[`year_${year}`]) : 0
           return isNaN(v) ? '0' : String(v)
         })
+
         // 仅允许数字与运算符
         const safe = this.safeEvalExpression(replaced)
         if (safe !== null && !isNaN(safe)) {

+ 39 - 1
src/views/costAudit/auditInfo/auditManage/details.vue

@@ -74,6 +74,7 @@
           >
             <work-draft
               :id="id"
+              ref="workDraft"
               :current-node="currentNode"
               :current-status="currentStatus"
             />
@@ -85,6 +86,7 @@
           >
             <extract-material
               :id="id"
+              ref="extractMaterial"
               :current-node="currentNode"
               :current-status="currentStatus"
             />
@@ -104,7 +106,7 @@
             />
           </el-tab-pane>
           <el-tab-pane label="消息通知" name="messageNotify">
-            <message-notify :id="id" />
+            <message-notify :id="id" ref="messageNotify" />
           </el-tab-pane>
         </el-tabs>
       </template>
@@ -548,6 +550,42 @@
             }
           })
         }
+        if (tab && tab.name === 'workDraft' && this.id) {
+          // 切换到工作底稿时,主动刷新(走接口)
+          this.$nextTick(() => {
+            if (this.$refs.workDraft) {
+              if (this.$refs.workDraft.getWorkingPaperRecords) {
+                this.$refs.workDraft.getWorkingPaperRecords()
+              }
+              if (this.$refs.workDraft.getWorkingPaperContent) {
+                this.$refs.workDraft.getWorkingPaperContent()
+              }
+            }
+          })
+        }
+        if (tab && tab.name === 'extractMaterial' && this.id) {
+          // 切换到提取材料登记时,主动刷新(走接口)
+          this.$nextTick(() => {
+            if (
+              this.$refs.extractMaterial &&
+              this.$refs.extractMaterial.getExtractMaterials
+            ) {
+              this.$refs.extractMaterial.getExtractMaterials()
+            }
+          })
+        }
+        if (tab && tab.name === 'messageNotify' && this.id) {
+          // 切换到消息通知时,主动刷新(走接口)
+          this.$nextTick(() => {
+            if (
+              this.$refs.messageNotify &&
+              this.$refs.messageNotify.getNoticeList
+            ) {
+              this.$refs.messageNotify.internalPagination.currentPage = 1
+              this.$refs.messageNotify.getNoticeList()
+            }
+          })
+        }
       },
 
       async loadSubmitMaterials() {

+ 2 - 2
src/views/costAudit/auditInfo/auditManage/index.vue

@@ -168,13 +168,13 @@
               >
                 审核
               </el-button> -->
-              <el-button
+              <!-- <el-button
                 v-if="scope.row.status === '300'"
                 type="text"
                 @click="handleHf(scope.row)"
               >
                 恢复
-              </el-button>
+              </el-button> -->
               <el-button
                 type="text"
                 @click="handleMessage(scope.row, 'chengben')"