Explorar el Código

解决了项目阶段的问题

wsx hace 1 año
padre
commit
cd68119397

+ 32 - 0
src/api/project-manage/index.js

@@ -44,6 +44,29 @@ export async function projectsUpdateAPI(data) {
   }
   return Promise.reject(new Error(res.data.message));
 }
+
+/**
+ * 项目阶段新增
+ * @data data
+ */
+export async function projectsstageSave(data) {
+  const res = await request.post('/pro/projectsstage/save', data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+export async function projectsstageSaveBatch(data) {
+  const res = await request.post('/pro/projectsstage/saveBatch', data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+
+
 /**
  * 项目详情
  * @id id
@@ -200,6 +223,15 @@ export async function projectsStageDeleteAPI(data) {
   return Promise.reject(new Error(res.data.message));
 }
 
+export async function projectsStageUpdateAPI(data) {
+  const res = await request.put(`/pro/projectsstage/update`,data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+
 
 /**
  * 项目完成

+ 8 - 0
src/views/BOMmanage/ProjectDetailDialog.vue

@@ -1,3 +1,4 @@
+<!-- 项目管理--项目信息 -->
 <template>
   <el-drawer
     :title="title"
@@ -323,6 +324,7 @@
                         :deptList="deptList"
                         :deptTreeList="deptTreeList"
                         :userList="userList"
+                        :responsibleDeptId="responsibleDeptId"
                       ></project-info-table>
                     </el-tab-pane>
                     <el-tab-pane
@@ -707,6 +709,7 @@ export default {
   },
   data() {
     return {
+      responsibleDeptId: '',
       userList: [],
       visible: false,
       title: '项目信息',
@@ -961,6 +964,7 @@ export default {
         groupId: row.responsibleDeptId
       });
       this.userList = res;
+      this.responsibleDeptId = row.responsibleDeptId;
 
       // -----
       if (this.rowData.id) {
@@ -1589,9 +1593,13 @@ export default {
       return ![2].includes(row.processStatus) || [4, 3].includes(row.status);
     },
     handleNodeClick(data) {
+      console.log('点击');
+
       this.treeId = data.id;
       this.currentNodeData = data;
+
       this.$nextTick(async () => {
+        // this.$refs.projectInfoTable.init();
         switch (data.type) {
           case 1:
             await this.$refs.attributeRef.setAttributeFormData(

+ 0 - 1
src/views/project-manage/project-initiation/components/project-form.vue

@@ -739,7 +739,6 @@ export default {
     },
     linkParentFn(obj) {
       console.log(obj);
-
       this.form.parentId = obj.id;
       this.form.parentName = obj.name;
     },

+ 153 - 48
src/views/project-manage/project-initiation/components/projectInfoTable.vue

@@ -11,7 +11,7 @@
       >
         新增项目阶段
       </el-button>
-      <!-- <el-button
+      <el-button
         v-if="dialogType !== 'view'"
         type="primary"
         class="ele-btn-icon"
@@ -19,7 +19,17 @@
         @click="save"
       >
         保存
-      </el-button> -->
+      </el-button>
+
+      <el-button
+        v-if="dialogType !== 'view'"
+        type="primary"
+        class="ele-btn-icon"
+        style="margin-bottom: 5px"
+        @click="updateFn"
+      >
+        确认修改
+      </el-button>
       <!-- 数据表格 -->
       <ele-pro-table
         ref="table"
@@ -28,15 +38,13 @@
         :needPage="false"
         :toolkit="[]"
         :minHeight="100"
-        :maxHeight="300"
         tool-class="ele-toolbar-form"
-        cache-key="eomContactPageTable"
       >
         <template v-slot:action="{ row, $index }">
           <el-popconfirm
             class="ele-action"
             title="确定要删除此信息吗?"
-            @confirm="handleDelInfo($index)"
+            @confirm="handleDelInfo(row, $index)"
           >
             <template v-slot:reference>
               <el-link type="danger" :underline="false" icon="el-icon-delete">
@@ -44,6 +52,16 @@
               </el-link>
             </template>
           </el-popconfirm>
+
+          <el-link
+            v-if="row.id"
+            type="primary"
+            :underline="false"
+            icon="el-icon-edit"
+            @click="editFn(row, $index)"
+          >
+            修改
+          </el-link>
         </template>
         <template v-slot:name="{ row, $index }" v-if="dialogType !== 'view'">
           <el-form-item
@@ -54,7 +72,11 @@
               trigger: ['blur', 'change']
             }"
           >
-            <el-input v-model="row.name" clearable></el-input>
+            <el-input
+              v-model="row.name"
+              clearable
+              :disabled="row.isEdit"
+            ></el-input>
           </el-form-item>
         </template>
         <template v-slot:content="{ row, $index }" v-if="dialogType !== 'view'">
@@ -76,11 +98,12 @@
           >
             <el-date-picker
               style="width: 100%"
-              :disabled="dialogType == 'view'"
+              :disabled="row.isEdit || dialogType == 'view'"
               v-model="row.planStartDate"
               :picker-options="{
                 disabledDate: (time) => {
                   return (
+                    row.isEdit &&
                     row.planEndDate &&
                     time.getTime() > new Date(row.planEndDate)
                   );
@@ -106,7 +129,7 @@
           >
             <el-date-picker
               style="width: 100%"
-              :disabled="dialogType == 'view'"
+              :disabled="row.isEdit || dialogType == 'view'"
               :picker-options="{
                 disabledDate: (time) => {
                   return (
@@ -123,20 +146,19 @@
           </el-form-item>
         </template>
         <template
-          v-slot:responsibleUserIds="{ row, $index }"
+          v-slot:responsibleUserId="{ row, $index }"
           v-if="dialogType !== 'view'"
         >
-          <el-form-item :prop="'datasource.' + $index + '.responsibleUserIds'">
+          <el-form-item :prop="'datasource.' + $index + '.responsibleUserId'">
             <el-select
-              v-model="row.responsibleUserIds"
-              multiple
+              v-model="row.responsibleUserId"
               collapse-tags
               filterable
               placeholder="请选择"
               style="width: 100%"
               clearable
               size="medium"
-              :disabled="dialogType == 'view'"
+              :disabled="row.isEdit || dialogType == 'view'"
               @change="(val) => personChange(val, $index)"
             >
               <el-option
@@ -212,7 +234,12 @@
         </template>
         <template v-slot:remark="{ row, $index }" v-if="dialogType !== 'view'">
           <el-form-item>
-            <el-input type="textarea" v-model="row.remark" clearable></el-input>
+            <el-input
+              type="textarea"
+              v-model="row.remark"
+              clearable
+              :disabled="row.isEdit"
+            ></el-input>
           </el-form-item>
         </template>
         <template v-slot:headerRequired="{ column }">
@@ -232,8 +259,15 @@ import { getFile } from '@/api/system/file';
 import PersonSelect from '@/components/CommomSelect/person-select.vue';
 import { proStatusEnum } from '@/enum/dict';
 import { listOrganizations } from '@/api/system/organization';
-import { deepClone } from '@/utils';
-import { projectsstage } from '@/api/project-manage';
+// import { deepClone } from '@/utils';
+import { deepClone } from '@/components/FormGenerator/utils/index';
+import {
+  projectsstageSave,
+  projectsstageSaveBatch,
+  projectsGetByIdDetailsAPI,
+  projectsStageUpdateAPI,
+  projectsStageDeleteAPI
+} from '@/api/project-manage';
 
 export default {
   name: 'stageInfoTable',
@@ -242,6 +276,9 @@ export default {
     fileUpload
   },
   props: {
+    responsibleDeptId: {
+      type: String
+    },
     dialogForm: {
       type: Object,
       default: () => {
@@ -276,11 +313,14 @@ export default {
   watch: {
     dialogForm: {
       handler(val) {
-        this.form.datasource = this.dialogForm.stageList || [];
+        this.form.datasource = deepClone(this.dialogForm.stageList) || [];
+        this.form.datasource.forEach((item) => {
+          this.$set(item, 'isEdit', true);
+        });
         this.$nextTick(async () => {
           if (this.dialogType === 'view') return;
-          this.form.datasource.forEach((item, index) => {
-            // this.getUserList(item.responsibleDeptId, index);
+          this.form.datasource.forEach((item) => {
+            this.$set(item, 'isEdit', true);
           });
         });
       },
@@ -340,7 +380,7 @@ export default {
           align: 'center',
           showOverflowTooltip: true,
           minWidth: 200,
-          slot: 'responsibleUserIds',
+          slot: 'responsibleUserId',
           headerSlot: 'headerRequired'
         },
         {
@@ -424,7 +464,7 @@ export default {
           slot: 'action',
           label: '操作',
           resizable: false,
-          width: 80,
+          minWidth: 180,
           align: 'center',
           showOverflowTooltip: true,
           fixed: 'right'
@@ -440,10 +480,9 @@ export default {
     // 选择负责人部门
     changeDeptInfo(id, index) {
       console.log(id, index);
-
       const info = this.deptList.find((e) => e.id == id) || {};
       this.$set(this.form.datasource[index], 'responsibleDeptName', info.name);
-      this.$set(this.form.datasource[index], 'responsibleUserIds', []);
+      this.$set(this.form.datasource[index], 'responsibleUserId', '');
       this.$set(this.form.datasource[index], 'responsibleUserName', '');
       // this.getUserList(id, index);
     },
@@ -453,33 +492,45 @@ export default {
       //   this.$refs['directorRef' + index].getList({groupId});
       // }
     },
-    // personChange(val, info, index) {
-    //   this.$set(this.form.datasource[index], 'responsibleUserName', info.name);
-    // },
     personChange(val, index) {
-      // const info = this.userList.find((e) => e.id == val) || {};
-      // this.$set(this.form.datasource[index], 'responsibleUserName', info.name);
+      const info = this.userList.find((e) => e.id == val) || {};
+      console.log(val, info, index);
+      console.log(this.dialogForm);
+      this.$set(this.form.datasource[index], 'responsibleUserName', info.name);
+      // this.$set(
+      //   this.form.datasource[index],
+      //   'responsibleDeptName',
+      //   this.dialogForm.responsibleDeptName
+      // );
     },
+    // personChange(val, index) {
+    //
+    //   // this.$set(this.form.datasource[index], 'responsibleUserName', info.name);
+    // },
     downloadFile(file) {
       getFile({ objectName: file.storePath }, file.name);
     },
     //新增计划数据
     handleAddInfo() {
-      this.form.datasource.push({
-        milepost: '',
-        isMilepost: 0,
-        responsibleUserList: [],
-        responsibleUserIds: [],
-        responsibleDeptId: '',
-        responsibleDeptName: '',
-        planStartDate: '',
-        planEndDate: '',
-        name: '',
-        content: '',
-        status: 0,
-        isOverTime: 0,
-        speedPercent: 0,
-        remark: ''
+      this.$nextTick(() => {
+        this.form.datasource.push({
+          projectId: localStorage.getItem('projectId'),
+          milepost: '',
+          isMilepost: 0,
+          responsibleUserList: [],
+          responsibleUserId: '',
+          responsibleDeptId: this.responsibleDeptId,
+          responsibleDeptName: this.dialogForm.responsibleDeptName,
+          planStartDate: '',
+          planEndDate: '',
+          name: '',
+          content: '',
+          status: 0,
+          isOverTime: 0,
+          speedPercent: 0,
+          remark: ''
+        });
+        console.log(this.form.datasource);
       });
     },
     //
@@ -489,7 +540,7 @@ export default {
         this.$set(this.form.datasource[index], 'isMilepost', 0);
         this.$set(this.form.datasource[index], 'isOverTime', 0);
         this.$set(this.form.datasource[index], 'speedPercent', 0);
-        this.$set(this.form.datasource[index], 'responsibleUserIds', '');
+        this.$set(this.form.datasource[index], 'responsibleUserId', '');
         this.$set(this.form.datasource[index], 'responsibleUserName', '');
         this.$set(this.form.datasource[index], 'responsibleDeptId', '');
         this.$set(this.form.datasource[index], 'responsibleDeptName', '');
@@ -501,8 +552,13 @@ export default {
     },
 
     //删除关联信息数据
-    handleDelInfo(index) {
-      this.form.datasource.splice(index, 1);
+    async handleDelInfo(row, index) {
+      if (!row.id) {
+        this.form.datasource.splice(index, 1);
+        return;
+      }
+      const res = await projectsStageDeleteAPI([row.id]);
+      this.init();
     },
     customColorMethod(percentage) {
       if (percentage < 30) {
@@ -514,9 +570,14 @@ export default {
       }
     },
     async save() {
-      console.log(this.form.datasource);
+      let form = await this.getTableValidate();
+      let saveForm = form.filter((item) => !item.id);
+      console.log(form);
+      const res = await projectsstageSaveBatch(saveForm);
 
-      // const res = await projectsstage(this.form.datasource);
+      if (res) {
+        this.init();
+      }
     },
     getTableValidate() {
       return new Promise((resolve, reject) => {
@@ -530,7 +591,51 @@ export default {
           }
         });
       });
+    },
+    init() {
+      this.$nextTick(async () => {
+        const res = await projectsGetByIdDetailsAPI(
+          localStorage.getItem('projectId')
+        );
+        console.log(res);
+
+        this.form.datasource = res.allStageList || [];
+        this.form.datasource.forEach((item) => {
+          this.$set(item, 'isEdit', true);
+        });
+        console.log(this.form);
+      });
+
+      // projectsGetByIdDetailsAPI
+      // this.form.datasource=
+    },
+    editFn(row, index) {
+      console.log('xiugai', index, this.form.datasource);
+      this.$nextTick(() => {
+        this.$set(this.form.datasource[index], 'isEdit', false);
+      });
+    },
+    async updateFn() {
+      let form = await this.getTableValidate();
+      let updateForm = form.filter((item) => !item.isEdit);
+      console.log(updateForm);
+
+      // const res = await projectsStageUpdateAPI(updateForm[0]);
+
+      for (const item of updateForm) {
+        await projectsStageUpdateAPI(item);
+      }
+      this.init();
+
+      // const res = await projectsStageUpdateAPI(saveForm);
+
+      // if (res) {
+      //   this.init();
+      // }
     }
+  },
+  created() {
+    this.init();
   }
 };
 </script>

+ 405 - 407
src/views/project-manage/project-initiation/index.vue

@@ -308,428 +308,426 @@
 </template>
 
 <script>
-  import ProjectDetailDialog from '@/views/BOMmanage/ProjectDetailDialog.vue';
-  import processSubmitDialog from '@/BIZComponents/processSubmitDialog/processSubmitDialog.vue';
-  import indexSearch from './components/index-search.vue';
-  import addOrEditDialog from './components/addOrEditDialog.vue';
-  import addPlanDialog from '../planManage/components/addOrEditDialog.vue';
-  import detailDialog from './components/detailDialog.vue';
-  import {
-    projectsDeleteAPI,
-    projectsPageAPI,
-    submit,
-    projectsFinishAPI,
-    projectsPauseAPI,
-    projectsStartupAPI,
-    projectsTerminationAPI,
-    getMyProjectsPage
-  } from '@/api/project-manage';
-  import { reviewStatusEnum } from '@/enum/dict';
-  import { mapGetters } from 'vuex';
-  import { getByCode } from '@/api/system/dictionary-data';
-  import popModal from '@/components/pop-modal/index.vue';
-  import AssetTree from '@/components/AssetTree';
-  export default {
-    name: 'index',
-    components: {
-      popModal,
-      addOrEditDialog,
-      detailDialog,
-      indexSearch,
-      processSubmitDialog,
-      addPlanDialog,
-      AssetTree,
-      ProjectDetailDialog
-    },
-    computed: {
-      ...mapGetters(['getDictValue']),
+import ProjectDetailDialog from '@/views/BOMmanage/ProjectDetailDialog.vue';
+import processSubmitDialog from '@/BIZComponents/processSubmitDialog/processSubmitDialog.vue';
+import indexSearch from './components/index-search.vue';
+import addOrEditDialog from './components/addOrEditDialog.vue';
+import addPlanDialog from '../planManage/components/addOrEditDialog.vue';
+import detailDialog from './components/detailDialog.vue';
+import {
+  projectsDeleteAPI,
+  projectsPageAPI,
+  submit,
+  projectsFinishAPI,
+  projectsPauseAPI,
+  projectsStartupAPI,
+  projectsTerminationAPI,
+  getMyProjectsPage
+} from '@/api/project-manage';
+import { reviewStatusEnum } from '@/enum/dict';
+import { mapGetters } from 'vuex';
+import { getByCode } from '@/api/system/dictionary-data';
+import popModal from '@/components/pop-modal/index.vue';
+import AssetTree from '@/components/AssetTree';
+export default {
+  name: 'index',
+  components: {
+    popModal,
+    addOrEditDialog,
+    detailDialog,
+    indexSearch,
+    processSubmitDialog,
+    addPlanDialog,
+    AssetTree,
+    ProjectDetailDialog
+  },
+  computed: {
+    ...mapGetters(['getDictValue']),
 
-      columns() {
-        return [
-          {
-            width: 45,
-            type: 'selection',
-            columnKey: 'selection',
-            align: 'center'
-          },
-          {
-            columnKey: 'index',
-            label: '序号',
-            type: 'index',
-            width: 55,
-            align: 'center',
-            showOverflowTooltip: true
-          },
-          {
-            prop: 'typeName',
-            label: '项目类型',
-            showOverflowTooltip: true,
-            minWidth: 150,
-            align: 'center'
-            // slot: 'type',
-          },
-          {
-            prop: 'code',
-            label: '项目编码',
-            showOverflowTooltip: true,
-            minWidth: 160,
-            slot: 'code',
-            align: 'center'
-          },
-          {
-            prop: 'name',
-            label: '项目名称',
-            align: 'center',
-            showOverflowTooltip: true,
-            minWidth: 140
-          },
+    columns() {
+      return [
+        {
+          width: 45,
+          type: 'selection',
+          columnKey: 'selection',
+          align: 'center'
+        },
+        {
+          columnKey: 'index',
+          label: '序号',
+          type: 'index',
+          width: 55,
+          align: 'center',
+          showOverflowTooltip: true
+        },
+        {
+          prop: 'typeName',
+          label: '项目类型',
+          showOverflowTooltip: true,
+          minWidth: 150,
+          align: 'center'
+          // slot: 'type',
+        },
+        {
+          prop: 'code',
+          label: '项目编码',
+          showOverflowTooltip: true,
+          minWidth: 160,
+          slot: 'code',
+          align: 'center'
+        },
+        {
+          prop: 'name',
+          label: '项目名称',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 140
+        },
 
-          {
-            prop: 'responsibleDeptName',
-            label: '负责部门',
-            align: 'center',
-            showOverflowTooltip: true,
-            minWidth: 100
-          },
-          {
-            prop: 'responsibleUserName',
-            label: '项目经理',
-            align: 'center',
-            showOverflowTooltip: true,
-            minWidth: 100
-          },
-          {
-            prop: 'teamName',
-            label: '项目团队',
-            align: 'center',
-            showOverflowTooltip: true,
-            minWidth: 100
-          },
-          {
-            prop: 'cycle',
-            label: '项目周期',
-            align: 'center',
-            showOverflowTooltip: true,
-            minWidth: 100
-          },
-          {
-            prop: 'budget',
-            label: '项目预算',
-            align: 'center',
-            showOverflowTooltip: true,
-            minWidth: 110,
-            formatter: (_row, _column, cellValue) => {
-              return cellValue
-                ? cellValue +
-                    this.getDictV('pro_projects_budget_unit', _row.unit)
-                : '';
-            }
-          },
-          {
-            prop: 'planStartDate',
-            label: '计划开始日期',
-            align: 'center',
-            showOverflowTooltip: true,
-            minWidth: 120
-          },
-          {
-            prop: 'planEndDate',
-            label: '计划完成日期',
-            align: 'center',
-            showOverflowTooltip: true,
-            minWidth: 120
-          },
-          {
-            prop: 'realStartTime',
-            label: '实际开始日期',
-            align: 'center',
-            showOverflowTooltip: true,
-            minWidth: 120
-          },
-          {
-            prop: 'realEndTime',
-            label: '实际完成日期',
-            align: 'center',
-            showOverflowTooltip: true,
-            minWidth: 120
-          },
-          {
-            prop: 'cost',
-            label: '费用(元)',
-            align: 'center',
-            showOverflowTooltip: true,
-            minWidth: 140
-          },
-          {
-            prop: 'status',
-            label: '项目状态',
-            align: 'center',
-            showOverflowTooltip: true,
-            minWidth: 100,
-            slot: 'status'
-          },
-          {
-            prop: 'processStatus',
-            label: '审核状态',
-            align: 'center',
-            showOverflowTooltip: true,
-            minWidth: 100,
-            formatter: (_row, _column, cellValue) => {
-              return reviewStatusEnum[_row.processStatus].label;
-            }
-          },
-          {
-            prop: 'isOverTime',
-            label: '是否超时',
-            align: 'center',
-            showOverflowTooltip: true,
-            minWidth: 100,
-            slot: 'isOverTime'
-          },
-          {
-            prop: 'isOverbudget',
-            label: '是否超预算',
-            align: 'center',
-            showOverflowTooltip: true,
-            minWidth: 100,
-            slot: 'isOverbudget'
-          },
-          {
-            prop: 'speedPercent',
-            label: '项目进度',
-            align: 'center',
-            showOverflowTooltip: true,
-            minWidth: 150,
-            slot: 'speedPercent'
-          },
-          {
-            columnKey: 'action',
-            label: '操作',
-            width: 280,
-            align: 'center',
-            resizable: false,
-            slot: 'action',
-            fixed: 'right'
+        {
+          prop: 'responsibleDeptName',
+          label: '负责部门',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 100
+        },
+        {
+          prop: 'responsibleUserName',
+          label: '项目经理',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 100
+        },
+        {
+          prop: 'teamName',
+          label: '项目团队',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 100
+        },
+        {
+          prop: 'cycle',
+          label: '项目周期',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 100
+        },
+        {
+          prop: 'budget',
+          label: '项目预算',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 110,
+          formatter: (_row, _column, cellValue) => {
+            return cellValue
+              ? cellValue + this.getDictV('pro_projects_budget_unit', _row.unit)
+              : '';
           }
-        ];
-      }
-    },
-    data() {
-      return {
-        projectsFinishAPI: projectsFinishAPI,
-        projectsPauseAPI: projectsPauseAPI,
-        projectsStartupAPI: projectsStartupAPI,
-        projectsTerminationAPI: projectsTerminationAPI,
-        parentId:'',
-        selection: [],
-        dictList: [],
-        // 表格列配置
+        },
+        {
+          prop: 'planStartDate',
+          label: '计划开始日期',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 120
+        },
+        {
+          prop: 'planEndDate',
+          label: '计划完成日期',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 120
+        },
+        {
+          prop: 'realStartTime',
+          label: '实际开始日期',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 120
+        },
+        {
+          prop: 'realEndTime',
+          label: '实际完成日期',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 120
+        },
+        {
+          prop: 'cost',
+          label: '费用(元)',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 140
+        },
+        {
+          prop: 'status',
+          label: '项目状态',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 100,
+          slot: 'status'
+        },
+        {
+          prop: 'processStatus',
+          label: '审核状态',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 100,
+          formatter: (_row, _column, cellValue) => {
+            return reviewStatusEnum[_row.processStatus].label;
+          }
+        },
+        {
+          prop: 'isOverTime',
+          label: '是否超时',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 100,
+          slot: 'isOverTime'
+        },
+        {
+          prop: 'isOverbudget',
+          label: '是否超预算',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 100,
+          slot: 'isOverbudget'
+        },
+        {
+          prop: 'speedPercent',
+          label: '项目进度',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 150,
+          slot: 'speedPercent'
+        },
+        {
+          columnKey: 'action',
+          label: '操作',
+          width: 280,
+          align: 'center',
+          resizable: false,
+          slot: 'action',
+          fixed: 'right'
+        }
+      ];
+    }
+  },
+  data() {
+    return {
+      projectsFinishAPI: projectsFinishAPI,
+      projectsPauseAPI: projectsPauseAPI,
+      projectsStartupAPI: projectsStartupAPI,
+      projectsTerminationAPI: projectsTerminationAPI,
+      parentId: '',
+      selection: [],
+      dictList: [],
+      // 表格列配置
 
-        // 是否显示编辑弹窗
-        addOrEditDialogFlag: false,
-        detailDialogFlag: false,
-        processSubmitDialogFlag: false,
-        delVisible: false,
-        addPlanDialogFLag: false,
-        // 全部菜单数据
-        menuList: [],
-        // 展开折叠
-        expandAllFlag: false
-      };
+      // 是否显示编辑弹窗
+      addOrEditDialogFlag: false,
+      detailDialogFlag: false,
+      processSubmitDialogFlag: false,
+      delVisible: false,
+      addPlanDialogFLag: false,
+      // 全部菜单数据
+      menuList: [],
+      // 展开折叠
+      expandAllFlag: false
+    };
+  },
+  async created() {
+    console.log(111);
+  },
+  watch: {
+    $route() {
+      this.reload && this.reload();
+    }
+  },
+  methods: {
+    getDictV(code, val) {
+      if (!this.dictList[code]) return '';
+      return this.dictList[code].find((item) => item.value == val)?.label;
     },
-    async created() {
-      console.log(111);
+    async getDictList(code) {
+      let { data: res } = await getByCode(code);
+      this.dictList[code] = res.map((item) => {
+        let values = Object.keys(item);
+        return {
+          value: values[0],
+          label: item[values[0]]
+        };
+      });
     },
-    watch: {
-      $route() {
-        this.reload && this.reload();
+    handelBOMConstructDetail(row, type = '') {
+      // this.$router.push({
+      //   path: '/BOMmanage/details',
+      //   query: {
+      //     id: row.id,
+      //     type
+      //   }
+      // });
+      localStorage.setItem('projectId', row.id);
+      this.$refs.ProjectDetailDialogFlag.open(row, type);
+    },
+    customColorMethod(percentage) {
+      if (percentage < 30) {
+        return '#909399';
+      } else if (percentage < 70) {
+        return '#e6a23c';
+      } else {
+        return '#67c23a';
       }
     },
-    methods: {
-      getDictV(code, val) {
-        if (!this.dictList[code]) return '';
-        return this.dictList[code].find((item) => item.value == val)?.label;
-      },
-      async getDictList(code) {
-        let { data: res } = await getByCode(code);
-        this.dictList[code] = res.map((item) => {
-          let values = Object.keys(item);
-          return {
-            value: values[0],
-            label: item[values[0]]
-          };
-        });
-      },
-      handelBOMConstructDetail(row, type = '') {
-        // this.$router.push({
-        //   path: '/BOMmanage/details',
-        //   query: {
-        //     id: row.id,
-        //     type
-        //   }
-        // });
-        this.$refs.ProjectDetailDialogFlag.open(row, type);
-      },
-      customColorMethod(percentage) {
-        if (percentage < 30) {
-          return '#909399';
-        } else if (percentage < 70) {
-          return '#e6a23c';
-        } else {
-          return '#67c23a';
-        }
-      },
-      /* 表格数据源 */
-      async datasource({ page, limit, where, parent }) {
-        await this.getDictList('pro_projects_status');
-        await this.getDictList('pro_projects_type');
-        await this.getDictList('pro_projects_budget_unit');
-        // /project-manage/myProject
-        const api =
-          this.$route.path == '/project-manage/myProject'
-            ? getMyProjectsPage
-            : projectsPageAPI;
-        return api({
-          pageNum: page,
-          size: limit,
-          parentId: parent?.id ?? '0',
-          // parentId:this.parentId,
-          ...where,
-          type: this.treeId
-        });
-      },
-      onDone(row) {
-        console.log(row);
-      },
-      /* 刷新表格 */
-      reload(where) {
-        this.$refs.table.reload({ where, size: 1, pageNum: 10, parentId: '0' });
-        this.$refs.table.reRenderTable();
-      },
-      handleNodeClick(data, node) {
-        this.parentId=data.parentId
-        this.treeId = data.id;
-        this.reload();
-      },
-      /* 显示编辑 */
-      openEdit(row = {}, type) {
-        this.addOrEditDialogFlag = true;
-        this.$nextTick(() => {
-          this.$refs.addOrEditDialogRef.init(row, type);
-        });
-      },
-      openDetail(row = {}) {
-        this.detailDialogFlag = true;
-        this.$nextTick(() => {
-          this.$refs.detailDialogRef.init(row);
-        });
-      },
-      handleAddPlan(row) {
-        console.log(row);
-        this.addPlanDialogFLag = true;
-        this.$nextTick(() => {
-          row.projectId = row.id;
-          this.$refs.addPlanDialogRef.init(row, 'add');
-        });
-      },
-      async handleStatus(API, msg, row) {
-        let message = '确定' + msg + '该项目吗';
-        this.$confirm(message, '提示', {
-          type: 'warning'
+    /* 表格数据源 */
+    async datasource({ page, limit, where, parent }) {
+      await this.getDictList('pro_projects_status');
+      await this.getDictList('pro_projects_type');
+      await this.getDictList('pro_projects_budget_unit');
+      // /project-manage/myProject
+      const api =
+        this.$route.path == '/project-manage/myProject'
+          ? getMyProjectsPage
+          : projectsPageAPI;
+      return api({
+        pageNum: page,
+        size: limit,
+        parentId: parent?.id ?? '0',
+        // parentId:this.parentId,
+        ...where,
+        type: this.treeId
+      });
+    },
+    onDone(row) {
+      console.log(row);
+    },
+    /* 刷新表格 */
+    reload(where) {
+      this.$refs.table.reload({ where, size: 1, pageNum: 10, parentId: '0' });
+      this.$refs.table.reRenderTable();
+    },
+    handleNodeClick(data, node) {
+      this.parentId = data.parentId;
+      this.treeId = data.id;
+      this.reload();
+    },
+    /* 显示编辑 */
+    openEdit(row = {}, type) {
+      this.addOrEditDialogFlag = true;
+      this.$nextTick(() => {
+        this.$refs.addOrEditDialogRef.init(row, type);
+      });
+    },
+    openDetail(row = {}) {
+      this.detailDialogFlag = true;
+      this.$nextTick(() => {
+        this.$refs.detailDialogRef.init(row);
+      });
+    },
+    handleAddPlan(row) {
+      console.log(row);
+      this.addPlanDialogFLag = true;
+      this.$nextTick(() => {
+        row.projectId = row.id;
+        this.$refs.addPlanDialogRef.init(row, 'add');
+      });
+    },
+    async handleStatus(API, msg, row) {
+      let message = '确定' + msg + '该项目吗';
+      this.$confirm(message, '提示', {
+        type: 'warning'
+      })
+        .then(async () => {
+          await API(row.id);
+          this.$message.success('操作成功');
+          this.reload();
+        })
+        .catch(() => {});
+    },
+    //流程提交
+    processSubmit(row) {
+      this.processSubmitDialogFlag = true;
+      this.$nextTick(() => {
+        let params = {
+          businessId: row.id,
+          businessKey: 'pro_project_approve',
+          formCreateUserId: row.createUserId
+        };
+        this.$refs.processSubmitDialogRef.init(params);
+      });
+      // submit({
+      //   projectId: row.id
+      // }).then((res) => {
+      //   this.$message.success('提交成功');
+      //   this.reload();
+      // });
+    },
+    //批量删除
+    allDelBtn() {
+      if (this.selection.length === 0) return;
+      let flag = this.selection.some((item) =>
+        [1, 2].includes(item.processStatus)
+      );
+      if (flag)
+        return this.$message.warning('抱歉已审核、审核中的数据不能删除,请检查');
+      this.delVisible = true;
+    },
+    //删除弹框确定
+    commitBtn() {
+      const dataId = this.selection.map((v) => v.id);
+      this.remove(dataId);
+    },
+    /* 删除 */
+    remove(ids) {
+      const loading = this.$loading({ lock: true });
+      projectsDeleteAPI(ids)
+        .then((res) => {
+          loading.close();
+          this.$message.success('删除成功');
+          this.reload();
         })
-          .then(async () => {
-            await API(row.id);
-            this.$message.success('操作成功');
-            this.reload();
-          })
-          .catch(() => {});
-      },
-      //流程提交
-      processSubmit(row) {
-        this.processSubmitDialogFlag = true;
-        this.$nextTick(() => {
-          let params = {
-            businessId: row.id,
-            businessKey: 'pro_project_approve',
-            formCreateUserId: row.createUserId
-          };
-          this.$refs.processSubmitDialogRef.init(params);
+        .catch((e) => {
+          loading.close();
+          // this.$message.error(e.message);
         });
-        // submit({
-        //   projectId: row.id
-        // }).then((res) => {
-        //   this.$message.success('提交成功');
-        //   this.reload();
-        // });
-      },
-      //批量删除
-      allDelBtn() {
-        if (this.selection.length === 0) return;
-        let flag = this.selection.some((item) =>
-          [1, 2].includes(item.processStatus)
-        );
-        if (flag)
-          return this.$message.warning(
-            '抱歉已审核、审核中的数据不能删除,请检查'
-          );
-        this.delVisible = true;
-      },
-      //删除弹框确定
-      commitBtn() {
-        const dataId = this.selection.map((v) => v.id);
-        this.remove(dataId);
-      },
-      /* 删除 */
-      remove(ids) {
-        const loading = this.$loading({ lock: true });
-        projectsDeleteAPI(ids)
-          .then((res) => {
-            loading.close();
-            this.$message.success('删除成功');
-            this.reload();
-          })
-          .catch((e) => {
-            loading.close();
-            // this.$message.error(e.message);
-          });
-      },
-      /* 展开/折叠全部 */
-      expandAll() {
-        this.expandAllFlag = !this.expandAllFlag;
-        this.$refs.table.toggleRowExpansionAll(this.expandAllFlag);
-      }
+    },
+    /* 展开/折叠全部 */
+    expandAll() {
+      this.expandAllFlag = !this.expandAllFlag;
+      this.$refs.table.toggleRowExpansionAll(this.expandAllFlag);
     }
-  };
+  }
+};
 </script>
 <style lang="scss" scoped>
-  :deep(.el-link--inner) {
-    margin-left: 0px !important;
-  }
-  ::v-deep .el-dropdown-link {
-    cursor: pointer;
-    color: #188ffd;
-  }
-  ::v-deep .el-dropdown-menu__item {
-    .el-link {
-      width: 100%;
-      display: flex;
-      flex: 1;
-      justify-content: flex-start;
-    }
-  }
-  .sys-organization-list {
-    height: calc(100vh - 230px);
-    box-sizing: border-box;
-    border-width: 1px;
-    border-style: solid;
-    overflow: auto;
+:deep(.el-link--inner) {
+  margin-left: 0px !important;
+}
+::v-deep .el-dropdown-link {
+  cursor: pointer;
+  color: #188ffd;
+}
+::v-deep .el-dropdown-menu__item {
+  .el-link {
+    width: 100%;
+    display: flex;
+    flex: 1;
+    justify-content: flex-start;
   }
+}
+.sys-organization-list {
+  height: calc(100vh - 230px);
+  box-sizing: border-box;
+  border-width: 1px;
+  border-style: solid;
+  overflow: auto;
+}
 
-  .sys-organization-list :deep(.el-tree-node__content) {
-    height: 40px;
+.sys-organization-list :deep(.el-tree-node__content) {
+  height: 40px;
 
-    & > .el-tree-node__expand-icon {
-      margin-left: 10px;
-    }
+  & > .el-tree-node__expand-icon {
+    margin-left: 10px;
   }
+}
 </style>