瀏覽代碼

feat: 任务进度管理中止、催报、催办完成,详情查看引入

shiyanyu 1 月之前
父節點
當前提交
e75261b2c5

+ 168 - 0
src/components/task/taskComponents/conclusionTab.vue

@@ -0,0 +1,168 @@
+<template>
+  <!-- 出具结论内容(只读默认) -->
+  <div class="conclusion-section">
+    <!-- <el-button v-if="!isView" type="primary" style="margin-bottom: 20px">
+      保存
+    </el-button> -->
+
+    <el-form
+      ref="conclusionForm"
+      :model="conclusionForm"
+      label-width="150px"
+      class="conclusion-form"
+      :disabled="true"
+    >
+      <el-row>
+        <el-col :span="24">
+          <el-form-item label="定价成本构成">
+            <el-input
+              v-model="conclusionForm.pricingCostStructure"
+              type="textarea"
+              :rows="4"
+              placeholder="填写 (非必填)"
+              style="width: 100%"
+            />
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-row>
+        <el-col :span="24">
+          <el-form-item label="审核的内容和方法">
+            <el-input
+              v-model="conclusionForm.auditContentMethod"
+              type="textarea"
+              :rows="4"
+              placeholder="填写 (非必填)"
+              style="width: 100%"
+            />
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-row>
+        <el-col :span="24">
+          <el-form-item label="成本费用项目核销(减)情况及理由">
+            <el-input
+              v-model="conclusionForm.costDeductionReason"
+              type="textarea"
+              :rows="4"
+              placeholder="填写 (非必填)"
+              style="width: 100%"
+            />
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-row>
+        <el-col :span="24">
+          <el-form-item label="成本监审结论">
+            <el-input
+              v-model="conclusionForm.costAuditConclusion"
+              type="textarea"
+              :rows="4"
+              placeholder="填写 (非必填)"
+              style="width: 100%"
+            />
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-row>
+        <el-col :span="24">
+          <el-form-item label="违约情况说明">
+            <el-input
+              v-model="conclusionForm.defaultConditions"
+              type="textarea"
+              :rows="4"
+              placeholder="填写 (非必填)"
+              style="width: 100%"
+            />
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+      <el-row>
+        <el-col :span="24">
+          <el-form-item label="其他需要说明的事项">
+            <el-input
+              v-model="conclusionForm.otherExplanations"
+              type="textarea"
+              :rows="4"
+              placeholder="填写 (非必填)"
+              style="width: 100%"
+            />
+          </el-form-item>
+        </el-col>
+      </el-row>
+    </el-form>
+  </div>
+</template>
+
+<script>
+  import { getConclusionDetail } from '@/api/taskProgressManage'
+  export default {
+    name: 'ConclusionTabReadonly',
+    props: {
+      project: { type: Object, default: () => ({}) },
+    },
+    data() {
+      return {
+        conclusionForm: {
+          pricingCostStructure: '',
+          auditContentMethod: '',
+          costDeductionReason: '',
+          costAuditConclusion: '',
+          defaultConditions: '',
+          otherExplanations: '',
+          conclusionStatus: '',
+          projectId: '',
+        },
+      }
+    },
+    watch: {
+      project: {
+        handler() {
+          this.getConclusionDetails()
+        },
+        immediate: true,
+        deep: false,
+      },
+    },
+    methods: {
+      getConclusionDetails() {
+        if (!this.project || !this.project.projectId) return
+        getConclusionDetail({ projectId: this.project.projectId }).then(
+          (res) => {
+            if (res && res.code === 200) {
+              const v = (res && res.value) || {}
+              this.conclusionForm = {
+                pricingCostStructure: v.pricingCostStructure || '',
+                auditContentMethod: v.auditContentMethod || '',
+                costDeductionReason: v.costDeductionReason || '',
+                costAuditConclusion: v.costAuditConclusion || '',
+                defaultConditions: v.defaultConditions || '',
+                otherExplanations: v.otherExplanations || '',
+                conclusionStatus: v.conclusionStatus || '',
+                projectId:
+                  v.projectId || (this.project && this.project.projectId) || '',
+              }
+            }
+          }
+        )
+      },
+    },
+  }
+</script>
+
+<style lang="scss" scoped>
+  /* 强制置灰禁用态的输入框与文本域 */
+  ::v-deep .el-input.is-disabled .el-input__inner {
+    background-color: #f5f7fa !important;
+    color: #c0c4cc !important;
+  }
+  ::v-deep .el-textarea.is-disabled .el-textarea__inner {
+    background-color: #f5f7fa !important;
+    color: #c0c4cc !important;
+  }
+</style>

+ 408 - 0
src/components/task/taskComponents/discussionTab.vue

@@ -0,0 +1,408 @@
+<template>
+  <!-- 集体审议内容(只读默认) -->
+  <div class="meeting-section">
+    <!-- 系统记录 -->
+    <div class="system-records">
+      <!-- <el-button
+        v-if="!isView"
+        style="margin-bottom: 20px"
+        plain
+        type="success"
+        icon="el-icon-circle-plus"
+        @click="addMeetingRecord"
+      >
+        添加记录
+      </el-button> -->
+      <CostAuditTable
+        :table-data="meetingRecords"
+        :columns="tableColumns"
+        :show-index="true"
+        :border="true"
+        style="width: 100%"
+        :show-pagination="true"
+        :pagination="pagination"
+        @size-change="handlePageSizeChange"
+        @current-change="handleCurrentChange"
+      >
+        <!-- 附件列自定义内容 -->
+        <template #attachments="{ row }">
+          <el-button
+            type="text"
+            size="small"
+            @click="viewMeetingAttachment(row)"
+          >
+            查看
+          </el-button>
+        </template>
+        <!-- 操作列自定义内容 -->
+        <template #action="{ row }">
+          <el-button
+            type="text"
+            size="small"
+            @click="handleViewMeetingRecord(row)"
+          >
+            查看
+          </el-button>
+          <!-- <el-button v-if="!isView" :disabled="isView" type="text" size="small" @click="editMeetingRecord(row)">
+            修改
+          </el-button>
+          <el-button v-if="!isView" type="text" size="small" class="delete-btn" @click="deleteMeetingRecord(row.id)">
+            删除
+          </el-button> -->
+        </template>
+      </CostAuditTable>
+    </div>
+    <!-- 集体审议记录表单 -->
+    <el-dialog
+      title="集体审议记录"
+      :visible.sync="meetingDialogVisible"
+      width="60%"
+      class="meeting-form-section"
+    >
+      <el-form
+        ref="meetingForm"
+        :model="meetingForm"
+        label-width="120px"
+        class="meeting-form"
+        :disabled="isView"
+      >
+        <el-row :gutter="20">
+          <el-col :span="24">
+            <el-form-item label="审议形式">
+              <el-input
+                v-model="meetingForm.deliberationForm"
+                placeholder="请填写"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="审议时间开始">
+              <el-date-picker
+                v-model="meetingForm.beginTime"
+                type="datetime"
+                placeholder="选择开始时间"
+                style="width: 100%"
+                format="yyyy-MM-dd HH:mm"
+                value-format="yyyy-MM-dd HH:mm"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="审议时间结束">
+              <el-date-picker
+                v-model="meetingForm.endTime"
+                type="datetime"
+                placeholder="选择结束时间"
+                style="width: 100%"
+                format="yyyy-MM-dd HH:mm"
+                value-format="yyyy-MM-dd HH:mm"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="24">
+            <el-form-item label="地点">
+              <el-input
+                v-model="meetingForm.location"
+                placeholder="请填写"
+                style="width: 100%"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="主持人">
+              <el-select
+                v-model="meetingForm.hostPerson"
+                placeholder="请选择人员"
+                style="width: 100%"
+              >
+                <el-option
+                  v-for="person in personList"
+                  :key="person.id"
+                  :label="person.name"
+                  :value="person.name"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="记录人">
+              <el-select
+                v-model="meetingForm.recordPerson"
+                placeholder="请选择人员"
+                style="width: 100%"
+              >
+                <el-option
+                  v-for="person in personList"
+                  :key="person.id"
+                  :label="person.name"
+                  :value="person.name"
+                ></el-option>
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="参加人员">
+              <el-input
+                v-model="meetingForm.participants"
+                placeholder="请填写"
+                style="width: 100%"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="审议项目">
+              <el-input
+                v-model="meetingForm.projectName"
+                placeholder="自动获取项目名称"
+                style="width: 100%"
+                disabled
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="监审单位id">
+              <el-input
+                v-model="meetingForm.enterpriseId"
+                placeholder="自动获取监审单位id"
+                style="width: 100%"
+                disabled
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="审议情况">
+              <el-input
+                v-model="meetingForm.deliberationContent"
+                type="textarea"
+                :rows="4"
+                placeholder="填写"
+                style="width: 100%"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="审议结论意见">
+              <el-input
+                v-model="meetingForm.conclusionOpinion"
+                type="textarea"
+                :rows="4"
+                placeholder="填写"
+                style="width: 100%"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="审议记录附件">
+              <UploadComponent
+                :upload-mode="'multiple'"
+                :files-list="meetingAttachmentList"
+                button-text="选择文件"
+                :is-disabled="isView"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="meetingDialogVisible = false">关闭</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+  import CostAuditTable from '@/components/costAudit/CostAuditTable.vue'
+  import UploadComponent from '@/components/costAudit/UploadComponent.vue'
+  import { getDeliberatePageList } from '@/api/taskProgressManage'
+  export default {
+    name: 'DiscussionTab',
+    components: { CostAuditTable, UploadComponent },
+    props: {
+      project: { type: Object, default: () => ({}) },
+      // 默认只读
+      isView: { type: Boolean, default: true },
+    },
+    data() {
+      return {
+        meetingDialogVisible: false,
+        // 集体审议相关数据
+        meetingRecords: [],
+
+        // 集体审议表单数据
+        meetingForm: {
+          deliberationForm: '',
+          beginTime: '',
+          endTime: '',
+          location: '',
+          hostPerson: '',
+          recordPerson: '',
+          participants: '',
+          projectName: '',
+          enterpriseId: '',
+          deliberationContent: '',
+          conclusionOpinion: '',
+          attachmentName: '',
+          attachmentIds: '',
+        },
+        // 附件列表
+        meetingAttachmentList: [],
+        // 分页相关
+        pagination: {
+          currentPage: 1,
+          pageSize: 10,
+          total: 0,
+        },
+        // 表格列配置
+        tableColumns: [
+          {
+            prop: 'deliberationForm',
+            label: '审议形式',
+            align: 'left',
+            width: 100,
+          },
+          { prop: 'location', label: '地点', align: 'left' },
+          { prop: 'hostPerson', label: '主持人', align: 'center', width: 120 },
+          { prop: 'beginTime', label: '审议时间', align: 'center', width: 150 },
+          {
+            prop: 'attachments',
+            label: '附件',
+            align: 'center',
+            width: 60,
+            slotName: 'attachments',
+          },
+          {
+            prop: 'action',
+            label: '操作',
+            align: 'center',
+            width: 150,
+            slotName: 'action',
+            showOverflowTooltip: false,
+          },
+        ],
+        // 人员选择列表(占位)
+        personList: [
+          { id: '1', name: '张**' },
+          { id: '2', name: '李**' },
+          { id: '3', name: '王**' },
+        ],
+      }
+    },
+    mounted() {
+      this.getMeetingRecords()
+    },
+    methods: {
+      addMeetingRecord() {
+        this.meetingForm = {
+          deliberationForm: '',
+          beginTime: '',
+          endTime: '',
+          location: '',
+          hostPerson: '',
+          recordPerson: '',
+          participants: '',
+          projectName: '',
+          enterpriseId: '',
+          deliberationContent: '',
+          conclusionOpinion: '',
+          attachmentName: '',
+          attachmentIds: '',
+        }
+        // 清空附件列表
+        this.meetingAttachmentList = []
+        this.meetingDialogVisible = true
+      },
+      getMeetingRecords() {
+        getDeliberatePageList({
+          projectId: this.project.id,
+          pageNum: this.pagination.currentPage,
+          pageSize: this.pagination.pageSize,
+        }).then((res) => {
+          if (res.value && res.value.value) {
+            this.meetingRecords = res.value.value.records || []
+            this.pagination.total = res.value.value.total || 0
+          }
+        })
+      },
+      handleEditMeetingRecord(row) {
+        this.meetingForm = { ...row }
+        // 处理附件列表回显
+        if (row.attachmentIds) {
+          this.meetingAttachmentList = row.attachmentIds
+            .split(',')
+            .map((id) => ({
+              id,
+              fileName: row.attachmentName,
+              status: 'success',
+            }))
+        } else {
+          this.meetingAttachmentList = []
+        }
+        this.meetingDialogVisible = true
+      },
+      handleDeleteMeetingRecord(row) {},
+      handleViewMeetingRecord(row) {
+        this.meetingForm = { ...row }
+        if (row.attachmentIds) {
+          this.meetingAttachmentList = row.attachmentIds
+            .split(',')
+            .map((id) => ({
+              id,
+              fileName: row.attachmentName,
+              status: 'success',
+            }))
+        } else {
+          this.meetingAttachmentList = []
+        }
+        this.meetingDialogVisible = true
+      },
+      // 查看附件
+      viewMeetingAttachment(row) {
+        if (row.attachmentIds) {
+          this.$message &&
+            this.$message.info &&
+            this.$message.info('查看附件功能待实现')
+        } else {
+          this.$message &&
+            this.$message.warning &&
+            this.$message.warning('没有附件可供查看')
+        }
+      },
+      // 分页大小变化
+      handlePageSizeChange(pageSize) {
+        this.pagination.pageSize = pageSize
+        this.pagination.currentPage = 1
+        this.getMeetingRecords()
+      },
+      // 当前页码变化
+      handleCurrentChange(currentPage) {
+        this.pagination.currentPage = currentPage
+        this.getMeetingRecords()
+      },
+    },
+  }
+</script>
+
+<style lang="scss" scoped>
+  @import '@/styles/costAudit.scss';
+</style>

+ 21 - 12
src/components/task/taskDetail.vue

@@ -61,18 +61,8 @@
             :survey-data="surveyData"
             :survey-data="surveyData"
           />
           />
         </el-tab-pane>
         </el-tab-pane>
-
-        <!-- 监审工作流程 -->
-        <el-tab-pane label="监审工作流程" name="workflow">
-          <workflowTab
-            :project="actualProject"
-            :is-view="isView"
-            :workflow-data.sync="workflowData"
-          />
-        </el-tab-pane>
-
-        <!-- 监审通知 -->
-        <el-tab-pane label="监审通知" name="auditNotice">
+        <!-- 监审文书 -->
+        <el-tab-pane label="监审文书" name="auditNotice">
           <auditNoticeTab
           <auditNoticeTab
             ref="auditNoticeTab"
             ref="auditNoticeTab"
             :project="actualProject"
             :project="actualProject"
@@ -82,6 +72,21 @@
             @paginationChange="handlePaginationChange"
             @paginationChange="handlePaginationChange"
           />
           />
         </el-tab-pane>
         </el-tab-pane>
+        <el-tab-pane label="集体审议" name="discussion">
+          <discussionTab :project="actualProject" :is-view="isView" />
+        </el-tab-pane>
+        <el-tab-pane label="出具结论" name="conclusion">
+          <conclusionTab :project="actualProject" :is-view="isView" />
+        </el-tab-pane>
+
+        <!-- 监审工作流程 -->
+        <el-tab-pane label="监审工作流程" name="workflow">
+          <workflowTab
+            :project="actualProject"
+            :is-view="isView"
+            :workflow-data.sync="workflowData"
+          />
+        </el-tab-pane>
       </el-tabs>
       </el-tabs>
     </div>
     </div>
   </el-dialog>
   </el-dialog>
@@ -98,6 +103,8 @@
   import surveyTab from './taskComponents/surveyTab.vue'
   import surveyTab from './taskComponents/surveyTab.vue'
   import workflowTab from './taskComponents/workflowTab.vue'
   import workflowTab from './taskComponents/workflowTab.vue'
   import auditNoticeTab from './taskComponents/auditNoticeTab.vue'
   import auditNoticeTab from './taskComponents/auditNoticeTab.vue'
+  import discussionTab from './taskComponents/discussionTab.vue'
+  import conclusionTab from './taskComponents/conclusionTab.vue'
   import { taskMixin } from '@/views/costAudit/projectInfo/auditTaskManage/taskCustomizedRelease/index.js'
   import { taskMixin } from '@/views/costAudit/projectInfo/auditTaskManage/taskCustomizedRelease/index.js'
   export default {
   export default {
     name: 'TaskDetail',
     name: 'TaskDetail',
@@ -108,6 +115,8 @@
       surveyTab,
       surveyTab,
       workflowTab,
       workflowTab,
       auditNoticeTab,
       auditNoticeTab,
+      discussionTab,
+      conclusionTab,
     },
     },
     mixins: [taskMixin],
     mixins: [taskMixin],
     props: {
     props: {

+ 348 - 63
src/views/costAudit/projectInfo/auditTaskManage/taskProgressManage/index.vue

@@ -25,7 +25,7 @@
             <el-button
             <el-button
               type="primary"
               type="primary"
               icon="el-icon-search"
               icon="el-icon-search"
-              @click="generateTableData"
+              @click="handleSearch"
             >
             >
               搜索
               搜索
             </el-button>
             </el-button>
@@ -47,21 +47,19 @@
         :columns="tableColumns"
         :columns="tableColumns"
         :border="true"
         :border="true"
         :row-class-name="getRowClassName"
         :row-class-name="getRowClassName"
-        :show-pagination="false"
+        :show-pagination="true"
+        :pagination="pagination"
         :table-props="{
         :table-props="{
           rowKey: 'id',
           rowKey: 'id',
           treeProps: { children: 'children', hasChildren: 'hasChildren' },
           treeProps: { children: 'children', hasChildren: 'hasChildren' },
           defaultExpandAll: true,
           defaultExpandAll: true,
           showExpandColumn: false,
           showExpandColumn: false,
         }"
         }"
+        @pagination-change="handlePaginationChange"
       >
       >
         <!-- 预警列自定义内容 -->
         <!-- 预警列自定义内容 -->
         <template #warning="{ row }">
         <template #warning="{ row }">
-          <span v-if="row.warning === 'red'" class="warning-point red"></span>
-          <span
-            v-else-if="row.warning === 'yellow'"
-            class="warning-point yellow"
-          ></span>
+          <span :class="['warning-point', computeWarning(row)]"></span>
         </template>
         </template>
 
 
         <!-- 操作列自定义内容 -->
         <!-- 操作列自定义内容 -->
@@ -74,6 +72,22 @@
             >
             >
               查看
               查看
             </el-button>
             </el-button>
+            <el-button
+              v-if="row.status != 400 && row.status != 300"
+              size="mini"
+              type="text"
+              @click="handlePause(row)"
+            >
+              中止
+            </el-button>
+            <el-button
+              v-if="row.status != 400 && row.status != 300"
+              size="mini"
+              type="text"
+              @click="handleUrgeReporting(row)"
+            >
+              催报
+            </el-button>
           </template>
           </template>
           <template v-else>
           <template v-else>
             <el-button
             <el-button
@@ -87,38 +101,34 @@
               v-if="row.status != 400 && row.status != 300"
               v-if="row.status != 400 && row.status != 300"
               size="mini"
               size="mini"
               type="text"
               type="text"
-              @click="handlePause(row)"
+              @click="handleDelegate(row)"
             >
             >
-              中止
+              催办
             </el-button>
             </el-button>
             <el-button
             <el-button
               v-if="row.status != 400 && row.status != 300"
               v-if="row.status != 400 && row.status != 300"
               size="mini"
               size="mini"
               type="text"
               type="text"
-              @click="handleDelegate(row)"
+              @click="handleUrge(row)"
             >
             >
-              
+              
             </el-button>
             </el-button>
             <el-button
             <el-button
               v-if="row.status != 400 && row.status != 300"
               v-if="row.status != 400 && row.status != 300"
               size="mini"
               size="mini"
               type="text"
               type="text"
-              @click="handleUrge(row)"
+              @click="handleToDo(row)"
             >
             >
-              
+              
             </el-button>
             </el-button>
           </template>
           </template>
         </template>
         </template>
       </cost-audit-table>
       </cost-audit-table>
     </div>
     </div>
     <!-- 详情内容 -->
     <!-- 详情内容 -->
-    <div v-if="activeView == 'detail'" class="detail-content">
-      <detail-tabs
-        :task-data="taskData"
-        :project="project"
-        @detailClose="handleDetailClose"
-      ></detail-tabs>
-    </div>
+    <!-- <div v-if="activeView == 'detail'" class="detail-content">
+      <detail-tabs :task-data="taskData" :project="project" @detailClose="handleDetailClose"></detail-tabs>
+    </div> -->
 
 
     <!-- 任务中止表单弹窗 -->
     <!-- 任务中止表单弹窗 -->
     <el-dialog
     <el-dialog
@@ -193,9 +203,57 @@
       </div>
       </div>
     </el-dialog>
     </el-dialog>
 
 
-    <!-- 任务代办弹窗 -->
+    <!-- 任务催报弹窗 -->
     <el-dialog
     <el-dialog
-      title="任务代办"
+      title="任务催报"
+      :visible.sync="showUrgeReportingForm"
+      width="50%"
+      :modal="true"
+      :close-on-click-modal="false"
+    >
+      <div class="dialog-content">
+        <el-form
+          ref="urgeReportingFormRef"
+          :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"
+              type="textarea"
+              rows="5"
+              placeholder="请输入催办内容"
+            ></el-input>
+          </el-form-item>
+        </el-form>
+      </div>
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="handleUrgeReportingCancel">取消</el-button>
+        <el-button type="primary" @click="handleUrgeReportingSubmit">
+          发送
+        </el-button>
+      </div>
+    </el-dialog>
+
+    <!-- 任务催办弹窗 -->
+    <el-dialog
+      title="任务催办"
       :visible.sync="showDelegateForm"
       :visible.sync="showDelegateForm"
       width="50%"
       width="50%"
       :modal="true"
       :modal="true"
@@ -203,10 +261,12 @@
     >
     >
       <div class="dialog-content">
       <div class="dialog-content">
         <el-form ref="delegateForm" :model="delegateForm" label-width="100px">
         <el-form ref="delegateForm" :model="delegateForm" label-width="100px">
-          <el-form-item label="代理人员:">
+          <el-form-item label="监审组人员:">
             <el-select
             <el-select
-              v-model="delegateForm.agentPerson"
-              placeholder="请选择代理人员"
+              v-model="delegateForm.userIds"
+              multiple
+              clearable
+              placeholder="请选择监审组人员"
               style="width: 100%"
               style="width: 100%"
             >
             >
               <el-option
               <el-option
@@ -217,12 +277,12 @@
               ></el-option>
               ></el-option>
             </el-select>
             </el-select>
           </el-form-item>
           </el-form-item>
-          <el-form-item label="代为内容:">
+          <el-form-item label="催办内容:">
             <el-input
             <el-input
               v-model="delegateForm.content"
               v-model="delegateForm.content"
               type="textarea"
               type="textarea"
               rows="5"
               rows="5"
-              placeholder="请输入代为内容"
+              placeholder="请输入催办内容"
             ></el-input>
             ></el-input>
           </el-form-item>
           </el-form-item>
           <!-- <el-form-item label="发送方式:">
           <!-- <el-form-item label="发送方式:">
@@ -238,21 +298,28 @@
         <el-button type="primary" @click="handleDelegateSubmit">发送</el-button>
         <el-button type="primary" @click="handleDelegateSubmit">发送</el-button>
       </div>
       </div>
     </el-dialog>
     </el-dialog>
+    <!-- 任务详情弹窗(统一详情/查看入口) -->
+    <task-detail
+      ref="taskDetail"
+      :visible.sync="taskDetailVisible"
+      :is-view="isView"
+    />
   </div>
   </div>
 </template>
 </template>
 
 
 <script>
 <script>
   import { taskList } from '@/api/taskProgressManage'
   import { taskList } from '@/api/taskProgressManage'
   import { dictMixin } from '@/mixins/useDict'
   import { dictMixin } from '@/mixins/useDict'
-  import detailTabs from './detailTabs.vue'
   import { getAllUnitList } from '@/api/auditEntityManage'
   import { getAllUnitList } from '@/api/auditEntityManage'
   import CostAuditTable from '@/components/costAudit/CostAuditTable.vue'
   import CostAuditTable from '@/components/costAudit/CostAuditTable.vue'
   import { getAllUserList } from '@/api/uc'
   import { getAllUserList } from '@/api/uc'
   import { getCostProjectDetail } from '@/api/taskCustomizedRelease.js'
   import { getCostProjectDetail } from '@/api/taskCustomizedRelease.js'
+  import { doProcessBtn } from '@/api/dataPreliminaryReview'
+  import TaskDetail from '@/components/task/taskDetail.vue'
   export default {
   export default {
     components: {
     components: {
-      detailTabs,
       CostAuditTable,
       CostAuditTable,
+      TaskDetail,
     },
     },
     mixins: [dictMixin],
     mixins: [dictMixin],
     data() {
     data() {
@@ -271,6 +338,13 @@
         taskData: {},
         taskData: {},
         project: {},
         project: {},
         tableData: [],
         tableData: [],
+        // 分页
+        pagination: {
+          currentPage: 1,
+          pageSize: 10,
+          pageSizes: [10, 20, 50, 100],
+          total: 0,
+        },
         // 表格列配置
         // 表格列配置
         tableColumns: [
         tableColumns: [
           {
           {
@@ -309,6 +383,8 @@
             headerAlign: 'center',
             headerAlign: 'center',
             showOverflowTooltip: true,
             showOverflowTooltip: true,
             formatter: (row) => {
             formatter: (row) => {
+              // 优先使用后端返回的名称,兼容多个名称逗号分隔
+              if (row && row.auditedUnitName) return row.auditedUnitName
               return this.getUnitName(row.auditedUnitId)
               return this.getUnitName(row.auditedUnitId)
             },
             },
           },
           },
@@ -324,7 +400,12 @@
             width: 100,
             width: 100,
             align: 'center',
             align: 'center',
             formatter: (row) => {
             formatter: (row) => {
-              return this.getDictName('projectProposal', row.sourceType)
+              return this.getDictName(
+                'projectProposal',
+                row && row.sourceType !== undefined && row.sourceType !== null
+                  ? String(row.sourceType)
+                  : ''
+              )
             },
             },
           },
           },
           {
           {
@@ -333,7 +414,12 @@
             width: 100,
             width: 100,
             align: 'center',
             align: 'center',
             formatter: (row) => {
             formatter: (row) => {
-              return this.getDictName('auditType', row.auditType)
+              return this.getDictName(
+                'auditType',
+                row && row.auditType !== undefined && row.auditType !== null
+                  ? String(row.auditType)
+                  : ''
+              )
             },
             },
           },
           },
           {
           {
@@ -342,7 +428,9 @@
             width: 100,
             width: 100,
             align: 'center',
             align: 'center',
             formatter: (row) => {
             formatter: (row) => {
-              return this.getStatusName(row.status)
+              const left = row.currentNodeName || ''
+              const right = row.statusName || this.getStatusName(row.status)
+              return left ? `${left}-${right}` : right
             },
             },
           },
           },
           {
           {
@@ -365,6 +453,7 @@
         showPauseForm: false,
         showPauseForm: false,
         showUrgeForm: false,
         showUrgeForm: false,
         showDelegateForm: false,
         showDelegateForm: false,
+        showUrgeReportingForm: false,
         // 当前选中的任务
         // 当前选中的任务
         currentTask: null,
         currentTask: null,
         // 表单数据
         // 表单数据
@@ -377,12 +466,18 @@
           // sendType: '站内消息',
           // sendType: '站内消息',
         },
         },
         delegateForm: {
         delegateForm: {
-          agentPerson: '',
+          userIds: [],
           content: '',
           content: '',
           // sendType: '站内消息',
           // sendType: '站内消息',
         },
         },
+        urgeReportingForm: {
+          auditedUnitIds: [],
+          content: '',
+        },
         unitList: [],
         unitList: [],
         userList: [],
         userList: [],
+        // 任务详情弹窗
+        taskDetailVisible: false,
       }
       }
     },
     },
     mounted() {
     mounted() {
@@ -436,21 +531,75 @@
           return unit ? unit.unitName : ''
           return unit ? unit.unitName : ''
         }
         }
       },
       },
+      computeWarning(row) {
+        // 优先使用后端返回的 warningStatus:green/yellow/res(red)
+        if (!row) return ''
+        const ws = (row.warningStatus || '').toString().toLowerCase()
+        if (ws === 'green') return 'green'
+        if (ws === 'yellow') return 'yellow'
+        if (ws === 'res' || ws === 'red') return 'red'
+
+        // 兼容无 warningStatus 时按截止期计算
+        const parse = (v) => (v ? new Date(v) : null)
+        const now = new Date()
+        const nodeDdl = parse(row.nodeDeadline)
+        const procDdl = parse(row.processDeadline)
+        if (nodeDdl && now <= nodeDdl) return 'green'
+        if (nodeDdl && procDdl) {
+          if (now > nodeDdl && now <= procDdl) return 'yellow'
+          if (now > procDdl) return 'red'
+        }
+        if (!nodeDdl && procDdl) return now <= procDdl ? 'green' : 'red'
+        return ''
+      },
       generateTableData() {
       generateTableData() {
+        this.loading = true
         taskList({
         taskList({
           projectName: this.searchForm.projectName,
           projectName: this.searchForm.projectName,
           year: this.searchForm.year,
           year: this.searchForm.year,
-        }).then((res) => {
-          this.tableData = res.value
-          // 移除不需要的属性
-          this.tableData = this.removeItemFromTree(this.tableData)
-          let parentIndex = 1
-          this.tableData.forEach((item, index) => {
-            if (item.pid == 0) {
-              item.parentIndex = parentIndex++
+          pageNum: this.pagination.currentPage,
+          pageSize: this.pagination.pageSize,
+        })
+          .then((res) => {
+            // console.log(res,'表格')
+            // 兼容分页与非分页返回
+            const records = res?.value?.records || res?.value || []
+            const total =
+              Number(res?.value?.total) ||
+              Number(res?.total) ||
+              (Array.isArray(records) ? records.length : 0)
+            // 统一将 childTasks 规范化为 children,并补齐 pid / isSubTask
+            const normalized = this.normalizeChildren(
+              Array.isArray(records) ? records : []
+            )
+            this.tableData = normalized
+            this.pagination.total = Number(total) || 0
+            // 同步后端分页信息(如有)
+            if (Number.isFinite(Number(res?.value?.current))) {
+              this.pagination.currentPage = Number(res.value.current)
+            }
+            if (Number.isFinite(Number(res?.value?.size))) {
+              this.pagination.pageSize = Number(res.value.size)
             }
             }
+            // 移除不需要的属性
+            this.tableData = this.removeItemFromTree(this.tableData)
+            let parentIndex = 1
+            this.tableData.forEach((item) => {
+              if (item.pid == 0) {
+                item.parentIndex = parentIndex++
+              }
+            })
+            this.loading = false
+          })
+          .catch(() => {
+            this.loading = false
+            this.$message.error('获取数据失败')
           })
           })
-        })
+      },
+      handlePaginationChange({ currentPage, pageSize }) {
+        this.pagination.currentPage = currentPage
+        this.pagination.pageSize = pageSize
+        this.generateTableData()
       },
       },
       removeItemFromTree(treeData) {
       removeItemFromTree(treeData) {
         // 边界条件检查
         // 边界条件检查
@@ -480,11 +629,38 @@
           return newItem
           return newItem
         })
         })
       },
       },
+      normalizeChildren(list, parentId = 0) {
+        if (!Array.isArray(list)) return []
+        return list.map((node) => {
+          const copied = { ...node }
+          const rawChildren = Array.isArray(node.children)
+            ? node.children
+            : Array.isArray(node.childTasks)
+            ? node.childTasks
+            : []
+          // 设置父子关系与子任务标识
+          copied.pid =
+            node.pid !== undefined && node.pid !== null ? node.pid : parentId
+          // 注意:后端可能返回字符串 '0',需要统一判断
+          const pidStr = copied.pid != null ? String(copied.pid) : '0'
+          copied.isSubTask = pidStr !== '0'
+          // 递归规范化子节点
+          const children = this.normalizeChildren(rawChildren, node.id)
+          delete copied.childTasks
+          copied.children = children
+          return copied
+        })
+      },
       handleReset() {
       handleReset() {
         this.searchForm = {
         this.searchForm = {
           projectName: '',
           projectName: '',
           year: '',
           year: '',
         }
         }
+        this.pagination.currentPage = 1
+        this.generateTableData()
+      },
+      handleSearch() {
+        this.pagination.currentPage = 1
         this.generateTableData()
         this.generateTableData()
       },
       },
 
 
@@ -495,7 +671,12 @@
         return ''
         return ''
       },
       },
       handleView(row) {
       handleView(row) {
-        console.log('查看子任务:', row)
+        // 子任务查看:打开统一任务详情弹窗
+        this.isView = true
+        this.taskDetailVisible = true
+        this.$nextTick(() => {
+          this.$refs.taskDetail && this.$refs.taskDetail.open(row, 'chengben')
+        })
       },
       },
       // 任务中止相关方法
       // 任务中止相关方法
       handlePause(row) {
       handlePause(row) {
@@ -532,12 +713,29 @@
         this.pauseForm.reason = ''
         this.pauseForm.reason = ''
       },
       },
       handlePauseFormSubmit() {
       handlePauseFormSubmit() {
-        console.log('提交中止原因:', this.pauseForm)
-        // 这里可以添加提交逻辑
-        this.showPauseForm = false
-        this.pauseForm.reason = ''
-        this.currentTask = null
-        this.$message.success('任务已中止')
+        if (!this.currentTask) return
+        const params = {
+          taskId: this.currentTask.id,
+          key: 2,
+          status: 300,
+          processNodeKey: this.currentTask.currentNode,
+          remark: this.pauseForm.reason,
+        }
+        doProcessBtn(params)
+          .then((res) => {
+            if (res && Number(res.code) === 200) {
+              this.$message.success('任务已中止')
+              this.showPauseForm = false
+              this.pauseForm.reason = ''
+              this.currentTask = null
+              this.generateTableData()
+            } else {
+              this.$message.error(res?.message || '操作失败')
+            }
+          })
+          .catch(() => {
+            this.$message.error('操作失败')
+          })
       },
       },
       // 任务督办相关方法
       // 任务督办相关方法
       handleUrge(row) {
       handleUrge(row) {
@@ -580,34 +778,61 @@
         console.log('任务代办:', row)
         console.log('任务代办:', row)
         this.currentTask = row
         this.currentTask = row
         this.showDelegateForm = true
         this.showDelegateForm = true
+        this.delegateForm = {
+          userIds: [],
+          content: '',
+        }
       },
       },
       handleDelegateCancel() {
       handleDelegateCancel() {
         this.showDelegateForm = false
         this.showDelegateForm = false
         this.delegateForm = {
         this.delegateForm = {
-          agentPerson: '',
+          userIds: [],
           content: '',
           content: '',
           // sendType: '站内消息',
           // sendType: '站内消息',
         }
         }
       },
       },
       handleDelegateSubmit() {
       handleDelegateSubmit() {
-        console.log('提交代办:', this.delegateForm)
-        // 这里可以添加提交逻辑
-        this.showDelegateForm = false
-        this.delegateForm = {
-          agentPerson: '',
-          content: '',
-          // sendType: '站内消息',
+        if (!this.currentTask) return
+        if (
+          !Array.isArray(this.delegateForm.userIds) ||
+          this.delegateForm.userIds.length === 0
+        ) {
+          this.$message.warning('请选择监审组人员')
+          return
         }
         }
-        this.currentTask = null
-        this.$message.success('代办信息已发送')
+        const params = {
+          taskId: this.currentTask.id,
+          key: 5,
+          status: this.currentTask.status,
+          processNodeKey: this.currentTask.currentNode,
+          remark: this.delegateForm.content,
+          userIds: this.delegateForm.userIds.join(','),
+        }
+        doProcessBtn(params)
+          .then((res) => {
+            if (res && Number(res.code) === 200) {
+              this.$message.success('催办信息已发送')
+              this.showDelegateForm = false
+              this.delegateForm = { userIds: [], content: '' }
+              this.currentTask = null
+              this.generateTableData()
+            } else {
+              this.$message.error(res?.message || '操作失败')
+            }
+          })
+          .catch(() => {
+            this.$message.error('操作失败')
+          })
       },
       },
 
 
       // 任务详情相关方法
       // 任务详情相关方法
       handleViewTaskDetail(row) {
       handleViewTaskDetail(row) {
-        console.log(row, '这行')
-        this.taskData = row
-        this.getProject()
-        this.activeView = 'detail'
+        // 主任务详情:打开统一任务详情弹窗
+        this.isView = true
+        this.taskDetailVisible = true
+        this.$nextTick(() => {
+          this.$refs.taskDetail && this.$refs.taskDetail.open(row, 'chengben')
+        })
       },
       },
       getProject() {
       getProject() {
         getCostProjectDetail({
         getCostProjectDetail({
@@ -626,12 +851,68 @@
         this.activeView = 'list'
         this.activeView = 'list'
         this.taskData = null
         this.taskData = null
       },
       },
+      // 代办
+      handleToDo(row) {
+        console.log('代办', row)
+      },
+      // 催报
+      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.currentTask = null
+      },
+      handleUrgeReportingSubmit() {
+        if (!this.currentTask) return
+        if (
+          !Array.isArray(this.urgeReportingForm.auditedUnitIds) ||
+          this.urgeReportingForm.auditedUnitIds.length === 0
+        ) {
+          this.$message.warning('请选择被监审单位')
+          return
+        }
+        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(','),
+        }
+        doProcessBtn(params)
+          .then((res) => {
+            if (res && Number(res.code) === 200) {
+              this.$message.success('催报信息已发送')
+              this.showUrgeReportingForm = false
+              this.urgeReportingForm = { auditedUnitIds: [], content: '' }
+              this.currentTask = null
+              this.generateTableData()
+            } else {
+              this.$message.error(res?.message || '操作失败')
+            }
+          })
+          .catch(() => {
+            this.$message.error('操作失败')
+          })
+      },
     },
     },
   }
   }
 </script>
 </script>
 
 
 <style scoped lang="scss">
 <style scoped lang="scss">
   @import '@/styles/costAudit.scss';
   @import '@/styles/costAudit.scss';
+
   .task-progress-manage {
   .task-progress-manage {
     padding: 20px;
     padding: 20px;
   }
   }
@@ -683,6 +964,10 @@
     background-color: #e6a23c;
     background-color: #e6a23c;
   }
   }
 
 
+  .warning-point.green {
+    background-color: #67c23a;
+  }
+
   .back-button-container {
   .back-button-container {
     margin-bottom: 20px;
     margin-bottom: 20px;
   }
   }