322 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			322 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <template>
 | |
|   <section class="ai-partyorg">
 | |
|     <el-button
 | |
|         v-if="!customClicker"
 | |
|         size="mini"
 | |
|         type="primary"
 | |
|         @click="showDialog"
 | |
|         :disabled="disabled">
 | |
|       {{ dialogTitle || '选择党组织' }}
 | |
|     </el-button>
 | |
|     <div v-else class="custom-clicker" @click="showDialog">
 | |
|       <slot/>
 | |
|     </div>
 | |
|     <ai-dialog
 | |
|         :visible.sync="dialog"
 | |
|         :modal-append-to-body='true'
 | |
|         :destroy-on-close="false"
 | |
|         append-to-body
 | |
|         :title="type === '0' ? '选择党组织' : '选择小区'"
 | |
|         custom-class="ai-partyorg__dialog"
 | |
|         @onConfirm="confirmParty"
 | |
|         width="720px">
 | |
|       <div v-if="mode=='tree'" class="left_tree">
 | |
|         <el-input v-if="showSearchInput" size="small" v-model="filterText"
 | |
|                   :placeholder="type === '0' ? '请输入党组织名称' : '请输入小区名称'" clearable/>
 | |
|         <div class="left_cont">
 | |
|           <el-tree
 | |
|               :data="treeData"
 | |
|               node-key="id"
 | |
|               :props="defaultProps"
 | |
|               :current-node-key="value"
 | |
|               :default-expanded-keys="defaultExpanded"
 | |
|               :default-checked-keys="defaultChecked"
 | |
|               highlight-current
 | |
|               ref="partyOrgTree"
 | |
|               :filter-node-method="filterNode"
 | |
|               @node-click="nodeClick"/>
 | |
|         </div>
 | |
|       </div>
 | |
|       <party-trans v-if="mode=='trans'" :orgs="treeData" @change="v=>selectedTemp=v"
 | |
|                    :multiple-selection="multipleSelection"/>
 | |
|     </ai-dialog>
 | |
|   </section>
 | |
| </template>
 | |
| 
 | |
| <script>
 | |
| import PartyTrans from "./partyTrans";
 | |
| 
 | |
| export default {
 | |
|   name: "AiParty",
 | |
|   components: {PartyTrans},
 | |
|   model: {
 | |
|     prop: "value",
 | |
|     event: "change",
 | |
|   },
 | |
|   props: {
 | |
|     topOrgId: {type: String, default: ''},
 | |
|     value: {type: [String, Array]},
 | |
|     instance: Function,
 | |
|     type: {
 | |
|       type: String,
 | |
|       default: '0'
 | |
|     },
 | |
|     dialogTitle: {
 | |
|       type: String
 | |
|     },
 | |
|     url: {
 | |
|       type: String,
 | |
|       default: '/app/partyOrganization/queryAllChildren'
 | |
|     },
 | |
|     customClicker: {type: Boolean, default: false},
 | |
|     mode: {type: String, default: 'tree'},
 | |
|     multipleSelection: {type: Boolean, default: false},
 | |
|     showSearchInput: {type: Boolean, default: true},
 | |
|     disabled: {type: Boolean, default: false},
 | |
|     isEmpty: {
 | |
|       type: Boolean,
 | |
|       default: true
 | |
|     },
 | |
|     name: String
 | |
|   },
 | |
|   watch: {
 | |
|     filterText(val) {
 | |
|       this.$refs.partyOrgTree.filter(val);
 | |
|     },
 | |
|     selectedFullName(v) {
 | |
|       v && this.$emit('update:name', v)
 | |
|     },
 | |
|     dialog(v) {
 | |
|       if (v) {
 | |
|         if (this.value) {
 | |
|           this.defaultChecked = [this.value]
 | |
|           this.defaultExpanded = [this.value]
 | |
| 
 | |
|           this.$nextTick(() => {
 | |
|             this.$refs.partyOrgTree.setCurrentKey(this.value)
 | |
|           })
 | |
|         } else {
 | |
|           this.defaultChecked = [this.treeData[0].id]
 | |
|           this.defaultExpanded = [this.treeData[0].id]
 | |
|           this.$nextTick(() => {
 | |
|             this.$refs.partyOrgTree.setCurrentKey([this.treeData[0].id])
 | |
|           })
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   },
 | |
|   data() {
 | |
|     return {
 | |
|       dialog: false,
 | |
|       filterText: '',
 | |
|       treeData: [],
 | |
|       selected: [],
 | |
|       selectedTemp: [],
 | |
|       selectParty: [],
 | |
|       valueType: "",
 | |
|       defaultChecked: [],
 | |
|       defaultExpanded: [],
 | |
|       childCount: 0
 | |
|     }
 | |
|   },
 | |
|   computed: {
 | |
|     selectedFullName() {
 | |
|       return this.selected.map(e => e.name).join("") || ''
 | |
|     },
 | |
|     defaultProps() {
 | |
|       return {
 | |
|         children: 'children',
 | |
|         label: 'name'
 | |
|       }
 | |
|     },
 | |
|   },
 | |
|   methods: {
 | |
|     showDialog() {
 | |
|       if (this.disabled) return
 | |
|       this.dialog = true
 | |
|     },
 | |
|     filterNode(value, data) {
 | |
|       if (!value) return true;
 | |
|       return data.name.indexOf(value) !== -1;
 | |
|     },
 | |
|     addChild(parent, pending) {
 | |
|       let doBeforeCount = pending.length
 | |
|       for (let i = pending.length - 1; i >= 0; i--) {
 | |
|         let e = pending[i]
 | |
|         if (e.parentId == parent.id) {
 | |
|           parent["children"] = [...(parent["children"] || []), e]
 | |
|           pending.splice(i, 1)
 | |
|         }
 | |
|       }
 | |
|       parent.children && (parent.children = parent.children.reverse())
 | |
|       if (pending.length > 0 && doBeforeCount > pending.length) {
 | |
|         parent.children.map(c => this.addChild(c, pending))
 | |
|       }
 | |
|     },
 | |
|     // 查询所有单位 树形结构
 | |
|     searchSysAll() {
 | |
|       this.instance.post(this.url, null, {
 | |
|         params: {
 | |
|           id: this.topOrgId
 | |
|         }
 | |
|       }).then((res) => {
 | |
|         if (res && res.data && (this.type === '0' || this.type === '2')) {
 | |
|           if (this.type === '2') {
 | |
|             this.treeData = res.data
 | |
|           } else {
 | |
|             res.data = res.data.map(a => {
 | |
|               return {...a, name: a.name}
 | |
|             });
 | |
|             if (this.valueType) {
 | |
|               this.selected = res.data.filter(e => (this.valueType == "string" && e.id == this.value) || this.value?.includes(e.id))
 | |
|               if (this.selected) {
 | |
|                 this.$emit('name', this.selected.map(e => e.name))
 | |
|                 this.$emit('origin', this.selected)
 | |
|               }
 | |
|             }
 | |
|             this.treeData = res.data.filter(e => !e.parentId || e.id === this.topOrgId);
 | |
|             this.treeData.map(t => this.addChild(t, res.data));
 | |
|           }
 | |
|         } else {
 | |
|           this.treeData = [res.data]
 | |
|         }
 | |
|       })
 | |
|     },
 | |
|     // 点击树节点
 | |
|     confirmParty() {
 | |
|       if (!this.selectedTemp.length && !this.isEmpty) {
 | |
|         return this.$message.error(this.type === '0' ? '党组织不能为空' : '小区不能为空')
 | |
|       }
 | |
| 
 | |
|       this.selected = this.selectedTemp;
 | |
|       this.selectParty.length && (this.selected = JSON.parse(JSON.stringify(this.selectParty)))
 | |
|       if (this.type === '1' && this.selected[0].isVan === '0') {
 | |
|         return this.$message.error('请选择小区')
 | |
|       }
 | |
|       this.dialog = false
 | |
|       this.$emit('change', this.valueType == "string" ? this.selected.map(e => e.id)[0] : this.selected.map(e => e.id))
 | |
|       this.$emit('name', this.selected.map(e => e.name))
 | |
|       this.$emit('origin', this.selected)
 | |
|     },
 | |
|     nodeClick(data) {
 | |
|       if (!this.multipleSelection) {
 | |
|         let {id, name, orgType, partyType, isVan, isLeaf} = data
 | |
|         this.selectParty = [{id, name, orgType, partyType, isVan, isLeaf}]
 | |
|       }
 | |
|     }
 | |
|   },
 | |
|   mounted() {
 | |
|     this.$nextTick(() => {
 | |
|       this.valueType = typeof this.value
 | |
|       this.searchSysAll();
 | |
|     })
 | |
|   }
 | |
| }
 | |
| </script>
 | |
| <style lang="scss" scoped>
 | |
| .left_tree {
 | |
|   height: 490px;
 | |
|   line-height: 1;
 | |
|   overflow-y: hidden;
 | |
| }
 | |
| 
 | |
| :deep(.el-dialog__header ){
 | |
|   line-height: 1;
 | |
|   // padding: 13px 16px;
 | |
|   // border-bottom: 1px solid #eee;
 | |
| }
 | |
| 
 | |
| :deep( .el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content ){
 | |
|   background: #eaf5ff !important;
 | |
|   color: #257fff !important;
 | |
| }
 | |
| 
 | |
| :deep(.el-dialog__body ){
 | |
|   padding: 16px 16px 0;
 | |
| }
 | |
| 
 | |
| :deep( .ai-dialog__content--wrapper ){
 | |
|   padding-right: 0 !important;
 | |
| }
 | |
| 
 | |
| :deep(.left_cont ){
 | |
|   height: calc(100% - 40px);
 | |
|   padding-top: 8px;
 | |
|   box-sizing: border-box;
 | |
|   overflow: auto;
 | |
| }
 | |
| 
 | |
| :deep(.el-tree ){
 | |
|   background: #fcfcfc;
 | |
| }
 | |
| 
 | |
| :deep( .el-dialog__body ){
 | |
|   background: #fcfcfc;
 | |
| }
 | |
| 
 | |
| :deep(.el-tree-node:focus > .el-tree-node__content ){
 | |
|   background: #eaf5ff !important;
 | |
|   color: #257fff !important;
 | |
| }
 | |
| 
 | |
| :deep(.el-tree-node__content:hover ){
 | |
|   background: #eaf5ff !important;
 | |
|   color: #257fff !important;
 | |
| }
 | |
| 
 | |
| .ai-partyorg {
 | |
| 
 | |
|   .input-clicker {
 | |
|     width: 320px;
 | |
|     cursor: pointer;
 | |
|     border: 1px solid #D0D4DC;
 | |
|     line-height: 32px;
 | |
|     border-radius: 2px;
 | |
|     font-size: 14px;
 | |
| 
 | |
|     .prepend {
 | |
|       background: rgba(245, 245, 245, 1);
 | |
|       width: auto;
 | |
|       border-right: 1px solid #D0D4DC;
 | |
|       padding: 0 8px;
 | |
|       white-space: nowrap;
 | |
| 
 | |
|     }
 | |
| 
 | |
|     .content {
 | |
|       text-align: left;
 | |
|       padding-left: 14px;
 | |
|       padding-right: 8px;
 | |
|     }
 | |
| 
 | |
|     .suffix {
 | |
|       width: auto;
 | |
|       padding: 0 12px
 | |
|     }
 | |
| 
 | |
|     &:hover {
 | |
|       border-color: $primaryColor;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   .select-party {
 | |
|   }
 | |
| 
 | |
|   .party-dialog-footer {
 | |
|     line-height: 1;
 | |
|     text-align: center;
 | |
| 
 | |
|     .el-button {
 | |
|       width: 72px;
 | |
|       height: 32px;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   .custom-clicker {
 | |
|     text-decoration: none;
 | |
|     cursor: pointer;
 | |
|     padding: 3px;
 | |
|   }
 | |
| }
 | |
| </style>
 |