Procházet zdrojové kódy

项目关联流程开发

Z před 1 rokem
rodič
revize
40460ea19b

+ 80 - 0
src/api/bpm/components/project-manage/team.js

@@ -0,0 +1,80 @@
+import request from '@/utils/request';
+
+/**
+ * 团队列表
+ * @data data
+ */
+export async function projectsTeamPageAPI(data) {
+  const res = await request.post('/pro/projectteam/page', data);
+  if (res.data.code == 0) {
+    return res.data.data.list;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+/**
+ * 保存团队
+ * @data data
+ */
+export async function projectsTeamSaveAPI(data) {
+  const res = await request.post('/pro/projectteam/save', data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+/**
+ * 修改团队
+ * @data data
+ */
+export async function projectsTeamUpdateAPI(data) {
+  const res = await request.put('/pro/projectteam/update', data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+/**
+ * 团队详情
+ * @id id
+ */
+export async function projectsTeamGetByIdAPI(id) {
+  const res = await request.get(`/pro/projectteam/getById/${id}`);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+/**
+ * 获取团队编码
+ * @id id
+ */
+export async function getProjectTeamCodeAPI() {
+  const res = await request.get(`/pro/projectteam/getProjectTeamCode`);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+/**
+ * 团队删除
+ * @id id
+ */
+export async function projectsTeamDeleteAPI(data) {
+  const res = await request.delete(`/pro/projectteam/delete`,{data});
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}
+
+/**
+ * 提交
+ */
+export async function submit(data) {
+  const res = await request.post(`/bpm/pro/projectteam/submit`, data);
+  if (res.data.code == 0) {
+    return res.data.data;
+  }
+  return Promise.reject(new Error(res.data.message));
+}

+ 2 - 1
src/enum/dict.js

@@ -71,7 +71,8 @@ export default {
   项目状态: 'pro_projects_status',
   项目任务类型: 'task_type',
   交付物类型: 'deliverables_type',
-  交付物流程类型:'pro_files_approve_type'
+  交付物流程类型:'pro_files_approve_type',
+  预算单位: 'pro_projects_budget_unit'
 };
 
 export const numberList = [

+ 5 - 0
src/views/bpm/handleTask/components/project-manage/plan-manage/detailDialog.vue

@@ -52,6 +52,11 @@ export default {
     async getProjectPlanInfo(id = '') {
       let res = await projectsPlanGetByIdAPI(id)
       this.dialogForm = deepClone(res)
+      this.dialogForm.responsibleUserIds = this.dialogForm.responsibleUserList.map(i => i.userName) || []
+      this.dialogForm.planStageList.forEach((item, index) => {
+        let userNames = item.responsibleUserList.map(i => i.userName) || []
+        this.$set(item, 'responsibleUserNames', userNames.join(','))
+      })
     },
     // 获取部门数据
     getDeptList() {

+ 96 - 57
src/views/bpm/handleTask/components/project-manage/plan-manage/plan-form.vue

@@ -46,7 +46,7 @@
         <el-col :span="8">
           <el-form-item
             label="计划编码">
-            <el-input v-model="form.code" disabled></el-input>
+            <el-input v-model="form.code" :disabled="dialogType=='view'"></el-input>
           </el-form-item>
         </el-col>
         <el-col :span="8">
@@ -69,6 +69,53 @@
             </el-select>
           </el-form-item>
         </el-col>
+        <el-col :span="8">
+          <!--          <el-form-item-->
+          <!--            label="申请部门"-->
+          <!--            prop="responsibleDeptId">-->
+          <!--            <ele-tree-select-->
+          <!--              :disabled="dialogType=='view'"-->
+          <!--              clearable-->
+          <!--              ref="deptRef"-->
+          <!--              :data="deptTreeList"-->
+          <!--              v-model="form.responsibleDeptId"-->
+          <!--              valueKey="id"-->
+          <!--              labelKey="name"-->
+          <!--              placeholder="请选择"-->
+          <!--              @change="changeDeptInfo"-->
+          <!--              default-expand-all-->
+          <!--            />-->
+          <!--          </el-form-item>-->
+        </el-col>
+        <el-col :span="8">
+          <el-form-item
+            prop="responsibleUserIds"
+            label="负责人">
+            <el-select v-model="form.responsibleUserIds" multiple :collapse-tags="dialogType!='view'"
+                       filterable
+                       placeholder="请选择" style="width: 100%;"
+                       clearable
+                       size="medium"
+                       :disabled="dialogType=='view'">
+              <el-option
+                v-for="item in userList"
+                :key="item.id"
+                :label="item.name"
+                :value="item.id">
+              </el-option>
+            </el-select>
+            <!--            <personSelect-->
+            <!--              :disabled="dialogType=='view'"-->
+            <!--              ref="userRef"-->
+            <!--              :init="false"-->
+            <!--              v-model="form.responsibleUserId"-->
+            <!--              @selfChange="personChange"/>-->
+          </el-form-item>
+        </el-col>
+
+
+      </el-row>
+      <el-row>
         <el-col :span="8">
           <el-form-item
             prop="planStartDate"
@@ -97,42 +144,39 @@
             </el-date-picker>
           </el-form-item>
         </el-col>
-
-      </el-row>
-      <el-row>
+        <!--        <el-col :span="8">-->
+        <!--          <el-form-item label="权重占比">-->
+        <!--            <el-input type="number" :min="0" :max="100" v-model="form.proportion" :disabled="dialogType=='view'">-->
+        <!--              <template slot="append">-->
+        <!--                %-->
+        <!--              </template>-->
+        <!--            </el-input>-->
+        <!--          </el-form-item>-->
+        <!--        </el-col>-->
         <el-col :span="8">
           <el-form-item
-            label="申请部门"
-            prop="responsibleDeptId">
-            <ele-tree-select
-              :disabled="dialogType=='view'"
-              clearable
-              ref="deptRef"
-              :data="deptTreeList"
-              v-model="form.responsibleDeptId"
-              valueKey="id"
-              labelKey="name"
-              placeholder="请选择"
-              @change="changeDeptInfo"
-              default-expand-all
+            label="附件">
+
+            <fileUpload
+              v-if="dialogType!='view'"
+              style="position: absolute"
+              v-model="form.files"
+              module="main"
+              :showLib="false"
             />
-          </el-form-item>
-        </el-col>
-        <el-col :span="8">
-          <el-form-item
-            prop="responsibleUserId"
-            label="负责人">
-            <personSelect
-              :disabled="dialogType=='view'"
-              ref="userRef"
-              :init="false"
-              v-model="form.responsibleUserId"
-              @selfChange="personChange"/>
+            <el-link
+              v-else
+              v-for="item in form.files"
+              type="primary"
+              :underline="false"
+              @click="downloadFile(item)">
+              {{ item.name }}
+            </el-link>
           </el-form-item>
         </el-col>
       </el-row>
       <el-row>
-        <el-col :span="24">
+        <el-col :span="16">
           <el-form-item label="备注">
             <el-input type="textarea" :rows="2" v-model="form.remark" :disabled="dialogType=='view'"></el-input>
           </el-form-item>
@@ -148,10 +192,11 @@ import PersonSelect from "@/components/CommomSelect/person-select.vue";
 import {getByCode} from "@/api/system/dictionary-data";
 import ProjectForm from "./project-form.vue";
 import {listOrganizations} from "@/api/system/organization";
+import fileUpload from "@/components/upload/fileUpload.vue";
 
 export default {
   name: "plan-form",
-  components: {ProjectForm, PersonSelect},
+  components: {fileUpload, ProjectForm, PersonSelect},
   props: {
     dialogType: {
       type: String,
@@ -172,6 +217,12 @@ export default {
         return []
       }
     },
+    userList: {
+      type: Array,
+      default() {
+        return []
+      }
+    },
     deptTreeList: {
       type: Array,
       default() {
@@ -182,9 +233,13 @@ export default {
   watch: {
     dialogForm: {
       handler(val) {
-        this.form = {...this.dialogForm}
+        this.form = {
+          ...this.form,
+          ...this.dialogForm
+        }
+        console.log(this.form);
         this.$nextTick(async () => {
-          await this.getUserList(this.dialogForm.responsibleDeptId);
+          // await this.getUserList(this.dialogForm.responsibleDeptId);
           await this.changeProjectInfo(this.form.projectId);
         })
 
@@ -204,9 +259,12 @@ export default {
         responsibleDeptName: "",
         responsibleUserName: '',
         responsibleUserId: '',
+        responsibleUserIds: [],
         remark: '',
+        proportion: '',
         planStartDate: '',
         planEndDate: '',
+        files: [],
       },
       popoverFlag: false,
       projectList: [],
@@ -216,7 +274,7 @@ export default {
         name: {required: true, message: '请输入项目名称', trigger: 'blur'},
         planStartDate: {required: true, message: '请选择计划开始日期', trigger: 'change'},
         planEndDate: {required: true, message: '请选择计划完成日期', trigger: 'change'},
-        responsibleUserId: {required: true, message: '请选择负责人', trigger: 'change'},
+        responsibleUserIds: {required: true, message: '请选择负责人', trigger: 'change'},
         responsibleDeptId: {required: true, message: '请选择部门', trigger: 'change'},
       }
     }
@@ -232,32 +290,13 @@ export default {
         return
       }
       this.projectStageList = await projectsSelectTreeDataAPI({treeType: 0, id: val, isTask: 0, isPlan: 0})
+      this.$emit('changeProject',val)
     },
 
-
-    getProjectInfo(id) {
-      this.popoverFlag = true;
-      this.$nextTick(() => {
-        this.$refs.projectForm.getInfo(id);
-      })
-    },
-    // 选择负责人部门
-    changeDeptInfo(id) {
-      const info = this.deptList.find((e) => e.id == id) || {};
-      this.form.responsibleDeptName = info.name;
-      this.form.responsibleUserId = '';
-      this.form.responsibleUserName = '';
-      this.getUserList(id);
-    },
-    // 获取人员数据
-    getUserList(groupId) {
-      if (groupId) {
-        this.$refs.userRef.getList({groupId});
-      }
-    },
-    personChange(val, info) {
-      this.form.responsibleUserName = info.name;
+    downloadFile(file) {
+      getFile({objectName: file.storePath}, file.type);
     },
+
     validForm() {
       return new Promise((resolve, reject) => {
         this.$refs.form.validate(valid => {

+ 95 - 47
src/views/bpm/handleTask/components/project-manage/plan-manage/planInfoTable.vue

@@ -99,14 +99,26 @@
             />
           </el-form-item>
         </template>
-        <template v-slot:responsibleUserId="{row,$index}">
-          <el-form-item :prop="'datasource.'+$index+'.responsibleUserId'">
-            <personSelect
-              :disabled="dialogType=='view'"
-              :ref="'directorRef'+$index"
-              v-model="row.responsibleUserId"
-              :init="false"
-              @selfChange="personChange"/>
+        <template v-slot:responsibleUserIds="{row,$index}" v-if="dialogType!=='view'">
+          <el-form-item :prop="'datasource.'+$index+'.responsibleUserIds'">
+            <el-select v-model="row.responsibleUserIds" multiple collapse-tags
+                       filterable placeholder="请选择" style="width: 100%;"
+                       clearable
+                       size="medium"
+                       :disabled="dialogType=='view'">
+              <el-option
+                v-for="item in userList"
+                :key="item.id"
+                :label="item.name"
+                :value="item.id">
+              </el-option>
+            </el-select>
+            <!--            <personSelect-->
+            <!--              :disabled="dialogType=='view'"-->
+            <!--              :ref="'directorRef'+$index"-->
+            <!--              v-model="row.responsibleUserIds"-->
+            <!--              :init="false"-->
+            <!--              @selfChange="personChange"/>-->
           </el-form-item>
         </template>
         <template v-slot:isMilepost="{row,$index}" v-if="dialogType!=='view'">
@@ -117,6 +129,10 @@
             </el-select>
           </el-form-item>
         </template>
+        <template v-slot:speedPercent="{ row }">
+          <el-progress :stroke-width="20" text-color="#606266" :text-inside="true" :percentage="row.speedPercent||0"
+                       :color="customColorMethod"></el-progress>
+        </template>
         <template v-slot:milepost="{row,$index}" v-if="dialogType!=='view'">
           <el-form-item>
             <el-input v-model="row.milepost" clearable></el-input>
@@ -127,6 +143,10 @@
             <el-input type="textarea" v-model="row.deliverContent" clearable></el-input>
           </el-form-item>
         </template>
+        <template v-slot:proportion="{ row }">
+          <el-input type="number" :min="0" :max="100" v-model="row.proportion" :disabled="dialogType=='view'">
+          </el-input>
+        </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>
@@ -152,9 +172,9 @@ import fileUpload from "@/components/upload/fileUpload.vue";
 import {getFile} from "@/api/system/file";
 import PersonSelect from "@/components/CommomSelect/person-select.vue";
 import {proStatusEnum} from "@/enum/dict";
-
+import {deepClone} from "@/utils";
 export default {
-  name: "relatedInfoTable",
+  name: "planInfoTable",
   components: {
     PersonSelect,
     fileUpload,
@@ -179,6 +199,12 @@ export default {
         return []
       }
     },
+    userList: {
+      type: Array,
+      default() {
+        return []
+      }
+    },
     deptTreeList: {
       type: Array,
       default() {
@@ -189,13 +215,12 @@ export default {
   watch: {
     dialogForm: {
       handler(val) {
-        console.log(this.dialogForm.planStageList, '======');
-        this.form.datasource = this.dialogForm.planStageList || []
-        this.$nextTick(async () => {
-          this.form.datasource.forEach((item, index) => {
-            this.getUserList(item.responsibleDeptId, index);
-          })
-        })
+        this.form.datasource =  deepClone(this.dialogForm.planStageList || [])
+        // this.$nextTick(async () => {
+        //   this.form.datasource.forEach((item, index) => {
+        //     this.getUserList(item.responsibleDeptId, index);
+        //   })
+        // })
       },
       deep: true,
     },
@@ -230,13 +255,31 @@ export default {
           slot: 'name',
           headerSlot: 'headerRequired',
         },
+        // {
+        //   prop: 'stage',
+        //   label: '计划节点',
+        //   align: 'center',
+        //   showOverflowTooltip: true,
+        //   minWidth: 120,
+        //   slot: 'stage',
+        //   headerSlot: 'headerRequired',
+        // },
+        // {
+        //   prop: 'responsibleDeptId',
+        //   label: '负责部门',
+        //   align: 'center',
+        //   showOverflowTooltip: true,
+        //   minWidth: 130,
+        //   slot: 'responsibleDeptId',
+        //   headerSlot: 'headerRequired',
+        // },
         {
-          prop: 'stage',
-          label: '计划节点',
+          prop: 'responsibleUserNames',
+          label: '负责人',
           align: 'center',
           showOverflowTooltip: true,
-          minWidth: 120,
-          slot: 'stage',
+          minWidth: 200,
+          slot: 'responsibleUserIds',
           headerSlot: 'headerRequired',
         },
         {
@@ -257,33 +300,13 @@ export default {
           slot: 'planEndDate',
           headerSlot: 'headerRequired',
         },
-        {
-          prop: 'responsibleDeptId',
-          label: '负责部门',
-          align: 'center',
-          showOverflowTooltip: true,
-          minWidth: 130,
-          slot: 'responsibleDeptId',
-          headerSlot: 'headerRequired',
-        },
-        {
-          prop: 'responsibleUserId',
-          label: '负责人',
-          align: 'center',
-          showOverflowTooltip: true,
-          minWidth: 130,
-          slot: 'responsibleUserId',
-          headerSlot: 'headerRequired',
-        },
+
         {
           prop: 'isMilepost',
           label: '是否里程碑',
           align: 'center',
           showOverflowTooltip: true,
           minWidth: 120,
-          formatter: (_row, _column, cellValue) => {
-            return cellValue? '是' : '否';
-          },
           slot: 'isMilepost',
         },
         {
@@ -302,6 +325,22 @@ export default {
           minWidth: 160,
           slot: 'remark',
         },
+        // {
+        //   prop: 'proportion',
+        //   label: '权重占比(%)',
+        //   align: 'center',
+        //   showOverflowTooltip: true,
+        //   minWidth: 110,
+        //   slot: 'proportion'
+        // },
+        {
+          prop: 'speedPercent',
+          label: '进度',
+          align: 'center',
+          showOverflowTooltip: true,
+          minWidth: 150,
+          slot: 'speedPercent'
+        },
         {
           prop: 'status',
           label: '状态',
@@ -339,8 +378,8 @@ export default {
           deliverContent: '',
           milepost: '',
           isMilepost: 0,
-          responsibleUserId: '',
-          responsibleUserName: '',
+          responsibleUserIds: [],
+          responsibleUserNames: [],
           planStartDate: '',
           planEndDate: '',
           name: '',
@@ -354,10 +393,19 @@ export default {
     changeDeptInfo(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], 'responsibleUserId', '');
+      this.$set(this.form.datasource[index], 'responsibleUserIds', '');
       this.$set(this.form.datasource[index], 'responsibleUserName', '');
       this.getUserList(id, index);
     },
+    customColorMethod(percentage) {
+      if (percentage < 30) {
+        return '#909399';
+      } else if (percentage < 70) {
+        return '#e6a23c';
+      } else {
+        return '#67c23a';
+      }
+    },
     // 获取人员数据
     getUserList(groupId, index) {
       if (groupId) {
@@ -365,7 +413,7 @@ export default {
       }
     },
     personChange(val, info, index) {
-      this.$set(this.form.datasource[index], 'responsibleUserName', info.name);
+      // this.$set(this.form.datasource[index], 'responsibleUserName', info.name);
     },
     //
     clearData() {
@@ -373,7 +421,7 @@ export default {
         this.$set(this.form.datasource[index], 'deliverContent', '')
         this.$set(this.form.datasource[index], 'milepost', '')
         this.$set(this.form.datasource[index], 'isMilepost', 0)
-        this.$set(this.form.datasource[index], 'responsibleUserId', '')
+        this.$set(this.form.datasource[index], 'responsibleUserIds', '')
         this.$set(this.form.datasource[index], 'responsibleUserName', '')
         this.$set(this.form.datasource[index], 'planStartDate', '')
         this.$set(this.form.datasource[index], 'planEndDate', '')

+ 18 - 3
src/views/bpm/handleTask/components/project-manage/project-initiation/detailDialog.vue

@@ -2,7 +2,7 @@
   <div>
     <headerTitle title="项目信息"></headerTitle>
     <project-form ref="projectForm" dialog-type="view" :dialogForm="dialogForm" :deptList="deptList"
-                  :deptTreeList="deptTreeList"></project-form>
+                  :deptTreeList="deptTreeList" :teamList="teamList"></project-form>
     <headerTitle title="项目阶段"></headerTitle>
     <project-info-table ref="planInfoTable" dialog-type="view" :dialogForm="dialogForm" :deptList="deptList"
                         :deptTreeList="deptTreeList"></project-info-table>
@@ -16,6 +16,7 @@ import {projectsGetByIdAPI} from "@/api/bpm/components/project-manage";
 import projectInfoTable from "./projectInfoTable.vue";
 import projectForm from "./project-form.vue";
 import {listOrganizations} from "@/api/system/organization";
+import {projectsTeamPageAPI} from "@/api/bpm/components/project-manage/team";
 
 export default {
   name: "project-initiation-detailDialog",
@@ -40,12 +41,13 @@ export default {
       dialogForm: {},
       deptList: [],
       deptTreeList: [],
+      teamList: [],
     }
   },
   async created() {
     await this.getDeptList()
     await this.getInfo()
-    console.log(this.businessId,'====');
+    await this.getTeamList();
   },
 
   methods: {
@@ -65,7 +67,20 @@ export default {
       this.dialogForm.type = this.dialogForm.type + ''
       this.dialogForm.level = this.dialogForm.level + ''
       this.dialogForm.parentId = this.dialogForm.parentId == 0 ? '' : this.dialogForm.parentId
-
+      this.dialogForm.stageList.forEach((item, index) => {
+        let userNames = item.responsibleUserList.map(i => i.userName) || []
+        this.$set(item, 'responsibleUserNames', userNames.join(','))
+      })
+    },
+    getTeamList() {
+      projectsTeamPageAPI(
+        {
+          pageNum: 1,
+          size: 999
+        }
+      ).then((list) => {
+        this.teamList = list;
+      });
     },
     getTableValue() {
       return new Promise((resolve, reject) => {

+ 171 - 26
src/views/bpm/handleTask/components/project-manage/project-initiation/project-form.vue

@@ -7,14 +7,15 @@
           <el-form-item
             prop="code"
             label="项目编码">
-            <el-input disabled v-model="form.code"></el-input>
+            <el-input :disabled="dialogType=='view'" v-model="form.code"></el-input>
           </el-form-item>
         </el-col>
         <el-col :span="8">
           <el-form-item
             prop="type"
             label="项目类型">
-            <dict-selection dict-name="项目类型" v-model="form.type" :disabled="dialogType=='view'"></dict-selection>
+            <dict-selection dict-name="项目类型" v-model="form.type" :disabled="dialogType=='view'"
+                            @change="changeType"></dict-selection>
           </el-form-item>
         </el-col>
         <el-col :span="8">
@@ -44,7 +45,7 @@
         </el-col>
         <el-col :span="8">
           <el-form-item
-            label="申请部门"
+            label="负责部门"
             prop="applyDeptId">
             <ele-tree-select
               :disabled="dialogType=='view'"
@@ -62,7 +63,7 @@
         <el-col :span="8">
           <el-form-item
             prop="responsibleUserId"
-            label="负责人">
+            label="项目经理">
             <personSelect
               :disabled="dialogType=='view'"
               ref="directorRef"
@@ -74,20 +75,34 @@
 
       </el-row>
       <el-row>
+
         <el-col :span="8">
           <el-form-item
-            prop="cycle"
-            label="项目周期">
-            <el-input v-model="form.cycle" :disabled="dialogType=='view'"></el-input>
+            prop="teamId"
+            label="项目团队">
+            <el-select v-model="form.teamId" placeholder="请选择" style="width: 100%;" :disabled="dialogType=='view'" clearable @change="teamChange">
+              <el-option
+                v-for="item in teamList"
+                :key="item.id"
+                :label="item.name"
+                :value="item.id">
+              </el-option>
+            </el-select>
           </el-form-item>
         </el-col>
         <el-col :span="8">
+
           <el-form-item label="项目预算">
-            <el-input type="number" :min="0" v-model="form.budget" :disabled="dialogType=='view'">
-              <template slot="append">
-                元
-              </template>
-            </el-input>
+            <el-row>
+              <el-col :span="18">
+                <el-input type="number" :min="0" v-model="form.budget" :disabled="dialogType=='view'">
+                </el-input>
+              </el-col>
+              <el-col :span="6">
+                <dict-selection dict-name="预算单位" v-model="form.unit"
+                                :disabled="dialogType=='view'"></dict-selection>
+              </el-col>
+            </el-row>
           </el-form-item>
         </el-col>
         <el-col :span="8">
@@ -98,8 +113,15 @@
         </el-col>
       </el-row>
       <el-row>
-
         <el-col :span="8">
+          <el-form-item
+            prop="cycle"
+            label="项目周期">
+            <el-input v-model="form.cycle" :disabled="dialogType=='view'"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="8">
+
           <el-form-item
             prop="planStartDate"
             label="计划开始日期">
@@ -127,11 +149,36 @@
             </el-date-picker>
           </el-form-item>
         </el-col>
+
+
+        <!--        <el-col :span="8">-->
+        <!--          <el-form-item label="权重占比">-->
+        <!--            <el-input type="number" :min="0" :max="100" v-model="form.proportion" :disabled="dialogType=='view'">-->
+        <!--              <template slot="append">-->
+        <!--                %-->
+        <!--              </template>-->
+        <!--            </el-input>-->
+        <!--          </el-form-item>-->
+        <!--        </el-col>-->
+
       </el-row>
       <el-row>
+        <el-col :span="8">
+          <el-form-item
+            label="关联合同"
+            prop="contractName">
+            <el-input
+              :disabled="dialogType=='view'"
+              clearable
+              v-model="form.contractName"
+              @click.native="handleContractBtn"
+            />
+          </el-form-item>
+
+        </el-col>
         <el-col :span="8">
           <el-form-item label="客户名称">
-            <el-input v-model="form.contactName" :disabled="dialogType=='view'"></el-input>
+            <el-input v-model="form.contactName" @click.native="handleGetCus" :disabled="dialogType=='view'"></el-input>
           </el-form-item>
         </el-col>
         <el-col :span="8">
@@ -141,6 +188,7 @@
             <el-input v-model="form.contactRelationPhone" :disabled="dialogType=='view'"></el-input>
           </el-form-item>
         </el-col>
+
         <!--        <el-col :span="8">-->
         <!--          <el-form-item-->
         <!--            prop="stage"-->
@@ -154,31 +202,52 @@
 
       </el-row>
       <el-row>
-        <el-col :span="24">
-          <el-form-item label="项目说明">
+        <el-col :span="16">
+          <el-form-item label="项目简介">
             <el-input type="textarea" :rows="2" v-model="form.content" :disabled="dialogType=='view'"></el-input>
           </el-form-item>
         </el-col>
-      </el-row>
-      <el-row>
-        <el-col :span="24">
-          <el-form-item label="备注">
-            <el-input type="textarea" :rows="2" v-model="form.remark" :disabled="dialogType=='view'"></el-input>
+        <el-col :span="8">
+          <el-form-item
+            label="附件">
+            <fileUpload
+              v-if="dialogType!='view'"
+              style="position: absolute"
+              v-model="form.files"
+              module="main"
+              :showLib="false"
+            />
+            <el-link
+              v-else
+              v-for="item in form.files"
+              type="primary"
+              :underline="false"
+              @click="downloadFile(item)">
+              {{ item.name }}
+            </el-link>
+
           </el-form-item>
         </el-col>
       </el-row>
-
+      <!--      <el-row>-->
+      <!--        <el-col :span="24">-->
+      <!--          <el-form-item label="备注">-->
+      <!--            <el-input type="textarea" :rows="2" v-model="form.remark" :disabled="dialogType=='view'"></el-input>-->
+      <!--          </el-form-item>-->
+      <!--        </el-col>-->
+      <!--      </el-row>-->
     </el-form>
+
   </div>
 </template>
 
 <script>
 import {projectsToTreeAPI} from "@/api/bpm/components/project-manage";
 import PersonSelect from "@/components/CommomSelect/person-select.vue";
-
+import {getFile} from "@/api/system/file";
 export default {
   name: "project-form",
-  components: {PersonSelect},
+  components: { PersonSelect},
   props: {
     dialogType: {
       type: String,
@@ -192,15 +261,21 @@ export default {
         }
       }
     },
+    teamList: {
+      type: Array,
+      default: () => {
+        return []
+      }
+    },
     deptList: {
       type: Array,
-      default() {
+      default: () => {
         return []
       }
     },
     deptTreeList: {
       type: Array,
-      default() {
+      default: () => {
         return []
       }
     },
@@ -220,6 +295,7 @@ export default {
     return {
       form: {
         budget: '',
+        unit: '1',
         code: "",
         contactId: '',
         contactName: "",
@@ -235,6 +311,7 @@ export default {
         monitorUserName: "",
         planStartDate: "",
         planEndDate: "",
+        proportion: undefined,
         name: "",
         parentId: '',
         remark: "",
@@ -243,22 +320,41 @@ export default {
         responsibleDeptId: "",
         responsibleDeptName: "",
         stage: "",
+        teamId: "",
+        teamName: "",
         type: '',
+        contractId: '',
+        contractName: '',
+        files: [],
       },
       projectList: [],
+      customDialogFlag: false,
+      contractDialogFlag: false,
       rules: {
         type: {required: true, message: '请选择项目类型', trigger: 'change'},
         name: {required: true, message: '请输入项目名称', trigger: 'blur'},
+        teamId: {required: true, message: '请选择项目团队', trigger: 'blur'},
+        responsibleUserId: {required: true, message: '请选择项目经理', trigger: 'blur'},
         planStartDate: {required: true, message: '请选择计划开始日期', trigger: 'blur'},
         planEndDate: {required: true, message: '请选择计划完成日期', trigger: 'blur'},
+        code: {required: true, message: '请输入项目编码', trigger: ['blur', 'change']},
       }
     }
   },
   async created() {
     this.projectList = await projectsToTreeAPI({processStatus: '2', treeType: '0'})
+
   },
 
   methods: {
+    async changeType(val) {
+      this.form.code = await getProjectCode(val)
+    },
+    async teamChange(val) {
+      let find = this.teamList.find(e => e.id == val) || {}
+      this.form.teamName = find.name
+      this.$emit('teamChange', val)
+    },
     // 选择负责人部门
     changeDeptInfo(id) {
       const info = this.deptList.find((e) => e.id == id) || {};
@@ -273,6 +369,55 @@ export default {
         this.$refs.directorRef.getList({groupId});
       }
     },
+    handleContractBtn(e) {
+      if (e.target.nodeName == 'I') {
+        this.form = Object.assign({}, this.form, {
+          contractName: '',
+          contractId: '',
+          contactId: '',
+          contactName: '',
+          contactRelationPhone: '',
+        });
+        return
+      }
+      this.contractDialogFlag = true;
+    },
+    //选择合同信息回调
+    getContractInfo(obj) {
+
+      this.form.contractId = obj.id
+      this.form.contractName = obj.contractName
+      if (obj.type == 1) {
+        this.form.contactId = obj.partaId
+        this.form.contactName = obj.partaName
+        this.form.contactRelationPhone = obj.partaTel
+      } else {
+        this.form.contactId = obj.partbId
+        this.form.contactName = obj.partbName
+        this.form.contactRelationPhone = obj.partbTel
+      }
+
+    },
+    //获取客户信息
+    handleGetCus() {
+      this.customDialogFlag = true;
+      let item = {id: this.form.contactId};
+      this.$nextTick(() => {
+        this.$refs.customRef.open(item);
+      })
+
+    },
+    //选择客户信息回调
+    getCusInfo(obj) {
+      this.form = Object.assign({}, this.form, {
+        contactId: obj.id,
+        contactName: obj.name,
+        contactRelationPhone: obj.phone,
+      });
+    },
+    downloadFile(file) {
+      getFile({objectName: file.storePath}, file.type);
+    },
     personChange(val, info) {
       this.form.responsibleUserName = info.name;
     },

+ 73 - 46
src/views/bpm/handleTask/components/project-manage/project-initiation/projectInfoTable.vue

@@ -83,17 +83,29 @@
             </el-date-picker>
           </el-form-item>
         </template>
-        <template v-slot:responsibleUserId="{row,$index}">
-          <el-form-item :prop="'datasource.'+$index+'.responsibleUserId'">
-            <personSelect
-              :disabled="dialogType=='view'"
-              :ref="'directorRef'+$index"
-              v-model="row.responsibleUserId"
-              :init="false"
-              @selfChange="(val, info)=>personChange(val,info,$index)"/>
+        <template v-slot:responsibleUserIds="{row,$index}" v-if="dialogType!=='view'">
+          <el-form-item :prop="'datasource.'+$index+'.responsibleUserIds'">
+            <el-select v-model="row.responsibleUserIds" multiple collapse-tags
+                       filterable placeholder="请选择" style="width: 100%;"
+                       clearable
+                       size="medium"
+                       :disabled="dialogType=='view'" @change="(val)=>personChange(val,$index)">
+              <el-option
+                v-for="item in userList"
+                :key="item.id"
+                :label="item.name"
+                :value="item.id">
+              </el-option>
+            </el-select>
+            <!--            <personSelect-->
+            <!--              :disabled="dialogType=='view'"-->
+            <!--              :ref="'directorRef'+$index"-->
+            <!--              v-model="row.responsibleUserIds"-->
+            <!--              :init="false"-->
+            <!--              @selfChange="(val, info)=>personChange(val,info,$index)"/>-->
           </el-form-item>
         </template>
-        <template v-slot:responsibleDeptId="{row,$index}">
+        <template v-slot:responsibleDeptId="{row,$index}" v-if="dialogType!=='view'">
           <el-form-item :prop="'datasource.'+$index+'.responsibleDeptId'">
             <ele-tree-select
               :disabled="dialogType=='view'"
@@ -126,6 +138,10 @@
           <el-tag v-if="row.isOverTime==0" type="success">正常</el-tag>
           <el-tag v-else type="danger">超时</el-tag>
         </template>
+        <template v-slot:proportion="{ row }">
+          <el-input type="number" :min="0" :max="100" v-model="row.proportion" :disabled="dialogType=='view'">
+          </el-input>
+        </template>
         <template v-slot:speedPercent="{ row }">
           <el-progress :stroke-width="20" text-color="#606266" :text-inside="true" :percentage="row.speedPercent||0"
                        :color="customColorMethod"></el-progress>
@@ -157,7 +173,7 @@ import {proStatusEnum} from "@/enum/dict";
 
 
 export default {
-  name: "projectInfoTable",
+  name: "relatedInfoTable",
   components: {
     PersonSelect,
     fileUpload,
@@ -178,13 +194,19 @@ export default {
     },
     deptList: {
       type: Array,
-      default() {
+      default: () => {
+        return []
+      }
+    },
+    userList: {
+      type: Array,
+      default: () => {
         return []
       }
     },
     deptTreeList: {
       type: Array,
-      default() {
+      default: () => {
         return []
       }
     },
@@ -192,10 +214,12 @@ export default {
   watch: {
     dialogForm: {
       handler(val) {
-        this.form.datasource = this.dialogForm.stageList
+        this.form.datasource = this.dialogForm.stageList || [];
         this.$nextTick(async () => {
+          if (this.dialogType === 'view') return
           this.form.datasource.forEach((item, index) => {
-            this.getUserList(item.responsibleDeptId,index);
+
+            // this.getUserList(item.responsibleDeptId, index);
           })
         })
       },
@@ -232,13 +256,22 @@ export default {
           slot: 'name',
           headerSlot: 'headerRequired',
         },
+        // {
+        //   prop: 'responsibleDeptName',
+        //   label: '负责部门',
+        //   align: 'center',
+        //   showOverflowTooltip: true,
+        //   minWidth: 130,
+        //   slot: 'responsibleDeptId',
+        //   headerSlot: 'headerRequired',
+        // },
         {
-          prop: 'content',
-          label: '阶段说明',
+          prop: 'responsibleUserNames',
+          label: '负责人',
           align: 'center',
           showOverflowTooltip: true,
-          minWidth: 120,
-          slot: 'content',
+          minWidth: 200,
+          slot: 'responsibleUserIds',
           headerSlot: 'headerRequired',
         },
         {
@@ -273,24 +306,6 @@ export default {
           showOverflowTooltip: true,
           minWidth: 170,
         },
-        {
-          prop: 'responsibleDeptId',
-          label: '负责部门',
-          align: 'center',
-          showOverflowTooltip: true,
-          minWidth: 130,
-          slot: 'responsibleDeptId',
-          headerSlot: 'headerRequired',
-        },
-        {
-          prop: 'responsibleUserId',
-          label: '负责人',
-          align: 'center',
-          showOverflowTooltip: true,
-          minWidth: 130,
-          slot: 'responsibleUserId',
-          headerSlot: 'headerRequired',
-        },
         {
           prop: 'remark',
           label: '备注',
@@ -307,6 +322,14 @@ export default {
           minWidth: 100,
           slot: 'isOverTime'
         },
+        // {
+        //   prop: 'proportion',
+        //   label: '权重占比(%)',
+        //   align: 'center',
+        //   showOverflowTooltip: true,
+        //   minWidth: 110,
+        //   slot: 'proportion'
+        // },
         {
           prop: 'speedPercent',
           label: '进度',
@@ -348,18 +371,22 @@ export default {
       const info = this.deptList.find((e) => e.id == id) || {};
 
       this.$set(this.form.datasource[index], 'responsibleDeptName', info.name);
-      this.$set(this.form.datasource[index], 'responsibleUserId', '');
+      this.$set(this.form.datasource[index], 'responsibleUserIds', []);
       this.$set(this.form.datasource[index], 'responsibleUserName', '');
-      this.getUserList(id, index);
+      // this.getUserList(id, index);
     },
     // 获取人员数据
     getUserList(groupId, index) {
-      if (groupId) {
-        this.$refs['directorRef' + index].getList({groupId});
-      }
+      // if (groupId) {
+      //   this.$refs['directorRef' + index].getList({groupId});
+      // }
     },
-    personChange(val, info, index) {
-      this.$set(this.form.datasource[index], 'responsibleUserName', info.name);
+    // 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);
     },
     downloadFile(file) {
       getFile({objectName: file.storePath}, file.name);
@@ -370,8 +397,8 @@ export default {
         {
           milepost: '',
           isMilepost: 0,
-          responsibleUserId: '',
-          responsibleUserName: '',
+          responsibleUserList: [],
+          responsibleUserIds: [],
           responsibleDeptId: '',
           responsibleDeptName: '',
           planStartDate: '',
@@ -392,7 +419,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], 'responsibleUserId', '')
+        this.$set(this.form.datasource[index], 'responsibleUserIds', '')
         this.$set(this.form.datasource[index], 'responsibleUserName', '')
         this.$set(this.form.datasource[index], 'responsibleDeptId', '')
         this.$set(this.form.datasource[index], 'responsibleDeptName', '')

+ 91 - 0
src/views/bpm/handleTask/components/project-manage/team-manage/detailDialog.vue

@@ -0,0 +1,91 @@
+<template>
+  <div >
+    <headerTitle title="基础信息"></headerTitle>
+    <team-form ref="teamForm" :dialogForm="dialogForm" dialog-type="view" ></team-form>
+    <headerTitle title="团队人员"></headerTitle>
+    <team-info-table ref="deliverablesInfoTable"  dialog-type="view" :dialogForm="dialogForm"></team-info-table>
+  </div>
+</template>
+
+<script>
+import dictMixins from '@/mixins/dictMixins';
+import teamForm from "./team-form.vue";
+import teamInfoTable from "./team-Info-table.vue";
+import {projectsTeamGetByIdAPI} from "@/api/bpm/components/project-manage/team";
+
+export default {
+  mixins: [dictMixins],
+  components: {
+    teamInfoTable,
+    teamForm
+  },
+  props: {
+    dialogType: {
+      type: String,
+      default: 'view',
+    },
+    businessId: {
+      default: ''
+    },
+    taskId: {
+      default: ''
+    },
+    taskDefinitionKey: {
+      default: ''
+    }
+  },
+  async created() {
+    await this.init(this.businessId)
+  },
+  data() {
+    return {
+      dialogForm: {},
+      deptList: [],
+      deptTreeList: [],
+      dictList: {},
+    };
+  },
+  methods: {
+    async init(id) {
+      this.dialogForm = await projectsTeamGetByIdAPI(id)
+      this.dialogForm.type = this.dialogForm.type + ''
+    },
+    cancel() {
+      this.$emit('update:detailDialogFlag', false);
+    },
+  }
+};
+</script>
+
+<style scoped lang="scss">
+.ele-dialog-form {
+  .el-form-item {
+    margin-bottom: 10px;
+  }
+}
+
+.headbox {
+  display: flex;
+  justify-content: flex-start;
+  align-items: center;
+
+  .amount {
+    font-size: 14px;
+    font-weight: bold;
+    margin-right: 20px;
+  }
+}
+
+.switch_left ul .active {
+  border-top: 4px solid var(--color-primary);
+  color: var(--color-primary-5);
+}
+
+.switch {
+  padding-bottom: 20px;
+}
+
+:deep .divider .content {
+  justify-content: flex-start;
+}
+</style>

+ 150 - 0
src/views/bpm/handleTask/components/project-manage/team-manage/submit.vue

@@ -0,0 +1,150 @@
+<template>
+  <el-col :span="16" :offset="6">
+    <el-form label-width="100px" ref="formRef" :model="form">
+      <el-form-item
+        label="审批建议"
+        prop="reason"
+        style="margin-bottom: 20px"
+        :rules="{
+          required: true,
+          message: '请输入',
+          trigger: 'change'
+        }"
+      >
+        <el-input
+          type="textarea"
+          v-model="form.reason"
+          placeholder="请输入审批建议"
+        />
+      </el-form-item>
+    </el-form>
+    <div style="margin-left: 10%; margin-bottom: 20px; font-size: 14px">
+      <el-button
+        icon="el-icon-edit-outline"
+        type="success"
+        size="mini"
+        @click="handleAudit(1)"
+      >通过
+      </el-button>
+
+      <el-button
+        icon="el-icon-circle-close"
+        type="danger"
+        size="mini"
+        @click="handleAudit(0)"
+        v-if="!['starter'].includes(taskDefinitionKey)"
+      >驳回
+      </el-button>
+
+      <el-dropdown @command="(command) => handleCommand(command)" style="margin-left: 30px;">
+        <span class="el-dropdown-link">
+          更多<i class="el-icon-arrow-down el-icon--right"></i>
+        </span>
+        <el-dropdown-menu slot="dropdown">
+          <el-dropdown-item command="cancel">作废</el-dropdown-item>
+        </el-dropdown-menu>
+      </el-dropdown>
+    </div>
+  </el-col>
+</template>
+
+<script>
+import {approveTaskWithVariables} from '@/api/bpm/task';
+import {cancel} from "@/api/bpm/components/project-manage/task";
+
+// 流程实例的详情页,可用于审批
+export default {
+  name: '',
+  components: {
+    //   Parser
+  },
+  props: {
+    businessId: {
+      default: ''
+    },
+    taskId: {
+      default: ''
+    },
+    id: {
+      default: ''
+    },
+    taskDefinitionKey: {
+      default: ''
+    }
+  },
+  data() {
+    return {
+      form: {
+        reason: ''
+      }
+    };
+  },
+  created() {
+  },
+  methods: {
+    /** 处理转办审批人 */
+    handleUpdateAssignee() {
+      this.$emit('handleUpdateAssignee');
+    },
+    /** 退回 */
+    handleBackList() {
+      this.$emit('handleBackList');
+    },
+
+    async handleAudit(status) {
+      await this._approveTaskWithVariables(status);
+    },
+    async _approveTaskWithVariables(status) {
+      let variables = {
+        pass: !!status
+      };
+
+      approveTaskWithVariables({
+        id: this.taskId,
+        reason: this.form.reason,
+        variables
+      }).then((res) => {
+        if (res.data.code != '-1') {
+          this.$emit('handleAudit', {
+            status,
+            title: status === 0 ? '驳回' : ''
+          });
+        }
+      });
+    },
+
+    getTableValue() {
+      return new Promise((resolve, reject) => {
+        this.$emit('getTableValue', async (data) => {
+          resolve(await data);
+        });
+      });
+    },
+
+    //更多
+    handleCommand(command) {
+      if (command === 'cancel') {
+        this.$confirm("是否确认作废?", {
+          type: 'warning',
+          cancelButtonText: '取消',
+          confirmButtonText: '确定'
+        }).then(() => {
+          cancel({
+            id: this.taskId,
+            reason: this.form.reason,
+            businessId: this.businessId,
+          }).then(() => {
+            this.$emit('handleClose');
+          }).catch(() => {
+            this.$message.error("流程作废失败");
+          });
+        }).catch(() => {
+        });
+      }
+    },
+
+  }
+};
+</script>
+
+<style lang="scss"></style>

+ 222 - 0
src/views/bpm/handleTask/components/project-manage/team-manage/team-Info-table.vue

@@ -0,0 +1,222 @@
+<template>
+  <div>
+    <el-form ref="form" :model="form">
+
+      <!-- 数据表格 -->
+      <ele-pro-table
+        ref="table"
+        :columns="columns"
+        :datasource="form.datasource"
+        :needPage="false"
+        :toolkit="[]"
+        :minHeight="100"
+        :maxHeight="300"
+        tool-class="ele-toolbar-form"
+        cache-key="eomContactPageTable"
+      >
+        <!-- 表头工具栏 -->
+        <template v-slot:toolbar>
+          <el-button
+            v-if="dialogType!=='view'"
+            size="small"
+            type="primary"
+            icon="el-icon-plus"
+            class="ele-btn-icon"
+            @click="handleAddInfo">
+            选择人员
+          </el-button>
+        </template>
+
+        <template v-slot:action="{row,$index}">
+          <el-popconfirm
+            class="ele-action"
+            title="确定要删除此信息吗?"
+            :disabled="form.datasource.length==1"
+            @confirm="handleDelInfo($index)"
+          >
+            <template v-slot:reference>
+              <el-link
+                :disabled="form.datasource.length==1"
+                type="danger"
+                :underline="false"
+                icon="el-icon-delete"
+              >
+                删除
+              </el-link>
+            </template>
+          </el-popconfirm>
+        </template>
+      </ele-pro-table>
+    </el-form>
+
+<!--    <select-person-dialog :select-person-dialog-flag.sync="selectPersonDialogFlag" :multiple="true" ref="selectPersonDialogRef"-->
+<!--                          v-if="selectPersonDialogFlag" @changeParent="changeParent"></select-person-dialog>-->
+  </div>
+</template>
+
+
+<script>
+
+
+import fileUpload from "@/components/upload/fileUpload.vue";
+// import selectPersonDialog from "@/views/project-manage/components/selectPersonDialog.vue";
+
+export default {
+  type: "team-Info-table",
+  components: {
+    fileUpload,
+    // selectPersonDialog
+
+  },
+  props: {
+    dialogForm: {
+      type: Object,
+      default: () => {
+        return {
+          ...this.form
+        }
+      }
+    },
+    dialogType: {
+      type: String,
+      default: ''
+    },
+  },
+  watch: {
+    dialogForm: {
+      handler(val) {
+        this.form.datasource = this.dialogForm.teamUserList || []
+
+      },
+      deep: true,
+    },
+  },
+  data() {
+    return {
+      editIndex: undefined,//当前修改数据的下标
+      selectPersonDialogFlag:false,
+      statusOptions: [
+        {value: 1, label: '全职'},
+        {value: 2, label: '兼职'},
+        {value: 3, label: '实习'},
+        {value: 4, label: '正式'},
+        {value: 5, label: '试用'},
+        {value: 6, label: '离职'}
+      ],
+      form: {
+        datasource: []
+      },
+
+    }
+  },
+  computed: {
+    columns() {
+      let list = [
+        {
+          columnKey: 'index',
+          label: '序号',
+          type: 'index',
+          width: 55,
+          align: 'center',
+          showOverflowTooltip: true,
+          fixed: 'left'
+        },
+        {
+          prop: 'name',
+          label: '姓名',
+          showOverflowTooltip: true,
+          align: 'center',
+          minWidth: 110
+        },
+        {
+          prop: 'deptName',
+          label: '部门',
+          showOverflowTooltip: true,
+          align: 'center',
+          minWidth: 110
+        },
+        {
+          prop: 'jobNumber',
+          label: '工号',
+          showOverflowTooltip: true,
+          align: 'center',
+          minWidth: 110
+        },
+        {
+          prop: 'sex',
+          label: '性别',
+          showOverflowTooltip: true,
+          minWidth: 80,
+          align: 'center',
+          formatter: (_row, _column, cellValue) => {
+            return cellValue == 1 ? '男' : cellValue == 2 ? '女' : '';
+          }
+        },
+        {
+          prop: 'status',
+          label: '状态',
+          align: 'center',
+          width: 100,
+          formatter: (_row, _column, cellValue) => {
+            const dom = this.statusOptions.find((item) => {
+              return item.value == cellValue;
+            });
+            return dom ? dom.label : '';
+          }
+        }
+
+      ]
+      let action = [{
+        columnKey: 'action',
+        slot: 'action',
+        label: '操作',
+        resizable: false,
+        width: 90,
+        align: 'center',
+        showOverflowTooltip: true,
+        fixed: 'right'
+      },]
+      this.dialogType === 'view' ? list = [...list] : list = [...list, ...action]
+      return list
+    },
+  },
+  methods: {
+
+    //新增人员
+    handleAddInfo() {
+      this.selectPersonDialogFlag = true
+    },
+
+    changeParent(list){
+      list.forEach(item => {
+        this.$delete(item, 'createTime')
+      });
+      this.form.datasource = list
+    },
+    //删除关联信息数据
+    handleDelInfo(index) {
+      this.form.datasource.splice(index, 1)
+    },
+    getTableValidate() {
+      return new Promise((resolve, reject) => {
+         if (this.form.datasource.length == 0) return this.$message.warning('请添加至少一位人员')
+        this.$refs.form.validate((valid) => {
+          if (!valid) {
+            this.$message.warning('有必填项未填,请检查')
+            reject('有必填项未填,请检查')
+          } else {
+            resolve(this.form.datasource)
+          }
+        })
+      })
+    },
+  }
+}
+</script>
+
+
+<style scoped lang="scss">
+:deep(.el-form-item) {
+  margin-bottom: 0;
+}
+</style>

+ 122 - 0
src/views/bpm/handleTask/components/project-manage/team-manage/team-form.vue

@@ -0,0 +1,122 @@
+<template>
+  <div>
+    <el-form ref="form" :model="form" :rules="rules" class="el-form-box" label-width="80px">
+      <el-row>
+        <el-col :span="12">
+          <el-form-item
+            prop="code"
+            label="编码">
+            <el-input v-model="form.code" :disabled="dialogType=='view'"></el-input>
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
+          <el-form-item
+            prop="name"
+            label="名称">
+            <el-input v-model="form.name" :disabled="dialogType=='view'"></el-input>
+          </el-form-item>
+        </el-col>
+      </el-row>
+      <el-row>
+        <el-col :span="24">
+          <el-form-item label="备注">
+            <el-input type="textarea" :rows="2" v-model="form.remark" :disabled="dialogType=='view'"></el-input>
+          </el-form-item>
+        </el-col>
+      </el-row>
+
+    </el-form>
+  </div>
+</template>
+
+<script>
+
+import PersonSelect from "@/components/CommomSelect/person-select.vue";
+
+
+export default {
+  name: "task-form",
+  components: {PersonSelect},
+  props: {
+    dialogType: {
+      type: String,
+      default: '',
+    },
+    dialogForm: {
+      type: Object,
+      default: () => {
+        return {}
+      }
+    },
+
+
+  },
+  watch: {
+    dialogForm: {
+      handler(val) {
+        this.form = {
+          ...this.form,
+          ...this.dialogForm
+        }
+      },
+      deep: true
+    },
+  },
+  data() {
+    return {
+      form: {
+        code: '',
+        name: '',
+        remark: '',
+        teamUserList: [],
+
+      },
+      rules: {
+        code: {required: true, message: '请选择任务类型', trigger: 'change'},
+        name: {required: true, message: '请输入任务名称', trigger: 'blur'},
+
+      }
+    }
+  },
+  async created() {
+
+  },
+
+  methods: {
+    // 选择负责人部门
+    changeDeptInfo(id) {
+      const info = this.deptList.find((e) => e.id == id) || {};
+      this.form.responsibleDeptName = info.name;
+      this.form.responsibleUserId = '';
+      this.form.responsibleUserName = '';
+      this.getUserList(id);
+    },
+    // 获取人员数据
+    getUserList(groupId) {
+      if (groupId) {
+        this.$refs.directorRef.getList({groupId});
+      }
+    },
+    personChange(val, info) {
+      this.form.responsibleUserName = info.name;
+    },
+    validForm() {
+      return new Promise((resolve, reject) => {
+        this.$refs.form.validate(valid => {
+          if (!valid) {
+            this.$message.warning('有必填项未填,请检查')
+            reject('有必填项未填,请检查')
+          } else {
+            resolve(this.form)
+          }
+        })
+      })
+    }
+  }
+}
+</script>
+
+
+<style scoped lang="scss">
+
+</style>