Преглед изворни кода

fix:修改 行业分析/历史分析页面查询条件项目名称选项接口地址

luzhixia пре 2 недеља
родитељ
комит
ec7322ff73

+ 9 - 0
src/api/comprehensive.js

@@ -8,3 +8,12 @@ export function analyzeStatistics(data) {
     data,
   })
 }
+
+// 获取项目名称-归档
+export function getAuditTaskList(data) {
+  return request({
+    url: `${url}/api/costProjectApproval/v1/analyze/list`,
+    method: 'post',
+    data,
+  })
+}

+ 42 - 12
src/views/costAudit/baseInfo/statistics/components/costAudit.vue

@@ -127,6 +127,7 @@
     getCostFormVersionsByTemplateId,
     batchSaveOrUpdate,
   } from '@/api/costFormManage'
+  import { getSurveyDetail } from '@/api/audit/survey'
   import {
     getlistBySurveyTemplateId,
     getVerifyTemplateDetail,
@@ -134,10 +135,10 @@
     exportExcel,
   } from '@/api/costVerifyManage'
   import { getDetail } from '@/api/auditInitiation'
-  // import { catalogMixin } from '@/mixins/useDict'
+  import { catalogMixin } from '@/mixins/useDict'
   export default {
     name: 'CostAudit',
-    // mixins: [catalogMixin],
+    mixins: [catalogMixin],
     props: {
       id: {
         type: [String, Number],
@@ -182,6 +183,8 @@
         auditFormList: [],
         // 成本调查表模板列表
         surveyFormList: [],
+        // 调查表详情数据
+        surveyDetailData: null,
         auditForm: {
           surveyTemplateName: '',
           surveyTemplateId: '',
@@ -446,19 +449,46 @@
             // taskId: this.selectedProject.taskId,
             surveyTemplateId: this.auditForm.surveyTemplateId,
           })
-          getVerifyTemplateDetail({
+
+          // 获取模板详情
+          const templateDetailRes = await getVerifyTemplateDetail({
             id: this.auditForm.surveyTemplateId,
-          }).then((res) => {
-            this.auditForm.surveyTemplateName = res.value.surveyTemplateName
-            this.auditForm.catalogId = res.value.catalogId
-            this.auditForm.templateType = res.value.createmode
-            if (res.value.createmode == '1') {
-              this.auditForm.dataTable = res.value.createtemplateid
-            } else if (res.value.createmode == '2') {
-              this.auditForm.historyTemplate = res.value.createtemplateid
-            }
           })
 
+          if (templateDetailRes.code === 200) {
+            this.auditForm.surveyTemplateName =
+              templateDetailRes.value.surveyTemplateName
+            this.auditForm.catalogId = templateDetailRes.value.catalogId
+            this.auditForm.templateType = templateDetailRes.value.createmode
+
+            if (templateDetailRes.value.createmode == '1') {
+              this.auditForm.dataTable =
+                templateDetailRes.value.createtemplateid
+
+              // // 如果是调查表类型,调用 getSurveyDetail 获取调查表详情
+              // if (this.auditForm.dataTable) {
+              //   try {
+              //     const surveyDetailRes = await getSurveyDetail({
+              //       surveyTemplateId: this.auditForm.dataTable,
+              //       taskId: this.selectedProject.taskId
+              //     })
+
+              //     if (surveyDetailRes.code === 200 && surveyDetailRes.value) {
+              //       // 在这里处理调查表详情数据
+              //       console.log('调查表详情数据:', surveyDetailRes.value)
+              //       // 可以根据需要将数据保存到组件的 data 中,或者直接使用
+              //       this.surveyDetailData = surveyDetailRes.value
+              //     }
+              //   } catch (error) {
+              //     console.error('获取调查表详情失败:', error)
+              //   }
+              // }
+            } else if (templateDetailRes.value.createmode == '2') {
+              this.auditForm.historyTemplate =
+                templateDetailRes.value.createtemplateid
+            }
+          }
+
           // 处理表头数据
           if (tableHeadersRes.code == 200) {
             this.parseAndDisplayTableHeaders(tableHeadersRes)

+ 1 - 0
src/views/costAudit/baseInfo/statistics/components/materialTab.vue

@@ -75,6 +75,7 @@
   import CostAuditTable from '@/components/costAudit/CostAuditTable.vue'
   import LegalDialog from '@/views/costAudit/baseInfo/catalogManage/legalDialog.vue'
   export default {
+    name: 'QueryMaterialTab',
     components: {
       CostAuditTable,
       LegalDialog,

+ 27 - 13
src/views/costAudit/baseInfo/statistics/historyAnalysis.vue

@@ -60,13 +60,20 @@
         ></el-date-picker>
       </el-form-item>
       <el-form-item>
-        <el-button
-          type="primary"
-          icon="iconfont-5039297 icon-chaxun"
-          @click="handleQuery"
+        <el-tooltip
+          class="item"
+          :content="'查询条件:项目名称、被监审单位都需要选择,否则无法查询'"
+          placement="top"
         >
-          查询
-        </el-button>
+          <el-button
+            type="primary"
+            icon="iconfont-5039297 icon-chaxun"
+            :disabled="!searchForm.projectId || !searchForm.auditedUnitId"
+            @click="handleQuery"
+          >
+            查询
+          </el-button>
+        </el-tooltip>
         <el-button icon="iconfont-5039297 icon-zhongzhi" @click="handleReset">
           重置
         </el-button>
@@ -494,7 +501,7 @@
           if (this.searchForm.auditedUnitId) {
             this.searchForm.auditedUnitName =
               this.auditedUnitOptions.find(
-                (item) => item.unitId === this.searchForm.unitId
+                (item) => item.unitId === this.searchForm.auditedUnitId
               )?.unitName || ''
           } else {
             this.searchForm.auditedUnitName = ''
@@ -512,18 +519,17 @@
           }
           const dataSource =
             res && res.costSurveysList && res.costSurveysList.length ? res : []
-          // 接口数据去重(按 id)
-          const dedupedList = this.dedupeCostSurveysList(
-            dataSource.costSurveysList || []
-          )
+          // 保留接口返回的原始列表,不再去重
           const normalizedDataSource = {
             ...dataSource,
-            costSurveysList: dedupedList,
+            costSurveysList: dataSource.costSurveysList || [],
           }
           // 保存原始数据源
           this.rawDataSource = normalizedDataSource
           // 构建指标树
-          this.indicatorData = this.buildIndicatorTree(dedupedList)
+          this.indicatorData = this.buildIndicatorTree(
+            normalizedDataSource.costSurveysList
+          )
           // 等待 DOM 更新后设置选中状态
           this.$nextTick(() => {
             // 再次检查组件是否已销毁
@@ -883,6 +889,14 @@
 
       // 处理查询
       handleQuery() {
+        if (!this.searchForm.projectId) {
+          this.$message.warning('请选择项目名称!')
+          return
+        }
+        if (!this.searchForm.auditedUnitId) {
+          this.$message.warning('请选择被监审单位!')
+          return
+        }
         // 查询后重置选中到默认
         this.selectedIndicators = []
         this.updateChartData(true)

+ 36 - 94
src/views/costAudit/baseInfo/statistics/index.js

@@ -1,7 +1,6 @@
 import * as echarts from 'echarts'
-import { getAuditTaskList } from '@/api/auditInitiation.js'
 import { getAllUnitList } from '@/api/auditEntityManage.js'
-import { analyzeStatistics } from '@/api/comprehensive'
+import { analyzeStatistics, getAuditTaskList } from '@/api/comprehensive'
 // 综合分析页面的通用mixin
 export const comprehensiveMixin = {
   data() {
@@ -61,11 +60,22 @@ export const comprehensiveMixin = {
         // 如果有子项,递归处理
         if (Array.isArray(item.costSurveysVos) && item.costSurveysVos.length) {
           node.children = item.costSurveysVos.map(processNode)
+          // 对子节点按照orderNum从小到大排序
+          node.children.sort((a, b) => {
+            const orderA = parseInt(a.orderNum || 0)
+            const orderB = parseInt(b.orderNum || 0)
+            return orderA - orderB
+          })
         }
         return node
       }
 
-      return costSurveysList.map(processNode)
+      // 处理根节点并按照orderNum从小到大排序
+      return costSurveysList.map(processNode).sort((a, b) => {
+        const orderA = parseInt(a.orderNum || 0)
+        const orderB = parseInt(b.orderNum || 0)
+        return orderA - orderB
+      })
     },
 
     // label 规则:parentId 为 -1 时,用 “number、name”,否则 “number.name”
@@ -106,80 +116,6 @@ export const comprehensiveMixin = {
       return { ids, items }
     },
 
-    // 去重成本列表:同级内去重,优先按 id,其次 rowId/rowid,再按 parentId+number+name
-    dedupeCostSurveysList(list = []) {
-      const dedupeLevel = (arr = []) => {
-        const seenIds = new Set()
-        const seenRowIds = new Set()
-        const seenCombo = new Set()
-        const result = []
-        for (const node of arr || []) {
-          if (!node) continue
-          const normId =
-            node.id !== undefined && node.id !== null
-              ? String(node.id).trim()
-              : ''
-          const normRowId =
-            node.rowId !== undefined && node.rowId !== null
-              ? String(node.rowId).trim()
-              : node.rowid !== undefined && node.rowid !== null
-              ? String(node.rowid).trim()
-              : ''
-          const normParent =
-            node.parentId !== undefined && node.parentId !== null
-              ? String(node.parentId).trim()
-              : ''
-          const normNumber =
-            node.number !== undefined && node.number !== null
-              ? String(node.number).trim()
-              : ''
-          const normName =
-            node.name !== undefined && node.name !== null
-              ? String(node.name).trim()
-              : ''
-          const comboKey = `p:${normParent}|num:${normNumber}|name:${normName}`
-
-          // 先用 id 去重
-          if (normId && seenIds.has(normId)) {
-            continue
-          }
-          // 其次用 rowId/rowid 去重
-          if (!normId && normRowId && seenRowIds.has(normRowId)) {
-            continue
-          }
-          // 再用组合字段去重(处理不同 id 但显示相同的重复)
-          if (!normId && !normRowId && seenCombo.has(comboKey)) {
-            continue
-          }
-          if (normId) {
-            seenIds.add(normId)
-          } else if (normRowId) {
-            seenRowIds.add(normRowId)
-          } else {
-            seenCombo.add(comboKey)
-          }
-
-          const next = {
-            ...node,
-            id: normId || node.id,
-            rowId: normRowId || node.rowId || node.rowid,
-            parentId: normParent || node.parentId,
-            number: normNumber || node.number,
-            name: normName || node.name,
-          }
-          if (
-            Array.isArray(node.costSurveysVos) &&
-            node.costSurveysVos.length > 0
-          ) {
-            next.costSurveysVos = dedupeLevel(node.costSurveysVos)
-          }
-          result.push(next)
-        }
-        return result
-      }
-      return dedupeLevel(list)
-    },
-
     // 统一请求统计数据(接口失败或无数据时使用mock)
     async requestStatistics(params = {}) {
       // 如果组件已销毁,直接返回 mock 数据
@@ -212,7 +148,6 @@ export const comprehensiveMixin = {
         .then((res) => {
           if (!this.isDestroyed && res && res.value) {
             this.projectOptions = res.value
-            console.log('项目列表:', this.projectOptions)
           }
         })
         .catch((e) => {
@@ -309,25 +244,16 @@ export const comprehensiveMixin = {
       return trendArr
     },
 
-    // 将 costSurveysList 汇总为构成数据 [{name, value}](叶子求和
+    // 将 costSurveysList 汇总为构成数据 [{name, value}](显示所有surveysVos
     transformCompositionFromCostList(costSurveysList = []) {
       const result = []
       const dfs = (node) => {
         if (!node) return
-        if (Array.isArray(node.costSurveysVos) && node.costSurveysVos.length) {
-          node.costSurveysVos.forEach(dfs)
-        } else {
-          const total = Array.isArray(node.surveysVos)
-            ? node.surveysVos.reduce(
-                (sum, sv) => sum + (Number(sv.value) || 0),
-                0
-              )
-            : 0
-          result.push({
-            name: node.name,
-            value: total,
-          })
-        }
+        result.push({
+          name: node.name,
+          value: node.rvalue,
+          surveysVos: node.svsurveysVos,
+        })
       }
       costSurveysList.forEach(dfs)
       return result
@@ -519,7 +445,23 @@ export const comprehensiveMixin = {
         tooltip: {
           show: true,
           trigger: 'item',
-          formatter: (p) => `${p.name}: ${p.value} (${p.percent}%)`,
+          formatter: (p) => {
+            let tooltipContent = `${p.name}: ${p.value} (${p.percent}%)`
+            // 如果有surveysVos信息,显示完整的surveysVos
+            if (p.data && p.data.surveysVos) {
+              const surveysVos = p.data.surveysVos
+              tooltipContent += '<br/>'
+              tooltipContent += `年份: ${surveysVos.name || ''}<br/>`
+              tooltipContent += `数值: ${surveysVos.value || ''}<br/>`
+              // 如果有其他属性,也可以显示
+              for (const key in surveysVos) {
+                if (key !== 'name' && key !== 'value') {
+                  tooltipContent += `${key}: ${surveysVos[key]}<br/>`
+                }
+              }
+            }
+            return tooltipContent
+          },
         },
         legend: {
           show: true,

+ 153 - 22
src/views/costAudit/baseInfo/statistics/industryAnalysis.vue

@@ -16,6 +16,7 @@
                 filterable
                 allow-create
                 default-first-option
+                @change="handleLeftProjectChange"
               >
                 <el-option
                   v-for="item in projectOptions"
@@ -157,6 +158,7 @@
                 filterable
                 allow-create
                 default-first-option
+                @change="handleRightProjectChange"
               >
                 <el-option
                   v-for="item in projectOptions"
@@ -1101,20 +1103,21 @@
           }
           const dataSource =
             res && res.costSurveysList && res.costSurveysList.length ? res : []
-          // 接口数据去重(按 id)
-          const dedupedList = this.dedupeCostSurveysList(
-            dataSource.costSurveysList || []
-          )
+          // 保留接口返回的原始列表,不再去重
           const normalizedDataSource = {
             ...dataSource,
-            costSurveysList: dedupedList,
+            costSurveysList: dataSource.costSurveysList || [],
           }
           // 保存数据源
           this.leftDataSource = normalizedDataSource
           this.rightDataSource = normalizedDataSource
           // 构建左右侧指标树结构
-          this.leftDataItems = this.buildIndicatorTree(dedupedList)
-          this.rightDataItems = this.buildIndicatorTree(dedupedList)
+          this.leftDataItems = this.buildIndicatorTree(
+            normalizedDataSource.costSurveysList
+          )
+          this.rightDataItems = this.buildIndicatorTree(
+            normalizedDataSource.costSurveysList
+          )
           // 设置默认选中状态(左侧与 history 页一致)
           this.$nextTick(() => {
             this.setLeftDefaultSelection()
@@ -1147,6 +1150,132 @@
         }
       },
 
+      // 左侧项目选择变化处理方法
+      handleLeftProjectChange() {
+        // 清空之前的选择
+        this.leftSearchForm.auditedUnitId = ''
+        this.leftSearchForm.auditedUnitName = ''
+        this.leftSearchForm.startYear = ''
+        this.leftSearchForm.endYear = ''
+
+        // 当选择了项目时,根据项目信息自动填充其他字段
+        if (this.leftSearchForm.projectId) {
+          // 通过projectId找到对应的项目信息
+          const selectedProject = this.projectOptions.find(
+            (item) => item.projectId === this.leftSearchForm.projectId
+          )
+
+          if (selectedProject) {
+            // 设置项目名称
+            this.leftSearchForm.projectName = selectedProject.projectName || ''
+
+            // 处理被监审单位
+            if (selectedProject.auditedUnitId) {
+              // 将字符串分割为数组并过滤空值
+              const unitIdArray = selectedProject.auditedUnitId
+                .split(',')
+                .map((id) => id.trim())
+                .filter(Boolean)
+
+              // 如果只有一个被监审单位,直接选中
+              if (unitIdArray.length === 1) {
+                this.leftSearchForm.auditedUnitId = unitIdArray[0]
+                this.leftSearchForm.auditedUnitName =
+                  this.auditedUnitOptions.find(
+                    (item) => item.unitId === unitIdArray[0]
+                  )?.unitName || ''
+              }
+            }
+
+            // 处理监审期间
+            if (selectedProject.auditPeriod) {
+              // 将auditPeriod字符串分割为年份数组
+              const yearArray = selectedProject.auditPeriod
+                .split(',')
+                .map((yearStr) => {
+                  const trimmed = yearStr.trim()
+                  return isNaN(parseInt(trimmed)) ? null : parseInt(trimmed)
+                })
+                .filter((year) => year !== null)
+
+              if (yearArray.length > 0) {
+                // 计算起止年份
+                this.leftSearchForm.startYear = Math.min(
+                  ...yearArray
+                ).toString()
+                this.leftSearchForm.endYear = Math.max(...yearArray).toString()
+              }
+            }
+          }
+        } else {
+          // 当项目ID为空时,清空项目名称
+          this.leftSearchForm.projectName = ''
+        }
+      },
+
+      // 右侧项目选择变化处理方法
+      handleRightProjectChange() {
+        // 清空之前的选择
+        this.rightSearchForm.auditedUnitId = ''
+        this.rightSearchForm.auditedUnitName = ''
+        this.rightSearchForm.startYear = ''
+        this.rightSearchForm.endYear = ''
+
+        // 当选择了项目时,根据项目信息自动填充其他字段
+        if (this.rightSearchForm.projectId) {
+          // 通过projectId找到对应的项目信息
+          const selectedProject = this.projectOptions.find(
+            (item) => item.projectId === this.rightSearchForm.projectId
+          )
+
+          if (selectedProject) {
+            // 设置项目名称
+            this.rightSearchForm.projectName = selectedProject.projectName || ''
+
+            // 处理被监审单位
+            if (selectedProject.auditedUnitId) {
+              // 将字符串分割为数组并过滤空值
+              const unitIdArray = selectedProject.auditedUnitId
+                .split(',')
+                .map((id) => id.trim())
+                .filter(Boolean)
+
+              // 如果只有一个被监审单位,直接选中
+              if (unitIdArray.length === 1) {
+                this.rightSearchForm.auditedUnitId = unitIdArray[0]
+                this.rightSearchForm.auditedUnitName =
+                  this.auditedUnitOptions.find(
+                    (item) => item.unitId === unitIdArray[0]
+                  )?.unitName || ''
+              }
+            }
+
+            // 处理监审期间
+            if (selectedProject.auditPeriod) {
+              // 将auditPeriod字符串分割为年份数组
+              const yearArray = selectedProject.auditPeriod
+                .split(',')
+                .map((yearStr) => {
+                  const trimmed = yearStr.trim()
+                  return isNaN(parseInt(trimmed)) ? null : parseInt(trimmed)
+                })
+                .filter((year) => year !== null)
+
+              if (yearArray.length > 0) {
+                // 计算起止年份
+                this.rightSearchForm.startYear = Math.min(
+                  ...yearArray
+                ).toString()
+                this.rightSearchForm.endYear = Math.max(...yearArray).toString()
+              }
+            }
+          }
+        } else {
+          // 当项目ID为空时,清空项目名称
+          this.rightSearchForm.projectName = ''
+        }
+      },
+
       // 左侧查询按钮点击事件
       async handleLeftQuery() {
         // 如果组件已销毁,不执行查询
@@ -1155,6 +1284,8 @@
         }
         try {
           this.loading = true
+          // 查询前清空选中,保持与 history 页一致的“重新默认选中”逻辑
+          this.leftSelectedItems = []
           // 根据左侧查询条件获取数据
           if (this.leftSearchForm.projectId) {
             this.leftSearchForm.projectName =
@@ -1167,10 +1298,10 @@
           if (this.leftSearchForm.auditedUnitId) {
             this.leftSearchForm.auditedUnitName =
               this.auditedUnitOptions.find(
-                (item) => item.unitId === this.leftSearchForm.unitId
+                (item) => item.unitId === this.leftSearchForm.auditedUnitId
               )?.unitName || ''
           } else {
-            this.leftSearchForm.unitName = ''
+            this.leftSearchForm.auditedUnitName = ''
           }
           // 构建查询参数
           const params = {
@@ -1183,18 +1314,17 @@
           }
           const dataSource =
             res && res.costSurveysList && res.costSurveysList.length ? res : []
-          // 接口数据去重(按 id)
-          const dedupedList = this.dedupeCostSurveysList(
-            dataSource.costSurveysList || []
-          )
+          // 保留接口返回的原始列表,不再去重
           const normalizedDataSource = {
             ...dataSource,
-            costSurveysList: dedupedList,
+            costSurveysList: dataSource.costSurveysList || [],
           }
           // 保存左侧数据源
           this.leftDataSource = normalizedDataSource
           // 更新左侧指标树结构
-          this.leftDataItems = this.buildIndicatorTree(dedupedList)
+          this.leftDataItems = this.buildIndicatorTree(
+            normalizedDataSource.costSurveysList
+          )
           this.$nextTick(() => {
             this.setLeftDefaultSelection()
           })
@@ -1224,6 +1354,8 @@
         }
         try {
           this.loading = true
+          // 查询前清空选中,保持与 history 页一致的“重新默认选中”逻辑
+          this.rightSelectedItems = []
           // 根据右侧查询条件获取数据
           if (this.rightSearchForm.projectId) {
             this.rightSearchForm.projectName =
@@ -1236,7 +1368,7 @@
           if (this.rightSearchForm.auditedUnitId) {
             this.rightSearchForm.auditedUnitName =
               this.auditedUnitOptions.find(
-                (item) => item.unitId === this.rightSearchForm.unitId
+                (item) => item.unitId === this.rightSearchForm.auditedUnitId
               )?.unitName || ''
           } else {
             this.rightSearchForm.auditedUnitName = ''
@@ -1252,18 +1384,17 @@
           }
           const dataSource =
             res && res.costSurveysList && res.costSurveysList.length ? res : []
-          // 接口数据去重(按 id)
-          const dedupedList = this.dedupeCostSurveysList(
-            dataSource.costSurveysList || []
-          )
+          // 保留接口返回的原始列表,不再去重
           const normalizedDataSource = {
             ...dataSource,
-            costSurveysList: dedupedList,
+            costSurveysList: dataSource.costSurveysList || [],
           }
           // 保存右侧数据源
           this.rightDataSource = normalizedDataSource
           // 更新右侧指标树结构
-          this.rightDataItems = this.buildIndicatorTree(dedupedList)
+          this.rightDataItems = this.buildIndicatorTree(
+            normalizedDataSource.costSurveysList
+          )
           // 校验原选中项;无效则清空
           if (this.rightSelectedItems.length > 0) {
             const selectedId = this.rightSelectedItems[0].id