audit-matters-tree.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724
  1. <template>
  2. <span>
  3. <!-- 选择部门 -->
  4. <a-select
  5. v-model="depvalue"
  6. :options="depOptions"
  7. :class="$style.depselect"
  8. @change="changedep"
  9. >
  10. </a-select>
  11. <a-spin ref="scroll" :spinning="false" :class="$style.spin">
  12. <a-empty v-if="empty" />
  13. <a-dropdown
  14. v-else
  15. v-model="showMenu"
  16. :get-popup-container="() => this.$refs.scroll.$el"
  17. :trigger="['contextmenu']"
  18. :disabled="single"
  19. @visibleChange="menuVisibleChange"
  20. >
  21. <div>
  22. <a-tree
  23. :key="key"
  24. ref="auditMattersTree"
  25. v-model="checkedKeys"
  26. :show-icon="true"
  27. :show-line="true"
  28. :check-strictly="true"
  29. :checkable="checkable"
  30. :draggable="draggable"
  31. :tree-data="treeData"
  32. :replace-fields="replaceFields"
  33. :selected-keys="defaultSelectedKeys"
  34. :expanded-keys="expandedKeys"
  35. :default-expanded-keys="defaultTreeExpandedKeys"
  36. :load-data="onLoadData"
  37. @click.native="treeClickNative"
  38. @select="treeSelect"
  39. @check="treeCheck"
  40. @rightClick="treeRightClick"
  41. @contextmenu.native.capture="treeRightClickNative"
  42. @expand="onExpand"
  43. >
  44. <!-- 如果已配置负责人,则展示用户图标 -->
  45. <template slot="showMatters" slot-scope="item">
  46. <a-icon type="file-ppt" @click="showMatters(item)" />
  47. </template>
  48. </a-tree>
  49. </div>
  50. <a-menu slot="overlay" @click="menuClick">
  51. <a-menu-item key="1" :disabled="!selectedNodeHasSelectableChild">
  52. <a-icon type="check" />选中下一级节点
  53. </a-menu-item>
  54. <a-menu-item key="2" :disabled="!selectedNodeHasSelectableChild">
  55. <a-icon type="close" />取消下一级节点
  56. </a-menu-item>
  57. </a-menu>
  58. </a-dropdown>
  59. </a-spin>
  60. </span>
  61. </template>
  62. <script>
  63. import { getUserInfo } from '@/common/store-mixin'
  64. import auditMattersTreeService from './audit-matters-tree-service'
  65. import components from './_import-components/audit-matters-tree-import'
  66. // 判断是否已经选择
  67. function isChecked(selectedKeys, eventKey) {
  68. return selectedKeys.indexOf(eventKey) === -1
  69. }
  70. export default {
  71. name: 'AuditMattersTree',
  72. metaInfo: {
  73. title: 'AuditMattersTree',
  74. },
  75. components,
  76. props: {
  77. // 默认选中节点
  78. selectedKeys: {
  79. type: Array,
  80. default: function() {
  81. return []
  82. },
  83. },
  84. // 是否显示复选框
  85. checkable: {
  86. type: Boolean,
  87. default: true,
  88. },
  89. // 是否可以拖拽
  90. draggable: {
  91. type: Boolean,
  92. default: false,
  93. },
  94. // 是否显示连线
  95. showLine: {
  96. type: Boolean,
  97. default: false,
  98. },
  99. // 根节点名称
  100. topNodeText: {
  101. type: String,
  102. default: '根节点',
  103. },
  104. // 地址树接口数据源
  105. treeparams: {
  106. type: Object,
  107. default: () => {
  108. return {}
  109. },
  110. },
  111. // 默认展开节点id
  112. defaultExpandedKeys: {
  113. type: Array,
  114. default: () => {
  115. return ['0']
  116. },
  117. },
  118. // 是否显示隐藏按钮
  119. showPrimary: {
  120. type: Boolean,
  121. default: true,
  122. },
  123. // 地址树是否单选
  124. single: {
  125. type: Boolean,
  126. default: false,
  127. },
  128. refreshKey: {
  129. type: Number,
  130. default: 0,
  131. },
  132. treeDataType: {
  133. type: String,
  134. default: '',
  135. },
  136. /**
  137. * 是否是审计框架拷贝事项
  138. */
  139. isFrameCopy: {
  140. type: Boolean,
  141. default: false,
  142. },
  143. // frameId
  144. frameId: {
  145. type: Number,
  146. default: -1,
  147. },
  148. },
  149. data() {
  150. return {
  151. treeData: [],
  152. defaultTreeExpandedKeys: ['0'],
  153. defaultSelectedKeys: ['0'],
  154. checkedKeys: {
  155. checked: [],
  156. halfChecked: [],
  157. }, // 选中的节点数据
  158. dataList: [], // 数组dataList,搜索要用
  159. spinning: true,
  160. empty: false,
  161. icontype: 'left',
  162. fold: false,
  163. replaceFields: {
  164. title: 'text',
  165. key: 'id',
  166. },
  167. openId: [], // 已经打开过的id
  168. expandedKeys: ['0'],
  169. backupsExpandedKeys: [],
  170. autoExpandParent: false,
  171. defaultTopNodeText: '根节点',
  172. defaultTopNodeId: '0',
  173. key: 0,
  174. newtree: [],
  175. depOptions: [], // 部门下拉框列表值
  176. edit: true, // 当前节点是否可编辑
  177. depvalue: [], // 选择的组织数据
  178. selectedNode: undefined,
  179. showMenu: false,
  180. setAllChecking: false,
  181. }
  182. },
  183. computed: {
  184. selectedNodeHasSelectableChild() {
  185. return this.selectedNode?.dataRef.children?.some((item) => !item.disabled)
  186. },
  187. },
  188. created() {
  189. // 如果有默认展开节点,则赋值
  190. if (this.defaultExpandedKeys) {
  191. this.defaultTreeExpandedKeys = [...this.defaultExpandedKeys]
  192. }
  193. // 如果有传根节点名称,则赋值
  194. if (this.topNodeText) {
  195. this.defaultTopNodeText = this.topNodeText
  196. }
  197. // 如果有传默认选中节点,则赋值
  198. if (this.selectedKeys.length > 0) {
  199. this.defaultSelectedKeys = [...this.selectedKeys]
  200. }
  201. // this.initTreeData()
  202. this.initDeptList('iamAuditMatters')
  203. },
  204. methods: {
  205. treeRightClickNative(evt) {
  206. // 右键如果没有点击到树节点,不触发右键菜单
  207. if (this.single) return
  208. if (evt.target.nodeName !== 'SPAN') evt.stopPropagation()
  209. },
  210. treeClickNative() {
  211. // 点击树的其他区域,隐藏菜单
  212. if (this.single) return
  213. this.hideContextMemu()
  214. },
  215. menuClick(menu) {
  216. this.selectedNode.dataRef.children?.forEach((item) => {
  217. if (!item.disabled) this.itemSelect(item.id, menu.key === '1')
  218. })
  219. this.hideContextMemu()
  220. },
  221. itemSelect(key, checked) {
  222. if (checked) {
  223. if (!this.checkedKeys.checked.includes(key)) {
  224. this.checkedKeys.checked.push(key)
  225. }
  226. } else {
  227. this.checkedKeys.checked.splice(this.checkedKeys.checked.indexOf(key), 1)
  228. }
  229. },
  230. hideContextMemu() {
  231. this.showMenu = false
  232. this.menuVisibleChange(false)
  233. },
  234. menuVisibleChange(visible) {
  235. if (!visible) this.selectedNode = undefined
  236. },
  237. treeRightClick({ node }) {
  238. // 记录当前点击的节点
  239. if (this.single) return
  240. this.selectedNode = node
  241. },
  242. // 初始化部门下拉 分级授权获取部门下拉列表 维护权限
  243. initDeptList(formId) {
  244. auditMattersTreeService.getManagedHierarchyOrg(formId).then((res) => {
  245. res.data.editNodes.forEach((item) => {
  246. this.depOptions.push({
  247. label: item.text,
  248. value: item.id,
  249. text: item.text,
  250. edit: true,
  251. })
  252. })
  253. // 取编辑和查看节点并集
  254. res.data.viewNodes.forEach((item, index) => {
  255. const node = this.depOptions.find((nodeinfo) => {
  256. return nodeinfo.value === item.id
  257. })
  258. if (!node) {
  259. this.depOptions.push({
  260. label: item.text,
  261. value: item.id,
  262. text: item.text,
  263. edit: false,
  264. })
  265. }
  266. })
  267. // 部门下拉框列表值赋值
  268. if (this.depOptions.length > 0) {
  269. this.depvalue = this.depOptions[0].value
  270. // 加载默认值
  271. this.defaultTopNodeId = this.depOptions[0].value
  272. this.defaultTopNodeText = this.depOptions[0].text + this.topNodeText
  273. this.defaultTreeExpandedKeys = [this.depOptions[0].value]
  274. this.defaultSelectedKeys = [this.depOptions[0].value]
  275. this.edit = this.depOptions[0].edit
  276. this.initTreeData(this.depOptions[0].value)
  277. } else {
  278. this.defaultTopNodeId = null
  279. this.defaultTopNodeText = null
  280. this.defaultTreeExpandedKeys = []
  281. this.defaultSelectedKeys = []
  282. this.spinning = false
  283. this.empty = true
  284. }
  285. })
  286. },
  287. setIsItem(data) {
  288. for (let i = 0; i < data.length; i++) {
  289. const node = data[i]
  290. const props = node.props
  291. if (node.isLeaf !== true && !this.isFrameCopy) {
  292. node.disabled = true
  293. }
  294. // 用来判断此几点是否已经配置了用户,需要后台返回标识位进行判断
  295. if (props && props.isItem) {
  296. data[i].scopedSlots.icon = 'showMatters'
  297. if (!data[i].id.toString().includes('-item')) {
  298. data[i].id = data[i].id + '-item'
  299. }
  300. }
  301. if (node.children) {
  302. this.setIsItem(node.children)
  303. }
  304. }
  305. },
  306. /**
  307. * 显示事项
  308. */
  309. showMatters(item) {
  310. this.$emit('showMatters', item)
  311. },
  312. // 选中当前节点下的所有节点
  313. checkAllNode(nodeinfo, checked) {
  314. if (nodeinfo.children) {
  315. nodeinfo.children.forEach((node) => {
  316. if (checked) {
  317. if (isChecked(this.checkedKeys.checked, node.id)) {
  318. this.checkedKeys.checked.push(node.id)
  319. }
  320. } else {
  321. if (this.checkedKeys.checked.indexOf(node.id) !== -1) {
  322. this.checkedKeys.checked.splice(this.checkedKeys.checked.indexOf(node.id), 1)
  323. }
  324. }
  325. // 下级节点也要处理
  326. if (node.children) {
  327. this.checkAllNode(node, checked)
  328. }
  329. })
  330. }
  331. },
  332. /***
  333. * 选中复选框时的事件
  334. */
  335. treeCheck(allKeys, echecked) {
  336. // echecked.checkedNodes 选中的所有节点信息为数组 .data.props 获取详细信息
  337. // echecked.node.dataRef 当前选中的节点信息
  338. if (this.single) {
  339. this.checkedKeys.checked = []
  340. this.checkedKeys.checked = [echecked.node.dataRef.id]
  341. }
  342. // 勾选复选框,则直接获取下级数据
  343. if (this.checkedKeys.checked.includes(echecked.node.dataRef.id)) {
  344. // 如果是事项,则不取下级
  345. if (echecked.node.dataRef.props.isItem) return
  346. this.$emit('checking', true)
  347. auditMattersTreeService
  348. .getAllNodeInfo(echecked.node.dataRef.id, this.frameId)
  349. .then((res) => {
  350. this.onCheckedLoadData(echecked.node, res.data.children)
  351. })
  352. .catch(() => {})
  353. }
  354. // 判断当前节点是否选中,选中的话,就把下级节点也一并选中,否则都去掉
  355. if (allKeys.checked.includes(echecked.node.dataRef.id)) {
  356. this.checkAllNode(echecked.node.dataRef, true)
  357. } else {
  358. this.checkAllNode(echecked.node.dataRef, false)
  359. }
  360. this.$emit('checkedKeys', echecked.node.dataRef, echecked.checkedNodes)
  361. },
  362. // 点击树
  363. treeSelect(selectedKeys, info) {
  364. this.defaultSelectedKeys = selectedKeys
  365. if (this.single) {
  366. this.checkedKeys = []
  367. this.checkedKeys = [info.node.dataRef.id]
  368. } else {
  369. if (isChecked(this.checkedKeys.checked, info.node.dataRef.id)) {
  370. this.checkedKeys.checked.push(info.node.dataRef.id)
  371. } else {
  372. this.checkedKeys.checked.splice(this.checkedKeys.checked.indexOf(info.node.dataRef.id), 1)
  373. }
  374. this.checkedKeys.checked = [...new Set(this.checkedKeys.checked)]
  375. }
  376. // 判断当前节点是否选中,选中的话,就把下级节点也一并选中,否则都去掉
  377. if (this.checkedKeys.checked.includes(info.node.dataRef.id)) {
  378. this.checkAllNode(info.node.dataRef, true)
  379. } else {
  380. this.checkAllNode(info.node.dataRef, false)
  381. }
  382. this.$emit('treeSelect', [...selectedKeys, ...this.checkedKeys.checked], info)
  383. },
  384. transformData(data) {
  385. return data.map((d) => {
  386. const { children, ...rest } = d
  387. return {
  388. ...rest,
  389. scopedSlots: { title: 'title' },
  390. children: children && this.transformData(children),
  391. }
  392. })
  393. },
  394. mmTree() {
  395. Object.assign(this.newtree, this.treeData)
  396. this.bindTree(this.newtree[0])
  397. this.getTree(this.newtree[0])
  398. },
  399. getTree(node) {
  400. const removeIndex = []
  401. node.id = (node.id + '').replace(/-item/g, '')
  402. node.children.forEach((item, index) => {
  403. if (item.hidden === true) {
  404. removeIndex.push(index)
  405. } else {
  406. if (item.children) {
  407. this.getTree(item)
  408. } else {
  409. item.id = (item.id + '').replace(/-item/g, '')
  410. item.children = []
  411. }
  412. }
  413. })
  414. if (node.children === null) {
  415. node.children = []
  416. } // 删除元素
  417. removeIndex.forEach((oneindex, index) => {
  418. node.children.splice(oneindex - index, 1)
  419. })
  420. },
  421. // 判断当前树需要展示的节点信息
  422. bindTree(nodeinfo) {
  423. const checklist = this.checkedKeys.checked
  424. nodeinfo.disabled = false
  425. if (nodeinfo.children) {
  426. this.bindTree(nodeinfo.children)
  427. const hiddenItem = nodeinfo.children.find((item, index) => {
  428. return item.hidden !== true
  429. })
  430. // 判断当前进节点是否隐藏
  431. if (!hiddenItem && checklist.indexOf(nodeinfo.id) === -1) {
  432. nodeinfo.hidden = true
  433. }
  434. // 如果显示但是没有在选择列表,则不可选中
  435. if (!nodeinfo.hidden && checklist.indexOf(nodeinfo.id) === -1) {
  436. nodeinfo.disabled = true
  437. }
  438. } else {
  439. nodeinfo.forEach((node, nodeindex) => {
  440. if (node.children) {
  441. // 判断子节点是否有选中的节点
  442. this.bindTree(node.children)
  443. const hiddenItem = node.children.find((item, index) => {
  444. return item.hidden !== true
  445. })
  446. // 判断当前进节点是否隐藏
  447. if (!hiddenItem && checklist.indexOf(node.id) === -1) {
  448. node.hidden = true
  449. }
  450. // 如果显示但是没有在选择列表,则不可选中
  451. if (!node.hidden && checklist.indexOf(node.id) === -1) {
  452. node.disabled = true
  453. }
  454. } else {
  455. if (checklist.indexOf(node.id) === -1) {
  456. node.hidden = true
  457. }
  458. // 如果显示但是没有在选择列表,则不可选中
  459. if (!node.hidden && checklist.indexOf(node.id) === -1) {
  460. node.disabled = true
  461. }
  462. }
  463. })
  464. }
  465. },
  466. onExpand(expandedKeys) {
  467. // 用户点击展开时,取消自动展开效果
  468. this.expandedKeys = expandedKeys
  469. this.autoExpandParent = false
  470. },
  471. // 点击地址树展开时调用
  472. onLoadData(treeNode) {
  473. const id = parseInt(treeNode.dataRef.id)
  474. if (!this.openId.includes(id)) {
  475. this.openId.push(id)
  476. }
  477. const orgId = this.depvalue
  478. return auditMattersTreeService
  479. .findIamAuditMattersTree(orgId, id, this.treeDataType)
  480. .then((res) => {
  481. if (res.data !== null) {
  482. // 没有打开过的节点,才进行赋值
  483. if (
  484. (treeNode.dataRef.children === null) |
  485. (treeNode.dataRef.children === undefined) |
  486. (treeNode.dataRef.children?.length === 0)
  487. ) {
  488. treeNode.dataRef.children = res.data
  489. }
  490. }
  491. // 如果根节点是选中状态,则展开式将下级节点也选中
  492. if (this.checkedKeys.checked.includes(id)) {
  493. res.data
  494. .map((item) => {
  495. if (item.props.isItem) return item.id + '-item'
  496. return item.id
  497. })
  498. .forEach((id) => {
  499. if (!this.checkedKeys.checked.includes(id)) {
  500. this.checkedKeys.checked.push(id)
  501. }
  502. })
  503. }
  504. this.treeData = this.transformData([...this.treeData])
  505. this.setIsItem(this.treeData)
  506. })
  507. },
  508. // 点击地址树前复选框时候调用
  509. onCheckedLoadData(treeNode, children) {
  510. const id = parseInt(treeNode.dataRef.id)
  511. if (!this.openId.includes(id)) {
  512. this.openId.push(id)
  513. }
  514. if (children !== null) {
  515. treeNode.dataRef.children = [...children]
  516. }
  517. // 如果根节点是选中状态,则将下级节点也选中
  518. if (this.checkedKeys.checked.includes(id)) {
  519. this.transformCheckData(children)
  520. setTimeout(() => {
  521. this.$emit('checking', false)
  522. }, 1000)
  523. }
  524. this.treeData = this.transformData([...this.treeData])
  525. this.setIsItem(this.treeData)
  526. },
  527. transformCheckData(data) {
  528. data = data || []
  529. data.forEach((d) => {
  530. const checkid = this.checkedKeys.checked
  531. if (!checkid.includes(d.id)) {
  532. if (d.props.isItem) {
  533. this.checkedKeys.checked.push(d.id + '-item')
  534. } else {
  535. this.checkedKeys.checked.push(d.id)
  536. }
  537. }
  538. const { children } = d
  539. this.transformCheckData(children)
  540. })
  541. },
  542. // 初始化地址树
  543. initTreeData(depId) {
  544. const topDepId = depId === null ? 0 : depId
  545. auditMattersTreeService
  546. .findIamAuditMattersTree(topDepId, topDepId, this.treeDataType)
  547. .then((res) => {
  548. // this.mmInitTreeData(res)
  549. this.spinning = false
  550. const treeNode = [
  551. {
  552. id: this.defaultTopNodeId,
  553. text: this.defaultTopNodeText,
  554. isLeaf: false,
  555. props: {},
  556. children: [],
  557. key: this.defaultTopNodeId,
  558. disabled: this.isFrameCopy,
  559. },
  560. ]
  561. if (res.data.length) {
  562. treeNode.children = res.data
  563. }
  564. this.treeData = this.transformData(treeNode)
  565. this.setIsItem(this.treeData)
  566. this.expandedKeys = this.defaultTreeExpandedKeys
  567. this.empty = false
  568. this.$emit('checking', false)
  569. })
  570. },
  571. mmInitTreeData(res) {
  572. this.spinning = false
  573. if (res.data.length) {
  574. this.treeData = this.transformData(res.data)
  575. // this.expandedKeys = this.defaultTreeExpandedKeys
  576. this.expandedKeys = [res.data[0].id]
  577. this.empty = false
  578. } else {
  579. this.empty = true
  580. }
  581. },
  582. // 刷新树方法
  583. refreshTree() {
  584. this.key++
  585. },
  586. // 组织下拉框change时触发
  587. changedep(value, option) {
  588. this.key++
  589. this.defaultTreeExpandedKeys = [value]
  590. this.defaultSelectedKeys = [value]
  591. this.defaultTopNodeId = value
  592. this.defaultTopNodeText = option.data.props.text + this.topNodeText
  593. this.initTreeData(value)
  594. },
  595. },
  596. }
  597. </script>
  598. <style module lang="scss">
  599. @use '@/common/design' as *;
  600. .depselect {
  601. width: 200px;
  602. }
  603. .spin {
  604. width: 100%;
  605. line-height: 30;
  606. }
  607. .ywlxtree {
  608. :global(.ant-tree-title) {
  609. display: inline-block;
  610. width: 100%;
  611. overflow: hidden;
  612. text-overflow: ellipsis;
  613. white-space: nowrap;
  614. }
  615. :global(.ant-input-search) {
  616. margin: 8px 0;
  617. overflow: hidden;
  618. }
  619. .active {
  620. color: $primary-color;
  621. }
  622. :global(.ant-select) {
  623. width: 100%;
  624. overflow: hidden;
  625. }
  626. }
  627. .treewrap {
  628. position: relative;
  629. display: flex;
  630. flex-direction: column;
  631. width: 20%;
  632. min-height: 100%;
  633. margin-right: $padding-lg;
  634. transition: width 0.2s;
  635. .fold {
  636. position: absolute;
  637. top: calc(50% - 30px);
  638. right: -15px;
  639. z-index: 2;
  640. width: 15px;
  641. height: 75px;
  642. padding: 0;
  643. border-radius: 0 10px 10px 0;
  644. }
  645. :global(.ant-tree) {
  646. overflow: hidden;
  647. text-overflow: ellipsis;
  648. white-space: nowrap;
  649. }
  650. :global(.ant-card-body) {
  651. background: $white;
  652. }
  653. }
  654. .collapse {
  655. width: 0;
  656. :global(.ant-card-body) {
  657. background: transparent;
  658. :global(.ant-empty) {
  659. display: none;
  660. }
  661. }
  662. }
  663. // 单选样式
  664. .single {
  665. :global .ant-tree-checkbox {
  666. .ant-tree-checkbox-inner {
  667. border-radius: 100px;
  668. &::after {
  669. position: absolute;
  670. top: 3px;
  671. left: 3px;
  672. display: table;
  673. width: 8px;
  674. height: 8px;
  675. content: ' ';
  676. background-color: $primary-color;
  677. border: 0;
  678. border-radius: 8px;
  679. opacity: 0;
  680. transition: all 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
  681. transform: scale(0);
  682. }
  683. }
  684. &.ant-tree-checkbox-checked {
  685. &::after {
  686. position: absolute;
  687. top: 16.67%;
  688. left: 0;
  689. width: 100%;
  690. height: 66.67%;
  691. content: '';
  692. border: 1px solid #1890ff;
  693. border-radius: 50%;
  694. animation: antRadioEffect 0.36s ease-in-out;
  695. animation-fill-mode: both;
  696. }
  697. .ant-tree-checkbox-inner {
  698. background-color: $white;
  699. &::after {
  700. opacity: 1;
  701. transition: all 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
  702. transform: scale(1);
  703. }
  704. }
  705. }
  706. }
  707. }
  708. </style>