Selaa lähdekoodia

feat:督办完成

shiyanyu 1 kuukausi sitten
vanhempi
commit
aa50a4bb19

+ 48 - 0
src/api/audit/supervise.js

@@ -0,0 +1,48 @@
+import request from '@/utils/request'
+
+const url = window.context.form
+
+// 创建(新增)督办任务
+export function createSuperviseTask(data) {
+  return request({
+    url: url + '/cost/project/supervise/v1/save',
+    method: 'post',
+    data,
+  })
+}
+
+//修改(上报)督办内容
+export function updateSuperviseTask(data) {
+  return request({
+    url: url + '/cost/project/supervise/v1/modify',
+    method: 'post',
+    data,
+  })
+}
+
+// (删除)停止督办
+export function deleteSuperviseTask(data) {
+  return request({
+    url: url + '/cost/project/supervise/v1/delete',
+    method: 'post',
+    data,
+  })
+}
+
+// 督办报告列表
+export function getSuperviseReportList(data) {
+  return request({
+    url: url + '/cost/project/supervise/v1/getList',
+    method: 'post',
+    data,
+  })
+}
+
+// 督办报告详情
+export function getSuperviseReportDetail(data) {
+  return request({
+    url: url + '/cost/project/supervise/v1/getReportList',
+    method: 'post',
+    data,
+  })
+}

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

@@ -345,6 +345,7 @@
               const params = {
                 uploadId: row.id,
                 auditedUnitId: this.auditedUnitId,
+                type: 2,
               }
               const res = await getSurveyDetail(params)
               console.log('单记录详情数据', res)
@@ -460,6 +461,7 @@
         formData.append('taskId', taskId)
         if (materialId) formData.append('materialId', materialId)
         if (periodRecordId) formData.append('periodRecordId', periodRecordId)
+        formData.append('type', '2')
 
         let loading
         try {
@@ -509,7 +511,7 @@
           //     this.$message.warning('缺少模板或版本信息,无法下载')
           //   return
           // }
-          const params = { surveyTemplateId, versionId }
+          const params = { surveyTemplateId, versionId, type: 2 }
           const res = await downloadTemplate(params)
           loading.close()
           // 处理响应数据(可能是 axios 响应或直接 Blob)
@@ -582,6 +584,7 @@
             auditedUnitId,
             catalogId,
             surveyTemplateId,
+            type: 2,
           }
 
           const res = await getDynamicTableData(params)
@@ -629,6 +632,7 @@
           try {
             const params = {
               surveyTemplateId: this.currentSurveyRow.surveyTemplateId,
+              type: 2,
             }
             // 调用 getListBySurveyTemplateIdAndVersion 获取完整的字段配置(包含校验规则)
             const res = await getListBySurveyTemplateIdAndVersion(params)
@@ -1114,8 +1118,10 @@
           try {
             const params = {
               surveyTemplateId: this.currentSurveyRow.surveyTemplateId,
+              type: 2,
             }
             const res = await getSingleRecordSurveyList(params)
+
             console.log('固定表配置数据', res)
             if (res && res.code === 200 && res.value) {
               // 将接口返回的数据转换为固定表配置格式
@@ -1192,7 +1198,9 @@
         try {
           const headerRes = await getListBySurveyTemplateIdAndVersion({
             surveyTemplateId: this.currentSurveyRow.surveyTemplateId,
+            type: 2,
           })
+
           if (headerRes && headerRes.code === 200) {
             this.fixedHeaders = headerRes.value || null
           } else {

+ 7 - 1
src/views/EntDeclaration/auditTaskManagement/components/DataRequirementsTab.vue

@@ -411,6 +411,7 @@
               const params = {
                 uploadId: row.uploadId || row.id,
                 auditedUnitId: this.auditedUnitId,
+                type: 1,
               }
               const res = await getSurveyDetail(params)
               if (res && res.code === 200 && res.value) {
@@ -613,6 +614,7 @@
         const taskId = this.pendingUploadRow.taskId
         // formData.append('auditedUnitId', auditedUnitId)
         formData.append('taskId', taskId)
+        formData.append('type', '1')
 
         const loading = this.$loading({
           lock: true,
@@ -666,7 +668,7 @@
           })
 
           // 构建请求参数,根据实际接口需求调整
-          const params = {}
+          const params = { type: 1 }
           const surveyTemplateId = this.getSurveyTemplateId(row)
           if (surveyTemplateId) {
             params.surveyTemplateId = surveyTemplateId
@@ -755,6 +757,7 @@
             auditedUnitId,
             catalogId,
             surveyTemplateId,
+            type: 1,
           }
           const res = await getDynamicTableData(params)
           if (res && res.code === 200) {
@@ -794,6 +797,7 @@
               surveyTemplateId: this.getSurveyTemplateId(
                 this.currentTemplateRow
               ),
+              type: 1,
             }
             const res = await getListBySurveyFdTemplateIdAndVersion(params)
             if (res && res.code === 200) {
@@ -850,6 +854,7 @@
               surveyTemplateId: this.getSurveyTemplateId(
                 this.currentTemplateRow
               ),
+              type: 1,
             }
             const res = await getSingleRecordSurveyList(params)
             if (res && res.code === 200 && res.value) {
@@ -905,6 +910,7 @@
         try {
           const headerRes = await getListBySurveyFdTemplateIdAndVersion({
             surveyTemplateId: this.getSurveyTemplateId(this.currentTemplateRow),
+            type: 1,
           })
           if (headerRes && headerRes.code === 200) {
             this.fixedHeaders = headerRes.value || null

+ 41 - 14
src/views/costAudit/projectInfo/auditTaskManage/taskProgressManage/index.vue

@@ -316,6 +316,7 @@
   import { getCostProjectDetail } from '@/api/taskCustomizedRelease.js'
   import { doProcessBtn } from '@/api/dataPreliminaryReview'
   import TaskDetail from '@/components/task/taskDetail.vue'
+  import { createSuperviseTask } from '@/api/audit/supervise'
   export default {
     components: {
       CostAuditTable,
@@ -757,21 +758,47 @@
         }
       },
       handleUrgeSubmit() {
-        // 提交前将数组转换为逗号分隔字符串
-        const submitForm = { ...this.urgeForm }
-        // if (Array.isArray(submitForm.sendType)) {
-        //   submitForm.sendType = submitForm.sendType.join(',')
-        // }
-        console.log('提交督办:', submitForm)
-        // 这里可以添加提交逻辑
-        this.showUrgeForm = false
-        this.urgeForm = {
-          remindPerson: '',
-          content: '',
-          // sendType: [],
+        if (!this.currentTask) return
+        const projectId =
+          this.currentTask.projectId || this.currentTask.projectID || ''
+        const supervisorId = this.urgeForm.remindPerson
+        const requireContent = (this.urgeForm.content || '').trim()
+        if (!projectId) {
+          this.$message.warning('缺少项目ID,无法发送督办')
+          return
         }
-        this.currentTask = null
-        this.$message.success('督办信息已发送')
+        if (!supervisorId) {
+          this.$message.warning('请选择督办人员')
+          return
+        }
+        if (!requireContent) {
+          this.$message.warning('请输入督办要求')
+          return
+        }
+        const loading = this.$loading({
+          lock: true,
+          text: '发送中...',
+          spinner: 'el-icon-loading',
+          background: 'rgba(0,0,0,0.3)',
+        })
+        createSuperviseTask({ projectId, supervisorId, requireContent })
+          .then((res) => {
+            if (res && Number(res.code) === 200) {
+              this.$message.success('督办信息已发送')
+              this.showUrgeForm = false
+              this.urgeForm = { remindPerson: '', content: '' }
+              this.currentTask = null
+              this.generateTableData()
+            } else {
+              this.$message.error(res?.message || '发送失败')
+            }
+          })
+          .catch(() => {
+            this.$message.error('发送失败')
+          })
+          .finally(() => {
+            loading && loading.close && loading.close()
+          })
       },
       // 任务代办相关方法
       handleDelegate(row) {

+ 138 - 24
src/views/costAudit/projectInfo/taskSuperviseManage/superviseMattersManage/index.vue

@@ -122,33 +122,33 @@
           {{ getDictName('auditType', scope.row.auditType) }}
         </template>
       </el-table-column>
-      <el-table-column prop="status" label="状态" width="100" align="center">
+      <el-table-column
+        prop="superviseStatus"
+        label="状态"
+        width="100"
+        align="center"
+      >
         <template slot-scope="scope">
-          <span :style="scope.row.style">{{ scope.row.status }}</span>
+          <span
+            v-if="!(scope.row.isSubTask || scope.row.pid != 0)"
+            :style="scope.row.style"
+          >
+            {{ getSuperviseStatusName(scope.row.superviseStatus) }}
+          </span>
         </template>
       </el-table-column>
       <el-table-column prop="warning" label="预警" width="80" align="center">
         <template slot-scope="scope">
-          <span
-            v-if="scope.row.warning === 'red'"
-            class="warning-dot red"
-          ></span>
-          <span
-            v-else-if="scope.row.warning === 'yellow'"
-            class="warning-dot yellow"
-          ></span>
+          <span :class="['warning-point', computeWarning(scope.row)]"></span>
         </template>
       </el-table-column>
       <el-table-column label="操作" width="180" align="center">
         <template slot-scope="scope">
-          <el-button
-            v-if="scope.row.isSubTask"
-            size="mini"
-            type="text"
-            @click="handleView(scope.row)"
-          >
-            查看
-          </el-button>
+          <template v-if="scope.row.isSubTask || scope.row.pid != 0">
+            <el-button size="mini" type="text" @click="handleView(scope.row)">
+              查看
+            </el-button>
+          </template>
           <template v-else>
             <el-button
               size="mini"
@@ -214,6 +214,8 @@
   import { getSupervisorList } from '@/api/superviseMattersManage'
   import { dictMixin } from '@/mixins/useDict'
   import UploadComponent from '@/components/costAudit/UploadComponent.vue'
+  import { updateSuperviseTask } from '@/api/audit/supervise'
+
   export default {
     name: 'TaskSupervision',
     components: {
@@ -235,6 +237,7 @@
         tableData: [],
         reportForm: {
           content: '',
+          uploadUrl: [],
         },
         fileList: [{ name: '督办说明.pdf', url: '' }],
         currentTask: null,
@@ -301,6 +304,31 @@
         }
         return ''
       },
+      computeWarning(row) {
+        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'
+
+        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 ''
+      },
+      getSuperviseStatusName(v) {
+        const val = String(v)
+        if (val === '0') return '在办'
+        if (val === '1') return '办结'
+        return v
+      },
       handleView(row) {
         console.log('查看子任务:', row)
         this.isView = true
@@ -312,17 +340,86 @@
       handleReport(row) {
         this.currentTask = row
         this.activeTab = '0'
+        this.reportForm = { content: '', uploadUrl: [] }
+        this.fileList = []
         this.isReport = true
       },
-      saveFiles(index) {
-        this.fileList.splice(index, 1)
+      // 与 UploadComponent 事件签名保持一致
+      // saveFiles(files, props)
+      saveFiles(files) {
+        const list = Array.isArray(files) ? files : []
+        this.reportForm.uploadUrl = list
+        this.fileList = list
       },
-      removeFile(index) {
-        this.fileList.splice(index, 1)
+      // removeFile(index, removedFile, files, props)
+      removeFile(index, removedFile, files) {
+        const list = Array.isArray(files) ? files : []
+        this.reportForm.uploadUrl = list
+        this.fileList = list
       },
       handleSubmit() {
-        console.log('提交报告:', this.reportForm)
-        // 这里可以添加提交逻辑
+        const reportContent = (
+          (this.reportForm &&
+            (this.reportForm.content || this.reportForm.projectName)) ||
+          ''
+        ).trim()
+        const files = [
+          ...(this.reportForm && Array.isArray(this.reportForm.uploadUrl)
+            ? this.reportForm.uploadUrl
+            : []),
+          ...(Array.isArray(this.fileList) ? this.fileList : []),
+        ]
+          .map((f) =>
+            typeof f === 'string'
+              ? f
+              : (f.response && f.response.value && f.response.value.savePath) ||
+                f.savePath ||
+                (f.response && f.response.data && f.response.data.savePath) ||
+                ''
+          )
+          .filter(Boolean)
+        console.log(files, 'files')
+        const attachmentUrls = files.join(',')
+
+        if (!reportContent) {
+          this.$message.warning('请输入报告内容')
+          return
+        }
+
+        const id =
+          (this.currentTask &&
+            (this.currentTask.superviseId || this.currentTask.ID)) ||
+          ''
+        if (!id) {
+          this.$message.warning('缺少ID,无法提交督办报告')
+          return
+        }
+
+        const loading = this.$loading({
+          lock: true,
+          text: '提交中...',
+          spinner: 'el-icon-loading',
+          background: 'rgba(0, 0, 0, 0.3)',
+        })
+
+        updateSuperviseTask({ id, reportContent, attachmentUrls })
+          .then((res) => {
+            if (res && Number(res.code) === 200) {
+              this.$message.success('提交成功')
+              this.isReport = false
+              this.reportForm = { content: '', uploadUrl: [] }
+              this.currentTask = null
+              this.generateTableData()
+            } else {
+              this.$message.error((res && res.message) || '提交失败')
+            }
+          })
+          .catch(() => {
+            this.$message.error('提交失败')
+          })
+          .finally(() => {
+            loading && loading.close && loading.close()
+          })
       },
       handleCancel() {
         console.log('取消')
@@ -439,4 +536,21 @@
   .el-table .sub-task-cell {
     padding-left: 40px !important;
   }
+
+  /* 预警点样式,保持与任务进度页面一致 */
+  .warning-point {
+    display: inline-block;
+    width: 12px;
+    height: 12px;
+    border-radius: 50%;
+  }
+  .warning-point.red {
+    background-color: #ff4949;
+  }
+  .warning-point.yellow {
+    background-color: #e6a23c;
+  }
+  .warning-point.green {
+    background-color: #67c23a;
+  }
 </style>

+ 192 - 41
src/views/costAudit/projectInfo/taskSuperviseManage/superviseResultManage/index.vue

@@ -169,6 +169,7 @@
               督办情况
             </el-button>
             <el-button
+              v-if="scope.row.supervisionStatus === '0'"
               size="mini"
               type="text"
               @click="handleEndSupervision(scope.row)"
@@ -223,6 +224,7 @@
               <span
                 v-if="scope.row.relatedFiles"
                 style="color: #409eff; cursor: pointer"
+                @click="handleDownload(scope.row.relatedFiles)"
               >
                 {{ scope.row.relatedFiles }}
               </span>
@@ -238,6 +240,11 @@
 </template>
 
 <script>
+  import {
+    deleteSuperviseTask,
+    getSuperviseReportList,
+    getSuperviseReportDetail,
+  } from '@/api/audit/supervise'
   export default {
     data() {
       return {
@@ -361,20 +368,116 @@
         this.generateTableData()
       },
       generateTableData() {
-        // 将主任务和子任务展平为表格数据
-        const data = []
-        this.projectList.forEach((project) => {
-          data.push(project)
-          if (project.subTasks && project.subTasks.length > 0) {
-            project.subTasks.forEach((subTask) => {
-              data.push({
-                ...subTask,
-                style: { paddingLeft: '40px' },
-              })
+        this.loading = true
+        const statusLabel = (this.searchForm.status || '').toString().trim()
+        const status =
+          statusLabel === '在办'
+            ? '0'
+            : statusLabel === '办结'
+            ? '1'
+            : statusLabel
+        const params = {
+          year: (this.searchForm.year || '').toString().trim(),
+          status,
+          supervisor: (this.searchForm.supervisor || '').toString().trim(),
+          project: (this.searchForm.project || '').toString().trim(),
+          pageNum: 1,
+          pageSize: 9999,
+        }
+        getSuperviseReportList(params)
+          .then((res) => {
+            // 兼容不同返回结构
+            const raw =
+              (res &&
+                res.value &&
+                (res.value.records || res.value.list || res.value)) ||
+              (res &&
+                res.data &&
+                (res.data.records || res.data.list || res.data)) ||
+              []
+            const arr = Array.isArray(raw) ? raw : []
+
+            const mapStatus = (s) => {
+              const v = s != null ? String(s) : ''
+              if (v === '100') return '待提交'
+              if (v === '200') return '审核中'
+              if (v === '300') return '中止'
+              if (v === '400') return '办结'
+              return v
+            }
+            const mapSupervise = (s) => {
+              const v = s != null ? String(s) : ''
+              if (v === '0') return '在办'
+              if (v === '1') return '办结'
+              return v || ''
+            }
+
+            const flat = []
+            arr.forEach((item, idx) => {
+              const parent = {
+                ...item,
+                serialNumber: idx + 1,
+                isSubTask: false,
+                // 映射列字段,避免后端字段名不一致
+                planYear: item.planYear || item.year || '',
+                auditedUnit:
+                  item.auditedUnit ||
+                  item.auditedUnitName ||
+                  item.auditedUnitNames ||
+                  '',
+                expectedDeadline:
+                  item.expectedDeadline ||
+                  item.processDeadline ||
+                  item.deadline ||
+                  '',
+                taskStatus:
+                  item.taskStatus || item.statusName || mapStatus(item.status),
+                supervisionStatus:
+                  item.supervisionStatus || mapSupervise(item.superviseStatus),
+                supervisionMessage:
+                  item.supervisionMessage || item.message || item.remark || '',
+              }
+              flat.push(parent)
+              const children =
+                (item && (item.children || item.subTasks || item.childTasks)) ||
+                []
+              if (Array.isArray(children) && children.length > 0) {
+                children.forEach((c) => {
+                  flat.push({
+                    ...c,
+                    isSubTask: true,
+                    serialNumber: '',
+                    style: { paddingLeft: '40px' },
+                    planYear: c.planYear || c.year || '',
+                    auditedUnit:
+                      c.auditedUnit ||
+                      c.auditedUnitName ||
+                      c.auditedUnitNames ||
+                      '',
+                    expectedDeadline:
+                      c.expectedDeadline ||
+                      c.processDeadline ||
+                      c.deadline ||
+                      '',
+                    taskStatus:
+                      c.taskStatus || c.statusName || mapStatus(c.status),
+                    supervisionStatus:
+                      c.supervisionStatus || mapSupervise(c.superviseStatus),
+                    supervisionMessage:
+                      c.supervisionMessage || c.message || c.remark || '',
+                  })
+                })
+              }
             })
-          }
-        })
-        this.tableData = data
+            this.tableData = flat
+          })
+          .catch(() => {
+            this.$message.error('获取数据失败')
+            this.tableData = []
+          })
+          .finally(() => {
+            this.loading = false
+          })
       },
       getRowClassName({ row }) {
         if (row.isSubTask) {
@@ -383,8 +486,7 @@
         return ''
       },
       handleSearch() {
-        console.log('搜索:', this.searchForm)
-        // 这里可以添加搜索逻辑
+        this.generateTableData()
       },
       handleView(row) {
         this.isViewDetails = true
@@ -395,33 +497,56 @@
         console.log('查看任务详情:', row)
       },
       handleSupervisionDetail(row) {
-        console.log('查看督办情况:', row)
         this.isSupervisionDetail = true
         this.currentTask = row
-        // 模拟督办记录数据
-        this.supervisionRecords = [
-          {
-            serialNumber: 1,
-            supervisor: '李***',
-            reportTime: '2025-5-11 09:30',
-            reportContent: '监审任务进展情况:.....................',
-            relatedFiles: '******文件.doc',
-          },
-          {
-            serialNumber: 2,
-            supervisor: '李***',
-            reportTime: '2025-5-23 09:30',
-            reportContent: '监审任务进展情况:.....................',
-            relatedFiles: '******文件.pdf',
-          },
-          {
-            serialNumber: 3,
-            supervisor: '.......',
-            reportTime: '.......',
-            reportContent: '.......',
-            relatedFiles: '.......',
-          },
-        ]
+        const id = row && (row.superviseId || row.id || row.ID)
+        if (!id) {
+          this.supervisionRecords = []
+          return
+        }
+        const loading = this.$loading({
+          lock: true,
+          text: '加载中...',
+          spinner: 'el-icon-loading',
+          background: 'rgba(0, 0, 0, 0.3)',
+        })
+        getSuperviseReportDetail({ id })
+          .then((res) => {
+            const raw = (res && (res.value || res.data)) || []
+            const arr = Array.isArray(raw)
+              ? raw
+              : Array.isArray(raw?.records)
+              ? raw.records
+              : []
+            this.supervisionRecords = arr.map((it, idx) => ({
+              serialNumber: idx + 1,
+              supervisor: it.supervisor || it.supervisorName || '',
+              reportTime: it.reportTime || it.createTime || it.reportDate || '',
+              reportContent: it.reportContent || it.content || '',
+              relatedFiles:
+                it.attachmentUrls || it.attachmentIds || it.relatedFiles || '',
+            }))
+          })
+          .catch(() => {
+            this.$message.error('获取督办情况失败')
+            this.supervisionRecords = []
+          })
+          .finally(() => {
+            loading && loading.close && loading.close()
+          })
+      },
+      handleDownload(paths) {
+        if (!paths) return
+        const base =
+          window.context && window.context.form ? window.context.form : ''
+        const list = String(paths)
+          .split(',')
+          .map((s) => s.trim())
+          .filter(Boolean)
+        list.forEach((p) => {
+          const url = p.startsWith('http') ? p : base + p
+          window.open(url)
+        })
       },
       handleEndSupervision(row) {
         console.log('结束督办:', row)
@@ -431,7 +556,33 @@
           type: 'warning',
         })
           .then(() => {
-            //todo
+            const loading = this.$loading({
+              lock: true,
+              text: '处理中...',
+              spinner: 'el-icon-loading',
+              background: 'rgba(0, 0, 0, 0.3)',
+            })
+            const id = row && (row.superviseId || row.ID)
+            if (!id) {
+              loading && loading.close && loading.close()
+              this.$message.error('缺少ID,无法结束督办')
+              return
+            }
+            deleteSuperviseTask({ id })
+              .then((res) => {
+                if (res && Number(res.code) === 200) {
+                  this.$message.success('已结束督办')
+                  this.generateTableData()
+                } else {
+                  this.$message.error((res && res.message) || '操作失败')
+                }
+              })
+              .catch(() => {
+                this.$message.error('操作失败')
+              })
+              .finally(() => {
+                loading && loading.close && loading.close()
+              })
           })
           .catch(() => {
             this.$message.info('已取消')