Просмотр исходного кода

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	vue.config.js
liuyc 3 лет назад
Родитель
Сommit
ff5e161971

+ 15 - 6
src/api/manager/contractinfo.js

@@ -43,18 +43,20 @@ export const saveUserInfoByProject = (list) => {
     })
 }
 
-export const findAllUserByCondition = (info) => {
+export const findAllUserByCondition = (info, size, current) => {
     return request({
-        url: '/api/blade-manager/contractInfo/findAllUserByCondition',
-        method: 'post',
-        data: info
+        url: `/api/blade-manager/contractInfo/findAllUserByCondition?size=${size}&current=${current}`,
+        method: 'get',
+        params: {
+            ...info,
+        }
     })
 }
 export const findUserListByCondition = (info) => {
     return request({
         url: '/api/blade-manager/contractInfo/findUserListByCondition',
-        method: 'post',
-        data: info
+        method: 'get',
+        params: info
     })
 }
 
@@ -145,4 +147,11 @@ export const saveUserInfoByProjectTow = (list) => {
         method: 'post',
         data: list
     })
+}
+export const searchRole = (list) => {
+    return request({
+        url: '/api/blade-system/search/role',
+        method: 'get',
+        data: list
+    })
 }

+ 61 - 61
src/api/manager/projectinfo.js

@@ -1,83 +1,83 @@
 import request from '@/router/axios';
 
 export const submitProject = (projectInfo) => {
-  return request({
-    url: '/api/blade-manager/projectInfo/submit',
-    method: 'post',
-    data: projectInfo
-  })
+    return request({
+        url: '/api/blade-manager/projectInfo/submit',
+        method: 'post',
+        data: projectInfo
+    })
 }
 
+//项目类型
 export const getProjectList = (current, size, params) => {
-  return request({
-    url: '/api/blade-manager/projectInfo/list',
-    method: 'get',
-    params: {
-      ...params,
-      current,
-      size,
-    }
-  })
+    return request({
+        url: '/api/blade-manager/projectInfo/list',
+        method: 'get',
+        params: {
+            ...params,
+            current,
+            size,
+        }
+    })
 }
 
 export const getProjectDeatil = (id) => {
-  return request({
-    url: '/api/blade-manager/projectInfo/detail',
-    method: 'get',
-    params: {
-      id
-    }
-  })
+    return request({
+        url: '/api/blade-manager/projectInfo/detail',
+        method: 'get',
+        params: {
+            id
+        }
+    })
 }
 
-export const getProjectDeatilWbsId = (id,ReferenceWbsTemplateId,ReferenceWbsTemplateType) => {
-  return request({
-    url: '/api/blade-manager/projectInfo/detail2',
-    method: 'get',
-    params: {
-      id,
-      ReferenceWbsTemplateId,
-      ReferenceWbsTemplateType
-    }
-  })
+export const getProjectDeatilWbsId = (id, ReferenceWbsTemplateId, ReferenceWbsTemplateType) => {
+    return request({
+        url: '/api/blade-manager/projectInfo/detail2',
+        method: 'get',
+        params: {
+            id,
+            ReferenceWbsTemplateId,
+            ReferenceWbsTemplateType
+        }
+    })
 }
 
 export const findWbsTreeList = (type) => {
-  return request({
-    url: '/api/blade-manager/projectInfo/findWbsTreeList',
-    method: 'get',
-    params: {
-      type
-    }
-  })
+    return request({
+        url: '/api/blade-manager/projectInfo/findWbsTreeList',
+        method: 'get',
+        params: {
+            type
+        }
+    })
 }
 
-export const findProjectTree = (projectId,wbsId) => {
-  return request({
-    url: '/api/blade-manager/projectInfo/tree',
-    method: 'get',
-    params: {
-      projectId,
-      wbsId
-    }
-  })
+export const findProjectTree = (projectId, wbsId) => {
+    return request({
+        url: '/api/blade-manager/projectInfo/tree',
+        method: 'get',
+        params: {
+            projectId,
+            wbsId
+        }
+    })
 }
 
 export const submitWbsTreeInProject = (obj) => {
-  return request({
-    url: '/api/blade-manager/projectInfo/submitWbsTreeInProject',
-    method: 'post',
-    data: obj
-  })
+    return request({
+        url: '/api/blade-manager/projectInfo/submitWbsTreeInProject',
+        method: 'post',
+        data: obj
+    })
 }
 
 export const removeProject = (ids) => {
-  return request({
-    url: '/api/blade-manager/projectInfo/remove',
-    method: 'post',
-    params: {
-      ids
-    }
-  })
-}
-
+    return request({
+        url: '/api/blade-manager/projectInfo/remove',
+        method: 'post',
+        params: {
+            ids
+        }
+    })
+}

+ 39 - 0
src/api/system/role.js

@@ -78,6 +78,17 @@ export const getRoleTree = () => {
     })
 }
 
+//所属角色
+export const roletree = () => {
+    return request({
+        url: '/api/blade-system/role/tree',
+        method: 'get',
+        params: {
+            tenantId: ''
+        }
+    })
+}
+
 export const getRoleTreeById = (roleId) => {
     return request({
         url: '/api/blade-system/role/tree-by-id',
@@ -86,4 +97,32 @@ export const getRoleTreeById = (roleId) => {
             roleId,
         }
     })
+}
+
+export const treeUser = (roleId) => {
+    return request({
+        url: '/api/blade-system/role/treeTow',
+        method: 'get',
+        params: {
+            roleId,
+        }
+    })
+}
+
+//编辑加载项目合同段信息
+export const findProjectAndContractList = (params) => {
+    return request({
+        url: '/api/blade-manager/projectInfo/findProjectAndContractList',
+        method: 'get',
+        params
+    })
+}
+
+//编辑新增项目合同段信息
+export const saveUserInfoByProjectTow = (params) => {
+    return request({
+        url: '/api/blade-manager/contractInfo/saveUserInfoByProjectTow',
+        method: 'post',
+        data: params
+    })
 }

+ 1 - 1
src/styles/xiaoyu.scss

@@ -3,7 +3,7 @@
     justify-content: flex-start;
 }
 
-.· {
+.flexEnd {
     display: flex;
     justify-content: flex-end;
 }

+ 77 - 0
src/views/formula/component/formulaTemplate.vue

@@ -0,0 +1,77 @@
+<template>
+  <div>
+    <div>{{template}}</div>
+    <div>{{formulainfo.example}}</div>
+    <div v-for="(item,index) in formulainfo.arguments" :key="index" class="mg-t-20">
+      <div>
+        <span>参数{{(index+1)}}({{formulainfo.template.args[index].m}}):</span>
+        <span>
+          <template v-if="(typeof item)=='object' && item.type == 'Element'">
+            <el-tag>{{item.name}}</el-tag>
+          </template>
+          <template v-else>
+            <el-input v-model="formulainfo.arguments[index]" placeholder="请输入内容" style="width:200px"></el-input>
+          </template>
+        </span>
+        <el-link type="primary" @click="changeType('text',index)" class="mg-l-10">输入文本</el-link>
+        <el-link type="primary" @click="changeType('ele',index)" class="mg-l-10">选择元素</el-link>
+        <el-link type="primary" @click="setCurEle(index)" class="mg-l-10">当前元素</el-link>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: "formulaTemplate",
+  props: {
+    formulainfo: {
+      type: Object,
+      default: function () {
+        return {};
+      }
+    },
+    curele: {
+      type: Object,
+      default: function () {
+        return {};
+      }
+    },
+  },
+  data(){
+    return{
+      template:'',
+
+    }
+  },
+  mounted(){
+    this.template = this.formulainfo.template.ft;
+    //console.log(this.formulainfo.template)
+    this.formulainfo.template.args.forEach(element => {
+      //console.log(element)
+      this.template = this.template.replace(element.key,element.m)
+    });
+  },
+  methods:{
+    //切换选择的状态
+    changeType(type,index){
+      if(type == 'text'){
+        this.$set(this.formulainfo.arguments,index,'');
+      }else if(type == 'ele'){
+        this.$emit('sele-ele-handle',{
+          arguments:this.formulainfo.arguments,
+          index
+        })
+      }
+    },
+
+    //选择当前元素
+    setCurEle(index){
+      this.$set(this.formulainfo.arguments,index,this.curele);
+    }
+  }
+}
+</script>
+<style scoped lang="scss">
+  
+</style>

+ 292 - 11
src/views/formula/edit.vue

@@ -31,13 +31,25 @@
     <div class="box-dashed">
       <div class="mg-b-20">函数公式</div>
       <div class="edit-text">
-        <span>默认A</span>
+        <span>
+          <formula-item 
+            v-for="(item,index) in resultFormula" :key="index" 
+            :item="item" @click="obj => equationClick(obj,index,'resultFormula')"
+          >
+          </formula-item>
+        </span>
         <span>=</span>
-        <span>元素B</span>
+        <span>
+          <formula-item 
+            v-for="(item,index) in processFormula" :key="index" 
+            :item="item" @click="obj => equationClick(obj,index,'processFormula')"
+          >
+          </formula-item>
+        </span>
       </div>
       <div class="flex jc-sb">
         <div></div>
-        <div><el-button type="info" size="small" @click="operationVisible = true">重置函数</el-button></div>
+        <div><el-button type="info" size="small" @click="operationEdit">重置函数</el-button></div>
       </div>
     </div>
     <div v-show="operationVisible" class="operation-box">
@@ -86,7 +98,7 @@
                 <el-link :underline="false" type="primary" class="mg-r-10" @click="addBrackets(')',true)">)</el-link>
                 <el-link :underline="false" type="primary" class="mg-r-10" @click="addBrackets('[',false)">【</el-link>
                 <el-link :underline="false" type="primary" class="mg-r-10" @click="addBrackets(']',true)">】</el-link>
-                <el-link :underline="false" type="primary">输入值</el-link>
+                <el-link :underline="false" type="primary" @click="addText">输入值</el-link>
               </div>
             </div>
             <div class="border-grey sele-ele-box">
@@ -101,12 +113,12 @@
           </el-col>
         </el-row>
         <div class="text-align-c">
-          <el-button size="small" type="primary">保存</el-button>
+          <el-button size="small" @click="operationHandle" type="primary">保存</el-button>
           <el-button size="small" @click="operationVisible = false">取消</el-button>
         </div>
       </div>
     </div>
-    <div v-show="!operationVisible">
+    <div v-show="!operationVisible && !showFunDetail">
       <div class="box-dashed">
         <div class="mg-b-20">函数公式运算执行溯源</div>
         <div>
@@ -136,9 +148,72 @@
       </div>
       <div class="text-align-c">
         <el-button type="warning">取消</el-button>
-        <el-button type="primary">保存</el-button>
+        <el-button type="primary" @click="saveFormula">保存</el-button>
       </div>
     </div>
+    <div v-if="!operationVisible && showFunDetail">
+      <el-tabs v-model="actiFunIndex" closable @tab-remove="removeFun" :before-leave="funLeave">
+        <el-tab-pane v-for="(item,index) in equationSelectEle.children" :key="item.name" :label="item.name" :name="index.toString()">
+          <formula-template :formulainfo="item" :curele="equationSelectEle" @sele-ele-handle="showChooseEle">
+            
+          </formula-template>
+        </el-tab-pane>
+      </el-tabs>
+    </div>
+
+    <el-dialog title="输入值" :visible.sync="inputVisible" width="300px" append-to-body :close-on-click-modal="false">
+      <el-input v-model="inputText" placeholder="请输入内容"></el-input>
+      <div class="text-align-c mg-t-10">
+        <el-button size="small" @click="addTextHandle" type="primary">保存</el-button>
+        <el-button size="small" @click="inputVisible = false">取消</el-button>
+      </div>
+    </el-dialog>
+
+    <el-dialog title="选择元素" :visible.sync="chooseEleVisible" width="800px" append-to-body :close-on-click-modal="false">
+      <div>
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <el-card shadow="never">
+              <el-scrollbar style="height: 460px">
+                <el-tree
+                  class="filter-tree"
+                  lazy
+                  :load="loadNode"
+                  @node-click="getNodeDetail"
+                  :props="defaultProps"
+                  :expand-on-click-node="false"
+                  highlight-current
+                  node-key="id"
+                  ref="tree"
+                >
+                </el-tree>
+              </el-scrollbar>
+            </el-card>
+          </el-col>
+          <el-col :span="16">
+            <el-select v-model="eleTableId" @change="getTableEle" placeholder="请选择元素表">
+              <el-option  v-for="item in eleTableList" :key="item.id" :label="item.tableName" :value="item.id"></el-option>
+            </el-select>
+            <div class="mg-t-10 mg-b-10 no-mb-col">
+              <el-scrollbar style="height: 210px">
+                <el-row>
+                  <el-col :span="6" v-for="item in eleList" :key="item.id">
+                    <div class="ele-box">
+                      <span>{{item.eName}}</span>
+                      <el-checkbox v-model="item.checked" @change="value => eleCheckHandle(value,item)"></el-checkbox>
+                    </div>
+                  </el-col>
+                </el-row>
+              </el-scrollbar>
+            </div>
+          </el-col>
+        </el-row>
+        <div class="text-align-c">
+          <el-button size="small" @click="chooseEleHandle" type="primary">保存</el-button>
+          <el-button size="small" @click="chooseEleVisible = false">取消</el-button>
+        </div>
+      </div>
+    </el-dialog>
   </basic-container>
 </template>
 
@@ -146,16 +221,23 @@
 import { getLazytree,selectByNodeTable,selectFormElements} from "@/api/manager/wbstree";
 import { getProjectList } from "@/api/manager/projectinfo";
 import { findContractByProjectId } from "@/api/manager/contractinfo";
+import { getDetail as getEleDeatil } from "@/api/manager/wbsformelement";
 import { getTypeMap } from "@/api/formula/formula";
 import {mapGetters} from "vuex";
+
 import formulaItem from "./component/formulaItem"
+import formulaTemplate from "./component/formulaTemplate"
+
+import {formulaArrayToString} from "./formulaArrayToString"
 export default {
   components: {
-    formulaItem
+    formulaItem,
+    formulaTemplate
   },
   data() {
     return {
       wbsid: "", //从哪个wbs树过来的
+      eleid: "", //元素id
 
       isRetain: false, //是否保留小数
       retainNum: 2, //保留几位小数
@@ -173,7 +255,7 @@ export default {
         children: "children",
         label: "title",
         isLeaf: function (data) {
-          return !data.hasChildren;
+          return !data.hasChildren || (data.isExistForm==1);
         },
       },
       eleTableId:'',//选中的元素表id
@@ -181,6 +263,16 @@ export default {
       eleList:[],
       selectEleFormula:[],
       curSeleEleIndex:0,//公式文字里面选中的元素索引
+      inputVisible:false,//输入弹窗
+      inputText:"",//输入值
+
+      resultFormula:[],//=等号左边的数组
+      processFormula:[],//=等号右边的数组
+      processType:'',//选中的元素在等号哪边
+      processSelectIndex:0,//选中的索引
+      actiFunIndex:0,//元素下挂载的计算式的索引
+      chooseEleVisible:false,//选择元素弹窗
+      argumenObj:{},
 
       symbolReg:/(\+|-|\*|\/)(.+)/,
     };
@@ -195,13 +287,33 @@ export default {
     //   })
     //   return text
     // }
+
+    //等式中选中的元素
+    equationSelectEle:function(){
+      if(this.processType){
+        return this[this.processType][this.processSelectIndex];
+      }else{  
+        return null;
+      }
+    },
+
+    //是否显示元素下挂载的计算式信息
+    showFunDetail:function(){
+      if(this.equationSelectEle && this.equationSelectEle.children && this.equationSelectEle.children.length>0){
+        return true;
+      }else{
+        return false;
+      }
+    }
   },
   created() {
     this.wbsid = this.$route.query.wbsid;
+    this.eleid = this.$route.query.eleid;
     this.init();
   },
   methods: {
     init() {
+      this.getEleDeatil();
       this.getProjectList();
       this.getTypeMap();
     },
@@ -234,10 +346,12 @@ export default {
       //console.log(indexPath,'indexPath')
       if(this.operationVisible){
         this.openerationSelect(index,indexPath)
+      }else{
+        this.equationSelect(index,indexPath)
       }
     },
 
-    //在选择元素模式下点选
+    //在选择元素模式下点选计算
     openerationSelect(index,indexPath){
       if(indexPath[0]!='基础运算'){
         this.$message({
@@ -265,6 +379,11 @@ export default {
       }
     },
 
+    operationEdit(){
+      this.selectEleFormula= JSON.parse(JSON.stringify(this.processFormula));
+      this.operationVisible = true;
+    },
+
     eleAddFormula(){
       for (let i = 0; i < this.eleList.length; i++) {
         if (this.eleList[i].checked) {
@@ -283,7 +402,8 @@ export default {
           name:ele.eName,
           id:ele.id,
           selected:false,
-          tableElementKey:ele.tableElementKey
+          tableElementKey:ele.tableElementKey,
+          children:[],
         })
       }else if(ele.template && ele.example){
         //运算符号
@@ -300,6 +420,13 @@ export default {
           name:ele.name,
           selected:false,
         })
+      }else if(ele.type == 'Text'){
+        //输入值
+        this.selectEleFormula.push({
+          type:'Text',
+          name:ele.name,
+          selected:false,
+        })
       }
     },
 
@@ -319,6 +446,19 @@ export default {
       }
     },
 
+    
+    addText(){
+      this.inputVisible = true;
+    },
+    //添加输入值
+    addTextHandle(){
+      this.eleAddFormulaHandle({
+        type:'Text',
+        name:this.inputText
+      })
+      this.inputVisible = false;
+    },
+
     //勾选元素
     eleCheckHandle(checked,item){
       if(checked){
@@ -343,6 +483,133 @@ export default {
       }
     },
 
+    //赋值给等号右边的数组
+    operationHandle(){
+      this.processFormula = JSON.parse(JSON.stringify(this.selectEleFormula));
+      this.operationVisible = false;
+    },
+
+    //点选等式中的元素
+    equationClick({selected,item},index,arrName){
+      if(selected){
+        this.resultFormula.forEach((ele)=>{
+          ele.selected = false;
+        })
+        this.processFormula.forEach((ele)=>{
+          ele.selected = false;
+        })
+        this.processSelectIndex = index;
+        this.processType = arrName;
+        item.selected = true;
+      }else{
+        this.processType = '';
+      }
+    },
+
+    //在等式模式下点选计算式
+    equationSelect(index,indexPath){
+      if(!this.equationSelectEle && this.equationSelectEle.type == 'Element'){
+        this.$message({
+          type: "warning",
+          message: "请先选中元素"
+        });
+        return;
+      }
+
+      let formulaindex = Number(indexPath[1].split('-')[1])-1;
+      let expression = this.formulaList[indexPath[0]][formulaindex];
+      if(expression.type ==1){
+        return;
+      }
+      //console.log(JSON.parse(expression.template));
+      let obj = Object.assign({}, expression);
+      obj.template = JSON.parse(obj.template);
+      obj.arguments = new Array(obj.template.args.length);
+      obj.arguments[0] = {
+          id:this.equationSelectEle.id,
+          name:this.equationSelectEle.name,
+          selected:false,
+          tableElementKey:this.equationSelectEle.tableElementKey,
+          type:"Element",
+      };
+      this.equationSelectEle.children.push(obj);
+    },
+
+    //选择元素
+    chooseEleHandle(){
+      for (let i = 0; i < this.eleList.length; i++) {
+        if (this.eleList[i].checked) {
+          let ele = this.eleList[i]
+          let obj = {
+            type:'Element',
+            name:ele.eName,
+            id:ele.id,
+            selected:false,
+            tableElementKey:ele.tableElementKey,
+            children:[],
+          }
+          this.$set(this.argumenObj.arguments,this.argumenObj.index,obj);
+          this.chooseEleVisible = false;
+          break;
+        }
+      }
+    },
+
+    //显示选择元素弹窗
+    showChooseEle(argumenObj){
+      this.argumenObj = argumenObj;
+      this.chooseEleVisible = true;
+    },
+
+    //移除挂载的函数
+    removeFun(name){
+      //console.log(name)
+      this.equationSelectEle.children.splice(Number(name), 1);
+    },
+
+    //切换公式tab标签
+    funLeave(activeName, oldActiveName){
+      if(oldActiveName){
+        let formula = this.equationSelectEle.children[Number(oldActiveName)];
+        if(formula){
+          return this.checkFormulaLegal(formula);
+        }
+      }
+      
+    },
+
+    //检测公式合法
+    checkFormulaLegal(formula){
+      if(!formula.arguments){
+        return false;
+      }
+
+      //当前选中的元素
+      let curEle = this.equationSelectEle;
+      let isIn = false;
+      for (let i = 0; i < formula.arguments.length; i++) {
+        if(formula.arguments[i] && formula.arguments[i].id ==curEle.id){
+          isIn = true;
+          break;
+        }
+      }
+      if(!isIn){
+        this.$message({
+          type: "warning",
+          message: "参数必须有一个值是当前元素"
+        });
+        return false;
+      }
+
+      return true;
+    },
+
+    //保存公式
+    saveFormula(){
+      let text = formulaArrayToString(this.processFormula,this.resultFormula);
+      console.log(text);
+    },
+
     getNodeDetail(data) {
       selectByNodeTable(data.id).then((res)=>{
         if(res.data.data.length){
@@ -353,6 +620,20 @@ export default {
       })
     },
 
+    getEleDeatil(){
+      getEleDeatil(this.eleid).then((res)=>{
+        let ele = res.data.data;
+        this.resultFormula = [{
+          type:'Element',
+          name:ele.eName,
+          id:ele.id,
+          selected:false,
+          tableElementKey:ele.tableElementKey,
+          children:[],
+        }]
+      })
+    },
+
     getTableEle(tableId){
       selectFormElements(tableId).then((res)=>{
         this.eleList = res.data.data;

+ 64 - 0
src/views/formula/formulaArrayToString.js

@@ -0,0 +1,64 @@
+
+
+function transformArguments(children,curEle){
+  let fcReg = /(FC\.\S+\().+(\))/;
+  let fcText = '';
+  for (let i = (children.length-1); i >= 0; i--) {
+    let ele = children[i];
+    //console.log(ele.name)
+    let tmpArr = fcReg.exec(ele.template.ft);
+    fcText = tmpArr[1] + fcText;//fc.XX( 左括号部分
+    //console.log(text)
+    ele.arguments.forEach((arg,index)=>{
+      if(arg.type == 'Element'){
+        if(i != (children.length-1) && curEle.id == arg.id){
+          //不是第一个嵌套的公式,且和当前挂载的是同一个元素
+          //认为这个参数是之前公式计算的结果,不再写入元素
+        }else{
+          fcText += `E[${arg.tableElementKey}]`;
+        }
+      }else{
+        fcText += arg;
+      }
+      if(index != ele.arguments.length-1){
+        fcText += ',';
+      }
+    })
+    fcText += ')';
+  }
+
+  return fcText;
+}
+
+export const formulaArrayToString = (processFormula,resultFormula) => {
+  // processFormula =  [{"type":"Element","name":"faf","id":"1534050101579087874","selected":false,"tableElementKey":"assa_faf","children":[{"name":"平方","template":{"ft":"FC.pow(#1,2)","args":[{"key":"#1","m":"底数"}]},"type":0,"example":"求元素最小值:FC.pow(E[元素码],2)","arguments":[{"id":"1534050101579087874","name":"faf","selected":false,"tableElementKey":"assa_faf","type":"Element"}]},{"name":"根号","template":{"ft":"FC.sqrt(#1,#2)","args":[{"key":"#1","m":"开方数"},{"key":"#2","m":"根指数"}]},"type":0,"example":"对元素开方:FC.sqrt(E[元素码],3)","arguments":[{"id":"1534050101579087874","name":"faf","selected":false,"tableElementKey":"assa_faf","type":"Element"},"2"]}]},{"type":"Operator","name":"+","selected":false,"template":"{\"ft\":\"+\",\"args\":[]}"},{"type":"Brackets","name":"(","selected":false},{"type":"Element","name":"aff","id":"1534054463428755457","selected":false,"tableElementKey":"assa_aff","children":[{"name":"日期偏移","template":{"ft":"FC.date(#1,#2)","args":[{"key":"#1","m":"当期日期"},{"key":"#2","m":"偏移天数"}]},"type":3,"example":"三天后的日期FC.date(E[元素码],3)","arguments":[{"id":"1534054463428755457","name":"aff","selected":false,"tableElementKey":"assa_aff","type":"Element"},"1"]},{"name":"包含","template":{"ft":"FC.contain(#1)","args":[{"key":"#1","m":"元素"}]},"type":2,"example":"是否包含","arguments":[{"id":"1534054463428755457","name":"aff","selected":false,"tableElementKey":"assa_aff","type":"Element"}]}]},{"type":"Operator","name":"-","selected":false,"template":"{\"ft\":\"-\",\"args\":[]}"},{"type":"Text","name":"1","selected":false},{"type":"Brackets","name":")","selected":false}];
+  // resultFormula =  [{"type":"Element","name":"sadas","id":"1531842911529267201","selected":false,"tableElementKey":"assa_sadas","children":[{"name":"最大值","template":{"ft":"FC.max(#1)","args":[{"key":"#1","m":"元素"}]},"type":0,"example":"求元素最大值:FC.max(E[元素码])","arguments":[{"id":"1531842911529267201","name":"sadas","selected":false,"tableElementKey":"assa_sadas","type":"Element"}]},{"name":"最小值","template":{"ft":"FC.min(#1)","args":[{"key":"#1","m":"元素"}]},"type":0,"example":"求元素最小值:FC.min(E[元素码])","arguments":[{"id":"1531842911529267201","name":"sadas","selected":false,"tableElementKey":"assa_sadas","type":"Element"}]}]}];
+  // //console.log(JSON.stringify(processFormula))
+  // //console.log(JSON.stringify(resultFormula))
+  // console.log(processFormula)
+  // console.log(resultFormula)
+  let text = '';
+
+  processFormula.forEach(item => {
+    if(item.type == 'Element'){
+      if(item.children.length <1){
+        text += `E[${item.tableElementKey}]`;
+      }else{
+        text += transformArguments(item.children,item);
+      }
+    }else{
+      text += item.name;
+    }
+  });
+
+  if(resultFormula[0].children.length){
+    //等号左侧部分
+    let resText = transformArguments(resultFormula[0].children,resultFormula[0]);
+  
+    //等号左侧元素不需要,左侧的公式嵌套右侧所有结果
+    text = resText.replace(`E[${resultFormula[0].tableElementKey}]`,text);
+  }
+
+  console.log(text);
+  return text;
+}

+ 98 - 54
src/views/manager/contractinfo/detail.vue

@@ -374,7 +374,7 @@
                     v-for="(item,key) in roleList"
                     :label="item.id"
                     :key="key"
-                  >{{item.title}}</el-radio-button>
+                  >{{item.roleName}}</el-radio-button>
                 </el-radio-group>
               </div>
               <div>
@@ -387,17 +387,18 @@
                   <el-option
                     v-for="item in postList"
                     :key="item.id"
-                    :label="item.postName"
+                    :label="item.roleName"
                     :value="item.id"
                   ></el-option>
                 </el-select>
               </div>
             </div>
+            <!-- table表 -->
             <div>
               <el-table
                 :data="contractUserList"
                 border
-                height="500"
+                height="420"
                 style="width: 100%"
               >
                 <el-table-column
@@ -444,9 +445,22 @@
                 style='opacity: 0;position: absolute;height:1px;overflow:hidden;'
               ></el-input>
             </div>
+            <div class="martop10 flexEnd">
+              <el-pagination
+                background
+                @size-change="handleSizeChange"
+                @current-change="handleCurrentChange"
+                :current-page.sync="pageindx"
+                :page-size="pagesize"
+                layout="total, prev, pager, next"
+                :total="total"
+              >
+              </el-pagination>
+            </div>
             <div class="flex jc-al-c mg-t-20">
               <span>添加项目人员</span>
               <el-select
+                class="marleft10"
                 v-model="userId"
                 filterable
                 placeholder="请输入搜索"
@@ -473,42 +487,36 @@
           </div>
         </el-tab-pane>
       </el-tabs>
-
-      <div class="flex jc-sb">
-        <div></div>
-        <div>
-          <el-button
-            type="success"
-            size="medium"
-            :loading="btnLoad"
-            @click="saveQuit"
-          >保存并退出</el-button>
-          <el-button
-            type="info"
-            size="medium"
-            :loading="btnLoad"
-            v-if="activeType != 1"
-            @click="saveNext('p')"
-          >保存并返回上一步</el-button>
-          <el-button
-            type="info"
-            size="medium"
-            :loading="btnLoad"
-            v-if="activeType != 3"
-            @click="saveNext('n')"
-          >保存并进入下一步</el-button>
-        </div>
+      <div class="flexEnd marbottom20">
+        <el-button
+          type="success"
+          size="medium"
+          :loading="btnLoad"
+          @click="saveQuit"
+        >保存并退出</el-button>
+        <el-button
+          type="info"
+          size="medium"
+          :loading="btnLoad"
+          v-if="activeType != 1"
+          @click="saveNext('p')"
+        >保存并返回上一步</el-button>
+        <el-button
+          type="info"
+          size="medium"
+          :loading="btnLoad"
+          v-if="activeType != 3"
+          @click="saveNext('n')"
+        >保存并进入下一步</el-button>
       </div>
     </div>
-
   </basic-container>
 </template>
 
 <script>
 import { getProjectDeatil, findProjectTree } from "@/api/manager/projectinfo";
 import {
-  submitContractInfo, getContractInfo, delFileFromUrl,
-  findPostByType, findAllUserByCondition, findUserByName,
+  submitContractInfo, getContractInfo, delFileFromUrl, searchRole, findAllUserByCondition, findUserByName,
   saveUserInfoByProjectTow, removeUsersByIds, resetPasswordByUserId,
   submitWbsTreeInContract, getContractInfoTree
 } from "@/api/manager/contractinfo";
@@ -555,8 +563,12 @@ export default {
       }
       callback();
     };
-
     return {
+      //#region 
+      pageindx: 1,
+      pagesize: 10,
+      total: 0,
+      //#endregion
       activeType: '1',
       typeChang: {
         1: false,
@@ -564,7 +576,6 @@ export default {
         3: false,
       },
       btnLoad: false,
-
       pid: '',
       cid: '',
       projectInfo: {},
@@ -630,11 +641,7 @@ export default {
       flageData: [],
 
       rId: '',
-      roleList: [
-        { title: '施工方人员', id: '1', },
-        { title: '监理方人员', id: '2', },
-        { title: '业主方人员', id: '3', }
-      ],
+      roleList: [],
       postId: '',
       postList: [],
       contractUserList: [],
@@ -659,19 +666,29 @@ export default {
     activeType: async function (newValue) {
       if (newValue == '3') {
         this.getUserByName();
+        this.searchRole()
       } else if (newValue == '2') {
         await this.getLeftTree();
         this.getRightTree();
       }
     },
     rId: function (newValue) {
-      findPostByType(newValue).then((res) => {
-        this.postList = res.data.data;
-      }).catch(() => {
-        this.postList = [];
-      }).finally(() => {
-        this.postId = '';
+      this.roleList.forEach(val => {
+        if (val.id === this.rId) {
+          if (val.children) {
+            this.postList = val.children
+          } else {
+            this.postList = []
+          }
+        }
       })
+      // findPostByType(newValue).then((res) => {
+      //   this.postList = res.data.data;
+      // }).catch(() => {
+      //   this.postList = [];
+      // }).finally(() => {
+      //   this.postId = '';
+      // })
     },
     postId: function (newValue) {
       if (newValue) {
@@ -682,7 +699,6 @@ export default {
     }
   },
   created () {
-    this.rId = '1'
     this.init();
     //console.log(this.userInfo)
   },
@@ -696,6 +712,30 @@ export default {
     })
   },
   methods: {
+    //#region //后加分页
+    handleSizeChange (val) {
+      this.pagesize = val
+      this.findAllUserByCondition()
+    },
+    handleCurrentChange (val) {
+      this.pageindx = val
+      this.findAllUserByCondition()
+    },
+    //#endregion
+
+    //#region 甘云杰
+    async searchRole () {
+      const { data: res } = await searchRole()
+      console.log(res);
+      if (res.code === 200) {
+        this.roleList = []
+        res.data.forEach(val => {
+          if (val.roleName == "施工方" || val.roleName == "监理方" || val.roleName == "业主方") {
+            this.roleList.push(val)
+          }
+        })
+      }
+    },
     async init () {
       this.pid = this.$route.query.pid;
       this.cid = this.$route.query.cid;
@@ -911,7 +951,7 @@ export default {
         projectId: this.pid,
         contractId: this.contractForm.id,
         userId: this.userId,
-        postId: this.postId,
+        roleId: this.postId,
       }];
       saveUserInfoByProjectTow(list).then(() => {
         // this.findAllUserByCondition();
@@ -919,14 +959,17 @@ export default {
     },
 
     findAllUserByCondition () {
-
       findAllUserByCondition({
-        "cId": this.contractForm.id,
-        "pId": this.pid,
-        "postId": this.postId,
-        "rId": this.rId
-      }).then((res) => {
-        this.contractUserList = res.data.data;
+        cId: this.contractForm.id,
+        pId: this.pid,
+        // "postId": this.postId,
+        rId: this.postId,
+      },
+        this.pagesize,
+        this.pageindx,
+      ).then((res) => {
+        this.contractUserList = res.data.data.records;
+        this.total = res.data.data.total
       })
     },
 
@@ -1087,7 +1130,8 @@ export default {
         });
         this.securityLevelList = res.data.data;
       })
-    }
+    },
+    //#endregion
 
   }
 };

+ 57 - 26
src/views/manager/projectinfo/detail.vue

@@ -124,6 +124,7 @@
                       :min="0"
                       label="路基"
                     ></el-input-number>
+                    <span>公里(KM)</span>
                   </el-form-item>
                   <el-form-item
                     label="计划完工日期"
@@ -238,6 +239,7 @@
             <div class="flex jc-al-c mg-b-10">
               <span>维护人员角色</span>
               <avue-input-tree
+                class="marleft10"
                 :check-strictly="true"
                 v-model="rId"
                 placeholder="请选择"
@@ -254,7 +256,7 @@
               <el-table
                 :data="contractUserList"
                 border
-                height="500"
+                max-height="440"
                 style="width: 100%"
               >
                 <el-table-column
@@ -286,9 +288,22 @@
                 </el-table-column>
               </el-table>
             </div>
+            <div class="martop10 flexEnd">
+              <el-pagination
+                background
+                @size-change="handleSizeChange"
+                @current-change="handleCurrentChange"
+                :current-page.sync="pageindx"
+                :page-size="pagesize"
+                layout="total, prev, pager, next"
+                :total="total"
+              >
+              </el-pagination>
+            </div>
             <div class="flex jc-al-c mg-t-20">
               <span>添加系统内部人员</span>
               <el-select
+                class="marleft10"
                 v-model="userId"
                 filterable
                 placeholder="请输入搜索"
@@ -302,6 +317,7 @@
               </el-select>
               <el-button
                 type="success"
+                class="marleft10"
                 @click="addUserToProject"
               >添加</el-button>
               <el-button type="primary">创建新用户</el-button>
@@ -315,30 +331,27 @@
         </el-tab-pane>
       </el-tabs>
 
-      <div class="flex jc-sb">
-        <div></div>
-        <div>
-          <el-button
-            type="success"
-            size="medium"
-            :loading="btnLoad"
-            @click="saveQuit"
-          >保存并退出</el-button>
-          <el-button
-            type="info"
-            size="medium"
-            :loading="btnLoad"
-            v-if="activeType != 1"
-            @click="saveNext('p')"
-          >保存并返回上一步</el-button>
-          <el-button
-            type="info"
-            size="medium"
-            :loading="btnLoad"
-            v-if="activeType != 3"
-            @click="saveNext('n')"
-          >保存并进入下一步</el-button>
-        </div>
+      <div class="flexEnd">
+        <el-button
+          type="success"
+          size="medium"
+          :loading="btnLoad"
+          @click="saveQuit"
+        >保存并退出</el-button>
+        <el-button
+          type="info"
+          size="medium"
+          :loading="btnLoad"
+          v-if="activeType != 1"
+          @click="saveNext('p')"
+        >保存并返回上一步</el-button>
+        <el-button
+          type="info"
+          size="medium"
+          :loading="btnLoad"
+          v-if="activeType != 3"
+          @click="saveNext('n')"
+        >保存并进入下一步</el-button>
       </div>
     </div>
   </basic-container>
@@ -410,6 +423,11 @@ export default {
     };
 
     return {
+      //#region 
+      pageindx: 1,
+      pagesize: 10,
+      total: 0,
+      //#endregion
       activeType: '1',
       typeChang: {
         1: false,
@@ -502,6 +520,16 @@ export default {
     })
   },
   methods: {
+    //#region //后加分页
+    handleSizeChange (val) {
+      this.pagesize = val
+      this.getUserByCondition();
+    },
+    handleCurrentChange (val) {
+      this.pageindx = val
+      this.getUserByCondition();
+    },
+    //#endregion
     init () {
       this.getHighwayGradeList();
       this.id = this.$route.query.id;
@@ -693,8 +721,11 @@ export default {
         pId: this.projectForm.id,
         postId: '',
         rId: this.rId,
+        size: this.pagesize,
+        current: this.pageindx
       }).then((res) => {
-        this.contractUserList = res.data.data;
+        this.contractUserList = res.data.data.records;
+        this.total = res.data.data.total
       })
     },
 

+ 71 - 52
src/views/manager/projectinfo/list.vue

@@ -11,7 +11,7 @@
           <el-option
             v-for="item in projectList"
             :key="item.id"
-            :label="item.projectName"
+            :label="item.projectAlias"
             :value="item.id"
           ></el-option>
         </el-select>
@@ -60,11 +60,30 @@
       <div class="flex jc-sb pd-b-10">
         <span class="flex1 mg-r-20">{{curProjiect.projectName}}</span>
         <div>
-          <el-button size="small" @click="editTree" type="success">WBS树管理</el-button>
-          <el-button size="small" @click="editProject" type="primary">编辑项目信息</el-button>
-          <el-button size="small" @click="addContract" type="info">创建新合同段</el-button>
-          <el-button size="small" @click="dellProject" type="danger">删除项目</el-button>
-          <el-button size="small" @click="projectVisible = false">返回</el-button>
+          <el-button
+            size="small"
+            @click="editTree"
+            type="success"
+          >WBS树管理</el-button>
+          <el-button
+            size="small"
+            @click="editProject"
+            type="primary"
+          >编辑项目信息</el-button>
+          <el-button
+            size="small"
+            @click="addContract"
+            type="info"
+          >创建新合同段</el-button>
+          <el-button
+            size="small"
+            @click="dellProject"
+            type="danger"
+          >删除项目</el-button>
+          <el-button
+            size="small"
+            @click="projectVisible = false"
+          >返回</el-button>
         </div>
       </div>
       <div
@@ -119,7 +138,7 @@
 </template>
 
 <script>
-import { getProjectList,removeProject } from "@/api/manager/projectinfo";
+import { getProjectList, removeProject } from "@/api/manager/projectinfo";
 import { findContractByProjectId, removeContractInfo } from "@/api/manager/contractinfo";
 // import {getDictionary} from "@/api/system/dict";
 import { mapGetters } from "vuex";
@@ -192,48 +211,48 @@ export default {
       }
     },
 
-      addContract(){
-        this.$router.push({
-          path:'/contract/detail',
-          query:{pid:this.curProjiect.id}
-        });
-      },
-      editContract(item){
-        this.$router.push({
-          path:'/contract/detail',
-          query:{
-            pid:item.pid,
-            cid:item.id,
-          }
-        });
-      },
-      editProject(){
-        this.$router.push({
-          path:'/manager/projectinfo/detail',
-          query:{
-            id:this.curProjiect.id
-          }
-        });
-      },
-      contractDetail(item,type){
-        this.$router.push({
-          path:'/contract/detail',
-          query:{
-            pid:item.pid,
-            cid:item.id,
-            type,
-          }
-        });
-      },
-      editTree(){
-        this.$router.push({
-          path:'/project/tree',
-          query:{
-            pid:this.curProjiect.id,
-            wbsid:this.curProjiect.referenceWbsTemplateId
-          }
-        });
-      },
+    addContract () {
+      this.$router.push({
+        path: '/contract/detail',
+        query: { pid: this.curProjiect.id }
+      });
+    },
+    editContract (item) {
+      this.$router.push({
+        path: '/contract/detail',
+        query: {
+          pid: item.pid,
+          cid: item.id,
+        }
+      });
+    },
+    editProject () {
+      this.$router.push({
+        path: '/manager/projectinfo/detail',
+        query: {
+          id: this.curProjiect.id
+        }
+      });
+    },
+    contractDetail (item, type) {
+      this.$router.push({
+        path: '/contract/detail',
+        query: {
+          pid: item.pid,
+          cid: item.id,
+          type,
+        }
+      });
+    },
+    editTree () {
+      this.$router.push({
+        path: '/project/tree',
+        query: {
+          pid: this.curProjiect.id,
+          wbsid: this.curProjiect.referenceWbsTemplateId
+        }
+      });
+    },
 
     delContract (item, index) {
       this.$confirm('是否删除【' + item.contractName + '】?', '提示', {
@@ -250,8 +269,8 @@ export default {
         })
       })
     },
-    dellProject(){
-      if(this.contractList.length){
+    dellProject () {
+      if (this.contractList.length) {
         this.$message({
           type: "warning",
           message: "只能删除下面无合同段的项目!"
@@ -264,7 +283,7 @@ export default {
         cancelButtonText: '取消',
         type: 'warning'
       }).then(() => {
-        removeProject(this.curProjiect.id).then(()=>{
+        removeProject(this.curProjiect.id).then(() => {
           this.$message({
             type: "success",
             message: "删除成功!"

+ 10 - 7
src/views/manager/wbsinfo/edit.vue

@@ -25,7 +25,7 @@
                         type="text" icon="el-icon-more" class="normal-black">
                       </el-button>
                       <el-dropdown-menu slot="dropdown">
-                        <el-dropdown-item @click.native="setLeftType(1,data,node)" icon="el-icon-circle-plus-outline" v-if="data.deptCategory != 6">新增子级</el-dropdown-item>
+                        <el-dropdown-item @click.native="setLeftType(1,data,node)" icon="el-icon-circle-plus-outline" v-if="data.deptCategory != 6 && data.isExistForm != 1">新增子级</el-dropdown-item>
                         <el-dropdown-item @click.native="setLeftType(2,data,node)" icon="el-icon-edit">编辑节点</el-dropdown-item>
                         <el-dropdown-item @click.native="setLeftType(3,data,node)" icon="el-icon-document-copy">复制节点</el-dropdown-item>
                         <el-dropdown-item @click.native="deleNode(data,node)" icon="el-icon-close" v-if="node.level !=1">删除节点</el-dropdown-item>
@@ -53,7 +53,7 @@
                         type="text" icon="el-icon-more" class="normal-black">
                       </el-button>
                       <el-dropdown-menu slot="dropdown">
-                        <el-dropdown-item @click.native="setLeftType(1,data,node)" icon="el-icon-circle-plus-outline" v-if="data.deptCategory != 6">新增子级</el-dropdown-item>
+                        <el-dropdown-item @click.native="setLeftType(1,data,node)" icon="el-icon-circle-plus-outline" v-if="data.deptCategory != 6 && data.isExistForm != 1">新增子级</el-dropdown-item>
                         <el-dropdown-item @click.native="setLeftType(2,data,node)" icon="el-icon-edit">编辑节点</el-dropdown-item>
                         <el-dropdown-item @click.native="setLeftType(3,data,node)" icon="el-icon-document-copy">复制节点</el-dropdown-item>
                         <el-dropdown-item @click.native="deleNode(data,node)" icon="el-icon-close" v-if="node.level !=1">删除节点</el-dropdown-item>
@@ -372,7 +372,7 @@
           </el-table-column>
           <el-table-column align="center" label="操作" width="200">
             <template slot-scope="scope">
-              <el-link type="primary" @click="toFormulaEdit">公式配置</el-link>
+              <el-link type="primary" @click="toFormulaEdit(scope.row)">公式配置</el-link>
               <el-link class="mg-l-10" type="danger" @click="delEleRowHandle(scope.$index,editEleList)">删除</el-link>
             </template>
           </el-table-column>
@@ -530,7 +530,7 @@
           children: 'children',
           label: 'title',
           isLeaf: function(data){
-            return !data.hasChildren;
+            return !data.hasChildren || (data.isExistForm==1);
           }
         },
         leftType:5,
@@ -708,9 +708,10 @@
           res.data.data.parentName = parentName;
           this.tableData = [res.data.data];
           if(type == 1){
+            //console.log(node.parent)
             this.nodeDetail = {
               parentId:res.data.data.id,
-              parentName:parentName
+              parentName:data.title
             };
           }else{
             this.nodeDetail = Object.assign({},res.data.data);
@@ -1011,7 +1012,7 @@
           return;
         }
         this.treeLoad = true;
-        getAlltree(this.userInfo.tenant_id,'',this.id).then((res)=>{
+        getAlltree(this.userInfo.tenant_id,1,this.id).then((res)=>{
           this.treeLoad = false;
           this.treeData = res.data.data;
           this.$nextTick(()=>{
@@ -1032,6 +1033,7 @@
             type: "warning",
             message: "请先选择文件再进行导入"
           });
+          return;
         }
         let forms = new FormData();
         forms.append('excelFile', this.upFile);
@@ -1154,11 +1156,12 @@
           }
       },
 
-      toFormulaEdit(){
+      toFormulaEdit(row){
         this.$router.push({
           path:'/formula/edit',
           query:{
             wbsid:this.id,
+            eleid:row.id
           }
         });
       },

+ 424 - 55
src/views/system/user.vue

@@ -21,6 +21,7 @@
           :table-loading="loading"
           :data="data"
           ref="crud"
+          :before-close="beforeClose"
           v-model="form"
           :permission="permissionList"
           @row-del="rowDel"
@@ -36,7 +37,137 @@
           @refresh-change="refreshChange"
           @on-load="onLoad"
         >
+          <!-- 自 定义按钮 -->
+          <template
+            slot-scope="{row,index}"
+            slot="menu"
+          >
+            <el-link
+              :underline="false"
+              type="primary"
+              icon="el-icon-edit"
+              size="small"
+              @click="$refs.crud.rowView(row,index)"
+            >查看</el-link>
+            <el-link
+              class="marleft10"
+              :underline="false"
+              type="primary"
+              icon="el-icon-edit"
+              size="small"
+              @click="editKJ(row, index)"
+            >编辑</el-link>
+            <el-link
+              class="marleft10"
+              :underline="false"
+              type="primary"
+              icon="el-icon-delete"
+              size="small"
+              @click="$refs.crud.rowDel(row,index)"
+            >删除</el-link>
+          </template>
+
+          <!-- 参建项目 -->
+          <template
+            slot-scope="{type}"
+            slot="projectAndUserListForm"
+          >
+            <div
+              class="flexStar martop10"
+              v-for="(item,key) in fromss.projectAndUserList"
+              :key='key'
+            >
+              <el-input
+                v-model="fromss.projectAndUserList[key].projectName"
+                :disabled="true"
+              ></el-input>
+              <el-input
+                class="marleft10"
+                v-model="fromss.projectAndUserList[key].contractName"
+                :disabled="true"
+              ></el-input>
+              <el-input
+                class="marleft10"
+                v-model="fromss.projectAndUserList[key].roleName"
+                :disabled="true"
+              ></el-input>
+              <el-button
+                @click="deleteProject(key,type)"
+                class="marleft10"
+                type="danger"
+                icon="el-icon-delete"
+                circle
+              ></el-button>
+            </div>
+          </template>
+
+          <!-- 参与项目自定义表单 -->
+          <template slot="projectIdForm">
+            <el-select
+              v-model="fromss.projectId"
+              placeholder="请选择"
+            >
+              <el-option
+                v-for="item in projectData"
+                :key="item.id"
+                :label="item.projectName"
+                :value="item.id"
+              >
+              </el-option>
+            </el-select>
+          </template>
+          <!-- 合同段自定义表单 -->
+          <template slot="contractIdForm">
+            <el-select
+              v-model="fromss.contractId"
+              placeholder="请选择"
+            >
+              <el-option
+                v-for="item in contractData"
+                :key="item.id"
+                :label="item.projectName"
+                :value="item.id"
+              >
+              </el-option>
+            </el-select>
+          </template>
+          <!-- 用户类型自定义表单 -->
+
+          <template
+            slot-scope="{type}"
+            slot="roleIdsForm"
+          >
+            <div class="flexStar">
+              <el-select
+                v-model="fromss.roleIds"
+                placeholder="请选择"
+              >
+                <el-option
+                  v-for="item in roleIdsData"
+                  :key="item.id"
+                  :label="item.roleName"
+                  :value="item.roleId"
+                >
+                </el-option>
+              </el-select>
+              <el-button
+                v-show="type!=='view'"
+                class="marleft10"
+                type="warning"
+                size="mini"
+                @click="addProject(type)"
+              >确认添加</el-button>
+            </div>
+          </template>
+
           <template slot="menuLeft">
+            <el-button
+              type="primary"
+              size="small"
+              icon="el-icon-plus"
+              @click="addKJ()"
+            >新 增
+            </el-button>
             <el-button
               type="danger"
               size="small"
@@ -231,9 +362,12 @@ import {
   grant,
   resetPassword, unlock
 } from "@/api/system/user";
+import { getProjectList } from "@/api/manager/projectinfo";
+
+import { findContractByProjectId, removeUsersByIds } from "@/api/manager/contractinfo";
 import { exportBlob } from "@/api/common";
 import { getDeptTree, getDeptLazyTree } from "@/api/system/dept";
-import { getRoleTree } from "@/api/system/role";
+import { roletree, treeUser, findProjectAndContractList, saveUserInfoByProjectTow } from "@/api/system/role";
 import { getPostList } from "@/api/system/post";
 import { mapGetters } from "vuex";
 import website from '@/config/website';
@@ -318,6 +452,16 @@ export default {
           children: 'children'
         }
       },
+      fromss: {
+        userId: '',//
+        projectAndUserList: [],
+        projectId: '',//参与项项目
+        contractId: '',//合同段
+        roleIds: '',//用户类型
+      },
+      projectData: [],//参与项项目
+      contractData: [],//合同段
+      roleIdsData: [],//用户类型
       option: {
         height: 'auto',
         calcHeight: 80,
@@ -327,7 +471,10 @@ export default {
         border: true,
         index: true,
         selection: true,
-        viewBtn: true,
+        addBtn: false,
+        // viewBtn: true,
+        editBtn: false,
+        delBtn: false,
         dialogType: 'drawer',
         dialogClickModal: false,
         column: [
@@ -353,7 +500,7 @@ export default {
             label: "所属角色",
             prop: "roleName",
             slot: true,
-            display: false
+            display: false,
           },
           {
             label: "所属部门",
@@ -409,7 +556,7 @@ export default {
                 rules: [{
                   required: true,
                   message: "请输入所属租户",
-                  trigger: "click"
+                  trigger: "change"
                 }],
                 span: 24,
               },
@@ -436,7 +583,7 @@ export default {
                 rules: [{
                   required: true,
                   message: "请选择用户平台",
-                  trigger: "blur"
+                  trigger: "change"
                 }]
               },
               {
@@ -462,16 +609,6 @@ export default {
             prop: 'detailInfo',
             icon: 'el-icon-s-order',
             column: [
-              {
-                label: "用户昵称",
-                prop: "name",
-                hide: true,
-                rules: [{
-                  required: true,
-                  message: "请输入用户昵称",
-                  trigger: "blur"
-                }]
-              },
               {
                 label: "用户姓名",
                 prop: "realName",
@@ -497,38 +634,20 @@ export default {
                 overHidden: true
               },
               {
-                label: "用户性别",
-                prop: "sex",
+                label: "账号状态",
+                prop: "status",
                 type: "select",
+                hide: true,
                 dicData: [
                   {
-                    label: "",
+                    label: "启用",
                     value: 1
                   },
                   {
-                    label: "",
-                    value: 2
+                    label: "禁用",
+                    value: 0
                   },
-                  {
-                    label: "未知",
-                    value: 3
-                  }
                 ],
-                hide: true
-              },
-              {
-                label: "用户生日",
-                type: "date",
-                prop: "birthday",
-                format: "yyyy-MM-dd hh:mm:ss",
-                valueFormat: "yyyy-MM-dd hh:mm:ss",
-                hide: true
-              },
-              {
-                label: "账号状态",
-                prop: "statusName",
-                hide: true,
-                display: false
               }
             ]
           },
@@ -548,14 +667,15 @@ export default {
                 type: "tree",
                 dicData: [],
                 props: {
-                  label: "title"
+                  label: 'title',
+                  value: 'id',
                 },
                 checkStrictly: true,
                 slot: true,
                 rules: [{
                   required: true,
                   message: "请选择所属角色",
-                  trigger: "click"
+                  trigger: "change"
                 }]
               },
               {
@@ -572,7 +692,7 @@ export default {
                 rules: [{
                   required: true,
                   message: "请选择所属部门",
-                  trigger: "click"
+                  trigger: "change"
                 }]
               },
               {
@@ -588,7 +708,65 @@ export default {
                 rules: [{
                   required: true,
                   message: "请选择所属岗位",
-                  trigger: "click"
+                  trigger: "change"
+                }],
+              },
+            ]
+          },
+          {
+            label: '职能描述',
+            prop: 'dutyInfo',
+            icon: 'el-icon-s-custom',
+            column: [
+              {
+                label: "参建项目",
+                prop: "projectAndUserList",
+                span: 24,
+              },
+              {
+                label: "参与项目",
+                prop: "projectId",
+                span: 16,
+              },
+              {
+                label: "合同段",
+                prop: "contractId",
+                span: 16,
+              }, {
+                label: "用户类型",
+                prop: "roleIds",
+                span: 16,
+              }, {
+                label: "单位名称",
+                prop: "companyName",
+                span: 16,
+                rules: [{
+                  required: true,
+                  message: "请输入单位名称",
+                  trigger: "change"
+                }],
+              }, {
+                label: "职位",
+                prop: "position",
+                span: 16,
+                rules: [{
+                  required: true,
+                  message: "请输入岗位信息",
+                  trigger: "change"
+                }],
+              },
+              {
+                label: "允许登录",
+                type: "select",
+                span: 16,
+                prop: "status",
+                dicData: [
+                  { value: 1, label: '是' },
+                  { value: 0, label: '否' }],
+                rules: [{
+                  required: true,
+                  message: "请选择是否允许登录",
+                  trigger: "change"
                 }],
               },
             ]
@@ -732,7 +910,14 @@ export default {
         const column = this.findObject(this.excelOption.column, "excelFile");
         column.action = `/api/blade-user/import-user?isCovered=${this.excelForm.isCovered}`;
       }
-    }
+    },
+    'fromss.projectId': function () {
+      if (this.fromss.projectId) {
+        this.findContractByProjectId(this.fromss.projectId)
+      } else {
+        this.contractData = []
+      }
+    },
   },
   computed: {
     ...mapGetters(["userInfo", "permission"]),
@@ -767,13 +952,198 @@ export default {
     }
   },
   methods: {
+    //#region 弹框事件及方法
+    addKJ () {
+      this.getProjectList()
+      this.treeUser()
+      this.$refs.crud.rowAdd()
+      this.fromss.projectAndUserList = []
+      this.fromss.projectId = ''
+      this.fromss.userId = ''
+      this.fromss.contractId = ''
+      this.fromss.roleIds = ''  //合同段Id
+      this.contractData = []       //合同段枚举
+    },
+    addProject (type) {//确定添加参建项目
+      if (type == 'add') {
+        this.addfangfa()
+      } else {
+        const tag = true
+        if (!this.fromss.projectId) {
+          this.$message({
+            type: "error",
+            message: "请选择参与项目!"
+          })
+          return tag = false
+        }
+        if (!this.fromss.contractId) {
+          this.$message({
+            type: "error",
+            message: "请选择合同段!"
+          })
+          return tag = false
+        }
+        if (!this.fromss.roleIds) {
+          this.$message({
+            type: "error",
+            message: "请选择用户类型!"
+          })
+          return tag = false
+        }
+        if (tag) {
+          this.saveUserInfoByProjectTow([{
+            projectId: this.fromss.projectId,
+            contractId: this.fromss.contractId,
+            roleId: this.fromss.roleIds,
+            userId: this.fromss.userId
+          }])
+        }
+      }
+    },
+    addfangfa () {//添加时确定添加按钮方法处理
+      let tag = true
+      if (!this.fromss.projectId) {
+        this.$message({
+          type: "error",
+          message: "请选择参与项目!"
+        })
+        tag = false
+        return
+      }
+      if (!this.fromss.contractId) {
+        this.$message({
+          type: "error",
+          message: "请选择合同段!"
+        })
+        tag = false
+        return
+      }
+      if (!this.fromss.roleIds) {
+        this.$message({
+          type: "error",
+          message: "请选择用户类型!"
+        })
+        tag = false
+        return
+      }
+      let tas = {
+        projectName: '',
+        contractName: '',
+        roleType: '',
+        roleName: ''
+      }
+      this.projectData.forEach(val => {
+        if (val.id === this.fromss.projectId) {
+          tas.projectName = val.projectName
+        }
+      })
+      this.contractData.forEach(val => {
+        if (val.id === this.fromss.contractId) {
+          tas.contractName = val.projectName
+        }
+      })
+      this.roleIdsData.forEach(val => {
+        if (val.roleId === this.fromss.contractId) {
+          tas.roleName = val.roleName
+        }
+      })
+      this.fromss.projectAndUserList.push({
+        projectId: this.fromss.projectId,
+        contractId: this.fromss.contractId,
+        roleId: this.fromss.roleIds,
+        projectName: '',
+        contractName: '',
+        roleName: ''
+      })
+    },
+    editKJ (row, index) {//编辑用户
+      console.log(row);
+      this.fromss.userId = row.id  //用户ID
+      this.fromss.contractId = ''  //合同段Id
+      this.contractData = []       //合同段枚举
+      this.getProjectList()
+      this.treeUser()
+      this.findProjectAndContractList(row.id)
+      this.$refs.crud.rowEdit(row, index)
+    },
+    deleteProject (key, type) {//删除参建项目按钮
+      if (type == 'add') {
+        delete this.fromss.projectAndUserList[key]
+      } else {
+        this.removeUsersByIds(this.fromss.projectAndUserList[key].id)
+      }
+    },
+    beforeClose (done) {//弹框关闭事件
+      this.fromss = {
+        userId: '',//
+        projectAndUserList: [],
+        projectId: '',//参与项项目
+        contractId: '',//合同段
+        roleIds: '',//用户类型
+      },
+        done()
+    },
+    async removeUsersByIds (ids) {//删除参建项目
+      const { data: res } = await removeUsersByIds(ids)
+      console.log(res);
+      if (res.code == 200) {
+        this.findProjectAndContractList(this.fromss.userId)
+      }
+    },
+    async getProjectList () {//项目类型
+      const { data: res } = await getProjectList()
+      console.log(res);
+      if (res.code === 200) {
+        this.projectData = res.data.records
+      }
+    },
+    async findContractByProjectId (pId) {//合同段
+      const { data: res } = await findContractByProjectId(pId)
+      console.log(res);
+      if (res.code === 200) {
+        this.contractData = res.data
+      }
+    },
+    async treeUser () {//获取用户类型枚举
+      const { data: res } = await treeUser()
+      console.log(res);
+      if (res.code === 200) {
+        this.roleIdsData = res.data
+      }
+    },
+    async findProjectAndContractList (userId) {//编辑获取参建项目
+      const { data: res } = await findProjectAndContractList({ userId })
+      console.log(res);
+      if (res.code === 200) {
+        res.data.forEach(val => {
+          if (val.roleType) {
+            val.roleName = val.roleName + ' | ' + val.roleType
+          }
+        })
+        this.fromss.projectAndUserList = res.data
+      }
+    },
+    async saveUserInfoByProjectTow (da) {//编辑添加参建项目
+      console.log('ss');
+      const { data: res } = await saveUserInfoByProjectTow(da)
+      console.log(res);
+      if (res.code == 200) {
+        this.fromss.projectId = ''    //参与项项目
+        this.fromss.contractId = ''   //合同段
+        this.fromss.roleIds = ''      //用户类型
+        this.findProjectAndContractList(this.fromss.userId)
+      }
+    },
+    //#endregion
+
+    //#region 甘云杰
     nodeClick (data) {
       this.treeDeptId = data.id;
       this.page.currentPage = 1;
       this.onLoad(this.page);
     },
     initData (tenantId) {
-      getRoleTree(tenantId).then(res => {
+      roletree(tenantId).then(res => {
         const column = this.findObject(this.option.group, "roleId");
         column.dicData = res.data.data;
       });
@@ -797,11 +1167,11 @@ export default {
         this.onLoad(this.page);
       });
     },
-    rowSave (row, done, loading) {
+    rowSave (row, done, loading) { //新增保存
       row.deptId = row.deptId.join(",");
       row.roleId = row.roleId.join(",");
       row.postId = row.postId.join(",");
-      add(row).then(() => {
+      add({ ...row, projectAndUserList: this.fromss.projectAndUserList }).then(() => {
         this.initFlag = false;
         this.onLoad(this.page);
         this.$message({
@@ -809,16 +1179,15 @@ export default {
           message: "操作成功!"
         });
         done();
-      }, error => {
-        window.console.log(error);
+      }, () => {
         loading();
       });
     },
-    rowUpdate (row, index, done, loading) {
+    rowUpdate (row, index, done, loading) {//修改按钮
       row.deptId = row.deptId.join(",");
       row.roleId = row.roleId.join(",");
       row.postId = row.postId.join(",");
-      update(row).then(() => {
+      update({ ...row, projectAndUserList: this.fromss.projectAndUserList }).then(() => {
         this.initFlag = false;
         this.onLoad(this.page);
         this.$message({
@@ -826,8 +1195,7 @@ export default {
           message: "操作成功!"
         });
         done();
-      }, error => {
-        window.console.log(error);
+      }, () => {
         loading();
       });
     },
@@ -918,7 +1286,7 @@ export default {
       if (this.selectionList.length === 1) {
         this.roleTreeObj = this.selectionList[0].roleId.split(",");
       }
-      getRoleTree().then(res => {
+      roletree().then(res => {
         this.roleGrantList = res.data.data;
         this.roleBox = true;
       });
@@ -1066,7 +1434,8 @@ export default {
         this.platformLoading = false;
         this.selectionClear();
       });
-    }
+    },
+    //#endregion
   }
 };
 </script>