shiyanyu před 1 týdnem
rodič
revize
6cdc4b3cc2

+ 12 - 0
src/api/uc.js

@@ -122,3 +122,15 @@ export function getOrgUserQuery(params) {
     data: params,
   })
 }
+
+export function getUserList(params = {}) {
+  const { projectId, type } = params
+  return request({
+    url: `${uc}/api/costProjectTask/v1/taskUser`,
+    method: 'get',
+    params: {
+      projectId,
+      type,
+    },
+  })
+}

+ 102 - 9
src/views/EntDeclaration/auditTaskManagement/components/CostSurveyTab.vue

@@ -666,8 +666,9 @@
       },
       // 动态表-数据下载
       async handleDataDownload(row) {
+        let loading
         try {
-          const loading = this.$loading({
+          loading = this.$loading({
             lock: true,
             text: '数据下载中...',
             spinner: 'el-icon-loading',
@@ -681,19 +682,82 @@
           const versionId =
             (row && (row.versionId || row.version || row.templateVersionId)) ||
             ''
-          // if (!surveyTemplateId || !versionId) {
-          //   loading.close()
-          //   this.$message &&
-          //     this.$message.warning &&
-          //     this.$message.warning('缺少模板或版本信息,无法下载')
-          //   return
-          // }
+
           const params = { surveyTemplateId, versionId, type: 1 }
           // 追加 taskId(来自行或页面 props)
           const taskId = (row && (row.taskId || row.taskID)) || this.taskId
           if (taskId) params.taskId = taskId
           const res = await downloadTemplate(params)
-          loading.close()
+
+          // 下载接口可能返回两类数据:
+          // 1) 正常:Blob(xlsx)
+          // 2) 异常:JSON({code:500,state:false,message:'...'}),但由于 responseType=blob,前端拿到的可能仍是 Blob
+          const getJsonFromBlobIfPossible = async (blob) => {
+            if (!(blob instanceof Blob)) return null
+            // 若后端明确返回 json 类型,可优先解析
+            const type = (blob.type || '').toLowerCase()
+            if (
+              !type.includes('application/json') &&
+              !type.includes('text/json') &&
+              !type.includes('application/problem+json')
+            ) {
+              // 有些后端 content-type 可能仍是 octet-stream,但内容是 json;这里也尝试一次解析
+              // 解析失败则返回 null
+            }
+            try {
+              const text = await blob.text()
+              if (!text) return null
+              return JSON.parse(text)
+            } catch (e) {
+              return null
+            }
+          }
+
+          // 优先从 res / res.data 判定是否为 JSON
+          let maybeJson = null
+          if (
+            res &&
+            res.data &&
+            typeof res.data === 'object' &&
+            !(res.data instanceof Blob)
+          ) {
+            maybeJson = res.data
+          } else if (
+            res &&
+            typeof res === 'object' &&
+            !(res instanceof Blob) &&
+            !(res.data instanceof Blob)
+          ) {
+            // 兼容:有些封装直接返回对象
+            maybeJson = res
+          } else if (res && res.data instanceof Blob) {
+            maybeJson = await getJsonFromBlobIfPossible(res.data)
+          } else if (res instanceof Blob) {
+            maybeJson = await getJsonFromBlobIfPossible(res)
+          }
+
+          console.log('下载模板接口返回数据:', maybeJson)
+
+          // 如果是错误 JSON:提示 message
+          if (
+            maybeJson &&
+            (maybeJson.state === false ||
+              (maybeJson.code !== undefined &&
+                maybeJson.code !== null &&
+                ![0, 200].includes(Number(maybeJson.code))))
+          ) {
+            const msg =
+              maybeJson.message ||
+              maybeJson.msg ||
+              '导出失败:该表存在跨表引用且部分年份数据缺失,请先完善后再下载'
+            this.$message && this.$message.warning && this.$message.warning(msg)
+            loading && loading.close()
+            return
+          }
+
+          // 关闭 loading(成功走下载)
+          if (loading && loading.close) loading.close()
+
           // 处理响应数据(可能是 axios 响应或直接 Blob)
           const headers = (res && res.headers) || {}
           const contentDisposition =
@@ -720,6 +784,35 @@
             this.$message.success &&
             this.$message.success('开始下载文件')
         } catch (e) {
+          // 兼容:axios 抛错时,错误信息可能在 e.response.data(同样可能是 Blob)
+          try {
+            const errRes = e && e.response
+            const errData = errRes && errRes.data
+            let errJson = null
+            if (
+              errData &&
+              typeof errData === 'object' &&
+              !(errData instanceof Blob)
+            ) {
+              errJson = errData
+            } else if (errData instanceof Blob) {
+              try {
+                const text = await errData.text()
+                errJson = text ? JSON.parse(text) : null
+              } catch (_) {
+                errJson = null
+              }
+            }
+            if (errJson && (errJson.message || errJson.msg)) {
+              this.$message &&
+                this.$message.warning &&
+                this.$message.warning(errJson.message || errJson.msg)
+            }
+          } catch (_) {
+            // ignore
+          }
+
+          if (loading && loading.close) loading.close()
           console.error('数据下载失败: ', e)
         }
       },

+ 109 - 28
src/views/EntDeclaration/auditTaskManagement/components/DataRequirementsTab.vue

@@ -1031,16 +1031,17 @@
       // 处理模板下载
       async handleTemplateDownload(row) {
         console.log(row)
+        let loading
         try {
           // 显示加载提示
-          const loading = this.$loading({
+          loading = this.$loading({
             lock: true,
             text: '模板下载中...',
             spinner: 'el-icon-loading',
             background: 'rgba(0, 0, 0, 0.7)',
           })
 
-          // 构建请求参数,根据实际接口需求调整
+          // 构建请求参数
           const params = { type: 2 }
           const surveyTemplateId = this.getSurveyTemplateId(row)
           if (surveyTemplateId) {
@@ -1051,49 +1052,96 @@
           if (taskId || this.taskId) {
             params.taskId = taskId || this.taskId
           }
-          // if (row.materialId) {
-          //   params.materialId = row.materialId
-          // }
-          // 如果接口需要其他参数,可以继续添加
 
-          // 调用下载接口
           const response = await downloadTemplate(params)
 
-          // 关闭加载提示
-          loading.close()
+          // 下载接口可能返回两类数据:
+          // 1) 正常:Blob(xlsx)
+          // 2) 异常:JSON({code:500,state:false,message:'...'}),但由于 responseType=blob,前端拿到的可能仍是 Blob
+          const getJsonFromBlobIfPossible = async (blob) => {
+            if (!(blob instanceof Blob)) return null
+            try {
+              const text = await blob.text()
+              if (!text) return null
+              return JSON.parse(text)
+            } catch (e) {
+              return null
+            }
+          }
+
+          let maybeJson = null
+          if (
+            response &&
+            response.data &&
+            typeof response.data === 'object' &&
+            !(response.data instanceof Blob)
+          ) {
+            maybeJson = response.data
+          } else if (
+            response &&
+            typeof response === 'object' &&
+            !(response instanceof Blob) &&
+            !(response.data instanceof Blob)
+          ) {
+            maybeJson = response
+          } else if (response && response.data instanceof Blob) {
+            maybeJson = await getJsonFromBlobIfPossible(response.data)
+          } else if (response instanceof Blob) {
+            maybeJson = await getJsonFromBlobIfPossible(response)
+          }
+
+          console.log('下载模板接口返回数据:', maybeJson)
+
+          if (
+            maybeJson &&
+            (maybeJson.state === false ||
+              (maybeJson.code !== undefined &&
+                maybeJson.code !== null &&
+                ![0, 200].includes(Number(maybeJson.code))))
+          ) {
+            const msg =
+              maybeJson.message ||
+              maybeJson.msg ||
+              '导出失败:该表存在跨表引用且部分年份数据缺失,请先完善后再下载'
+            this.$message && this.$message.warning && this.$message.warning(msg)
+            return
+          }
 
           // 处理响应数据
           // response 可能是 { data, headers } 格式,也可能是直接的 Blob
-          let blob = response.data || response
-          let fileName = ''
-          const headers = response.headers || {}
+          const blobData = (response && response.data) || response
+          const blob =
+            blobData instanceof Blob ? blobData : new Blob([blobData])
 
-          // 尝试从响应头中获取文件名
-          if (headers['content-disposition']) {
-            const contentDisposition = headers['content-disposition']
+          // 文件名:优先从响应头获取
+          let fileName = ''
+          const headers = (response && response.headers) || {}
+          const contentDisposition =
+            headers['content-disposition'] || headers['Content-Disposition']
+          if (contentDisposition) {
             const fileNameMatch = contentDisposition.match(
               /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/
             )
             if (fileNameMatch && fileNameMatch[1]) {
-              fileName = decodeURIComponent(
-                fileNameMatch[1].replace(/['"]/g, '')
-              )
+              try {
+                fileName = decodeURIComponent(
+                  fileNameMatch[1].replace(/['"]/g, '')
+                )
+              } catch (e) {
+                fileName = fileNameMatch[1].replace(/['"]/g, '')
+              }
             }
           }
 
-          // 如果响应头中没有文件名,使用默认文件名
           if (!fileName) {
-            const defaultName = row.informationName || row.name || '模板文件'
+            const defaultName = row?.informationName || row?.name || '模板文件'
             fileName = `${defaultName}_模板.xlsx`
           }
-
-          // 确保文件名有扩展名
           if (!/\.[a-zA-Z0-9]+$/.test(fileName)) {
             fileName += '.xlsx'
           }
 
-          // 创建 Blob URL 并触发下载
-          const url = window.URL.createObjectURL(new Blob([blob]))
+          const url = window.URL.createObjectURL(blob)
           const link = document.createElement('a')
           link.style.display = 'none'
           link.href = url
@@ -1101,14 +1149,47 @@
           document.body.appendChild(link)
           link.click()
           document.body.removeChild(link)
-
-          // 释放 URL 对象
           window.URL.revokeObjectURL(url)
 
-          this.$message.success('模板下载成功')
+          this.$message &&
+            this.$message.success &&
+            this.$message.success('开始下载文件')
         } catch (error) {
+          // 兼容:axios 抛错时,错误信息可能在 error.response.data(同样可能是 Blob)
+          try {
+            const errRes = error && error.response
+            const errData = errRes && errRes.data
+            let errJson = null
+            if (
+              errData &&
+              typeof errData === 'object' &&
+              !(errData instanceof Blob)
+            ) {
+              errJson = errData
+            } else if (errData instanceof Blob) {
+              try {
+                const text = await errData.text()
+                errJson = text ? JSON.parse(text) : null
+              } catch (_) {
+                errJson = null
+              }
+            }
+            if (errJson && (errJson.message || errJson.msg)) {
+              this.$message &&
+                this.$message.warning &&
+                this.$message.warning(errJson.message || errJson.msg)
+              return
+            }
+          } catch (_) {
+            // ignore
+          }
+
           console.error('模板下载失败:', error)
-          this.$message.error(error.message || '模板下载失败,请稍后重试')
+          this.$message &&
+            this.$message.error &&
+            this.$message.error(error.message || '模板下载失败,请稍后重试')
+        } finally {
+          if (loading && loading.close) loading.close()
         }
       },
       // 以下为在线填报所需方法,与 CostSurveyTab 对齐

+ 1 - 0
src/views/costAudit/auditInfo/archivesManage/archiveList.vue

@@ -361,6 +361,7 @@
       },
       // 档案详情预览
       handleArchivePreview(row) {
+        console.log('row', row)
         if (!row.archiveUrl) {
           this.$message.error('文件预览地址不存在')
           return

+ 58 - 0
src/views/costAudit/auditInfo/auditManage/details.vue

@@ -98,6 +98,7 @@
           >
             <audit-opinion
               :id="id"
+              ref="auditOpinion"
               :key="opinionKey"
               :current-node="currentNode"
               :current-status="currentStatus"
@@ -105,6 +106,7 @@
               @close="handleClose"
             />
           </el-tab-pane>
+
           <el-tab-pane label="消息通知" name="messageNotify">
             <message-notify :id="id" ref="messageNotify" />
           </el-tab-pane>
@@ -372,6 +374,17 @@
                 }
               })
             }
+            // 若程序设置的活动标签页为“成本审核意见”,切换过来就调接口刷新
+            if (this.activeTab === 'auditOpinion') {
+              this.$nextTick(() => {
+                if (
+                  this.$refs.auditOpinion &&
+                  this.$refs.auditOpinion.getPreliminaryOpinionData
+                ) {
+                  this.$refs.auditOpinion.getPreliminaryOpinionData()
+                }
+              })
+            }
           })
         }
       },
@@ -399,6 +412,17 @@
                 }
               })
             }
+            // 如果当前应显示“成本审核意见”,主动触发加载
+            if (this.activeTab === 'auditOpinion') {
+              this.$nextTick(() => {
+                if (
+                  this.$refs.auditOpinion &&
+                  this.$refs.auditOpinion.getPreliminaryOpinionData
+                ) {
+                  this.$refs.auditOpinion.getPreliminaryOpinionData()
+                }
+              })
+            }
           })
         }
       },
@@ -441,6 +465,17 @@
                 }
               })
             }
+            // 若当前为成本审核意见标签,主动加载
+            if (this.activeTab === 'auditOpinion') {
+              this.$nextTick(() => {
+                if (
+                  this.$refs.auditOpinion &&
+                  this.$refs.auditOpinion.getPreliminaryOpinionData
+                ) {
+                  this.$refs.auditOpinion.getPreliminaryOpinionData()
+                }
+              })
+            }
           })
         }
       },
@@ -469,6 +504,17 @@
               }
             })
           }
+          // 如果默认即处于成本审核意见页签,也要主动触发加载
+          if (this.activeTab === 'auditOpinion') {
+            this.$nextTick(() => {
+              if (
+                this.$refs.auditOpinion &&
+                this.$refs.auditOpinion.getPreliminaryOpinionData
+              ) {
+                this.$refs.auditOpinion.getPreliminaryOpinionData()
+              }
+            })
+          }
         })
       }
     },
@@ -550,6 +596,18 @@
             }
           })
         }
+        if (tab && tab.name === 'auditOpinion' && this.id) {
+          // 切换到成本审核意见时,立即调接口刷新
+          this.$nextTick(() => {
+            if (
+              this.$refs.auditOpinion &&
+              this.$refs.auditOpinion.getPreliminaryOpinionData
+            ) {
+              this.$refs.auditOpinion.getPreliminaryOpinionData()
+            }
+          })
+        }
+
         if (tab && tab.name === 'workDraft' && this.id) {
           // 切换到工作底稿时,主动刷新(走接口)
           this.$nextTick(() => {

+ 23 - 6
src/views/costAudit/auditInfo/auditManage/index.vue

@@ -162,16 +162,16 @@
               >
                 审核
               </el-button>
-              <!-- <el-button
+              <el-button
                 v-if="
-                  scope.row.currentNode === 'yjfk' &&
-                  scope.row.status === '200'
+                  scope.row.currentNode === 'jtsy' && scope.row.status === '260'
                 "
                 type="text"
-                @click="handleOpenDetails(scope.row)"
+                @click="handleOpenDetails(scope.row, 'auditOpinion')"
               >
                 审核
-              </el-button> -->
+              </el-button>
+
               <!-- <el-button
                 v-if="scope.row.status === '300'"
                 type="text"
@@ -411,7 +411,8 @@
 
       // 搜索
       handleSearch() {
-        // 搜索逻辑
+        // 查询时重置到第一页
+        this.pageNum = 1
         this.loadAuditProjectList()
       },
 
@@ -462,8 +463,24 @@
           if (this.$refs.detailsRef) {
             this.$refs.detailsRef.open()
           }
+
+          // “审核1”:打开弹窗后,自动切换到“成本审核意见”页签
+          // 注意:details.vue 在 visible watcher 里会调用 setActiveTab(),可能覆盖父组件设置
+          // 因此这里用一次异步延迟,确保在其默认逻辑之后再强制切换
+          if (type === 'auditOpinion') {
+            setTimeout(() => {
+              const dlg = this.$refs.detailsRef
+              if (!dlg) return
+              dlg.activeTab = 'auditOpinion'
+              // 主动触发一次 tab-click 对应逻辑(刷新接口)
+              if (typeof dlg.handleTabClick === 'function') {
+                dlg.handleTabClick({ name: 'auditOpinion' })
+              }
+            }, 80)
+          }
         })
       },
+
       handleOpenMainDetails(project) {
         // console.log('project', project)
         this.selectedProject = project

+ 15 - 4
src/views/costAudit/baseInfo/costFormManage/infoMaintain.vue

@@ -2394,11 +2394,22 @@
 
         const jsonstr = JSON.stringify(jsonStrArray)
 
-        // calculationTemplateId:选中的模版id拼接(逗号分隔)
+        // calculationTemplateId:选中的 surveyTemplateId 拼接(逗号分隔)
+        // selectedTemplateId 存的是 option 的 pkVal(版本/记录主键),这里需要映射到 surveyTemplateId
         const calculationTemplateId = Array.isArray(this.selectedTemplateId)
-          ? this.selectedTemplateId
-              .filter((x) => x !== undefined && x !== null && x !== '')
-              .join(',')
+          ? Array.from(
+              new Set(
+                this.selectedTemplateId
+                  .filter((x) => x !== undefined && x !== null && x !== '')
+                  .map((pkVal) => {
+                    const t = this.templateList.find(
+                      (item) => item.pkVal === pkVal
+                    )
+                    return t ? t.surveyTemplateId : ''
+                  })
+                  .filter((x) => x !== undefined && x !== null && x !== '')
+              )
+            ).join(',')
           : ''
 
         // 更新当前编辑行的计算公式值

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

@@ -197,7 +197,7 @@
             <el-button
               type="text"
               size="small"
-              @click="handleDownloadFile(scope.row)"
+              @click="handleArchivePreview(scope.row)"
             >
               监审卷宗
             </el-button>
@@ -235,6 +235,32 @@
       :current-node="cbjsInfoData && cbjsInfoData.currentNode"
       :current-status="cbjsInfoData && cbjsInfoData.status"
     />
+
+    <!-- 档案详情预览弹窗(监审卷宗) -->
+    <el-dialog
+      :visible.sync="previewDialogVisible"
+      :width="isMaximized ? '95%' : '65%'"
+      title="档案详情预览"
+      :close-on-click-modal="false"
+    >
+      <div slot="title" class="dialog-header-with-actions">
+        <span>档案详情预览</span>
+        <el-button type="text" size="small" @click="toggleMaximized">
+          <i :class="isMaximized ? 'el-icon-crop' : 'el-icon-full-screen'"></i>
+        </el-button>
+      </div>
+      <div
+        class="preview-container"
+        :style="{ height: isMaximized ? '80vh' : '600px' }"
+      >
+        <iframe
+          v-if="previewUrl"
+          :src="previewUrl"
+          frameborder="0"
+          class="preview-iframe"
+        ></iframe>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
@@ -245,6 +271,8 @@
   import cbjsInfo from './components/cbjsInfo.vue'
   import { getCostProjectDetail } from '@/api/taskCustomizedRelease.js'
   import { getAllUnitList } from '@/api/auditEntityManage.js'
+  import { getSysPropertiesAlias } from '@/api/properties'
+  import { Base64 } from 'js-base64'
   export default {
     name: 'ComprehensiveQuery',
     components: {
@@ -285,10 +313,20 @@
         cbjsInfoData: null,
         loading: false,
         auditedUnitOptions: [],
+
+        // 系统属性值(用于档案预览)
+        sysKkUrl: '',
+        sysPlatUrl: '',
+        // 预览对话框
+        previewDialogVisible: false,
+        previewUrl: '',
+        // 弹窗最大化状态
+        isMaximized: false,
       }
     },
     mounted() {
       this.getOptions()
+      this.getSysProperties()
       this.handleQuery()
     },
     methods: {
@@ -350,6 +388,8 @@
                 record.childTasks.forEach((child) => {
                   this.auditProjectList.push({
                     ...child,
+                    // 继承父级卷宗地址(子级没有时用父级的)
+                    archiveUrl: child.archiveUrl || record.archiveUrl,
                     // 合并列:这些列会被合并显示,使用父项的值
                     year: child.year || record.year, // 立项年度
                     areaName: child.areaName || record.areaName, // 监审地区
@@ -434,10 +474,51 @@
         this.handleQuery() // 重新加载当前页数据
       },
 
-      // 处理下载监审卷宗
+      // 获取系统属性值(用于档案预览)
+      async getSysProperties() {
+        try {
+          const kkUrlResponse = await getSysPropertiesAlias('sys_kk_url')
+          if (kkUrlResponse) {
+            this.sysKkUrl = kkUrlResponse
+          }
+
+          const platUrlResponse = await getSysPropertiesAlias('sys_plat_url')
+          if (platUrlResponse) {
+            this.sysPlatUrl = platUrlResponse
+          }
+        } catch (error) {
+          console.error('获取系统属性值失败:', error)
+        }
+      },
+
+      // 监审卷宗(档案详情预览)
+      handleArchivePreview(row) {
+        console.log('handleArchivePreview', row)
+        const archiveUrl = row && row.archiveUrl
+        if (!archiveUrl) {
+          this.$message.error('文件预览地址不存在')
+          return
+        }
+        if (!this.sysKkUrl || !this.sysPlatUrl) {
+          this.$message.error('系统预览配置缺失,请联系管理员')
+          return
+        }
+
+        this.previewUrl =
+          this.sysKkUrl +
+          encodeURIComponent(Base64.encode(this.sysPlatUrl + archiveUrl))
+        this.previewDialogVisible = true
+        this.isMaximized = false
+      },
+
+      // 切换弹窗最大化状态
+      toggleMaximized() {
+        this.isMaximized = !this.isMaximized
+      },
+
+      // 处理下载监审卷宗(旧逻辑占位,已改为预览)
       handleDownloadFile(row) {
-        console.log('下载监审卷宗:', row)
-        this.$message.success('监审卷宗功能待实现')
+        this.handleArchivePreview(row)
       },
 
       // 查看任务详情
@@ -594,4 +675,32 @@
   ::v-deep .el-table__header th {
     border-right: 1px solid #ebeef5 !important;
   }
+
+  .preview-container {
+    width: 100%;
+    height: 600px;
+  }
+
+  .preview-iframe {
+    width: 100%;
+    height: 100%;
+  }
+
+  .dialog-header-with-actions {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    width: 100%;
+    height: 36px;
+  }
+
+  .dialog-header-with-actions .el-button {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    height: 36px;
+    margin-right: 40px;
+    margin-top: -10px;
+    font-size: 18px;
+  }
 </style>

+ 40 - 45
src/views/costAudit/projectInfo/auditTaskManage/taskProgressManage/index.vue

@@ -195,7 +195,7 @@
               style="width: 100%"
             >
               <el-option
-                v-for="(item, index) in userList"
+                v-for="(item, index) in urgeUserList"
                 :key="index"
                 :label="item.fullname"
                 :value="item.userId"
@@ -241,22 +241,6 @@
           :model="urgeReportingForm"
           label-width="100px"
         >
-          <el-form-item label="被监审单位:">
-            <el-select
-              v-model="urgeReportingForm.auditedUnitIds"
-              multiple
-              clearable
-              placeholder="请选择被监审单位"
-              style="width: 100%"
-            >
-              <el-option
-                v-for="(item, index) in unitList"
-                :key="index"
-                :label="item.unitName"
-                :value="item.unitId"
-              ></el-option>
-            </el-select>
-          </el-form-item>
           <el-form-item label="催办内容:">
             <el-input
               v-model="urgeReportingForm.content"
@@ -297,7 +281,7 @@
               style="width: 100%"
             >
               <el-option
-                v-for="(item, index) in userList"
+                v-for="(item, index) in delegateUserList"
                 :key="index"
                 :label="item.fullname"
                 :value="item.userId"
@@ -363,7 +347,7 @@
   import { dictMixin } from '@/mixins/useDict'
   import { getAllUnitList } from '@/api/auditEntityManage'
   import CostAuditTable from '@/components/costAudit/CostAuditTable.vue'
-  import { getAllUserList } from '@/api/uc'
+  import { getUserList } from '@/api/uc'
   import { getCostProjectDetail } from '@/api/taskCustomizedRelease.js'
   import { doProcessBtn } from '@/api/dataPreliminaryReview'
   import TaskDetail from '@/components/task/taskDetail.vue'
@@ -534,11 +518,12 @@
           // sendType: '站内消息',
         },
         urgeReportingForm: {
-          auditedUnitIds: [],
           content: '',
         },
         unitList: [],
-        userList: [],
+        // 弹窗人员列表(按接口 getUserList(projectId,type) 动态加载)
+        delegateUserList: [], // 催办弹窗:监审组人员(type=0)
+        urgeUserList: [], // 督办弹窗:督办人员(type=1)
         // 任务详情弹窗
         taskDetailVisible: false,
         // 成本监审任务制定弹窗
@@ -547,16 +532,17 @@
     },
     mounted() {
       this.getAllUnitList()
-      this.getUser()
       this.generateTableData()
     },
     methods: {
-      getUser() {
-        getAllUserList()
-          .then((res) => {
-            this.userList = res.value || []
-          })
-          .catch(() => {})
+      async fetchUserListByProjectId({ projectId, type }) {
+        if (!projectId) return []
+        try {
+          const res = await getUserList({ projectId, type })
+          return (res && res.value) || []
+        } catch (e) {
+          return []
+        }
       },
       getStatusName(status) {
         // 100待提交、200审核中、400办结、300中止
@@ -840,7 +826,7 @@
           })
       },
       // 任务督办相关方法
-      handleUrge(row) {
+      async handleUrge(row) {
         console.log('任务督办:', row)
         this.currentTask = row
         this.urgeForm = {
@@ -848,6 +834,13 @@
           content: '',
           // sendType: [],
         }
+
+        const projectId = row?.projectId || row?.projectID || row?.id || ''
+        this.urgeUserList = await this.fetchUserListByProjectId({
+          projectId,
+          type: 1,
+        })
+
         this.showUrgeForm = true
       },
       handleUrgeCancel() {
@@ -857,6 +850,7 @@
           content: '',
           // sendType: [],
         }
+        this.urgeUserList = []
       },
       handleUrgeSubmit() {
         if (!this.currentTask) return
@@ -902,7 +896,7 @@
           })
       },
       // 任务代办相关方法
-      handleDelegate(row) {
+      async handleDelegate(row) {
         console.log('任务代办:', row)
         this.currentTask = row
         this.showDelegateForm = true
@@ -910,6 +904,12 @@
           userIds: [],
           content: '',
         }
+
+        const projectId = row?.projectId || row?.projectID || row?.id || ''
+        this.delegateUserList = await this.fetchUserListByProjectId({
+          projectId,
+          type: 0,
+        })
       },
       handleDelegateCancel() {
         this.showDelegateForm = false
@@ -918,6 +918,7 @@
           content: '',
           // sendType: '站内消息',
         }
+        this.delegateUserList = []
       },
       handleDelegateSubmit() {
         if (!this.currentTask) return
@@ -1009,44 +1010,38 @@
       // 催报
       handleUrgeReporting(row) {
         this.currentTask = row
-        const ids =
-          row && row.auditedUnitId
-            ? String(row.auditedUnitId).split(',').filter(Boolean)
-            : []
         this.urgeReportingForm = {
-          auditedUnitIds: ids,
           content: '',
         }
         this.showUrgeReportingForm = true
       },
       handleUrgeReportingCancel() {
         this.showUrgeReportingForm = false
-        this.urgeReportingForm = { auditedUnitIds: [], content: '' }
+        this.urgeReportingForm = { content: '' }
         this.currentTask = null
       },
       handleUrgeReportingSubmit() {
         if (!this.currentTask) return
-        if (
-          !Array.isArray(this.urgeReportingForm.auditedUnitIds) ||
-          this.urgeReportingForm.auditedUnitIds.length === 0
-        ) {
-          this.$message.warning('请选择被监审单位')
-          return
-        }
+
+        // 不再由弹窗选择被监审单位:默认取当前行的 auditedUnitId
+        const auditedUnitIds = this.currentTask.auditedUnitId
+          ? String(this.currentTask.auditedUnitId)
+          : ''
+
         const params = {
           taskId: this.currentTask.id,
           key: 10,
           status: this.currentTask.status,
           processNodeKey: this.currentTask.currentNode,
           remark: this.urgeReportingForm.content,
-          auditedUnitIds: this.urgeReportingForm.auditedUnitIds.join(','),
+          auditedUnitIds,
         }
         doProcessBtn(params)
           .then((res) => {
             if (res && Number(res.code) === 200) {
               this.$message.success('催报信息已发送')
               this.showUrgeReportingForm = false
-              this.urgeReportingForm = { auditedUnitIds: [], content: '' }
+              this.urgeReportingForm = { content: '' }
               this.currentTask = null
               this.generateTableData()
             } else {

+ 1 - 0
src/views/costAudit/projectInfo/taskSuperviseManage/superviseMattersManage/index.vue

@@ -272,6 +272,7 @@
       TaskDetail,
       cbjsInfo,
       TaskCustomizedReleaseDialog,
+      UploadComponent,
     },
     mixins: [dictMixin],
     data() {