511 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			511 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <template>
 | |
|   <section class="AiPeople">
 | |
|     <a v-if="customCliker" class="custom-clicker" @click="dialog.visible=true">
 | |
|       <slot></slot>
 | |
|     </a>
 | |
|     <el-button v-else size="small" @click="dialog.visible=true">{{btnText}}</el-button>
 | |
|     <el-dialog
 | |
|       width="912px"
 | |
|       :title="dialogTitle"
 | |
|       top="5vh"
 | |
|       custom-class="ai-people"
 | |
|       :visible.sync="dialog.visible"
 | |
|       :close-on-click-modal="false"
 | |
|       :modal="true"
 | |
|       destroy-on-close
 | |
|       :append-to-body="true"
 | |
|       :show-close="false"
 | |
|       @close="selectPeople=[],$refs.peopleTable.clearSelection()"
 | |
|     >
 | |
|       <div style="transform: translateY(-30px)">
 | |
|         <p style="margin-bottom: 16px">
 | |
|           <ai-area-select
 | |
|             v-if="!hasMeta&&showAiArea"
 | |
|             :instance="instance"
 | |
|             v-model="aid"
 | |
|             @areaObj="v=>selectArea=v"
 | |
|             @change="peopleList=[],getUnits()"
 | |
|             clearable
 | |
|             :disabled="isShowUnit"
 | |
|           />
 | |
|         </p>
 | |
|         <el-row type="flex" justify="space-between">
 | |
|           <el-row class="search-panel" type="flex" justify="space-between">
 | |
|             <div class="add-item" style="width: 320px">
 | |
|               <p class="add_top">
 | |
|                 <span>单位列表</span>
 | |
|                 <el-input
 | |
|                   placeholder="单位名称"
 | |
|                   size="small"
 | |
|                   style="width:166px;"
 | |
|                   v-model="filterText"
 | |
|                   prefix-icon="el-icon-search"
 | |
|                   clearable
 | |
|                 ></el-input>
 | |
|               </p>
 | |
|               <div class="tree_list">
 | |
|                 <el-tree
 | |
|                   :data="unitsData"
 | |
|                   class="dialog-tree"
 | |
|                   :props="unitTreeProp"
 | |
|                   ref="unitTree"
 | |
|                   node-key="id"
 | |
|                   :current-node-key="unitId"
 | |
|                   :highlight-current="true"
 | |
|                   @node-click="treeNodeClick"
 | |
|                   :filter-node-method="filterNode"
 | |
|                 ></el-tree>
 | |
|               </div>
 | |
|             </div>
 | |
|             <div class="add-item" style="padding-bottom:3px;border-left:none;overflow-x: hidden">
 | |
|               <p class="add_top">
 | |
|                 <span>单位人员</span>
 | |
|                 <el-input
 | |
|                   placeholder="姓名/手机号"
 | |
|                   size="small"
 | |
|                   style="width:166px;"
 | |
|                   clearable
 | |
|                   prefix-icon="el-icon-search"
 | |
|                   v-model="searchObj.condition"
 | |
|                   @change="getPeopleByUnit"
 | |
|                 ></el-input>
 | |
|               </p>
 | |
|               <el-table
 | |
|                 ref="peopleTable"
 | |
|                 :data="peopleList"
 | |
|                 size="mini"
 | |
|                 height="355"
 | |
|                 header-cell-class-name="table-header"
 | |
|                 :header-cell-style="{lineHeight:'26px'}"
 | |
|                 :cell-style="{padding:0,lineHeight:'26px'}"
 | |
|                 tooltip-effect="light"
 | |
|                 cell-class-name="table-cell-add"
 | |
|                 @select="onSelect"
 | |
|                 @select-all="onSelectAll"
 | |
|                 @selection-change="onChooseChange"
 | |
|               >
 | |
|                 <el-table-column type="selection" />
 | |
|                 <el-table-column prop="userName" align="center" label="姓名" show-overflow-tooltip>
 | |
|                   <template slot-scope="scope">
 | |
|                     <span class="el-icon-user-solid"></span>
 | |
|                     {{scope.row.userName || scope.row.name}}
 | |
|                   </template>
 | |
|                 </el-table-column>
 | |
|                 <el-table-column prop="phone" label="手机号码" show-overflow-tooltip />
 | |
|                 <div
 | |
|                   slot="empty"
 | |
|                   style="font-size: 14px;margin-top: -20px;height: 20px;line-height: 20px"
 | |
|                 >当前部门暂无人员</div>
 | |
|               </el-table>
 | |
|             </div>
 | |
|           </el-row>
 | |
|           <div class="selected-people add-item">
 | |
|             <p class="add_top">
 | |
|               <span>已选择</span>
 | |
|               <el-button
 | |
|                 icon="iconfont iconDelete"
 | |
|                 size="mini"
 | |
|                 @click="selectPeople=[],$refs.peopleTable.clearSelection()"
 | |
|               >清空</el-button>
 | |
|             </p>
 | |
|             <div class="add_tag" v-if="selectPeople.length" style="width:100%;">
 | |
|               <el-tag
 | |
|                 v-for="(item,i) in selectPeople"
 | |
|                 :disable-transitions="true"
 | |
|                 :key="i"
 | |
|                 closable
 | |
|                 @close="cancelSelect(item,i)"
 | |
|               >{{item.userName || item.name}}</el-tag>
 | |
|             </div>
 | |
|             <div
 | |
|               class="add_tag"
 | |
|               v-else
 | |
|               style="display:flex;align-items:center;justify-content:center;width:100%;"
 | |
|             >
 | |
|               <span>暂无数据</span>
 | |
|             </div>
 | |
|           </div>
 | |
|         </el-row>
 | |
|       </div>
 | |
|       <div slot="footer" style="text-align: center;">
 | |
|         <el-button
 | |
|           style="width:92px"
 | |
|           size="small"
 | |
|           class="delete-btn"
 | |
|           @click="dialog.visible=false"
 | |
|         >取消</el-button>
 | |
|         <el-button
 | |
|           style="width:92px"
 | |
|           size="small"
 | |
|           type="primary"
 | |
|           @click="$emit('change', selectPeople),dialog.visible=false"
 | |
|         >确认</el-button>
 | |
|       </div>
 | |
|     </el-dialog>
 | |
|   </section>
 | |
| </template>
 | |
| 
 | |
| <script>
 | |
| export default {
 | |
|   name: "AiPeople",
 | |
|   model: {
 | |
|     prop: "value",
 | |
|     event: "change"
 | |
|   },
 | |
|   props: {
 | |
|     value: Array,
 | |
|     instance: Function,
 | |
|     btnText: { type: String, default: "选择人员" },
 | |
|     dialogTitle: { type: String, default: "选择人员" },
 | |
|     meta: { type: Array, default: () => [] },
 | |
|     action: String,
 | |
|     customCliker: { type: Boolean, default: false },
 | |
|     areaId: String,
 | |
|     disable: {
 | |
|       type: Array,
 | |
|       default: () => []
 | |
|     },
 | |
|     unitUrl: {
 | |
|       type: String
 | |
|     },
 | |
|     showAiArea: { type: Boolean, default: true },
 | |
|     isSingle: { type: Boolean, default: false },
 | |
|     isShowUnit: {
 | |
|       type: Boolean,
 | |
|       default: false
 | |
|     },
 | |
|     unitId: {
 | |
|       type: String,
 | |
|       default: ''
 | |
|     }
 | |
|   },
 | |
|   data() {
 | |
|     return {
 | |
|       aid: "",
 | |
|       dialog: {
 | |
|         visible: false
 | |
|       },
 | |
|       filterText: "",
 | |
|       searchObj: {
 | |
|         unitId: "",
 | |
|         condition: ""
 | |
|       },
 | |
|       unitTreeProp: {
 | |
|         children: "children",
 | |
|         label: "name",
 | |
|         disabled: 'disabled'
 | |
|       },
 | |
|       unitsData: [],
 | |
|       peopleList: [],
 | |
|       selecteds: [],
 | |
|       selectPeople: [],
 | |
|       selectArea: {}
 | |
|     };
 | |
|   },
 | |
|   computed: {
 | |
|     hasMeta() {
 | |
|       return Boolean(this.meta.length);
 | |
|     }
 | |
|   },
 | |
|   watch: {
 | |
|     selecteds(v, old) {
 | |
|       var list = []
 | |
|       this.selectPeople.map(o => {
 | |
|         let index = this.peopleList.findIndex(d => d.userId == o.userId);
 | |
|         if (index === -1) {
 | |
|           list.push(o)
 | |
|         }
 | |
|       });
 | |
|       old.map(o => {
 | |
|         let index = this.selectPeople.findIndex(d => d.userId == o.userId);
 | |
|         if (index > -1) {
 | |
|           this.selectPeople.splice(index, 1);
 | |
|         }
 | |
|       });
 | |
|       if (this.isSingle) {
 | |
|         this.selectPeople = v;
 | |
|       } else {
 | |
|         this.selectPeople = [...v, ...list];
 | |
|       }
 | |
|     },
 | |
|     "dialog.visible"() {
 | |
|       if (this.value) {
 | |
|         this.selectPeople = JSON.parse(JSON.stringify(this.value));
 | |
|       }
 | |
|     },
 | |
|     filterText(val) {
 | |
|       if (this.$refs.unitTree) {
 | |
|         this.$refs.unitTree.filter(val);
 | |
|       }
 | |
|     }
 | |
|   },
 | |
|   methods: {
 | |
|     onChooseChange(v) {
 | |
|       if (!this.isSingle) {
 | |
|         this.selecteds = v;
 | |
|       } else {
 | |
| 
 | |
|       }
 | |
|     },
 | |
| 
 | |
|     onSelectAll() {
 | |
|       if (this.isSingle) {
 | |
|         if (this.peopleList.length) {
 | |
|           this.peopleList.forEach(item => {
 | |
|             this.$refs.peopleTable.toggleRowSelection(item, false);
 | |
|           });
 | |
| 
 | |
|           this.selecteds = [];
 | |
|         }
 | |
|       }
 | |
|     },
 | |
| 
 | |
|     onSelect(v, row) {
 | |
|       const isSame = v.length ? (v[0].id === row.id ? true : false) : false;
 | |
|       if (this.isSingle) {
 | |
|         this.peopleList.forEach(item => {
 | |
|           this.$refs.peopleTable.toggleRowSelection(item, false);
 | |
| 
 | |
|           if (item.id === row.id) {
 | |
|             this.$refs.peopleTable.toggleRowSelection(
 | |
|               row,
 | |
|               isSame ? true : false
 | |
|             );
 | |
|           }
 | |
|         });
 | |
| 
 | |
|         this.selecteds = isSame ? [row] : [];
 | |
|       }
 | |
|     },
 | |
| 
 | |
|     getUnits() {
 | |
|       if (this.hasMeta) {
 | |
|         this.getPeopleByUnit();
 | |
|         let units = this.meta.map(e => {
 | |
|           return { id: e.unitId, name: e.unitName, parentId: e.unitParentId };
 | |
|         });
 | |
|         if (units.length) {
 | |
|           let pending = [],
 | |
|             unitsData = [];
 | |
|           //生成指定范围人员单位树
 | |
|           units.map(u => {
 | |
|             if (units.some(e => e.id == u.parentId)) {
 | |
|               pending.push(u);
 | |
|             } else {
 | |
|               unitsData.push(u);
 | |
|             }
 | |
|           });
 | |
|           unitsData.map(t => this.addChild(t, pending));
 | |
|           this.unitsData = [
 | |
|             {
 | |
|               name: "全部",
 | |
|               children: unitsData
 | |
|             }
 | |
|           ];
 | |
|         }
 | |
|       } else if (this.aid) {
 | |
|         this.instance.post(`${this.unitUrl ? this.unitUrl : '/admin/sysunit/getAll'}`, null, { params: { areaId: this.aid } })
 | |
|           .then(res => {
 | |
|             res.data = res.data.map(a => {
 | |
|               return { ...a, label: a.name };
 | |
|             });
 | |
| 
 | |
|             this.unitsData = res.data.filter(e => {
 | |
|               if (this.isShowUnit) {
 | |
|                 return e.id === this.unitId
 | |
|               }
 | |
|               return !e.parentId
 | |
|             });
 | |
|             this.unitsData.map(t => this.addChild(t, res.data));
 | |
|           });
 | |
|       }
 | |
|     },
 | |
|     addChild(parent, pending) {
 | |
|       let doBeforeCount = pending.length;
 | |
|       parent["children"] = parent["children"] || [];
 | |
|       pending.map((e, index, arr) => {
 | |
|         if (e.parentId == parent.id) {
 | |
|           parent.children.push(e);
 | |
|           arr.splice(index, 1);
 | |
|           this.addChild(parent, arr);
 | |
|         }
 | |
|       });
 | |
|       if (pending.length > 0 && doBeforeCount > pending.length) {
 | |
|         parent.children.map(c => this.addChild(c, pending));
 | |
|       }
 | |
|     },
 | |
|     getPeopleByUnit(unit) {
 | |
|       if (unit) this.searchObj.unitId = unit.id;
 | |
|       if (this.hasMeta) {
 | |
|         return new Promise(resolve => {
 | |
|           this.peopleList = this.meta.filter(f => {
 | |
|             if (this.searchObj.unitId) {
 | |
|               return f.unitId == this.searchObj.unitId;
 | |
|             } else if (this.searchObj.condition) {
 | |
|               return (
 | |
|                 [f.userName, f.phone]
 | |
|                   .join("|")
 | |
|                   .indexOf(this.searchObj.condition) > -1
 | |
|               );
 | |
|             } else return true;
 | |
|           });
 | |
|           this.peopleList = this.peopleList.map(p => {
 | |
|             return { ...p, area: this.selectArea };
 | |
|           });
 | |
| 
 | |
|           this.$nextTick(() => {
 | |
|             this.filter();
 | |
|           });
 | |
|           resolve();
 | |
|         });
 | |
|       } else {
 | |
|         return this.instance
 | |
|           .post(this.action || "/admin/user/choicePerson", null, {
 | |
|             params: { ...this.searchObj }
 | |
|           })
 | |
|           .then(res => {
 | |
|             this.peopleList = res.data.map(p => {
 | |
|               return { ...p, area: this.selectArea };
 | |
|             });
 | |
| 
 | |
|             this.$nextTick(() => {
 | |
|               this.filter();
 | |
|             });
 | |
|           });
 | |
|       }
 | |
|     },
 | |
| 
 | |
|     filter() {
 | |
|       if (this.disable.length) {
 | |
|         this.peopleList = this.peopleList.filter(item => {
 | |
|           let index = this.disable.findIndex(d => d.userId == item.userId);
 | |
| 
 | |
|           return index === -1;
 | |
|         });
 | |
|       }
 | |
|     },
 | |
| 
 | |
|     treeNodeClick(unit) {
 | |
|       let temp = JSON.parse(JSON.stringify(this.selectPeople));
 | |
|       this.getPeopleByUnit(unit).then(() => {
 | |
|         if (temp) {
 | |
|           this.selectPeople = JSON.parse(JSON.stringify(temp));
 | |
|           this.relatedTableAndTags();
 | |
|         }
 | |
|       });
 | |
|     },
 | |
|     filterNode(value, data) {
 | |
|       if (!value) return true;
 | |
|       return data.label.indexOf(value) !== -1;
 | |
|     },
 | |
|     cancelSelect(row, index) {
 | |
|       let tableItem = this.peopleList.find(s => s.userId == row.userId);
 | |
|       if (tableItem) {
 | |
|         this.$refs.peopleTable.toggleRowSelection(tableItem);
 | |
|       }
 | |
|       this.selectPeople.splice(index, 1);
 | |
|     },
 | |
|     relatedTableAndTags() {
 | |
|       this.peopleList.map(p => {
 | |
|         let index = this.selectPeople.findIndex(s => s.userId == p.userId);
 | |
|         if (index > -1) {
 | |
|           if (!this.isSingle) {
 | |
|             // this.selectPeople.splice(index, 1);
 | |
|           }
 | |
|           this.$refs.peopleTable.toggleRowSelection(p, true);
 | |
|         }
 | |
|       });
 | |
|     }
 | |
|   },
 | |
|   mounted() {
 | |
|     this.aid = this.areaId;
 | |
|     this.getUnits();
 | |
|     if (this.isShowUnit) {
 | |
|       this.treeNodeClick({
 | |
|         id: this.unitId
 | |
|       })
 | |
|     }
 | |
|   }
 | |
| };
 | |
| </script>
 | |
| 
 | |
| <style lang="scss" scoped>
 | |
| 
 | |
| .ai-people {
 | |
|   .search-panel {
 | |
|     width: auto;
 | |
|     padding-right: 10px;
 | |
|   }
 | |
| 
 | |
|   .add-item {
 | |
|     width: 280px;
 | |
|     height: 400px;
 | |
|     background: rgba(252, 252, 252, 1);
 | |
|     border-radius: 2px;
 | |
|     border: 1px solid rgba(208, 212, 220, 1);
 | |
|     position: relative;
 | |
|     overflow: auto;
 | |
|     box-sizing: border-box;
 | |
| 
 | |
|     .add_top {
 | |
|       width: 100%;
 | |
|       height: 40px;
 | |
|       background: rgba(245, 245, 245, 1);
 | |
|       border-bottom: 1px solid rgba(208, 212, 220, 1);
 | |
|       padding: 0 8px;
 | |
|       box-sizing: border-box;
 | |
|       display: flex;
 | |
|       justify-content: space-between;
 | |
|       align-items: center;
 | |
|     }
 | |
| 
 | |
|     .tree_list {
 | |
|       width: 100%;
 | |
|       overflow: auto;
 | |
|       height: calc(100% - 40px);
 | |
| 
 | |
|       .el-tree {
 | |
|         height: 100%;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     .add_buttom {
 | |
|       position: absolute;
 | |
|       left: 0;
 | |
|       bottom: 0;
 | |
|       font-size: 12px;
 | |
|       width: 310px;
 | |
|       height: 32px;
 | |
|       line-height: 32px;
 | |
|       z-index: 10000;
 | |
|       background: rgba(245, 246, 247, 1);
 | |
|       color: rgba(51, 51, 51, 1);
 | |
|       box-shadow: 0 1px 0 0 rgba(216, 220, 227, 1);
 | |
|       display: flex;
 | |
|       justify-content: center;
 | |
|       align-items: center;
 | |
|       cursor: pointer;
 | |
|     }
 | |
| 
 | |
|     .add_tag {
 | |
|       width: 310px;
 | |
|       height: calc(100% - 40px);
 | |
|       overflow-y: auto;
 | |
| 
 | |
|       .el-tag {
 | |
|         margin: 8px;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| .el-input--mini {
 | |
|   height: 22px;
 | |
|   line-height: 22px;
 | |
| }
 | |
| 
 | |
| .table-cell-add {
 | |
|   padding: 0 !important;
 | |
| }
 | |
| </style>
 |