Bläddra i källkod

Merge branch 'master' of http://1.71.9.215:3000/feiyi/cbjsxt-front-master

15110620229@163.com 2 veckor sedan
förälder
incheckning
8c9c23c93e

+ 47 - 4
src/views/costAudit/auditInfo/completedSupervisionQuery/index.vue

@@ -148,11 +148,20 @@
     <taskInfo ref="taskInfo" />
     <cbjs-info
       :id="cbjsInfoData && cbjsInfoData.id"
+      :selected-project="cbjsInfoData"
       :visible.sync="cbjsInfoVisible"
       :current-node="cbjsInfoData && cbjsInfoData.currentNode"
       :current-status="cbjsInfoData && cbjsInfoData.status"
     />
     <taskDetail ref="taskDetail" />
+    <!-- 成本监审任务制定弹窗(用于“任务详情”只读查看) -->
+    <task-customized-release-dialog
+      :visible.sync="taskReleaseDialogVisible"
+      :project="project"
+      :is-view="true"
+      @backToList="taskReleaseDialogVisible = false"
+      @close="taskReleaseDialogVisible = false"
+    />
   </div>
 </template>
 
@@ -162,12 +171,15 @@
   import taskInfo from '@/components/task/taskInfo.vue'
   import cbjsInfo from '@/components/task/cbjsInfo.vue'
   import taskDetail from '@/components/task/taskDetail.vue'
+  import TaskCustomizedReleaseDialog from '@/components/task/TaskCustomizedReleaseDialog.vue'
+  import { getCostProjectDetail } from '@/api/taskCustomizedRelease.js'
   export default {
     name: 'CompletedSupervisionQuery',
     components: {
       taskDetail,
       taskInfo,
       cbjsInfo,
+      TaskCustomizedReleaseDialog,
     },
     data() {
       return {
@@ -195,6 +207,8 @@
         // cbjsInfo弹窗相关
         cbjsInfoVisible: false,
         cbjsInfoData: null,
+        // 任务详情(项目)弹窗
+        taskReleaseDialogVisible: false,
       }
     },
     created() {
@@ -330,12 +344,41 @@
         }
       },
 
+      // // 查看任务详情
+      // handleViewTaskDetail(row) {
+      //   // this.selectedTask = row
+      //   // this.activeTab = 'detail'
+      //   // this.showTaskDetail = true
+      //   this.$refs.taskDetail.open(row, 'chengben')
+      // },
+
       // 查看任务详情
       handleViewTaskDetail(row) {
-        // this.selectedTask = row
-        // this.activeTab = 'detail'
-        // this.showTaskDetail = true
-        this.$refs.taskDetail.open(row, 'chengben')
+        // 使用成本监审任务制定弹窗(只读)
+        this.openTaskReleaseDialog(row)
+      },
+      // 打开成本监审任务制定弹窗(只读查看)
+      openTaskReleaseDialog(row) {
+        if (!row) return
+        const projectId =
+          row.projectId || row.projectID || row.id || row.taskId || ''
+        if (!projectId) {
+          this.$message &&
+            this.$message.warning &&
+            this.$message.warning('缺少项目ID,无法查看详情')
+          return
+        }
+        this.isView = true
+        getCostProjectDetail({ id: projectId })
+          .then((res) => {
+            this.project = (res && res.value) || {}
+            this.taskReleaseDialogVisible = true
+          })
+          .catch(() => {
+            // 回退:接口失败时至少展示当前行数据
+            this.project = row || {}
+            this.taskReleaseDialogVisible = true
+          })
       },
 
       // 切换视图

+ 127 - 184
src/views/costAudit/baseInfo/catalogManage/surveyDialog.vue

@@ -67,52 +67,50 @@
               style="width: 100%"
               :row-class-name="getFixedPreviewRowClass"
             >
-              <el-table-column label="序号" width="80" align="center">
+              <!-- <el-table-column label="序号" width="80" align="center">
                 <template slot-scope="scope">
                   {{ scope.row._displaySeq || '-' }}
                 </template>
-              </el-table-column>
-              <!-- <el-table-column label="项目" min-width="200" align="left">
-                <template slot-scope="scope">
-                  <span
-                    :class="[
-                      'table-item-text',
-                      scope.row._isCategory ? 'category-name' : '',
-                    ]"
-                    :style="{ paddingLeft: `${scope.row._indentLevel * 20}px` }"
-                  >
-                    {{ scope.row._displayName || '-' }}
-                  </span>
-                </template>
-              </el-table-column>
-              <el-table-column label="单位" width="100" align="center">
-                <template slot-scope="scope">
-                  <span v-if="!scope.row._isCategory">
-                    {{ scope.row._displayUnit || '-' }}
-                  </span>
-                </template>
               </el-table-column> -->
+
+              <!-- 动态生成 fixedFields 中的列 -->
               <el-table-column
-                v-for="column in fixedTableValueColumns"
-                :key="column.key"
-                :label="column.label"
-                min-width="120"
+                v-for="field in contentEditForm.fixedTable.fixedTablesTitle"
+                :key="field.rkey"
+                :label="field.rkey"
+                min-width="150"
                 align="center"
+                :prop="field.rkey"
               >
                 <template slot-scope="scope">
-                  <el-input
-                    v-if="!scope.row._isCategory"
-                    :value="scope.row._displayValues[column.key] || ''"
-                    :placeholder="column.placeholder"
-                    disabled
-                  />
+                  <!-- 显示内容 -->
+                  <span v-if="scope.row[field.rkey] !== undefined">
+                    {{ scope.row[field.rkey] || '-' }}
+                  </span>
+                  <span
+                    v-else-if="
+                      scope.row.fixedValues &&
+                      scope.row.fixedValues[field.rkey] !== undefined
+                    "
+                  >
+                    {{ scope.row.fixedValues[field.rkey] || '-' }}
+                  </span>
+                  <span
+                    v-else-if="
+                      scope.row._displayValues &&
+                      scope.row._displayValues[field.rkey] !== undefined
+                    "
+                  >
+                    {{ scope.row._displayValues[field.rkey] || '-' }}
+                  </span>
+                  <span v-else>
+                    {{ '-' }}
+                  </span>
                 </template>
               </el-table-column>
-              <el-table-column label="备注" min-width="160" align="left">
+
+              <!-- <el-table-column label="备注" min-width="160" align="left">
                 <template slot-scope="scope">
-                  <!-- <span v-if="!scope.row._isCategory">
-                    {{ scope.row._displayRemark || '-' }}
-                  </span> -->
                   <el-input
                     v-if="!scope.row._isCategory"
                     :value="scope.row._displayRemark || ''"
@@ -120,7 +118,7 @@
                     disabled
                   />
                 </template>
-              </el-table-column>
+              </el-table-column> -->
               <!-- <el-table-column label="指标编号" width="120" align="center">
                 <template slot-scope="scope">
                   <span v-if="!scope.row._isCategory">
@@ -415,92 +413,26 @@
         }
         return Array.from(labels)
       },
-      fixedTableValueColumns() {
-        const auditYears = this.auditPeriodYears
-        const candidateLabels = this.fixedTableColumnCandidates
-        const usedLabels = new Set()
-        const resultColumns = []
-        const extractYear = (label) => {
-          if (!label) return ''
-          const match = String(label).match(/(19|20)\d{2}/)
-          return match ? match[0] : ''
-        }
-        const buildColumn = ({ key, label, placeholder, candidates }) => ({
-          key,
-          label,
-          placeholder,
-          candidates,
-        })
-
-        auditYears.forEach((year) => {
-          const matchLabel =
-            candidateLabels.find((label) => {
-              const normalized = extractYear(label)
-              return normalized && normalized === String(year)
-            }) || ''
-          const displayLabel = matchLabel || `${year}年`
-          const columnKey = `year-${year}`
-          usedLabels.add(matchLabel)
-          resultColumns.push(
-            buildColumn({
-              key: columnKey,
-              label: displayLabel,
-              placeholder: `请输入${displayLabel}数据`,
-              candidates: [
-                matchLabel,
-                displayLabel,
-                `${year}年`,
-                `${year}年度`,
-                `${year}`,
-                `year_${year}`,
-              ].filter(Boolean),
-            })
-          )
-        })
-
-        candidateLabels.forEach((label) => {
-          if (!label || usedLabels.has(label)) {
-            return
-          }
-          if (
-            ['序号', '项目', '指标编号', '计算公式', '单位', '备注'].includes(
-              label
-            )
-          ) {
-            return
-          }
-          resultColumns.push(
-            buildColumn({
-              key: `col-${label}`,
-              label,
-              placeholder: `请输入${label}`,
-              candidates: [label],
-            })
-          )
-          usedLabels.add(label)
-        })
-
-        return resultColumns
-      },
       fixedTableDisplayData() {
         const rows =
-          (this.contentEditForm &&
-            this.contentEditForm.fixedTable &&
+          (this.contentEditForm.fixedTable &&
             this.contentEditForm.fixedTable.fixedTables) ||
           []
-        if (!Array.isArray(rows) || rows.length === 0) {
-          return []
-        }
+        if (!rows.length) return []
 
-        const normalizeId = (val) => {
-          if (val === undefined || val === null) return ''
-          return String(val)
+        const normalizeId = (id) => {
+          if (id === undefined || id === null) return ''
+          return String(id).trim()
         }
 
+        // 创建行ID到父ID的映射
         const parentMap = {}
+        const childMap = {}
+
         rows.forEach((row, index) => {
           const rowId = normalizeId(row.rowid || row.itemId || index)
           const parentId = row.parentid
+
           if (
             parentId !== undefined &&
             parentId !== null &&
@@ -514,7 +446,7 @@
           }
         })
 
-        const childMap = {}
+        // 创建子项映射
         Object.keys(parentMap).forEach((rowId) => {
           const parentId = parentMap[rowId]
           if (parentId) {
@@ -525,27 +457,24 @@
           }
         })
 
+        // 计算缩进级别
         const computedLevels = {}
         const getLevel = (rowId, depth = 0) => {
           if (!rowId) return 0
-          if (computedLevels[rowId] !== undefined) {
-            return computedLevels[rowId]
-          }
-          if (depth > rows.length) {
-            return 0
-          }
+          if (computedLevels[rowId] !== undefined) return computedLevels[rowId]
+          if (depth > rows.length) return 0
+
           const parentId = parentMap[rowId]
           if (!parentId) {
             computedLevels[rowId] = 0
             return 0
           }
+
           const level = 1 + getLevel(parentId, depth + 1)
           computedLevels[rowId] = level
           return level
         }
 
-        const columnDefs = this.fixedTableValueColumns || []
-
         return rows.map((row, index) => {
           const rowId = normalizeId(row.rowid || row.itemId || index)
           const fixedValues = row.fixedValues || {}
@@ -555,14 +484,29 @@
             row.orderNum ||
             row.seq ||
             ''
-          const displayName =
-            fixedValues['项目'] ||
-            fixedValues['项目名称'] ||
-            row.itemName ||
-            row.projectName ||
-            ''
-          const displayUnit = fixedValues['单位'] || row.unit || ''
-          const displayRemark = fixedValues['备注'] || row.remark || ''
+
+          // 获取所有字段的显示值
+          const displayValues = { ...fixedValues }
+
+          // 确保所有fixedFields中的字段都有值
+          const fixedFields =
+            this.contentEditForm.fixedTable.fixedTablesTitle || []
+          fixedFields.forEach((field) => {
+            const fieldName = field.rkey
+            if (displayValues[fieldName] === undefined) {
+              displayValues[fieldName] = ''
+            }
+          })
+
+          // 设置默认显示名称(使用第一个非序号字段)
+          let displayName = ''
+          const nonSeqField = fixedFields.find((f) => f.rkey !== '序号')
+          if (nonSeqField) {
+            displayName = displayValues[nonSeqField.rkey] || ''
+          }
+
+          const displayUnit = displayValues['单位'] || row.unit || ''
+          const displayRemark = displayValues['备注'] || row.remark || ''
           const hasChildren = !!childMap[rowId]
           const isChild =
             row.isChild ||
@@ -572,62 +516,21 @@
               row.parentid !== '' &&
               row.parentid !== '-1' &&
               row.parentid !== -1)
-          const isCategory =
-            row.isCategory === true || (!isChild && hasChildren)
-
-          const displayValues = {}
-          columnDefs.forEach((column) => {
-            let value = ''
-            const candidates = column.candidates || []
-            for (let i = 0; i < candidates.length; i += 1) {
-              const candidate = candidates[i]
-              if (!candidate) continue
-              if (
-                fixedValues[candidate] !== undefined &&
-                fixedValues[candidate] !== null &&
-                fixedValues[candidate] !== ''
-              ) {
-                value = fixedValues[candidate]
-                break
-              }
-              if (
-                row[candidate] !== undefined &&
-                row[candidate] !== null &&
-                row[candidate] !== ''
-              ) {
-                value = row[candidate]
-                break
-              }
-              const altKey = String(candidate).replace(/年|年度/g, '')
-              if (
-                altKey &&
-                fixedValues[altKey] !== undefined &&
-                fixedValues[altKey] !== null &&
-                fixedValues[altKey] !== ''
-              ) {
-                value = fixedValues[altKey]
-                break
-              }
-            }
-            displayValues[column.key] = value
-          })
-
-          const remarkValue =
-            fixedValues['备注'] !== undefined && fixedValues['备注'] !== null
-              ? fixedValues['备注']
-              : displayRemark
+          const level = getLevel(rowId)
+          const indentLevel = Math.min(level, 5)
+          const isCategory = hasChildren || isChild
 
           return {
             ...row,
-            _rowId: rowId,
             _displaySeq: displaySeq,
             _displayName: displayName,
             _displayUnit: displayUnit,
-            _displayRemark: remarkValue,
+            _displayRemark: displayRemark,
+            _displayValues: displayValues,
             _hasChildren: hasChildren,
             _isCategory: isCategory,
-            _indentLevel: getLevel(rowId),
-            _displayValues: displayValues,
+            _indentLevel: indentLevel,
+            _rowId: rowId,
           }
         })
       },
@@ -692,6 +595,7 @@
        * @param {Object} responseData - listByCurrentTemplateId接口返回的数据
        */
       parseAndDisplayFixedTableData(responseData) {
+        // 解析fixedFields
         if (responseData.value.fixedFields) {
           this.contentEditForm.fixedTable.fixedTablesTitle =
             this.stringToObjects(responseData.value.fixedFields || '')
@@ -702,10 +606,11 @@
           this.contentEditForm.fixedTable.fixedTablesTitle =
             this.stringToObjects(fixedFields || '')
         }
+
         const fixedTitles = this.contentEditForm.fixedTable.fixedTablesTitle
-        this.contentEditForm.fixedTable.fixedTableHeaders = fixedTitles.filter(
-          (title) => title.rkey !== '序号'
-        )
+        // 保留所有字段,包括序号
+        this.contentEditForm.fixedTable.fixedTableHeaders = [...fixedTitles]
+
         if (
           !responseData ||
           !responseData.value ||
@@ -721,12 +626,14 @@
         this.contentEditForm.fixedTable.fixedTables = []
 
         // 遍历itemList,为每个项目创建一行数据
-        itemList.forEach((item, index) => {
+        itemList.forEach((item) => {
           // 判断是否为子项(parentid不为-1且不为"-1")
           const isSubItem =
             item.parentid && item.parentid !== -1 && item.parentid !== '-1'
 
+          // 创建新行数据
           const newRow = {
+            ...item, // 首先展开所有原始字段
             orderText: item.orderNum || '', // 显示用序号
             orderNum: item.orderNum || '', // 保留原始序号用于发送后端
             surveyTemplateId: item.surveyTemplateId,
@@ -741,6 +648,7 @@
             isSubItem: isSubItem,
             rowid: item.rowid || this.generateUUID(),
             jsonstr: item.jsonstr || null,
+            remark: item.remark || '', // 添加备注字段
           }
 
           // 确保orderNum是数字类型
@@ -750,7 +658,17 @@
 
           // 初始化fixedValues并填充实际值
           fixedTitles.forEach((title) => {
-            newRow.fixedValues[title.rkey] = item[title.rkey] || ''
+            // 优先从item中获取值,如果没有则从其他可能的位置获取
+            const fieldValue =
+              item[title.rkey] !== undefined
+                ? item[title.rkey]
+                : item.fixedValues && item.fixedValues[title.rkey] !== undefined
+                ? item.fixedValues[title.rkey]
+                : ''
+
+            // 处理可能的null或undefined值
+            newRow.fixedValues[title.rkey] =
+              fieldValue !== undefined && fieldValue !== null ? fieldValue : ''
           })
 
           allRows.push(newRow)
@@ -865,20 +783,45 @@
       flattenHierarchy(rows) {
         const sortedRows = []
         const parentMap = {}
+        const rowMap = {}
+
+        // 首先将所有行添加到rowMap中,方便后续查找
         rows.forEach((row) => {
+          rowMap[row.rowid] = row
           parentMap[row.parentid] = parentMap[row.parentid] || []
           parentMap[row.parentid].push(row)
         })
-        function addRows(parentId) {
+
+        // 递归添加行,并设置层级信息
+        function addRows(parentId, level = 0) {
           if (parentMap[parentId]) {
             parentMap[parentId].forEach((row) => {
+              // 设置层级信息
+              row._level = level
+              row._isCategory = true // 标记为分类(父级)
+
+              // 确保子项的父级也被标记为分类
+              if (row.parentid && row.parentid !== -1 && rowMap[row.parentid]) {
+                rowMap[row.parentid]._isCategory = true
+              }
+
               sortedRows.push(row)
-              addRows(row.rowid)
+              // 递归添加子项
+              addRows(row.rowid, level + 1)
             })
           }
         }
+
+        // 从顶级(parentid为-1或undefined)开始添加
         addRows(-1)
-        return sortedRows
+
+        // 确保所有行都有必要的属性
+        return sortedRows.map((row) => ({
+          ...row,
+          _isCategory: row._isCategory || false,
+          _level: row._level || 0,
+          _hasChildren: parentMap[row.rowid] && parentMap[row.rowid].length > 0,
+        }))
       },
       // 字符串转对象数组
       stringToObjects(str) {

+ 3 - 3
src/views/costAudit/baseInfo/statistics/components/TaskCustomizedReleaseDialog.vue

@@ -101,7 +101,7 @@
 
           <!-- 报送资料要求 -->
           <el-tab-pane label="报送资料要求" name="material">
-            <materialTab :project="project" :is-view="isView" />
+            <MaterialTab :project="project" :is-view="isView" />
           </el-tab-pane>
 
           <!-- 成本调查表 -->
@@ -138,7 +138,7 @@
 <script>
   import UploadComponent from '@/components/costAudit/UploadComponent.vue'
   import basicInfoTab from './BasicInfoTab.vue'
-  import materialTab from './materialTab.vue'
+  import MaterialTab from './materialTab.vue'
   import surveyTab from './surveyTab.vue'
   import workflowTab from './workflowTab.vue'
   import auditNoticeTab from './auditNoticeTab.vue'
@@ -153,7 +153,7 @@
     components: {
       UploadComponent,
       basicInfoTab,
-      materialTab,
+      MaterialTab,
       surveyTab,
       workflowTab,
       auditNoticeTab,

+ 33 - 4
src/views/costAudit/baseInfo/statistics/comprehensiveQuery.vue

@@ -33,12 +33,28 @@
           ></el-date-picker>
         </el-form-item>
         <el-form-item label="被监审单位:">
-          <el-input
+          <!-- <el-input
             v-model="searchForm.auditedUnitName"
             placeholder="请输入被监审单位"
             style="width: 200px"
             clearable
-          ></el-input>
+          ></el-input> -->
+          <el-select
+            v-model="searchForm.auditedUnitId"
+            placeholder="请选择被监审单位"
+            style="width: 200px"
+            clearable
+            filterable
+            allow-create
+            default-first-option
+          >
+            <el-option
+              v-for="item in auditedUnitOptions"
+              :key="item.unitId"
+              :label="item.unitName"
+              :value="item.unitId"
+            ></el-option>
+          </el-select>
         </el-form-item>
         <el-form-item label="立项年度:">
           <el-date-picker
@@ -228,7 +244,7 @@
   import TaskCustomizedReleaseDialog from '@/components/task/TaskCustomizedReleaseDialog.vue'
   import cbjsInfo from './components/cbjsInfo.vue'
   import { getCostProjectDetail } from '@/api/taskCustomizedRelease.js'
-
+  import { getAllUnitList } from '@/api/auditEntityManage.js'
   export default {
     name: 'ComprehensiveQuery',
     components: {
@@ -246,7 +262,7 @@
           projectName: '',
           startYear: '',
           endYear: '',
-          auditedUnitName: '',
+          auditedUnitId: '',
           year: '',
         },
         // 表格数据
@@ -268,12 +284,25 @@
         cbjsInfoVisible: false,
         cbjsInfoData: null,
         loading: false,
+        auditedUnitOptions: [],
       }
     },
     mounted() {
+      this.getOptions()
       this.handleQuery()
     },
     methods: {
+      getOptions() {
+        getAllUnitList()
+          .then((res) => {
+            if (res && res.value) {
+              this.auditedUnitOptions = res.value
+            }
+          })
+          .catch((e) => {
+            console.warn('获取单位列表失败', e)
+          })
+      },
       // 加载项目列表(优化分页数据处理)
       async handleQuery() {
         try {

+ 55 - 2
src/views/costAudit/baseInfo/statistics/historyAnalysis.vue

@@ -11,6 +11,7 @@
           filterable
           allow-create
           default-first-option
+          @change="handleProjectChange"
         >
           <el-option
             v-for="item in projectOptions"
@@ -29,9 +30,10 @@
           filterable
           allow-create
           default-first-option
+          :disabled="!searchForm.projectId"
         >
           <el-option
-            v-for="item in auditedUnitOptions"
+            v-for="item in projectAuditedUnitOptions"
             :key="item.unitId"
             :label="item.unitName"
             :value="item.unitId"
@@ -187,6 +189,8 @@
         selectedIndicators: [],
         // 原始数据源(用于过滤)
         rawDataSource: null,
+        // 项目被监审单位选项
+        projectAuditedUnitOptions: [],
         // 分页相关属性
         trendTotalPages: 0,
         trendCurrentPage: 1,
@@ -206,7 +210,7 @@
     },
     mounted() {
       this.initCharts()
-      this.updateChartData()
+      // this.updateChartData()
     },
     beforeDestroy() {
       // 组件销毁时停止轮播,避免内存泄漏
@@ -214,6 +218,55 @@
       this.pauseCompositionCarousel()
     },
     methods: {
+      handleProjectChange() {
+        // 清空之前的选择
+        this.searchForm.auditedUnitId = ''
+        this.searchForm.auditedUnitName = ''
+        this.searchForm.startYear = ''
+        this.searchForm.endYear = ''
+        this.projectAuditedUnitOptions = []
+
+        if (this.searchForm.projectId) {
+          // 获取项目的被监审单位,监审期间
+          const selectedProject = this.projectOptions.find(
+            (item) => item.projectId === this.searchForm.projectId
+          )
+
+          if (selectedProject) {
+            // 设置被监审单位选项
+            if (selectedProject.auditedUnitId) {
+              const unit = selectedProject.auditedUnitId.split(',')
+              this.auditedUnitOptions.forEach((item) => {
+                if (unit.includes(item.unitId)) {
+                  this.projectAuditedUnitOptions.push(item)
+                }
+              })
+            }
+
+            // 设置监审期间
+            if (selectedProject.auditPeriod) {
+              if (typeof selectedProject.auditPeriod === 'string') {
+                const auditPeriod = selectedProject.auditPeriod
+                  .split(',')
+                  .map((year) => year.trim())
+                // 转换为数字并过滤无效年份
+                const yearNumbers = auditPeriod
+                  .map((year) => parseInt(year, 10))
+                  .filter((year) => !isNaN(year) && year > 0)
+
+                if (yearNumbers.length > 0) {
+                  // 计算最小和最大年份
+                  const start = Math.min(...yearNumbers)
+                  const end = Math.max(...yearNumbers)
+                  // 确保赋值为字符串类型
+                  this.searchForm.startYear = start.toString()
+                  this.searchForm.endYear = end.toString()
+                }
+              }
+            }
+          }
+        }
+      },
       // 初始化图表
       initCharts() {
         this.initTrendChart()

+ 1 - 0
src/views/costAudit/baseInfo/statistics/index.js

@@ -212,6 +212,7 @@ export const comprehensiveMixin = {
         .then((res) => {
           if (!this.isDestroyed && res && res.value) {
             this.projectOptions = res.value
+            console.log('项目列表:', this.projectOptions)
           }
         })
         .catch((e) => {

+ 88 - 86
src/views/costAudit/baseInfo/statistics/industryAnalysis.vue

@@ -92,31 +92,17 @@
             <div class="custom-list">
               <div class="list-header">项目</div>
               <div class="list-content">
-                <div v-if="leftDataItems && leftDataItems.length > 0">
-                  <div v-for="item in leftDataItems" :key="item.id">
-                    <div
-                      class="list-item level-0"
-                      :class="{ selected: isSelected(item.id, 'left') }"
-                      @click="selectItem(item.id, 'left')"
-                    >
-                      <span class="item-label">{{ item.label }}</span>
-                    </div>
-                    <div
-                      v-if="item.children && item.children.length > 0"
-                      class="list-children"
-                    >
-                      <div
-                        v-for="child in item.children"
-                        :key="child.id"
-                        class="list-item level-1"
-                        :class="{ selected: isSelected(child.id, 'left') }"
-                        @click="selectItem(child.id, 'left')"
-                      >
-                        <span class="item-label">{{ child.label }}</span>
-                      </div>
-                    </div>
-                  </div>
-                </div>
+                <el-tree
+                  v-if="leftDataItems && leftDataItems.length > 0"
+                  ref="leftIndicatorTree"
+                  class="indicator-tree"
+                  :data="leftDataItems"
+                  show-checkbox
+                  node-key="id"
+                  :props="treeProps"
+                  :check-strictly="true"
+                  @check="handleLeftCheck"
+                ></el-tree>
                 <Empty v-else description="暂无数据"></Empty>
               </div>
             </div>
@@ -354,6 +340,10 @@
         rightProportionAllData: [],
         rightProportionTotalPages: 0,
         rightProportionCurrentPage: 1,
+        treeProps: {
+          children: 'children',
+          label: 'label',
+        },
       }
     },
     computed: {
@@ -422,7 +412,7 @@
       // 初始化图表
       this.initCharts()
       // 加载初始数据
-      this.loadInitialData()
+      // this.loadInitialData()
       // 监听窗口大小变化,调整图表大小
       window.addEventListener('resize', this.handleResize)
     },
@@ -920,6 +910,16 @@
         }
       },
 
+      // 左侧树选中变更
+      handleLeftCheck() {
+        const checkedKeys =
+          this.$refs.leftIndicatorTree?.getCheckedKeys?.() || []
+        this.leftSelectedItems = checkedKeys
+          .map((id) => this.findItemById(id, 'left'))
+          .filter(Boolean)
+        this.updateLeftChartsBySelection()
+      },
+
       // 判断节点是否被选中
       isSelected(id, type = 'left') {
         const selectedItems =
@@ -1060,14 +1060,16 @@
         }
       },
 
-      // 获取树的父级(拥有子节点)id 列表
+      // 获取根节点(parentId 为 -1)的 id 列表与节点列表(与 history 页一致)
       getParentIds(tree = []) {
         const ids = []
         const items = []
         const dfs = (node) => {
-          if (node.children && node.children.length > 0) {
+          if (String(node.parentId) === '-1') {
             ids.push(node.id)
             items.push(node)
+          }
+          if (node.children && node.children.length > 0) {
             node.children.forEach(dfs)
           }
         }
@@ -1075,16 +1077,6 @@
         return { ids, items }
       },
 
-      // 获取根节点(parentId 为 -1 或未定义)的列表
-      getRootItems(tree = []) {
-        return (tree || []).filter(
-          (item) =>
-            item.parentId === '-1' ||
-            item.parentId === null ||
-            item.parentId === undefined
-        )
-      },
-
       // 加载初始数据和树形结构
       async loadInitialData() {
         // 如果组件已销毁,不执行查询
@@ -1123,27 +1115,26 @@
           // 构建左右侧指标树结构
           this.leftDataItems = this.buildIndicatorTree(dedupedList)
           this.rightDataItems = this.buildIndicatorTree(dedupedList)
-          // 设置默认选中状态
-          setTimeout(() => {
-            // 从数据中获取所有父级节点作为默认选中项
-            if (this.leftDataItems && this.leftDataItems.length > 0) {
+          // 设置默认选中状态(左侧与 history 页一致)
+          this.$nextTick(() => {
+            this.setLeftDefaultSelection()
+            if (this.rightDataItems && this.rightDataItems.length > 0) {
               const { items: parentItems } = this.getParentIds(
-                this.leftDataItems
+                this.rightDataItems
               )
-
-              // 设置左右侧默认选中项(单选,优先第一个父级,否则第一个节点)
               const defaultItem =
-                parentItems.length > 0 ? parentItems[0] : this.leftDataItems[0]
-              this.leftSelectedItems = defaultItem ? [defaultItem] : []
+                parentItems.length > 0
+                  ? parentItems[0]
+                  : this.rightDataItems[0] || null
               this.rightSelectedItems = defaultItem ? [defaultItem] : []
-
-              // 更新图表
-              if (!this.isDestroyed) {
-                this.updateLeftChartsBySelection()
-                this.updateRightChartsBySelection()
-              }
+            } else {
+              this.rightSelectedItems = []
+            }
+            if (!this.isDestroyed) {
+              this.updateLeftChartsBySelection()
+              this.updateRightChartsBySelection()
             }
-          }, 100)
+          })
         } catch (error) {
           // 如果是请求中止错误,静默处理
           if (error && error.message && !error.message.includes('aborted')) {
@@ -1204,25 +1195,9 @@
           this.leftDataSource = normalizedDataSource
           // 更新左侧指标树结构
           this.leftDataItems = this.buildIndicatorTree(dedupedList)
-          // 校验原选中项;无效则清空
-          if (this.leftSelectedItems.length > 0) {
-            const selectedId = this.leftSelectedItems[0].id
-            const found = this.findItemById(selectedId, 'left')
-            if (!found) {
-              this.leftSelectedItems = []
-            }
-          }
-          // 若无选中项,默认选中 parentId 为 -1 的根节点(单选),否则用第一个节点
-          if (this.leftSelectedItems.length === 0) {
-            const rootItems = this.getRootItems(this.leftDataItems)
-            const defaultItem =
-              (rootItems && rootItems.length > 0
-                ? rootItems[0]
-                : this.leftDataItems && this.leftDataItems.length > 0
-                ? this.leftDataItems[0]
-                : null) || null
-            this.leftSelectedItems = defaultItem ? [defaultItem] : []
-          }
+          this.$nextTick(() => {
+            this.setLeftDefaultSelection()
+          })
           // 重置左侧占比轮播页
           this.leftProportionCurrentPage = 1
           // 根据选中的项更新图表
@@ -1299,7 +1274,7 @@
           }
           // 若无选中项,默认选中 parentId 为 -1 的根节点(单选),否则用第一个节点
           if (this.rightSelectedItems.length === 0) {
-            const rootItems = this.getRootItems(this.rightDataItems)
+            const { items: rootItems } = this.getParentIds(this.rightDataItems)
             const defaultItem =
               (rootItems && rootItems.length > 0
                 ? rootItems[0]
@@ -1336,25 +1311,44 @@
           endYear: '2025',
         }
         // 重置左侧树形选择
-        if (this.$refs.leftDataTree) {
-          this.$refs.leftDataTree.clearChecked()
-        }
-        // 重置后默认选中第一个父级节点(单选)
-        if (this.leftDataItems && this.leftDataItems.length > 0) {
-          const { items: parentItems } = this.getParentIds(this.leftDataItems)
-          const defaultItem =
-            parentItems.length > 0 ? parentItems[0] : this.leftDataItems[0]
-          this.leftSelectedItems = defaultItem ? [defaultItem] : []
-        } else {
-          // 如果没有数据,清空选中项
-          this.leftSelectedItems = []
+        if (this.$refs.leftIndicatorTree) {
+          this.$refs.leftIndicatorTree.clearChecked()
         }
+        // 重置后默认选中(与 history 页一致)
+        this.setLeftDefaultSelection()
         // 重置左侧图表
         this.leftProportionCurrentPage = 1
         this.updateLeftTrendChart()
         this.updateLeftProportionChart()
       },
 
+      // 左侧默认选中:优先根节点(parentId 为 -1),否则第一个叶子
+      setLeftDefaultSelection() {
+        if (!this.$refs.leftIndicatorTree || !this.leftDataItems.length) {
+          this.leftSelectedItems = []
+          return
+        }
+        const { ids: parentIds } = this.getParentIds(this.leftDataItems)
+        if (parentIds.length > 0) {
+          this.leftSelectedItems = parentIds
+            .map((id) => this.findItemById(id, 'left'))
+            .filter(Boolean)
+          this.$refs.leftIndicatorTree.setCheckedKeys(parentIds)
+          return
+        }
+        const leafIds = this.getLeafIds(this.leftDataItems)
+        if (leafIds.length > 0) {
+          const firstLeaf = leafIds[0]
+          this.leftSelectedItems = [
+            this.findItemById(firstLeaf, 'left'),
+          ].filter(Boolean)
+          this.$refs.leftIndicatorTree.setCheckedKeys([firstLeaf])
+        } else {
+          this.leftSelectedItems = []
+          this.$refs.leftIndicatorTree.setCheckedKeys([])
+        }
+      },
+
       // 右侧重置按钮点击事件
       handleRightReset() {
         // 重置右侧搜索表单
@@ -1451,6 +1445,14 @@
     overflow-x: hidden;
   }
 
+  .indicator-tree {
+    border: 1px solid #e8e8e8;
+    height: 500px;
+    max-height: 500px;
+    overflow-y: auto;
+    overflow-x: hidden;
+  }
+
   .chart-section {
     flex: 1;
     display: flex;

+ 9 - 1
src/views/costAudit/projectInfo/auditTaskManage/taskCustomizedRelease/auditNoticeTab.vue

@@ -186,7 +186,7 @@
               <el-input
                 v-model="document.documentNumber"
                 placeholder="请选择通知书文号"
-                style="width: 80%"
+                style="width: 78%"
                 disabled
               ></el-input>
               <!-- disabled -->
@@ -813,6 +813,10 @@
                   // 获取当前时间,格式为YYYY-MM-DD
                   item.dataValue = moment(new Date()).format('YYYY-MM-DD')
                 }
+                if (item.pinyin.includes('JieLunBaoGaoChuangJianRiQi')) {
+                  // 获取当前时间,格式为YYYY-MM-DD
+                  item.dataValue = moment(new Date()).format('YYYY-MM-DD')
+                }
                 if (item.pinyin.includes('JianShenRenWuFaBuShiJian')) {
                   let dataValue = this.resCostDocumentTemplateFiles.find(
                     (item2) => item2.pinyin === 'JianShenRenWuFaBuShiJian'
@@ -954,6 +958,10 @@
                   // 获取当前时间,格式为YYYY-MM-DD
                   item.dataValue = moment(new Date()).format('YYYY-MM-DD')
                 }
+                if (item.pinyin.includes('JieLunBaoGaoChuangJianRiQi')) {
+                  // 获取当前时间,格式为YYYY-MM-DD
+                  item.dataValue = moment(new Date()).format('YYYY-MM-DD')
+                }
                 if (item.pinyin.includes('JianShenRenWuFaBuShiJian')) {
                   let dataValue = this.resCostDocumentTemplateFiles.find(
                     (item2) => item2.pinyin === 'JianShenRenWuFaBuShiJian'