123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724 |
- <template>
- <span>
- <!-- 选择部门 -->
- <a-select
- v-model="depvalue"
- :options="depOptions"
- :class="$style.depselect"
- @change="changedep"
- >
- </a-select>
- <a-spin ref="scroll" :spinning="false" :class="$style.spin">
- <a-empty v-if="empty" />
- <a-dropdown
- v-else
- v-model="showMenu"
- :get-popup-container="() => this.$refs.scroll.$el"
- :trigger="['contextmenu']"
- :disabled="single"
- @visibleChange="menuVisibleChange"
- >
- <div>
- <a-tree
- :key="key"
- ref="auditMattersTree"
- v-model="checkedKeys"
- :show-icon="true"
- :show-line="true"
- :check-strictly="true"
- :checkable="checkable"
- :draggable="draggable"
- :tree-data="treeData"
- :replace-fields="replaceFields"
- :selected-keys="defaultSelectedKeys"
- :expanded-keys="expandedKeys"
- :default-expanded-keys="defaultTreeExpandedKeys"
- :load-data="onLoadData"
- @click.native="treeClickNative"
- @select="treeSelect"
- @check="treeCheck"
- @rightClick="treeRightClick"
- @contextmenu.native.capture="treeRightClickNative"
- @expand="onExpand"
- >
- <!-- 如果已配置负责人,则展示用户图标 -->
- <template slot="showMatters" slot-scope="item">
- <a-icon type="file-ppt" @click="showMatters(item)" />
- </template>
- </a-tree>
- </div>
- <a-menu slot="overlay" @click="menuClick">
- <a-menu-item key="1" :disabled="!selectedNodeHasSelectableChild">
- <a-icon type="check" />选中下一级节点
- </a-menu-item>
- <a-menu-item key="2" :disabled="!selectedNodeHasSelectableChild">
- <a-icon type="close" />取消下一级节点
- </a-menu-item>
- </a-menu>
- </a-dropdown>
- </a-spin>
- </span>
- </template>
- <script>
- import { getUserInfo } from '@/common/store-mixin'
- import auditMattersTreeService from './audit-matters-tree-service'
- import components from './_import-components/audit-matters-tree-import'
- // 判断是否已经选择
- function isChecked(selectedKeys, eventKey) {
- return selectedKeys.indexOf(eventKey) === -1
- }
- export default {
- name: 'AuditMattersTree',
- metaInfo: {
- title: 'AuditMattersTree',
- },
- components,
- props: {
- // 默认选中节点
- selectedKeys: {
- type: Array,
- default: function() {
- return []
- },
- },
- // 是否显示复选框
- checkable: {
- type: Boolean,
- default: true,
- },
- // 是否可以拖拽
- draggable: {
- type: Boolean,
- default: false,
- },
- // 是否显示连线
- showLine: {
- type: Boolean,
- default: false,
- },
- // 根节点名称
- topNodeText: {
- type: String,
- default: '根节点',
- },
- // 地址树接口数据源
- treeparams: {
- type: Object,
- default: () => {
- return {}
- },
- },
- // 默认展开节点id
- defaultExpandedKeys: {
- type: Array,
- default: () => {
- return ['0']
- },
- },
- // 是否显示隐藏按钮
- showPrimary: {
- type: Boolean,
- default: true,
- },
- // 地址树是否单选
- single: {
- type: Boolean,
- default: false,
- },
- refreshKey: {
- type: Number,
- default: 0,
- },
- treeDataType: {
- type: String,
- default: '',
- },
- /**
- * 是否是审计框架拷贝事项
- */
- isFrameCopy: {
- type: Boolean,
- default: false,
- },
- // frameId
- frameId: {
- type: Number,
- default: -1,
- },
- },
- data() {
- return {
- treeData: [],
- defaultTreeExpandedKeys: ['0'],
- defaultSelectedKeys: ['0'],
- checkedKeys: {
- checked: [],
- halfChecked: [],
- }, // 选中的节点数据
- dataList: [], // 数组dataList,搜索要用
- spinning: true,
- empty: false,
- icontype: 'left',
- fold: false,
- replaceFields: {
- title: 'text',
- key: 'id',
- },
- openId: [], // 已经打开过的id
- expandedKeys: ['0'],
- backupsExpandedKeys: [],
- autoExpandParent: false,
- defaultTopNodeText: '根节点',
- defaultTopNodeId: '0',
- key: 0,
- newtree: [],
- depOptions: [], // 部门下拉框列表值
- edit: true, // 当前节点是否可编辑
- depvalue: [], // 选择的组织数据
- selectedNode: undefined,
- showMenu: false,
- setAllChecking: false,
- }
- },
- computed: {
- selectedNodeHasSelectableChild() {
- return this.selectedNode?.dataRef.children?.some((item) => !item.disabled)
- },
- },
- created() {
- // 如果有默认展开节点,则赋值
- if (this.defaultExpandedKeys) {
- this.defaultTreeExpandedKeys = [...this.defaultExpandedKeys]
- }
- // 如果有传根节点名称,则赋值
- if (this.topNodeText) {
- this.defaultTopNodeText = this.topNodeText
- }
- // 如果有传默认选中节点,则赋值
- if (this.selectedKeys.length > 0) {
- this.defaultSelectedKeys = [...this.selectedKeys]
- }
- // this.initTreeData()
- this.initDeptList('iamAuditMatters')
- },
- methods: {
- treeRightClickNative(evt) {
- // 右键如果没有点击到树节点,不触发右键菜单
- if (this.single) return
- if (evt.target.nodeName !== 'SPAN') evt.stopPropagation()
- },
- treeClickNative() {
- // 点击树的其他区域,隐藏菜单
- if (this.single) return
- this.hideContextMemu()
- },
- menuClick(menu) {
- this.selectedNode.dataRef.children?.forEach((item) => {
- if (!item.disabled) this.itemSelect(item.id, menu.key === '1')
- })
- this.hideContextMemu()
- },
- itemSelect(key, checked) {
- if (checked) {
- if (!this.checkedKeys.checked.includes(key)) {
- this.checkedKeys.checked.push(key)
- }
- } else {
- this.checkedKeys.checked.splice(this.checkedKeys.checked.indexOf(key), 1)
- }
- },
- hideContextMemu() {
- this.showMenu = false
- this.menuVisibleChange(false)
- },
- menuVisibleChange(visible) {
- if (!visible) this.selectedNode = undefined
- },
- treeRightClick({ node }) {
- // 记录当前点击的节点
- if (this.single) return
- this.selectedNode = node
- },
- // 初始化部门下拉 分级授权获取部门下拉列表 维护权限
- initDeptList(formId) {
- auditMattersTreeService.getManagedHierarchyOrg(formId).then((res) => {
- res.data.editNodes.forEach((item) => {
- this.depOptions.push({
- label: item.text,
- value: item.id,
- text: item.text,
- edit: true,
- })
- })
- // 取编辑和查看节点并集
- res.data.viewNodes.forEach((item, index) => {
- const node = this.depOptions.find((nodeinfo) => {
- return nodeinfo.value === item.id
- })
- if (!node) {
- this.depOptions.push({
- label: item.text,
- value: item.id,
- text: item.text,
- edit: false,
- })
- }
- })
- // 部门下拉框列表值赋值
- if (this.depOptions.length > 0) {
- this.depvalue = this.depOptions[0].value
- // 加载默认值
- this.defaultTopNodeId = this.depOptions[0].value
- this.defaultTopNodeText = this.depOptions[0].text + this.topNodeText
- this.defaultTreeExpandedKeys = [this.depOptions[0].value]
- this.defaultSelectedKeys = [this.depOptions[0].value]
- this.edit = this.depOptions[0].edit
- this.initTreeData(this.depOptions[0].value)
- } else {
- this.defaultTopNodeId = null
- this.defaultTopNodeText = null
- this.defaultTreeExpandedKeys = []
- this.defaultSelectedKeys = []
- this.spinning = false
- this.empty = true
- }
- })
- },
- setIsItem(data) {
- for (let i = 0; i < data.length; i++) {
- const node = data[i]
- const props = node.props
- if (node.isLeaf !== true && !this.isFrameCopy) {
- node.disabled = true
- }
- // 用来判断此几点是否已经配置了用户,需要后台返回标识位进行判断
- if (props && props.isItem) {
- data[i].scopedSlots.icon = 'showMatters'
- if (!data[i].id.toString().includes('-item')) {
- data[i].id = data[i].id + '-item'
- }
- }
- if (node.children) {
- this.setIsItem(node.children)
- }
- }
- },
- /**
- * 显示事项
- */
- showMatters(item) {
- this.$emit('showMatters', item)
- },
- // 选中当前节点下的所有节点
- checkAllNode(nodeinfo, checked) {
- if (nodeinfo.children) {
- nodeinfo.children.forEach((node) => {
- if (checked) {
- if (isChecked(this.checkedKeys.checked, node.id)) {
- this.checkedKeys.checked.push(node.id)
- }
- } else {
- if (this.checkedKeys.checked.indexOf(node.id) !== -1) {
- this.checkedKeys.checked.splice(this.checkedKeys.checked.indexOf(node.id), 1)
- }
- }
- // 下级节点也要处理
- if (node.children) {
- this.checkAllNode(node, checked)
- }
- })
- }
- },
- /***
- * 选中复选框时的事件
- */
- treeCheck(allKeys, echecked) {
- // echecked.checkedNodes 选中的所有节点信息为数组 .data.props 获取详细信息
- // echecked.node.dataRef 当前选中的节点信息
- if (this.single) {
- this.checkedKeys.checked = []
- this.checkedKeys.checked = [echecked.node.dataRef.id]
- }
- // 勾选复选框,则直接获取下级数据
- if (this.checkedKeys.checked.includes(echecked.node.dataRef.id)) {
- // 如果是事项,则不取下级
- if (echecked.node.dataRef.props.isItem) return
- this.$emit('checking', true)
- auditMattersTreeService
- .getAllNodeInfo(echecked.node.dataRef.id, this.frameId)
- .then((res) => {
- this.onCheckedLoadData(echecked.node, res.data.children)
- })
- .catch(() => {})
- }
- // 判断当前节点是否选中,选中的话,就把下级节点也一并选中,否则都去掉
- if (allKeys.checked.includes(echecked.node.dataRef.id)) {
- this.checkAllNode(echecked.node.dataRef, true)
- } else {
- this.checkAllNode(echecked.node.dataRef, false)
- }
- this.$emit('checkedKeys', echecked.node.dataRef, echecked.checkedNodes)
- },
- // 点击树
- treeSelect(selectedKeys, info) {
- this.defaultSelectedKeys = selectedKeys
- if (this.single) {
- this.checkedKeys = []
- this.checkedKeys = [info.node.dataRef.id]
- } else {
- if (isChecked(this.checkedKeys.checked, info.node.dataRef.id)) {
- this.checkedKeys.checked.push(info.node.dataRef.id)
- } else {
- this.checkedKeys.checked.splice(this.checkedKeys.checked.indexOf(info.node.dataRef.id), 1)
- }
- this.checkedKeys.checked = [...new Set(this.checkedKeys.checked)]
- }
- // 判断当前节点是否选中,选中的话,就把下级节点也一并选中,否则都去掉
- if (this.checkedKeys.checked.includes(info.node.dataRef.id)) {
- this.checkAllNode(info.node.dataRef, true)
- } else {
- this.checkAllNode(info.node.dataRef, false)
- }
- this.$emit('treeSelect', [...selectedKeys, ...this.checkedKeys.checked], info)
- },
- transformData(data) {
- return data.map((d) => {
- const { children, ...rest } = d
- return {
- ...rest,
- scopedSlots: { title: 'title' },
- children: children && this.transformData(children),
- }
- })
- },
- mmTree() {
- Object.assign(this.newtree, this.treeData)
- this.bindTree(this.newtree[0])
- this.getTree(this.newtree[0])
- },
- getTree(node) {
- const removeIndex = []
- node.id = (node.id + '').replace(/-item/g, '')
- node.children.forEach((item, index) => {
- if (item.hidden === true) {
- removeIndex.push(index)
- } else {
- if (item.children) {
- this.getTree(item)
- } else {
- item.id = (item.id + '').replace(/-item/g, '')
- item.children = []
- }
- }
- })
- if (node.children === null) {
- node.children = []
- } // 删除元素
- removeIndex.forEach((oneindex, index) => {
- node.children.splice(oneindex - index, 1)
- })
- },
- // 判断当前树需要展示的节点信息
- bindTree(nodeinfo) {
- const checklist = this.checkedKeys.checked
- nodeinfo.disabled = false
- if (nodeinfo.children) {
- this.bindTree(nodeinfo.children)
- const hiddenItem = nodeinfo.children.find((item, index) => {
- return item.hidden !== true
- })
- // 判断当前进节点是否隐藏
- if (!hiddenItem && checklist.indexOf(nodeinfo.id) === -1) {
- nodeinfo.hidden = true
- }
- // 如果显示但是没有在选择列表,则不可选中
- if (!nodeinfo.hidden && checklist.indexOf(nodeinfo.id) === -1) {
- nodeinfo.disabled = true
- }
- } else {
- nodeinfo.forEach((node, nodeindex) => {
- if (node.children) {
- // 判断子节点是否有选中的节点
- this.bindTree(node.children)
- const hiddenItem = node.children.find((item, index) => {
- return item.hidden !== true
- })
- // 判断当前进节点是否隐藏
- if (!hiddenItem && checklist.indexOf(node.id) === -1) {
- node.hidden = true
- }
- // 如果显示但是没有在选择列表,则不可选中
- if (!node.hidden && checklist.indexOf(node.id) === -1) {
- node.disabled = true
- }
- } else {
- if (checklist.indexOf(node.id) === -1) {
- node.hidden = true
- }
- // 如果显示但是没有在选择列表,则不可选中
- if (!node.hidden && checklist.indexOf(node.id) === -1) {
- node.disabled = true
- }
- }
- })
- }
- },
- onExpand(expandedKeys) {
- // 用户点击展开时,取消自动展开效果
- this.expandedKeys = expandedKeys
- this.autoExpandParent = false
- },
- // 点击地址树展开时调用
- onLoadData(treeNode) {
- const id = parseInt(treeNode.dataRef.id)
- if (!this.openId.includes(id)) {
- this.openId.push(id)
- }
- const orgId = this.depvalue
- return auditMattersTreeService
- .findIamAuditMattersTree(orgId, id, this.treeDataType)
- .then((res) => {
- if (res.data !== null) {
- // 没有打开过的节点,才进行赋值
- if (
- (treeNode.dataRef.children === null) |
- (treeNode.dataRef.children === undefined) |
- (treeNode.dataRef.children?.length === 0)
- ) {
- treeNode.dataRef.children = res.data
- }
- }
- // 如果根节点是选中状态,则展开式将下级节点也选中
- if (this.checkedKeys.checked.includes(id)) {
- res.data
- .map((item) => {
- if (item.props.isItem) return item.id + '-item'
- return item.id
- })
- .forEach((id) => {
- if (!this.checkedKeys.checked.includes(id)) {
- this.checkedKeys.checked.push(id)
- }
- })
- }
- this.treeData = this.transformData([...this.treeData])
- this.setIsItem(this.treeData)
- })
- },
- // 点击地址树前复选框时候调用
- onCheckedLoadData(treeNode, children) {
- const id = parseInt(treeNode.dataRef.id)
- if (!this.openId.includes(id)) {
- this.openId.push(id)
- }
- if (children !== null) {
- treeNode.dataRef.children = [...children]
- }
- // 如果根节点是选中状态,则将下级节点也选中
- if (this.checkedKeys.checked.includes(id)) {
- this.transformCheckData(children)
- setTimeout(() => {
- this.$emit('checking', false)
- }, 1000)
- }
- this.treeData = this.transformData([...this.treeData])
- this.setIsItem(this.treeData)
- },
- transformCheckData(data) {
- data = data || []
- data.forEach((d) => {
- const checkid = this.checkedKeys.checked
- if (!checkid.includes(d.id)) {
- if (d.props.isItem) {
- this.checkedKeys.checked.push(d.id + '-item')
- } else {
- this.checkedKeys.checked.push(d.id)
- }
- }
- const { children } = d
- this.transformCheckData(children)
- })
- },
- // 初始化地址树
- initTreeData(depId) {
- const topDepId = depId === null ? 0 : depId
- auditMattersTreeService
- .findIamAuditMattersTree(topDepId, topDepId, this.treeDataType)
- .then((res) => {
- // this.mmInitTreeData(res)
- this.spinning = false
- const treeNode = [
- {
- id: this.defaultTopNodeId,
- text: this.defaultTopNodeText,
- isLeaf: false,
- props: {},
- children: [],
- key: this.defaultTopNodeId,
- disabled: this.isFrameCopy,
- },
- ]
- if (res.data.length) {
- treeNode.children = res.data
- }
- this.treeData = this.transformData(treeNode)
- this.setIsItem(this.treeData)
- this.expandedKeys = this.defaultTreeExpandedKeys
- this.empty = false
- this.$emit('checking', false)
- })
- },
- mmInitTreeData(res) {
- this.spinning = false
- if (res.data.length) {
- this.treeData = this.transformData(res.data)
- // this.expandedKeys = this.defaultTreeExpandedKeys
- this.expandedKeys = [res.data[0].id]
- this.empty = false
- } else {
- this.empty = true
- }
- },
- // 刷新树方法
- refreshTree() {
- this.key++
- },
- // 组织下拉框change时触发
- changedep(value, option) {
- this.key++
- this.defaultTreeExpandedKeys = [value]
- this.defaultSelectedKeys = [value]
- this.defaultTopNodeId = value
- this.defaultTopNodeText = option.data.props.text + this.topNodeText
- this.initTreeData(value)
- },
- },
- }
- </script>
- <style module lang="scss">
- @use '@/common/design' as *;
- .depselect {
- width: 200px;
- }
- .spin {
- width: 100%;
- line-height: 30;
- }
- .ywlxtree {
- :global(.ant-tree-title) {
- display: inline-block;
- width: 100%;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
- :global(.ant-input-search) {
- margin: 8px 0;
- overflow: hidden;
- }
- .active {
- color: $primary-color;
- }
- :global(.ant-select) {
- width: 100%;
- overflow: hidden;
- }
- }
- .treewrap {
- position: relative;
- display: flex;
- flex-direction: column;
- width: 20%;
- min-height: 100%;
- margin-right: $padding-lg;
- transition: width 0.2s;
- .fold {
- position: absolute;
- top: calc(50% - 30px);
- right: -15px;
- z-index: 2;
- width: 15px;
- height: 75px;
- padding: 0;
- border-radius: 0 10px 10px 0;
- }
- :global(.ant-tree) {
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
- :global(.ant-card-body) {
- background: $white;
- }
- }
- .collapse {
- width: 0;
- :global(.ant-card-body) {
- background: transparent;
- :global(.ant-empty) {
- display: none;
- }
- }
- }
- // 单选样式
- .single {
- :global .ant-tree-checkbox {
- .ant-tree-checkbox-inner {
- border-radius: 100px;
- &::after {
- position: absolute;
- top: 3px;
- left: 3px;
- display: table;
- width: 8px;
- height: 8px;
- content: ' ';
- background-color: $primary-color;
- border: 0;
- border-radius: 8px;
- opacity: 0;
- transition: all 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
- transform: scale(0);
- }
- }
- &.ant-tree-checkbox-checked {
- &::after {
- position: absolute;
- top: 16.67%;
- left: 0;
- width: 100%;
- height: 66.67%;
- content: '';
- border: 1px solid #1890ff;
- border-radius: 50%;
- animation: antRadioEffect 0.36s ease-in-out;
- animation-fill-mode: both;
- }
- .ant-tree-checkbox-inner {
- background-color: $white;
- &::after {
- opacity: 1;
- transition: all 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
- transform: scale(1);
- }
- }
- }
- }
- }
- </style>
|