123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608 |
- <template>
- <!-- <a-select :value="valueTitle" :disabled="disabled" :clearable="clearable" @clear="clearHandle"> -->
- <div v-loading="loading">
- <a-popover :disabled="disabled" class="dhc-select-tree_popover" ref="popover" placement="bottom" width="360"
- height="300" v-model:visible="visiable" trigger="click">
- <template #content>
- <!-- <div v-clickoutside="() => { visiable = false }"> -->
- <!-- 多选树 -->
- <pro-tree v-if="showCheckbox == true" id="tree-option" ref="selectTree" :accordion="accordion"
- :data="dataOptions" :props="props" :node-key="props.key" :default-expanded-keys="defaultExpandedKey"
- :show-checkbox="true" :isProSelectTree="true" proSelectTreeStyle="max-height: 300px;overflow: auto;"
- default-expand-all @check-change="handleCheckChange" @check="check" @handler-check="handlerCheck"
- :disabledNode="disabledNode" :disabledNodeSts="disabledNodeSts" :expandTier="expandTier"
- v-bind="$attrs" :filterNodeName="filterNodeName">
- </pro-tree>
- <!-- 单选树 -->
- <pro-tree v-else id="tree-option" ref="selectTree" :accordion="accordion" :data="dataOptions"
- v-model:selectedKeys="valueId" :dataList="dataList" :props="props" :fieldNames="props"
- :node-key="props.key" :default-expanded-keys="defaultExpandedKey" :show-checkbox="false"
- :expand-on-click-node="false" highlight-current :isProSelectTree="true" :expandTier="expandTier"
- proSelectTreeStyle="max-height: 300px;overflow: auto;" @node-click="handleNodeClick" v-bind="$attrs"
- :filterNodeName="filterNodeName">
- </pro-tree>
- <!-- </div> -->
- </template>
- <!-- 展示输入框 -->
- <a-input v-model:value="inputValue" :disabled="disabled" placeholder="请选择" :size="size">
- <span slot="suffix">
- <span v-if="showCheckbox && tagLengthComp > 1" class="inputSuffix"
- v-text="'+' + tagLengthComp"></span>
- <i v-if="inputValue != '' && clearable && !disabled" class="a-icon-circle-close" @click="clearValue"
- style="margin-left: 5px;cursor:pointer"></i>
- </span>
- </a-input>
- </a-popover>
- </div>
- </template>
- <script lang="jsx">
- import { queryCategoryType } from '@/api/public/flowable'
- import { getDepartmentTree } from '@/api/common'
- import { ComDepartSobTreeController } from '@/api/department'
- import { getUserNo } from '@/utils/auth'
- import { isEmpty } from '@/utils/validate'
- import { message } from 'ant-design-vue'
- export default {
- name: 'ProSelectTree',
- props: {
- /* 配置项 */
- props: {
- type: Object,
- default: () => {
- return {
- // value: 'id', // ID字段名
- // label: 'title', // 显示名称
- key: 'id', // ID字段名
- title: 'name', // 显示名称
- children: 'children' // 子级字段名
- }
- }
- },
- /* 选项列表数据(树形结构的对象数组) */
- options: {
- type: Array,
- default: () => { return [] }
- },
- /* 初始值 */
- value: {
- type: [String, Array],
- default: () => { return [] }
- },
- /* 可清空选项 */
- clearable: {
- type: Boolean,
- default: () => { return true }
- },
- /* 自动收起 */
- accordion: {
- type: Boolean,
- default: () => { return false }
- },
- disabled: {
- type: Boolean,
- default: () => { return false }
- },
- showCheckbox: Boolean,
- /* 排除的节点(不展示) */
- excludeNode: {
- type: Array,
- default: () => { return [] }
- },
- /* 禁用的节点(不可选中) */
- disabledNode: {
- type: Array,
- default: () => ([])
- },
- /* 禁用节点选中状态(true将一直被选中,false将一直不可选中) */
- disabledNodeSts: {
- type: Boolean,
- default: () => true
- },
- size: {
- type: String,
- default: () => { return "default" }
- },
- //默认展开的层级
- expandTier: {
- type: [String, Number],
- default: () => 1,
- },
- //是否添加数据权限
- hasDataLevel: {
- type: Boolean,
- default: () => true
- },
- //过滤时的节点名
- filterNodeName: {
- type: String,
- default: 'nodeName'
- },
- },
- data () {
- return {
- valueId: this.value, // 初始值
- valueTitle: '',
- defaultExpandedKey: [],
- dataOptions: [], //树形数据
- dataList: [], //列表数据
- loading: false,
- visiable: false,
- props: {
- title: 'name',
- key: 'id',
- children: 'children'
- }
- }
- },
- mounted () {
- console.log("xxx mounted", this.$attrs);
- //处理下拉数据
- this.dealData()
- },
- methods: {
- //---------暴露给父组件的方法-------------
- //设置数据源
- loadData (data) {
- this.dataOptions = data
- },
- //---------------------------------------
- // 初始化值
- initHandle () {
- let that = this
- // 这里要延迟执行,否则有BUG
- setTimeout(function () {
- if (that.valueId) {
- if (that.showCheckbox || that.valueId instanceof Array) {
- //根据默认值自动选中子节点
- if (!(that.$attrs["cascadeType"] === 'noneCascade' || that.$attrs["cascadeType"] === 'settableCascade' || that.$attrs["check-strictly"])) {
- if (that.showCheckbox && that.valueId.length == 1) {
- //被选中keys
- let checkedKeys = []
- let node = that.getNodeByKey(that.dataOptions, that.valueId[0])
- //当前节点的孩子节点
- that.getChildrenKeys(node, checkedKeys)
- if (checkedKeys.length > 1) {
- //修改变量值,如果在表格中自动触发表格查询方法
- that.$emit('input', checkedKeys, true)
- }
- }
- }
- that.$refs.selectTree?.getOrignRef()?.setCheckedKeys(that.valueId)
- } else {
- that.valueTitle = that.$refs.selectTree?.getOrignRef()?.getNode(that.valueId)?.data[that.props.name] // 初始化显示
- that.$refs.selectTree?.getOrignRef()?.setCurrentKey(that.valueId) // 设置默认选中
- that.defaultExpandedKey = [that.valueId] // 设置默认展开
- }
- } else {
- that.valueTitle = null // 初始化显示
- that.$refs.selectTree?.getOrignRef()?.setCurrentKey([]) // 设置默认选中
- }
- }, 400)
- this.$nextTick(() => {
- let scrollWrap = document.querySelectorAll('.dhc-select-tree_popover .el-scrollbar .el-select-dropdown__wrap')[0]
- let scrollBar = document.querySelectorAll('.dhc-select-tree_popover .el-scrollbar .el-scrollbar__bar')
- if (scrollWrap) {
- scrollWrap.style.cssText = 'margin: 0px; max-height: none; overflow: hidden;'
- }
- if (Array.isArray(scrollBar)) {
- scrollBar.forEach(ele => ele.style.width = 0)
- }
- })
-
- },
- //处理下拉数据
- dealData () {
- //处理下拉数据
- console.log("xxxdealData", this.options);
- const { options, type, url } = this.$attrs
- if (options || !isEmpty(this.options)) {
- this.dataOptions = options || this.options
- console.log("xxxdataOptions", this.dataOptions);
- } else {
- if (type == 'sob_tree') {
- this.getDepartmentTree("sobTree")
- } else if (type == 'tree') {
- this.searchTreeData()
- }
- }
- },
- // 切换选项
- handleNodeClick (data, node) {
- if (this.$attrs.type === 'sob_tree' && data[0] == '2@') {
- message.error('只能选择账套信息!');
- this.valueId = []
- node.searchName = this.props.key
- // const { onUpdateSearchParam } = this.$attrs
- // onUpdateSearchParam([], node)
- return
- } else if (this.$attrs.type === 'sob_tree') {
- this.visiable = false
- this.valueTitle = node[this.props.title]
- this.valueId.push(node[this.props.key])
- this.defaultExpandedKey = []
- // const { updateSearchParam, searchName } = this.$attrs
- // node.searchName = searchName
- // updateSearchParam(data, node)
- }
-
- },
- handleCheckChange (data, checked, indeterminate) {
- this.$emit('check-change', data, checked, indeterminate)
- },
- /**
- * 当复选框被点击的时候触发
- * @param {*} data
- * @param {*} node
- */
- check (data, node) {
- let { checkedKeys } = node
- let disabledNode = this.disabledNode.filter(item => item != undefined)
- //处理禁用节点
- if (disabledNode.length > 0) {
- if (this.disabledNodeSts) {
- checkedKeys = Array.from(new Set([...checkedKeys, ...disabledNode]))
- } else {
- checkedKeys = checkedKeys.filter(item => disabledNode.indexOf(item) == -1)
- }
- }
- this.$emit('check', data, node)
- this.$emit('input', checkedKeys)
- },
- handlerCheck (values) {
- let value = values
- let disabledNode = this.disabledNode.filter(item => item != undefined)
- //处理禁用节点
- if (disabledNode.length > 0) {
- if (this.disabledNodeSts) {
- value = Array.from(new Set([...value, ...disabledNode]))
- } else {
- value = value.filter(item => disabledNode.indexOf(item) == -1)
- }
- }
- this.$emit('input', value)
- },
- // 清除选中
- clearHandle () {
- //处理禁用节点
- if (this.disabledNode.length > 0 && this.disabledNodeSts) {
- this.valueId = [...this.disabledNode]
- } else {
- this.valueId = this.showCheckbox == true ? [] : ''
- }
- this.valueTitle = ''
- this.defaultExpandedKey = []
- this.clearSelected()
- //this.$emit('getValue',null)
- this.$emit('input', this.valueId)
- },
- /* 清空选中样式 */
- clearSelected () {
- let allNode = document.querySelectorAll('#tree-option .el-tree-node')
- allNode.forEach((element) => element.classList.remove('is-current'))
- },
- //递归获取树型数据label
- getLabel (value, data) {
- for (let i = 0; i < data.length; i++) {
- if (data[i][this.props.key] == value) {
- console.log("xxxdata", data[i]);
- return data[i][this.props.title]
- } else if (data[i].children?.length > 0) {
- let resultValue = this.getLabel(value, data[i].children)
- if (resultValue && resultValue != '') {
- return resultValue
- }
- }
- }
- },
- //递归过滤非账务机构
- filterNotGather (data) {
- let indexs = []
- for (let i = 0; i < data.length; i++) {
- if (data[i].children) {
- data[i].children = this.filterNotGather(data[i].children)
- // data[i].disabled = true
- } else if (data[i].dcInd != 'Y') {
- indexs.push(i)
- }
- }
- if (indexs.length > 0) {
- data = data.filter((item, index) => indexs.indexOf(index) == -1)
- }
- return data
- },
- //递归删除排除的节点
- filterExcludeNode (data) {
- let indexs = []
- for (let i = 0; i < data.length; i++) {
- if (this.excludeNode.indexOf(data[i][this.props.key]) != -1) {
- indexs.push(i)
- } else if (data[i].children) {
- data[i].children = this.filterExcludeNode(data[i].children)
- }
- }
- if (indexs.length > 0) {
- data = data.filter((item, index) => indexs.indexOf(index) == -1)
- }
- return data
- },
- //递归添加禁用的节点
- filterDisabledNode (data) {
- for (let i = 0; i < data.length; i++) {
- data[i].disabled = false
- if (this.disabledNode.indexOf(data[i][this.props.key]) != -1) {
- data[i].disabled = true
- if (data[i].children?.length > 0) {
- data[i].children = this.filterDisabledNode(data[i].children)
- }
- } else if (data[i].children?.length > 0) {
- data[i].children = this.filterDisabledNode(data[i].children)
- }
- }
- return data
- },
- //加载数据源
- getDepartmentTree (treeName) {
- let that = this
- that.loading = true
- ComDepartSobTreeController(treeName).then(resp => {
- that.dataList = resp
- if (resp.length > 0) {
- const parentNodes = resp.filter(item => item.id.indexOf('@') != -1)
- parentNodes.forEach((item) => {
- item.title = item.name
- item.children = []
- })
- resp.forEach((item) => {
- if (item.id.indexOf('@') == -1) {
- parentNodes.forEach((parentNode) => {
- if (parentNode.id == item.pid) {
- item.title = item.name
- parentNode.children.push(item)
- }
- })
- }
- })
- //过滤掉删除状态的机构
- let data = that.filterByDepSts(parentNodes)
- that.dataOptions = data
- that.$emit("dataIsReady")
- //设置默认展开的层级
- //异步执行,否则prop的数据无法获取到
- setTimeout(() => {
- this.setDefaultExpandedKeys(data)
- }, 0)
- // that.$refs.selectTree?.getOrignRef()?.setCurrentKey(that.valueId)
- // this.initHandle()
- }
- }).finally(() => {
- that.loading = false
- })
- },
- searchTreeData () {
- let that = this
- that.loading = true
- },
- getMenuTree (treeName) {
- let that = this
- that.loading = true
- getDepartmentTree(`/sys/common/getTree`, {
- treeName: treeName,
- }).then(resp => {
- if (resp.success) {
- let data = resp.data
- //过滤界面和按钮
- data = that.filterMenuData(data)
- that.dataOptions = data
- this.initHandle()
- }
- }).finally(() => {
- that.loading = false
- })
- },
-
- categoryLoadTree () {
- let that = this
- that.loading = true
- queryCategoryType({ userNo: getUserNo() }).then(resp => {
- if (resp.success) {
- let data = resp.data
- //过滤界面和按钮
- data = that.filterMenuData(data)
- that.dataOptions = data
- this.initHandle()
- }
- }).finally(() => {
- that.loading = false
- })
- },
- //过滤界面和按钮
- filterMenuData (data) {
- let indexs = []
- for (let i = 0; i < data.length; i++) {
-
- if (data[i].children) {
- data[i].children = this.filterMenuData(data[i].children)
- } else if (data[i].interfaceType === 'I' || data[i].interfaceType === 'B') {
- indexs.push(i)
- }
- }
- if (indexs.length > 0) {
- data = data.filter((item, index) => indexs.indexOf(index) == -1)
- }
- return data
- },
- //过滤掉删除状态的机构
- filterByDepSts (data) {
- let indexs = []
- for (let i = 0; i < data.length; i++) {
- if (data[i].children) {
- data[i].children = this.filterByDepSts(data[i].children)
- } else if (data[i].depSts == '*') {
- indexs.push(i)
- }
- }
- if (indexs.length > 0) {
- data = data.filter((item, index) => indexs.indexOf(index) == -1)
- }
- return data
- },
- //清除下拉值
- clearValue () {
- this.clearHandle()
- },
- setDefaultExpandedKeys (data) {
- let that = this
- let { expandTier } = this
- if (expandTier > 0) {
- let defaultExpandedKey = []
- that.getDataTier(data, 0, defaultExpandedKey, expandTier)
- that.defaultExpandedKey = defaultExpandedKey
- } else {
- that.defaultExpandedKey = []
- }
- },
- /**
- * 根据设置层级返回要展开的keys
- * @param {*} data 数据源
- * @param {*} expandTierFlag 递归次数
- * @param {*} dataTier 层级
- * @param {*} expandTier 返回的展开keys
- */
- getDataTier (data, expandTierFlag, dataTier, expandTier) {
- for (let i = 0, len = data.length; i < len; i++) {
- dataTier.push(data[i][this.props.key])
- }
- expandTierFlag++
- if (expandTierFlag >= expandTier) {
- return
- } else {
- for (let i = 0, len = data.length; i < len; i++) {
- if (data[i].children && data[i].children.length > 0) {
- this.getDataTier(data[i].children, expandTierFlag, dataTier, expandTier)
- }
- }
- }
- },
- /**
- * 根据key获取指定节点的详细数据
- * @param {*} data 数据源
- * @param {*} key 要查询的节点key
- */
- getNodeByKey (data, key) {
- for (let i = 0; i < data.length; i++) {
- let item = data[i]
- if (item[this.props.key] == key) {
- return item;
- } else if (item.children?.length > 0) {
- let result = this.getNodeByKey(item.children, key);
- if (result) {
- return result;
- }
- }
- }
- },
- //获取子节点的keys
- getChildrenKeys (data, childrenKeys) {
- const _this = this;
- if (data?.children?.length > 0) {
- childrenKeys.push(data[this.props.key])
- data.children.forEach(item => {
- _this.getChildrenKeys(item, childrenKeys)
- })
- } else {
- childrenKeys.push(data[this.props.key])
- }
- },
- },
- computed: {
- inputValue () {
- if (Array.isArray(this.valueId)) {
- if (this.valueId.length > 0) {
- return this.getLabel(this.valueId[0], this.dataOptions)
- // if(this.valueId.length == 1){
- // return label
- // }else{
- // return label + " +" + (this.valueId.length - 1);
- // }
- }
- return ""
- } else {
- let value = ''
- value = this.getLabel(this.valueId, this.dataOptions)
- return value ? value : ''
- }
- },
-
- tagLengthComp () {
- if (Array.isArray(this.valueId)) {
- return this.valueId.length
- }
- return this.valueId ? this.valueId.split(',').length : 0
- }
- },
- watch: {
- value () {
- this.valueId = this.value
- // this.initHandle()
- },
- excludeNode (newValue, oldValue) {
- //比较数组内容是否相等
- if (newValue.toString() !== oldValue.toString()) {
- this.dealData()
- }
- },
- disabledNode (newValue) {
- //处理禁用的节点
- if (newValue.length > 0) {
- this.dataOptions = this.filterDisabledNode(this.dataOptions)
- }
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- // @import '@/styles/element-variables.scss';
-
- // .el-scrollbar .el-scrollbar__view .el-select-dropdown__item {
- // height: auto;
- // max-height: 274px;
- // padding: 0;
- // overflow: hidden;
- // overflow-y: auto;
- // }
-
- // .el-select-dropdown__item.selected {
- // font-weight: normal;
- // }
-
- // ul li>>>.el-tree .el-tree-node__content {
- // height: auto;
- // padding: 0 20px;
- // }
-
- // .el-tree-node__label {
- // font-weight: normal;
- // }
-
- // .el-tree>>>.is-current .el-tree-node__label {
- // color: $--color-primary;
- // font-weight: 700;
- // }
-
- // .el-tree>>>.is-current .el-tree-node__children .el-tree-node__label {
- // color: #606266;
- // font-weight: normal;
- // }
-
- // #tree-option {
- // margin-top: 10px;
- // }
-
- .inputSuffix {
- background-color: white;
- color: rgb(24, 144, 255);
- border: 1px solid rgb(220, 223, 230);
- border-radius: 5px;
- padding: 4px 8px;
- }
- </style>
|