196 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			196 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <template>
 | |
|   <section class="SelectDeptUser">
 | |
|     <el-input :value="selectText" disabled size="small" @click.native="dialog=true">
 | |
|       <el-button type="text" slot="append">开始选择</el-button>
 | |
|     </el-input>
 | |
|     <ai-dialog :visible.sync="dialog" title="选择部门/人员" width="700px" @onConfirm="handleSubmit" @close="selected=[],getDepts()">
 | |
|       <el-breadcrumb separator="/">
 | |
|         <el-breadcrumb-item v-for="(item, index) in selectDeptPath" :key="index">
 | |
|           <el-button type="text" @click="deptNameClick(item)">{{ item.name }}</el-button>
 | |
|         </el-breadcrumb-item>
 | |
|       </el-breadcrumb>
 | |
|       <div class="optionsItem" v-for="(row, index) in options" :key="index">
 | |
|         <el-row type="flex">
 | |
|           <el-checkbox class="fill" :label="row.uid" v-model="row.checked" @change="handleCheck(row,index)">{{ row.name }}</el-checkbox>
 | |
|           <el-button type="text" v-if="!row.parentid&&row.kind=='dept'" @click="openDialogTag(row)">添加标签</el-button>
 | |
|           <el-button type="text" v-if="row.kind=='dept'" @click="itemClick(row)">更多</el-button>
 | |
|         </el-row>
 | |
|         <el-tag effect="dark" size="small" v-for="tag in row.selectedTags" :key="tag.id" class="mar-4">{{ tag.name }}</el-tag>
 | |
|       </div>
 | |
|       <ai-empty v-if="!options.length"/>
 | |
|       <ai-dialog :visible.sync="dialogTag" title="选择标签" width="500px" @onConfirm="handleSelectTag" @close="selectedTags=[]" append-to-body>
 | |
|         <el-checkbox-group v-model="selectedTags">
 | |
|           <div class="optionsItem" v-for="(cls, index) in tagOps" :key="index">
 | |
|             <ai-title :title="cls.name"/>
 | |
|             <el-checkbox class="fill" v-for="(op, i) in cls.tagList" :key="i" :label="op.id">{{ op.name }}</el-checkbox>
 | |
|           </div>
 | |
|         </el-checkbox-group>
 | |
|         <ai-empty v-if="!tagOps.length"/>
 | |
|       </ai-dialog>
 | |
|     </ai-dialog>
 | |
|   </section>
 | |
| </template>
 | |
| 
 | |
| <script>
 | |
| export default {
 | |
|   name: "SelectDeptUser",
 | |
|   model: {
 | |
|     event: "change",
 | |
|     prop: "value"
 | |
|   },
 | |
|   props: {
 | |
|     value: {default: ""},
 | |
|     instance: Function,
 | |
|     dict: Object,
 | |
|     source: {default: 1}
 | |
|   },
 | |
|   computed: {
 | |
|     selectText: v => v.value?.length > 0 ? "已选择" : "请选择",
 | |
|     tagAction: v => v.source == 2 ? '/app/wxcp/wxgroupchattag/listAllByCorp' : '/app/wxcp/wxcorptag/listAllByCorp'
 | |
|   },
 | |
|   data() {
 | |
|     return {
 | |
|       dialog: false,
 | |
|       dialogTag: false,
 | |
|       currentCorp: {},
 | |
|       selected: [],
 | |
|       selectDeptPath: [],
 | |
|       selectedTags: [],
 | |
|       options: [],
 | |
|       tagOps: [],
 | |
|       allData: [],
 | |
|       tags: {}
 | |
|     }
 | |
|   },
 | |
|   methods: {
 | |
|     getDepts() {
 | |
|       this.instance.post('/app/wxcp/wxdepartment/listAllByCorp').then(res => {
 | |
|         if (res?.data) {
 | |
|           let parents = res.data.map(e => e.parentid)
 | |
|           this.allData = res.data.map(e => ({
 | |
|             ...e,
 | |
|             hasChildren: parents.includes(e.id),
 | |
|             uid: [e.corpId, e.id].join("_"),
 | |
|             kind: 'dept',
 | |
|             checked: false
 | |
|           }))
 | |
|           this.deptInit()
 | |
|         }
 | |
|       })
 | |
|     },
 | |
|     getTagsByCorp(dvcpCorpId) {
 | |
|       return this.instance.post(this.tagAction, null, {
 | |
|         params: {
 | |
|           dvcpCorpId,
 | |
|           size: 9999
 | |
|         }
 | |
|       }).then(res => {
 | |
|         if (res?.data) {
 | |
|           return this.tagOps = res.data.records || []
 | |
|         }
 | |
|       })
 | |
|     },
 | |
|     deptInit() {
 | |
|       this.options = this.allData.filter(e => !e.parentid)
 | |
|       this.selectDeptPath = [{name: "可选范围", id: ''}]
 | |
|     },
 | |
|     itemClick(row) {
 | |
|       let index = this.selectDeptPath.findIndex(e => e.id == row.id)
 | |
|       if (index == -1) {
 | |
|         this.selectDeptPath.push(row)
 | |
|         this.getDeptsAndUsersByParent(row)
 | |
|       }
 | |
|     },
 | |
|     getDeptsAndUsersByParent(row) {
 | |
|       let {id: departmentId, corpId: cid} = row
 | |
|       this.options = this.allData.filter(e => e.parentid == departmentId && e.corpId == cid) || []
 | |
|       this.instance.post(`/app/wxcp/wxuser/listByDeptId`, null, {
 | |
|         params: {departmentId, status: 1, cid}
 | |
|       }).then(res => {
 | |
|         if (res?.data) {
 | |
|           res.data = res.data.map(e => ({
 | |
|             ...e, kind: "user", checked: this.selected.some(s => {
 | |
|               if (e.id == s.id) return true
 | |
|             })
 | |
|           }))
 | |
|           this.options = [this.options, res.data].flat()
 | |
|         }
 | |
|       })
 | |
|     },
 | |
|     deptNameClick(row, index) {
 | |
|       if (!index) { //第一级别
 | |
|         this.deptInit()
 | |
|       } else {
 | |
|         let length = this.selectDeptPath.length - index
 | |
|         this.selectDeptPath.splice(index + 1, length)
 | |
|         this.getDeptsAndUsersByParent(row.id)
 | |
|       }
 | |
|     },
 | |
|     openDialogTag(row) {
 | |
|       this.getTagsByCorp(row.corpId).then(() => {
 | |
|         this.currentCorp = row
 | |
|         this.dialogTag = true
 | |
|       })
 | |
|     },
 | |
|     handleSelectTag() {
 | |
|       let {corpId} = this.currentCorp
 | |
|       this.currentCorp.selectedTags = this.$copy(this.tagOps.map(e => e.tagList).flat().filter(e => this.selectedTags.includes(e.id)))
 | |
|       this.tags[corpId] = this.$copy(this.currentCorp.selectedTags)
 | |
|       this.dialogTag = false
 | |
|     },
 | |
|     handleSubmit() {
 | |
|       let result = {}
 | |
|       this.selected?.map(e => {
 | |
|         let {kind, id} = e
 | |
|         result[e.corpId] = [result[e.corpId], {kind, id}].flat()
 | |
|       })
 | |
|       let selected = Object.keys(result).map(corpId => {
 | |
|         let res
 | |
|         if (result[corpId]) {
 | |
|           res = {
 | |
|             corpId,
 | |
|             objList: result[corpId].filter(e => !!e)
 | |
|           }
 | |
|           if (this.tags[corpId]?.length > 0) {
 | |
|             res.tagId = this.tags[corpId]?.map(e => e.id)
 | |
|           }
 | |
|         }
 | |
|         return res
 | |
|       }).filter(e => !!e)
 | |
|       this.$emit("change", selected)
 | |
|       this.dialog = false
 | |
|     },
 | |
|     isSelected(uid) {
 | |
|       return !!this.selected.find(e => e.uid == uid)
 | |
|     },
 | |
|     handleCheck(row, i) {
 | |
|       if (row.checked) {
 | |
|         this.selected.push(row)
 | |
|       } else {
 | |
|         this.selected.splice(i, 1)
 | |
|       }
 | |
|       this.$forceUpdate()
 | |
|     }
 | |
|   },
 | |
|   created() {
 | |
|     this.getDepts()
 | |
|   }
 | |
| }
 | |
| </script>
 | |
| 
 | |
| <style lang="scss" scoped>
 | |
| .SelectDeptUser {
 | |
|   :deep(.optionsItem ){
 | |
|     border: 1px solid #eee;
 | |
|     margin-bottom: 8px;
 | |
|     padding: 8px;
 | |
|     border-radius: 4px;
 | |
| 
 | |
|     .mar-4 {
 | |
|       margin-right: 4px;
 | |
|       margin-bottom: 4px;
 | |
|     }
 | |
|   }
 | |
| }
 | |
| </style>
 |