suhp hai 3 semanas
pai
achega
311dce362d

+ 1736 - 0
src/views/costAudit/auditInfo/archivesManage/ArchiveDetail.vue

@@ -0,0 +1,1736 @@
+<template>
+  <div class="archive-detail-container">
+    <el-breadcrumb
+      separator-class="el-icon-arrow-right"
+      style="margin-bottom: 20px"
+    >
+      <el-breadcrumb-item>
+        <a href="javascript:void(0)" @click="backToList">待归档列表</a>
+      </el-breadcrumb-item>
+      <el-breadcrumb-item>归档</el-breadcrumb-item>
+    </el-breadcrumb>
+    <!-- 步骤导航 -->
+    <el-steps
+      :active="currentStep"
+      finish-status="success"
+      class="custom-steps"
+    >
+      <el-step title="档案资料归纳"></el-step>
+      <el-step title="档案目录核对"></el-step>
+      <el-step title="档案预览"></el-step>
+    </el-steps>
+
+    <!-- 标签页 -->
+    <el-tabs
+      v-model="archiveTab"
+      style="margin-bottom: 20px"
+      @tab-click="handleTabClick"
+    >
+      <el-tab-pane label="资料归纳" name="dataCollect">
+        <el-button
+          plain
+          type="success"
+          icon="el-icon-circle-plus"
+          style="margin-bottom: 20px"
+          @click="addData()"
+        >
+          添加资料
+        </el-button>
+
+        <!-- 资料列表表格 -->
+        <CostAuditTable
+          v-loading="loading"
+          :table-data="archiveData"
+          :columns="archiveColumns"
+          :show-index="true"
+          :border="true"
+          :show-pagination="false"
+        >
+          <template slot="action" slot-scope="{ row, index }">
+            <el-button type="text" size="small" @click="handleView(row)">
+              查看
+            </el-button>
+            <el-button type="text" size="small" @click="handleEditArchive(row)">
+              修改
+            </el-button>
+            <el-button
+              type="text"
+              size="small"
+              @click="handleDelete(row, index)"
+            >
+              删除
+            </el-button>
+          </template>
+          <template slot="sort" slot-scope="{ row, index }">
+            <el-button
+              v-if="index !== 0"
+              type="text"
+              size="small"
+              @click="moveUp(row, index)"
+            >
+              上移
+            </el-button>
+            <el-button
+              v-if="index !== archiveData.length - 1"
+              type="text"
+              size="small"
+              @click="moveDown(row, index)"
+            >
+              下移
+            </el-button>
+          </template>
+        </CostAuditTable>
+      </el-tab-pane>
+      <el-tab-pane label="档案校对" name="proofread">
+        <div class="proofread-content">
+          <CostAuditTable
+            v-loading="loading"
+            :table-data="proofreadData"
+            :columns="proofreadColumns"
+            :show-index="true"
+            :border="true"
+            :show-pagination="false"
+          >
+            <template slot="action" slot-scope="{ row, index }">
+              <el-button type="text" size="small" @click="handleView(row)">
+                查看
+              </el-button>
+              <el-button type="text" size="small" @click="handlePreview(row)">
+                生成
+              </el-button>
+              <el-button
+                type="text"
+                size="small"
+                @click="handleEdit(row, index)"
+              >
+                修改
+              </el-button>
+            </template>
+          </CostAuditTable>
+        </div>
+      </el-tab-pane>
+      <el-tab-pane label="档案预览" name="preview">
+        <div class="preview-content">
+          <div class="doc-actions">
+            <el-button plain type="primary" icon="el-icon-success">
+              保存
+            </el-button>
+            <el-button plain type="primary" icon="el-icon-download">
+              下载
+            </el-button>
+            <el-button plain type="primary" icon="el-icon-refresh">
+              重新生成
+            </el-button>
+            <el-button
+              plain
+              type="primary"
+              icon="el-icon-back"
+              @click="backToList"
+            >
+              返回
+            </el-button>
+          </div>
+          <div class="doc-title">******成本监审档案</div>
+          <div class="doc-container">
+            <div class="doc-catalogue">
+              <div
+                v-for="item in catalogueData"
+                :key="item.id"
+                class="doc-catalogue-item"
+              >
+                {{ item.name }}
+              </div>
+            </div>
+            <div class="doc-content">
+              <div class="doc-content-item">文档内容</div>
+            </div>
+          </div>
+        </div>
+      </el-tab-pane>
+    </el-tabs>
+
+    <CostAuditDialog
+      :visible.sync="dataDialogVisible"
+      :title="dataDialogTitle"
+      :show-confirm-btn="false"
+      :show-footer="false"
+      width="80%"
+      @cancel="handleCancel('dataDialog')"
+    >
+      <div :class="{ 'view-mode-container': isViewMode }">
+        <el-form
+          ref="dataDialogForm"
+          :model="dataDialogForm"
+          :rules="dataDialogRules"
+          style="width: 100%"
+        >
+          <el-row :gutter="20">
+            <el-col :span="8">
+              <el-form-item label="资料名称" prop="materialName">
+                <el-input
+                  v-model="dataDialogForm.materialName"
+                  placeholder="请输入资料名称"
+                  clearable
+                  :disabled="isViewMode"
+                  @input="handleMaterialNameInput"
+                ></el-input>
+              </el-form-item>
+            </el-col>
+            <el-col :span="8">
+              <el-form-item label="序号" prop="materialOrderNum">
+                <el-input-number
+                  v-model="dataDialogForm.materialOrderNum"
+                  :min="1"
+                  placeholder="请输入序号"
+                  :disabled="isViewMode"
+                  style="width: 100%"
+                ></el-input-number>
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </el-form>
+        <!-- 查询结果列表 -->
+        <div v-if="materialQueryList.length > 0" style="margin-top: 20px">
+          <div style="margin-bottom: 10px; font-weight: 500">
+            查询结果列表(点击行添加)
+          </div>
+          <el-table
+            v-loading="dataDialogLoading"
+            :data="materialQueryList"
+            border
+            style="width: 100%"
+            :row-style="{ cursor: isViewMode ? 'default' : 'pointer' }"
+            @row-click="!isViewMode && handleAddFileFromList"
+          >
+            <el-table-column
+              type="index"
+              label="序号"
+              width="60"
+              align="center"
+            />
+            <el-table-column
+              prop="materialOrderNum"
+              label="序号"
+              width="100"
+              align="center"
+            />
+            <el-table-column
+              prop="materialName"
+              label="资料名称"
+              min-width="200"
+              align="left"
+            />
+            <el-table-column
+              prop="documentName"
+              label="文书名称"
+              min-width="200"
+              align="left"
+            />
+            <el-table-column
+              prop="documentNo"
+              label="文号"
+              width="150"
+              align="center"
+            />
+            <el-table-column
+              prop="auditedUnit"
+              label="被监审单位"
+              min-width="150"
+              align="left"
+            />
+            <el-table-column
+              prop="generateTime"
+              label="生成(上传)时间"
+              width="180"
+              align="center"
+            />
+            <el-table-column
+              prop="fileSource"
+              label="文件来源"
+              width="120"
+              align="center"
+            />
+            <el-table-column
+              label="操作"
+              width="100"
+              align="center"
+              fixed="right"
+            >
+              <template slot-scope="{ row }">
+                <el-button
+                  v-if="!isViewMode"
+                  type="text"
+                  size="small"
+                  style="color: #409eff"
+                  @click.stop="handleAddFileFromList(row)"
+                >
+                  添加
+                </el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+        <!-- 已添加列表 -->
+        <div style="margin-top: 20px">
+          <div style="margin-bottom: 10px; font-weight: 500">
+            已添加列表(共 {{ selectedFileList.length }} 条)
+          </div>
+          <el-table :data="selectedFileList" border style="width: 100%">
+            <el-table-column
+              prop="materialOrderNum"
+              label="序号"
+              width="100"
+              align="center"
+            >
+              <template slot-scope="{ row }">
+                <el-input-number
+                  v-model="row.materialOrderNum"
+                  :min="1"
+                  size="mini"
+                  :disabled="isViewMode"
+                  style="width: 100%"
+                  @change="handleOrderNumChange"
+                />
+              </template>
+            </el-table-column>
+            <el-table-column
+              prop="documentName"
+              label="文书名称"
+              min-width="200"
+              align="left"
+            >
+              <template slot-scope="{ row }">
+                <el-input
+                  v-model="row.documentName"
+                  size="mini"
+                  placeholder="请输入文书名称"
+                  :disabled="isViewMode"
+                />
+              </template>
+            </el-table-column>
+            <el-table-column
+              prop="documentNo"
+              label="文号"
+              width="150"
+              align="center"
+            >
+              <template slot-scope="{ row }">
+                <el-input
+                  v-model="row.documentNo"
+                  size="mini"
+                  placeholder="请输入文号"
+                  :disabled="isViewMode"
+                />
+              </template>
+            </el-table-column>
+            <el-table-column
+              prop="auditedUnit"
+              label="被监审单位"
+              min-width="150"
+              align="left"
+            >
+              <template slot-scope="{ row }">
+                <!-- <el-input
+                v-model="row.auditedUnit"
+                size="mini"
+                placeholder="请输入被监审单位"
+              /> -->
+                <el-select
+                  v-model="row.auditedUnit"
+                  size="mini"
+                  style="width: 100%"
+                  placeholder="请选择被监审单位"
+                  :disabled="isViewMode"
+                  clearable
+                  filterable
+                  multiple
+                  collapse-tags
+                >
+                  <el-option
+                    v-for="item in allUnits"
+                    :key="item.unitId"
+                    :label="item.unitName"
+                    :value="item.unitId"
+                  ></el-option>
+                </el-select>
+              </template>
+            </el-table-column>
+            <el-table-column
+              prop="generateTime"
+              label="生成(上传)时间"
+              width="180"
+              align="center"
+            >
+              <template slot-scope="{ row }">
+                <el-date-picker
+                  v-model="row.generateTime"
+                  type="datetime"
+                  size="mini"
+                  style="width: 100%"
+                  format="yyyy-MM-dd HH:mm"
+                  value-format="yyyy-MM-dd HH:mm"
+                  placeholder="选择时间"
+                  :disabled="isViewMode"
+                />
+              </template>
+            </el-table-column>
+            <el-table-column
+              prop="fileSource"
+              label="文件来源"
+              width="120"
+              align="center"
+            >
+              <template slot-scope="{ row }">
+                <el-select
+                  v-model="row.fileSource"
+                  size="mini"
+                  style="width: 100%"
+                  placeholder="请选择文件来源"
+                  :disabled="isViewMode"
+                  clearable
+                  filterable
+                  allow-create
+                  default-first-option
+                >
+                  <el-option
+                    label="系统生成电子文书"
+                    value="系统生成电子文书"
+                  />
+                  <el-option
+                    label="监审单位反馈文件"
+                    value="监审单位反馈文件"
+                  />
+                  <el-option
+                    label="监管主体上传文件"
+                    value="监管主体上传文件"
+                  />
+                </el-select>
+              </template>
+            </el-table-column>
+            <el-table-column
+              v-if="!isViewMode"
+              label="操作"
+              width="100"
+              align="center"
+              fixed="right"
+            >
+              <template slot-scope="{ row, $index }">
+                <el-button
+                  type="text"
+                  size="small"
+                  style="color: #f56c6c"
+                  @click="handleDeleteFile(row, $index)"
+                >
+                  删除
+                </el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+        <div slot="footer" style="text-align: right; margin-top: 10px">
+          <el-button v-if="!isViewMode" type="primary" @click="handleAddFile">
+            添加文件
+          </el-button>
+          <el-button
+            v-if="!isViewMode"
+            type="primary"
+            @click="handleSaveDataDialog"
+          >
+            保存
+          </el-button>
+          <el-button v-if="!isViewMode" @click="handleCancel('dataDialog')">
+            取消
+          </el-button>
+        </div>
+      </div>
+    </CostAuditDialog>
+  </div>
+</template>
+
+<script>
+  import CostAuditTable from '@/components/costAudit/CostAuditTable.vue'
+  import CostAuditDialog from '@/components/costAudit/CostAuditDialog.vue'
+  import {
+    getDataInductionList,
+    addDataInductionList,
+    saveDataInductionWithDetails,
+    deleteDataInductionWithDetails,
+    moveDataInductionWithDetails,
+  } from '@/api/audit/dataInduction'
+  import { getAllUnitList } from '@/api/auditEntityManage'
+
+  export default {
+    name: 'ArchiveDetail',
+    components: {
+      CostAuditTable,
+      CostAuditDialog,
+    },
+    props: {
+      taskId: {
+        type: String,
+        default: '',
+      },
+    },
+    data() {
+      return {
+        allUnits: [],
+        loading: false,
+        currentStep: 0, // 当前步骤 0:资料归纳 1:目录核对 2:档案预览
+        archiveTab: 'dataCollect', // 归档页面标签页  dataCollect preview
+        archiveColumns: [
+          {
+            prop: 'name',
+            label: '资料名称',
+            minWidth: 300,
+            align: 'left',
+          },
+          {
+            prop: 'pageCount',
+            label: '资料页数',
+            width: 120,
+          },
+          {
+            prop: 'lastModified',
+            label: '最后修改时间',
+            width: 180,
+          },
+          {
+            slotName: 'action',
+            label: '操作',
+            width: 150,
+          },
+          {
+            slotName: 'sort',
+            label: '排序',
+            width: 100,
+          },
+        ],
+        proofreadColumns: [
+          {
+            prop: 'name',
+            label: '资料名称',
+            minWidth: 300,
+            align: 'left',
+          },
+          {
+            prop: 'pageCount',
+            label: '资料页数',
+            width: 120,
+          },
+          {
+            prop: 'startEndPageCount',
+            label: '起止页码',
+            width: 120,
+          },
+          {
+            slotName: 'action',
+            label: '文书排序',
+            width: 200,
+          },
+        ],
+        archiveData: [],
+        proofreadData: [
+          {
+            id: 1,
+            name: '档案封面',
+            pageCount: 1,
+            startEndPageCount: '--',
+          },
+          {
+            id: 2,
+            name: '卷内目录',
+            pageCount: 1,
+            startEndPageCount: '--',
+          },
+          {
+            id: 3,
+            name: '成本监审报告(含成本监审报告修改稿、送达回证)',
+            pageCount: 30,
+            startEndPageCount: '1-30',
+          },
+          {
+            id: 4,
+            name: '被监审单位申请(报告)价格表(复印件)',
+            pageCount: 5,
+            startEndPageCount: '31-35',
+          },
+          {
+            id: 5,
+            name: '成本监审评审书(含送达回证)',
+            pageCount: 13,
+            startEndPageCount: '36-48',
+          },
+          {
+            id: 6,
+            name: '经营者需提供成本费用清单',
+            pageCount: 5,
+            startEndPageCount: '49-53',
+          },
+          {
+            id: 7,
+            name: '政府定价成本监审调查笔录',
+            pageCount: 5,
+            startEndPageCount: '54-58',
+          },
+          {
+            id: 8,
+            name: '成本监审补充资料通知书(含送达回证)',
+            pageCount: 5,
+            startEndPageCount: '59-63',
+          },
+          {
+            id: 9,
+            name: '成本审核初步意见告知书(含送达回证)',
+            pageCount: 5,
+            startEndPageCount: '64-68',
+          },
+          {
+            id: 10,
+            name: '经营者书面反馈的材料',
+            pageCount: 1,
+            startEndPageCount: '69',
+          },
+          {
+            id: 11,
+            name: '成本审核初步意见表(集体审议用)',
+            pageCount: 1,
+            startEndPageCount: '70',
+          },
+          {
+            id: 12,
+            name: '成本监审集体审议记录',
+            pageCount: 1,
+            startEndPageCount: '71',
+          },
+          {
+            id: 13,
+            name: '成本监审工作底稿',
+            pageCount: 1,
+            startEndPageCount: '72',
+          },
+          {
+            id: 14,
+            name: '成本监审委员会审议记录',
+            pageCount: 1,
+            startEndPageCount: '73',
+          },
+          {
+            id: 15,
+            name: '提取的成本资料会计凭证等复印件',
+            pageCount: 10,
+            startEndPageCount: '74-83',
+          },
+          {
+            id: 16,
+            name: '成本监审备考表',
+            pageCount: 1,
+            startEndPageCount: '--',
+          },
+        ],
+        dataDialogTitle: '添加资料',
+        dataDialogVisible: false,
+        dataDialogLoading: false,
+        dataDialogForm: {
+          materialName: '',
+          materialOrderNum: 1,
+        },
+        dataDialogRules: {
+          materialName: [
+            { required: true, message: '请输入资料名称', trigger: 'blur' },
+          ],
+          materialOrderNum: [
+            { required: true, message: '请输入序号', trigger: 'blur' },
+          ],
+        },
+        dataDialogColumns: [
+          {
+            prop: 'materialOrderNum',
+            label: '序号',
+            width: 100,
+            align: 'center',
+          },
+          {
+            prop: 'materialName',
+            label: '资料名称',
+            minWidth: 200,
+            align: 'left',
+          },
+          {
+            prop: 'documentName',
+            label: '文书名称',
+            minWidth: 200,
+            align: 'left',
+          },
+          {
+            prop: 'documentNo',
+            label: '文号',
+            width: 150,
+            align: 'center',
+          },
+          {
+            prop: 'auditedUnit',
+            label: '被监审单位',
+            minWidth: 150,
+            align: 'left',
+          },
+          {
+            prop: 'generateTime',
+            label: '生成(上传)时间',
+            width: 180,
+            align: 'center',
+          },
+          {
+            prop: 'fileSource',
+            label: '文件来源',
+            width: 120,
+            align: 'center',
+          },
+          {
+            slotName: 'action',
+            label: '操作',
+            width: 100,
+            fixed: 'right',
+          },
+        ],
+        dataDialogData: [], // 已废弃,保留用于兼容
+        materialQueryList: [], // 查询结果列表
+        selectedFileList: [], // 已选择的文件列表(待保存)
+        isEditingDataDialog: false, // 是否为编辑模式
+        isViewMode: false, // 是否为查看模式
+        currentEditMaterialId: null, // 当前编辑的资料ID
+        materialNameSearchTimer: null, // 搜索防抖定时器
+        catalogueData: [
+          {
+            id: 1,
+            name: '卷宗封面',
+          },
+          {
+            id: 2,
+            name: '卷内目录',
+          },
+          {
+            id: 3,
+            name: '卷宗内容',
+          },
+          {
+            id: 4,
+            name: '卷宗封底',
+          },
+        ],
+      }
+    },
+    created() {
+      this.loadAllUnits()
+      if (this.taskId) {
+        this.loadArchiveData()
+      }
+    },
+    methods: {
+      // 标签页切换事件
+      handleTabClick(tab) {
+        this.archiveTab = tab.name
+        // 如果切换到资料归纳标签页,加载资料归纳数据
+        if (tab.name === 'dataCollect' && this.taskId) {
+          this.loadArchiveData()
+        }
+      },
+      // 加载资料归纳列表数据
+      async loadArchiveData() {
+        if (!this.taskId) {
+          return
+        }
+
+        try {
+          this.loading = true
+          const response = await getDataInductionList({ taskId: this.taskId })
+
+          // 根据API返回格式处理数据
+          if (response && response.value) {
+            // 处理返回的数据,映射到archiveData格式
+            this.archiveData = (
+              Array.isArray(response.value)
+                ? response.value
+                : response.value.list || []
+            ).map((item) => {
+              return {
+                id: item.id,
+                name: item.materialName || item.name || '',
+                pageCount: item.pageCount || item.pageNum || '--',
+                lastModified:
+                  item.updateTime ||
+                  item.createTime ||
+                  item.lastModified ||
+                  '--',
+                sortOrder: item.sortOrder || item.orderNum || 0,
+                // 保留原始数据,便于后续操作
+                originalData: item,
+              }
+            })
+
+            // 按sortOrder排序
+            this.archiveData.sort((a, b) => {
+              return (a.sortOrder || 0) - (b.sortOrder || 0)
+            })
+          } else {
+            this.archiveData = []
+          }
+        } catch (error) {
+          // this.$message.error('加载资料归纳列表失败')
+          console.error('加载资料归纳列表失败:', error)
+          this.archiveData = []
+        } finally {
+          this.loading = false
+        }
+      },
+      // 添加资料按钮点击事件
+      addData() {
+        // 重置表单和数据
+        this.dataDialogForm = {
+          materialName: '',
+          materialOrderNum: 1,
+        }
+        this.materialQueryList = []
+        this.selectedFileList = []
+        this.dataDialogData = []
+        this.isEditingDataDialog = false
+        this.isViewMode = false
+        this.currentEditMaterialId = null
+        this.dataDialogTitle = '添加资料'
+        this.dataDialogVisible = true
+      },
+      // 资料名称输入时自动查询列表
+      handleMaterialNameInput() {
+        // 防抖处理,延迟500ms执行查询
+        if (this.materialNameSearchTimer) {
+          clearTimeout(this.materialNameSearchTimer)
+        }
+        // this.materialNameSearchTimer = setTimeout(() => {
+        //   this.queryMaterialList()
+        // }, 500)
+      },
+      // 查询资料列表
+      async queryMaterialList() {
+        if (
+          !this.dataDialogForm.materialName ||
+          !this.dataDialogForm.materialName.trim()
+        ) {
+          this.materialQueryList = []
+          return
+        }
+
+        if (!this.taskId) {
+          this.$message.warning('缺少任务信息')
+          return
+        }
+
+        try {
+          this.dataDialogLoading = true
+          const params = {
+            taskId: this.taskId,
+            materialName: this.dataDialogForm.materialName.trim(),
+          }
+
+          const response = await addDataInductionList(params)
+
+          // 处理返回的数据
+          if (response && response.value) {
+            const list = Array.isArray(response.value)
+              ? response.value
+              : response.value.list || []
+            this.materialQueryList = list.map((item) => {
+              return {
+                id: item.id,
+                materialOrderNum:
+                  item.materialOrderNum ||
+                  item.orderNum ||
+                  this.dataDialogForm.materialOrderNum,
+                materialName:
+                  item.materialName || this.dataDialogForm.materialName,
+                documentName: item.documentName || item.name || '',
+                documentNo: item.documentNo || item.number || '',
+                auditedUnit: item.auditedUnit || item.auditedUnitName || '',
+                generateTime:
+                  item.generateTime || item.createTime || item.updateTime || '',
+                fileSource: item.fileSource || item.source || '',
+                // 保留原始数据
+                originalData: item,
+              }
+            })
+          } else {
+            this.materialQueryList = []
+          }
+        } catch (error) {
+          // this.$message.error('查询资料列表失败')
+          console.error('查询资料列表失败:', error)
+          this.materialQueryList = []
+        } finally {
+          this.dataDialogLoading = false
+        }
+      },
+      // 从查询结果列表中添加文件
+      handleAddFileFromList(row) {
+        // if (!row) {
+        //   return
+        // }
+
+        // 检查是否已经添加过
+        // const exists = this.selectedFileList.some(
+        //   (item) =>
+        //     item.id === row.id ||
+        //     (item.materialName === row.materialName &&
+        //       item.materialOrderNum === row.materialOrderNum)
+        // )
+
+        // if (exists) {
+        //   this.$message.warning('该文件已添加')
+        //   return
+        // }
+
+        // 添加到已选择列表,序号自动递增
+        const newOrderNum =
+          this.selectedFileList.length > 0
+            ? Math.max(
+                ...this.selectedFileList.map(
+                  (item) => item.materialOrderNum || 0
+                )
+              ) + 1
+            : 1
+
+        // 确保 auditedUnit 是数组格式
+        let auditedUnitArray = []
+        if (row.auditedUnit) {
+          if (Array.isArray(row.auditedUnit)) {
+            auditedUnitArray = row.auditedUnit
+          } else if (typeof row.auditedUnit === 'string') {
+            // 如果是字符串,尝试转换为数组(可能是逗号分隔的单位名称)
+            // 这里假设查询结果中的 auditedUnit 可能是单位名称字符串,需要转换为 unitId
+            // 如果已经是 unitId,直接使用
+            const unitItem = this.allUnits.find(
+              (unit) =>
+                unit.unitId === row.auditedUnit ||
+                unit.unitId === String(row.auditedUnit) ||
+                unit.unitName === row.auditedUnit
+            )
+            if (unitItem) {
+              auditedUnitArray = [unitItem.unitId]
+            }
+          }
+        }
+
+        this.selectedFileList.push({
+          ...row,
+          // 使用自动递增的序号
+          materialOrderNum: newOrderNum,
+          // 确保 auditedUnit 是数组格式
+          auditedUnit: auditedUnitArray,
+        })
+
+        this.$message.success('添加成功')
+      },
+      // 序号变化时处理
+      handleOrderNumChange() {
+        // 可以在这里添加序号验证逻辑,比如检查是否重复
+      },
+      // 添加文件(手动输入添加)
+      handleAddFile() {
+        // 验证表单
+        this.$refs.dataDialogForm.validate((valid) => {
+          if (!valid) {
+            return false
+          }
+
+          // if (
+          //   !this.dataDialogForm.materialName ||
+          //   !this.dataDialogForm.materialName.trim()
+          // ) {
+          //   this.$message.warning('请输入资料名称')
+          //   return
+          // }
+
+          // 检查是否已经添加过
+          const exists = this.selectedFileList.some(
+            (item) =>
+              item.materialName === this.dataDialogForm.materialName.trim() &&
+              item.materialOrderNum === this.dataDialogForm.materialOrderNum
+          )
+
+          // if (exists) {
+          //   this.$message.warning('该文件已添加')
+          //   return
+          // }
+
+          // 添加到已选择列表
+          this.selectedFileList.push({
+            id: null, // 新添加的行没有ID
+            materialOrderNum: this.dataDialogForm.materialOrderNum,
+            materialName: this.dataDialogForm.materialName.trim(),
+            documentName: '',
+            documentNo: '',
+            auditedUnit: [], // 多选,初始化为空数组
+            generateTime: '',
+            fileSource: '',
+            isNew: true, // 标记为新添加的行
+          })
+
+          // 序号自动递增,资料名称不清空
+          this.dataDialogForm.materialOrderNum =
+            this.selectedFileList.length + 1 || 1
+          // this.$message.success('添加成功')
+        })
+      },
+      // 删除文件
+      handleDeleteFile(row, index) {
+        this.$confirm('确定要删除该文件吗?', '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning',
+        })
+          .then(() => {
+            this.selectedFileList.splice(index, 1)
+            this.$message.success('删除成功')
+          })
+          .catch(() => {
+            this.$message.info('已取消删除')
+          })
+      },
+      // 保存资料对话框数据
+      async handleSaveDataDialog() {
+        // 判断列表有没有数据
+        if (!this.selectedFileList || this.selectedFileList.length === 0) {
+          this.$message.warning('请先添加文件')
+          return
+        }
+
+        if (!this.taskId) {
+          this.$message.warning('缺少任务信息')
+          return
+        }
+
+        // 验证资料名称
+        if (
+          !this.dataDialogForm.materialName ||
+          !this.dataDialogForm.materialName.trim()
+        ) {
+          this.$message.warning('请输入资料名称')
+          return
+        }
+
+        try {
+          this.dataDialogLoading = true
+          // 判断是否有主表ID(编辑模式)
+          const hasMainId =
+            this.currentEditMaterialId !== null &&
+            this.currentEditMaterialId !== undefined
+
+          // 构建明细列表(detailList)
+          const detailList = this.selectedFileList.map((item) => {
+            // 格式化时间:转换为年月日时分格式 (yyyy-MM-dd HH:mm)
+            let generateTimeFormatted = item.generateTime || ''
+            if (generateTimeFormatted) {
+              try {
+                // 如果是字符串格式
+                if (typeof generateTimeFormatted === 'string') {
+                  // 如果已经是 yyyy-MM-dd HH:mm 格式,直接使用
+                  if (
+                    /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/.test(
+                      generateTimeFormatted
+                    )
+                  ) {
+                    // 已经是正确格式,保持不变
+                  } else if (
+                    /^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/.test(
+                      generateTimeFormatted
+                    )
+                  ) {
+                    // 如果是 yyyy-MM-dd HH:mm:ss 格式,截取掉秒数
+                    generateTimeFormatted = generateTimeFormatted.substring(
+                      0,
+                      16
+                    )
+                  } else if (generateTimeFormatted.includes('T')) {
+                    // ISO 格式:2025-05-11T16:40:00 或 2025-05-11T16:40:00.000Z
+                    generateTimeFormatted = generateTimeFormatted
+                      .replace('T', ' ')
+                      .replace(/\.\d{3}Z?$/, '')
+                      .substring(0, 16)
+                  } else {
+                    // 尝试解析并格式化
+                    const date = new Date(generateTimeFormatted)
+                    if (!isNaN(date.getTime())) {
+                      const year = date.getFullYear()
+                      const month = String(date.getMonth() + 1).padStart(2, '0')
+                      const day = String(date.getDate()).padStart(2, '0')
+                      const hours = String(date.getHours()).padStart(2, '0')
+                      const minutes = String(date.getMinutes()).padStart(2, '0')
+                      generateTimeFormatted = `${year}-${month}-${day} ${hours}:${minutes}`
+                    }
+                  }
+                } else if (generateTimeFormatted instanceof Date) {
+                  // 如果是 Date 对象
+                  const year = generateTimeFormatted.getFullYear()
+                  const month = String(
+                    generateTimeFormatted.getMonth() + 1
+                  ).padStart(2, '0')
+                  const day = String(generateTimeFormatted.getDate()).padStart(
+                    2,
+                    '0'
+                  )
+                  const hours = String(
+                    generateTimeFormatted.getHours()
+                  ).padStart(2, '0')
+                  const minutes = String(
+                    generateTimeFormatted.getMinutes()
+                  ).padStart(2, '0')
+                  generateTimeFormatted = `${year}-${month}-${day} ${hours}:${minutes}`
+                }
+              } catch (error) {
+                console.warn('时间格式转换失败:', error)
+                generateTimeFormatted = ''
+              }
+            }
+
+            // 处理被监审单位:如果是unitId数组,转换为unitName数组,然后转换为逗号分隔的字符串
+            let auditedUnitName = ''
+            if (
+              item.auditedUnit &&
+              Array.isArray(item.auditedUnit) &&
+              item.auditedUnit.length > 0
+            ) {
+              // 将unitId数组转换为unitName数组
+              const unitNames = item.auditedUnit
+                .map((unitId) => {
+                  const unitItem = this.allUnits.find(
+                    (unit) =>
+                      unit.unitId === unitId || unit.unitId === String(unitId)
+                  )
+                  return unitItem ? unitItem.unitName : ''
+                })
+                .filter((name) => name) // 过滤掉空值
+              // 转换为逗号分隔的字符串
+              auditedUnitName = unitNames.join(',')
+            } else if (item.auditedUnit && !Array.isArray(item.auditedUnit)) {
+              // 兼容旧数据:单个unitId字符串
+              const unitItem = this.allUnits.find(
+                (unit) =>
+                  unit.unitId === item.auditedUnit ||
+                  unit.unitId === String(item.auditedUnit)
+              )
+              if (unitItem) {
+                auditedUnitName = unitItem.unitName
+              }
+            }
+
+            const detailItem = {
+              documentName: item.documentName || '', // 必填
+              documentNumber: item.documentNo || '', // 可选,注意字段名是 documentNumber
+              auditedUnitName: auditedUnitName, // 可选,注意字段名是 auditedUnitName
+              generateTime: generateTimeFormatted, // 可选,年月日时分格式 (yyyy-MM-dd HH:mm)
+              fileSource: item.fileSource || '', // 可选
+              pageCount: item.pageCount || item.originalData?.pageCount || null, // 可选
+              attachmentId:
+                item.attachmentId || item.originalData?.attachmentId || null, // 可选
+              orderNum: item.materialOrderNum || null, // 可选,不传自动生成
+            }
+
+            // 编辑明细时需要包含 id(必填)
+            if (item.id && hasMainId) {
+              detailItem.id = item.id
+            }
+
+            return detailItem
+          })
+
+          // 构建请求参数
+          const params = {
+            taskId: this.taskId, // 必填
+            materialName: this.dataDialogForm.materialName.trim(), // 必填
+            detailList: detailList, // 明细列表
+          }
+
+          // 新增模式:materialOrderNum 可选,不传自动生成
+          if (!hasMainId) {
+            if (this.dataDialogForm.materialOrderNum) {
+              params.materialOrderNum = this.dataDialogForm.materialOrderNum
+            }
+          } else {
+            // 编辑模式:需要主表 id
+            params.id = this.currentEditMaterialId
+          }
+
+          const response = await saveDataInductionWithDetails(params)
+
+          if (response && response.success !== false) {
+            this.$message.success(response.message || '保存成功')
+            this.handleCancel('dataDialog')
+            // 刷新资料归纳列表
+            if (this.archiveTab === 'dataCollect') {
+              this.loadArchiveData()
+            }
+          } else {
+            this.$message.error(response.message || '保存失败')
+          }
+        } catch (error) {
+          // this.$message.error('保存失败')
+          console.error('保存资料失败:', error)
+        } finally {
+          this.dataDialogLoading = false
+        }
+      },
+      // 取消/关闭弹窗
+      handleCancel(type) {
+        if (type === 'dataDialog') {
+          this.dataDialogVisible = false
+          // 重置表单和数据
+          this.$nextTick(() => {
+            if (this.$refs.dataDialogForm) {
+              this.$refs.dataDialogForm.resetFields()
+            }
+            this.dataDialogForm = {
+              materialName: '',
+              materialOrderNum: 1,
+            }
+            this.materialQueryList = []
+            this.selectedFileList = []
+            this.dataDialogData = []
+            this.isEditingDataDialog = false
+            this.isViewMode = false
+            this.currentEditMaterialId = null
+            this.dataDialogTitle = '添加资料'
+            // 清除搜索定时器
+            if (this.materialNameSearchTimer) {
+              clearTimeout(this.materialNameSearchTimer)
+              this.materialNameSearchTimer = null
+            }
+          })
+        }
+      },
+      // 查看按钮点击事件
+      async handleView(row) {
+        if (!row || !row.originalData) {
+          this.$message.warning('缺少数据信息')
+          return
+        }
+
+        const originalData = row.originalData
+        const materialId = row.id || originalData.id
+
+        if (!materialId) {
+          this.$message.warning('缺少资料ID')
+          return
+        }
+
+        try {
+          this.dataDialogLoading = true
+
+          // 设置查看模式
+          this.isViewMode = true
+          this.isEditingDataDialog = false
+          this.currentEditMaterialId = materialId
+          this.dataDialogTitle = '查看资料'
+
+          // 设置表单数据
+          this.dataDialogForm = {
+            materialName: originalData.materialName || row.name || '',
+            materialOrderNum:
+              originalData.materialOrderNum || originalData.orderNum || 1,
+          }
+
+          // 获取明细数据
+          // 如果有 detailList 数据,直接使用;否则需要通过接口获取
+          if (
+            originalData.detailList &&
+            Array.isArray(originalData.detailList)
+          ) {
+            // 直接使用返回的明细数据
+            this.selectedFileList = originalData.detailList.map((detail) => {
+              // 处理被监审单位:如果是unitName(可能是逗号分隔的字符串),查找对应的unitId数组
+              let auditedUnit = []
+              const auditedUnitNameStr =
+                detail.auditedUnitName || detail.auditedUnit || ''
+              if (auditedUnitNameStr && this.allUnits.length > 0) {
+                // 如果是逗号分隔的字符串,分割成数组
+                const unitNameArray = auditedUnitNameStr
+                  .split(',')
+                  .map((name) => name.trim())
+                  .filter((name) => name)
+                // 将unitName数组转换为unitId数组
+                auditedUnit = unitNameArray
+                  .map((unitName) => {
+                    const unitItem = this.allUnits.find(
+                      (unit) => unit.unitName === unitName
+                    )
+                    return unitItem ? unitItem.unitId : null
+                  })
+                  .filter((unitId) => unitId !== null) // 过滤掉未找到的
+              }
+
+              return {
+                id: detail.id || null,
+                materialOrderNum:
+                  detail.orderNum || detail.materialOrderNum || 1,
+                materialName:
+                  detail.materialName || this.dataDialogForm.materialName || '',
+                documentName: detail.documentName || '',
+                documentNo: detail.documentNumber || detail.documentNo || '',
+                auditedUnit: auditedUnit, // 数组格式
+                generateTime: detail.generateTime || '',
+                fileSource: detail.fileSource || '',
+                pageCount: detail.pageCount || null,
+                attachmentId: detail.attachmentId || null,
+                originalData: detail,
+              }
+            })
+          } else {
+            // 如果没有明细数据,尝试通过接口获取
+            // 这里假设可以通过 id 获取详情,如果接口不支持,则使用空列表
+            this.selectedFileList = []
+          }
+
+          // 清空查询结果列表
+          this.materialQueryList = []
+
+          // 打开弹窗
+          this.dataDialogVisible = true
+        } catch (error) {
+          // this.$message.error('加载数据失败')
+          console.error('加载资料数据失败:', error)
+        } finally {
+          this.dataDialogLoading = false
+        }
+      },
+
+      // 预览按钮点击事件
+      handlePreview(row) {
+        this.$message.info(`预览资料:${row.name}`)
+        // 实际项目中这里应该打开资料预览功能
+      },
+      // 修改资料归纳按钮点击事件
+      async handleEditArchive(row) {
+        if (!row || !row.originalData) {
+          this.$message.warning('缺少数据信息')
+          return
+        }
+
+        const originalData = row.originalData
+        const materialId = row.id || originalData.id
+
+        if (!materialId) {
+          this.$message.warning('缺少资料ID')
+          return
+        }
+
+        try {
+          this.dataDialogLoading = true
+
+          // 设置编辑模式
+          this.isEditingDataDialog = true
+          this.isViewMode = false
+          this.currentEditMaterialId = materialId
+          this.dataDialogTitle = '修改资料'
+
+          // 设置表单数据
+          this.dataDialogForm = {
+            materialName: originalData.materialName || row.name || '',
+            materialOrderNum:
+              originalData.materialOrderNum || originalData.orderNum || 1,
+          }
+
+          // 获取明细数据
+          // 如果有 detailList 数据,直接使用;否则需要通过接口获取
+          if (
+            originalData.detailList &&
+            Array.isArray(originalData.detailList)
+          ) {
+            // 直接使用返回的明细数据
+            this.selectedFileList = originalData.detailList.map((detail) => {
+              // 处理被监审单位:如果是unitName(可能是逗号分隔的字符串),查找对应的unitId数组
+              let auditedUnit = []
+              const auditedUnitNameStr =
+                detail.auditedUnitName || detail.auditedUnit || ''
+              if (auditedUnitNameStr && this.allUnits.length > 0) {
+                // 如果是逗号分隔的字符串,分割成数组
+                const unitNameArray = auditedUnitNameStr
+                  .split(',')
+                  .map((name) => name.trim())
+                  .filter((name) => name)
+                // 将unitName数组转换为unitId数组
+                auditedUnit = unitNameArray
+                  .map((unitName) => {
+                    const unitItem = this.allUnits.find(
+                      (unit) => unit.unitName === unitName
+                    )
+                    return unitItem ? unitItem.unitId : null
+                  })
+                  .filter((unitId) => unitId !== null) // 过滤掉未找到的
+              }
+
+              return {
+                id: detail.id || null,
+                materialOrderNum:
+                  detail.orderNum || detail.materialOrderNum || 1,
+                materialName:
+                  detail.materialName || this.dataDialogForm.materialName || '',
+                documentName: detail.documentName || '',
+                documentNo: detail.documentNumber || detail.documentNo || '',
+                auditedUnit: auditedUnit, // 数组格式
+                generateTime: detail.generateTime || '',
+                fileSource: detail.fileSource || '',
+                pageCount: detail.pageCount || null,
+                attachmentId: detail.attachmentId || null,
+                originalData: detail,
+              }
+            })
+          } else {
+            // 如果没有明细数据,尝试通过接口获取
+            // 这里假设可以通过 id 获取详情,如果接口不支持,则使用空列表
+            this.selectedFileList = []
+          }
+
+          // 清空查询结果列表
+          this.materialQueryList = []
+
+          // 打开弹窗
+          this.dataDialogVisible = true
+        } catch (error) {
+          // this.$message.error('加载数据失败')
+          console.error('加载资料数据失败:', error)
+        } finally {
+          this.dataDialogLoading = false
+        }
+      },
+
+      // 删除按钮点击事件
+      handleDelete(row, index) {
+        this.$confirm(`确定要删除资料"${row.name}"吗?`, '提示', {
+          confirmButtonText: '确定',
+          cancelButtonText: '取消',
+          type: 'warning',
+        })
+          .then(() => {
+            // this.archiveData.splice(index, 1)
+            deleteDataInductionWithDetails({ id: row.id })
+              .then((response) => {
+                if (response && response.success !== false) {
+                  this.$message.success(response.message || '删除成功')
+                  this.loadArchiveData()
+                } else {
+                  this.$message.error(response.message || '删除失败')
+                }
+              })
+              .catch((error) => {
+                // this.$message.error('删除失败')
+                console.error('删除资料失败:', error)
+              })
+          })
+          .catch(() => {
+            this.$message.info('已取消删除')
+          })
+      },
+
+      // 上移按钮点击事件
+      async moveUp(row, index) {
+        if (!row) {
+          this.$message.warning('缺少数据信息')
+          return
+        }
+
+        const materialId = row.id || (row.originalData && row.originalData.id)
+        if (!materialId) {
+          this.$message.warning('缺少资料ID')
+          return
+        }
+
+        try {
+          const params = {
+            id: materialId,
+            direction: 'up',
+          }
+
+          const response = await moveDataInductionWithDetails(params)
+
+          if (response && response.success !== false) {
+            this.$message.success(response.message || '上移成功')
+            // 刷新列表
+            this.loadArchiveData()
+          } else {
+            this.$message.error(response.message || '上移失败')
+          }
+        } catch (error) {
+          // this.$message.error('上移失败')
+          console.error('上移资料失败:', error)
+        }
+      },
+
+      // 下移按钮点击事件
+      async moveDown(row, index) {
+        if (!row) {
+          this.$message.warning('缺少数据信息')
+          return
+        }
+
+        const materialId = row.id || (row.originalData && row.originalData.id)
+        if (!materialId) {
+          this.$message.warning('缺少资料ID')
+          return
+        }
+
+        try {
+          const params = {
+            id: materialId,
+            direction: 'down',
+          }
+
+          const response = await moveDataInductionWithDetails(params)
+
+          if (response && response.success !== false) {
+            this.$message.success(response.message || '下移成功')
+            // 刷新列表
+            this.loadArchiveData()
+          } else {
+            this.$message.error(response.message || '下移失败')
+          }
+        } catch (error) {
+          // this.$message.error('下移失败')
+          console.error('下移资料失败:', error)
+        }
+      },
+
+      // 下一步按钮点击事件
+      nextStep() {
+        if (this.currentStep < 2) {
+          this.currentStep++
+          // 如果进入第三步,自动切换到档案预览标签页
+          if (this.currentStep === 2) {
+            this.archiveTab = 'preview'
+          }
+        } else {
+          this.$message.success('归档完成')
+          this.backToList()
+        }
+      },
+      // 加载所有被监审单位列表
+      async loadAllUnits() {
+        try {
+          const response = await getAllUnitList()
+          if (response && response.value) {
+            const list = Array.isArray(response.value)
+              ? response.value
+              : response.value.list || []
+            this.allUnits = list.map((item) => ({
+              unitId: item.unitId || item.id,
+              unitName: item.unitName || item.name || '',
+            }))
+          } else {
+            this.allUnits = []
+          }
+        } catch (error) {
+          console.error('加载被监审单位列表失败:', error)
+          this.allUnits = []
+        }
+      },
+      backToList() {
+        this.$emit('back')
+      },
+    },
+  }
+</script>
+
+<style scoped lang="scss">
+  .archive-detail-container {
+    width: 100%;
+    max-width: 1400px;
+    margin: 0 auto;
+    padding: 20px;
+    background-color: #fff;
+    border-radius: 4px;
+  }
+
+  .custom-steps {
+    width: 100%;
+    max-width: 800px;
+    margin: 0 auto 30px;
+    padding: 20px;
+    background-color: #fff;
+    border-radius: 4px;
+    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+  }
+
+  .proofread-content {
+    padding: 20px 0;
+  }
+
+  .preview-content {
+    width: 100%;
+    display: flex;
+    flex-direction: column;
+
+    .doc-actions {
+      display: flex;
+      justify-content: flex-start;
+      gap: 10px;
+      margin-bottom: 20px;
+      padding: 15px;
+      background-color: #f5f7fa;
+      border-radius: 4px;
+    }
+
+    .doc-title {
+      height: 50px;
+      line-height: 50px;
+      text-align: center;
+      border: 1px solid #dcdfe6;
+      border-radius: 4px 4px 0 0;
+      padding: 0 20px;
+      background: linear-gradient(to right, #409eff, #66b1ff);
+      color: #fff;
+      font-size: 18px;
+      font-weight: 500;
+      margin-top: 0;
+      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12), 0 0 6px rgba(0, 0, 0, 0.04);
+    }
+
+    .doc-container {
+      display: flex;
+      border: 1px solid #dcdfe6;
+      border-top: none;
+      border-radius: 0 0 4px 4px;
+      box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+      overflow: hidden;
+      min-height: 600px;
+
+      .doc-catalogue {
+        width: 200px;
+        min-height: 100%;
+        background-color: #fafafa;
+        border-right: 1px solid #dcdfe6;
+        padding: 10px 0;
+
+        .doc-catalogue-item {
+          height: 40px;
+          line-height: 40px;
+          padding: 0 20px;
+          cursor: pointer;
+          transition: all 0.3s;
+          color: #606266;
+          font-size: 14px;
+          border-left: 3px solid transparent;
+
+          &:hover {
+            color: #409eff;
+            background-color: #ecf5ff;
+            border-left-color: #409eff;
+          }
+
+          &:active {
+            background-color: #b3d8ff;
+          }
+        }
+      }
+
+      .doc-content {
+        flex: 1;
+        min-height: 600px;
+        padding: 40px;
+        background-color: #fff;
+        position: relative;
+
+        .doc-content-item {
+          width: 100%;
+          min-height: 500px;
+          padding: 20px;
+          background-color: #fafafa;
+          border: 1px solid #e4e7ed;
+          border-radius: 4px;
+          box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1);
+        }
+      }
+    }
+  }
+
+  /* 表格操作按钮样式优化 */
+  .action-buttons {
+    display: inline-flex;
+    gap: 8px;
+  }
+
+  /* 查看模式容器样式 - 置灰所有内容 */
+  .view-mode-container {
+    pointer-events: none;
+
+    .el-input,
+    .el-input-number,
+    .el-select,
+    .el-date-picker,
+    .el-textarea {
+      pointer-events: none;
+    }
+
+    .el-input__inner,
+    .el-input-number__input-inner,
+    .el-select__input,
+    .el-textarea__inner {
+      background-color: #f5f7fa;
+      border-color: #e4e7ed;
+      color: #909399;
+      cursor: not-allowed;
+    }
+
+    .el-select .el-input.is-disabled .el-input__inner {
+      background-color: #f5f7fa;
+      border-color: #e4e7ed;
+      color: #909399;
+      cursor: not-allowed;
+    }
+
+    .el-date-editor.el-input {
+      .el-input__inner {
+        background-color: #f5f7fa;
+        border-color: #e4e7ed;
+        color: #909399;
+        cursor: not-allowed;
+      }
+    }
+
+    .el-input-number.is-disabled .el-input__inner {
+      background-color: #f5f7fa;
+      border-color: #e4e7ed;
+      color: #909399;
+      cursor: not-allowed;
+    }
+  }
+
+  /* 响应式优化 */
+  @media (max-width: 1200px) {
+    .archive-container {
+      padding: 15px;
+    }
+
+    .custom-steps {
+      padding: 15px;
+    }
+
+    .preview-content {
+      .doc-container {
+        flex-direction: column;
+
+        .doc-catalogue {
+          width: 100%;
+          border-right: none;
+          border-bottom: 1px solid #dcdfe6;
+          display: flex;
+          overflow-x: auto;
+
+          .doc-catalogue-item {
+            white-space: nowrap;
+            flex-shrink: 0;
+          }
+        }
+
+        .doc-content {
+          min-height: 400px;
+          padding: 20px;
+        }
+      }
+    }
+  }
+</style>

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 22 - 859
src/views/costAudit/auditInfo/archivesManage/pendingArchiveList.vue


Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio