audit-maintain-classify-tree.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757
  1. <template>
  2. <a-card
  3. :class="[
  4. $style.treewrap,
  5. $style.ywlxtree,
  6. { [$style.collapse]: fold, [$style.single]: single },
  7. ]"
  8. >
  9. <!-- 选择部门 -->
  10. <!-- <a-select v-show="isSelectDep" v-model="depvalue" :options="depOptions" @change="changedep">
  11. </a-select> -->
  12. <a-form-model>
  13. <a-form-model-item :label="null" prop="orgValue">
  14. <a-select
  15. v-model="allTreeDataKeys"
  16. show-search
  17. :filter-option="filterOption"
  18. @change="onSelectName"
  19. >
  20. <a-select-option v-for="item in allTreeData" :key="item.id" :value="item.id">
  21. {{ item.text }}
  22. </a-select-option>
  23. </a-select>
  24. </a-form-model-item>
  25. </a-form-model>
  26. <a-spin :spinning="spinning" :class="$style.spin" />
  27. <a-empty v-if="empty" />
  28. <a-tree
  29. v-else
  30. :key="key"
  31. ref="auditMaintainCatalogTree"
  32. v-model="checkedKeys"
  33. :block-node="false"
  34. :show-icon="true"
  35. :show-line="showLine"
  36. :check-strictly="true"
  37. :checkable="false"
  38. :draggable="draggable"
  39. :tree-data="treeData"
  40. :replace-fields="replaceFields"
  41. :selected-keys="defaultSelectedKeys"
  42. :expanded-keys="expandedKeys"
  43. :default-expanded-keys="defaultTreeExpandedKeys"
  44. :default-selected-keys="defaultSelectedKeys"
  45. @select="treeSelect"
  46. @check="treeCheck"
  47. @expand="onExpand"
  48. @drop="onDrop"
  49. >
  50. </a-tree>
  51. </a-card>
  52. </template>
  53. <script>
  54. import { Message } from 'ant-design-vue'
  55. import { getUserInfo } from '@/common/store-mixin'
  56. // import AuditGroupPicker from '../../components/picker/audit-group-picker.vue'
  57. import auditMaintainService from './audit-maintain-service'
  58. import components from './_import-components/audit-maintain-catalog-tree-import'
  59. export default {
  60. name: 'AuditMaintainClassifyTree',
  61. metaInfo: {
  62. title: 'AuditMaintainClassifyTree',
  63. },
  64. components: {
  65. ...components,
  66. // AuditGroupPicker,
  67. },
  68. props: {
  69. // 默认选中节点
  70. selectedKeys: {
  71. type: Array,
  72. default: function() {
  73. return []
  74. },
  75. },
  76. // 查看模式 manager维护权限 read查看权限
  77. managerType: {
  78. type: String,
  79. default: 'manager',
  80. },
  81. // 是否显示复选框
  82. checkable: {
  83. type: Boolean,
  84. default: true,
  85. },
  86. // 是否可以拖拽
  87. draggable: {
  88. type: Boolean,
  89. default: false,
  90. },
  91. // 是否显示连线
  92. showLine: {
  93. type: Boolean,
  94. default: false,
  95. },
  96. // 根节点名称
  97. topNodeText: {
  98. type: String,
  99. default: '根节点',
  100. },
  101. // 地址树接口数据源
  102. treeparams: {
  103. type: Object,
  104. default: () => {
  105. return {}
  106. },
  107. },
  108. // 默认展开节点id
  109. defaultExpandedKeys: {
  110. type: Array,
  111. default: () => {
  112. return ['0']
  113. },
  114. },
  115. // 是否显示隐藏按钮
  116. showPrimary: {
  117. type: Boolean,
  118. default: true,
  119. },
  120. // 地址树是否单选
  121. single: {
  122. type: Boolean,
  123. default: false,
  124. },
  125. refreshKey: {
  126. type: Number,
  127. default: 0,
  128. },
  129. /**
  130. * 是否展示部门下拉列表
  131. */
  132. isSelectDep: {
  133. type: Boolean,
  134. default: false,
  135. },
  136. cate: {
  137. type: Boolean,
  138. default: false,
  139. },
  140. },
  141. data() {
  142. return {
  143. treeData: [],
  144. // 搜索数据
  145. allTreeData: [],
  146. allTreeDataKeys: null,
  147. defaultTreeExpandedKeys: ['0'],
  148. defaultSelectedKeys: ['0'],
  149. checkedKeys: [], // 选中的节点数据
  150. dataList: [], // 数组dataList,搜索要用
  151. spinning: true,
  152. empty: false,
  153. icontype: 'left',
  154. fold: false,
  155. replaceFields: {
  156. title: 'text',
  157. key: 'id',
  158. },
  159. expandedKeys: ['0'],
  160. backupsExpandedKeys: [],
  161. autoExpandParent: false,
  162. defaultTopNodeText: '审计事项分类',
  163. defaultTopNodeId: '0',
  164. key: 0,
  165. newtree: [],
  166. depOptions: [], // 部门下拉框列表值
  167. edit: true, // 当前节点是否可编辑
  168. depvalue: '', // 选择的组织数据
  169. orgValue: '',
  170. orgId: null,
  171. }
  172. },
  173. created() {
  174. // 如果有默认展开节点,则赋值
  175. if (this.defaultExpandedKeys) {
  176. this.defaultTreeExpandedKeys = [...this.defaultExpandedKeys]
  177. }
  178. // 如果有传根节点名称,则赋值
  179. if (this.topNodeText) {
  180. this.defaultTopNodeText = this.topNodeText
  181. }
  182. // 如果有传默认选中节点,则赋值
  183. if (this.selectedKeys.length > 0) {
  184. this.defaultSelectedKeys = [...this.selectedKeys]
  185. }
  186. // this.initTreeData()
  187. this.initDeptList('iamModelCategory')
  188. this.getAllFindModelCategoryTreeAll()
  189. },
  190. methods: {
  191. filterOption(input, option) {
  192. return option.componentOptions.children[0].text.indexOf(input) >= 0
  193. },
  194. onSelectName(val) {
  195. this.defaultSelectedKeys = [val]
  196. this.key++
  197. const onInfo = this.allTreeData.find((item) => item.id === val)
  198. // 根据当前节点id寻找所有上级节点id
  199. let parentId = onInfo.props.parentId
  200. while (parentId !== '0') {
  201. this.expandedKeys.push(parentId)
  202. const parentInfo = this.allTreeData.find((item) => item.id === parentId)
  203. parentId = parentInfo?.props?.parentId || '0'
  204. }
  205. const onSelected = []
  206. // if (onInfo.children !== null && onInfo.children?.length > 0) {
  207. onSelected.push({
  208. data: {
  209. props: {
  210. id: onInfo.id,
  211. text: onInfo.text,
  212. edit: true,
  213. props: {
  214. ...onInfo.props,
  215. },
  216. },
  217. },
  218. })
  219. // }
  220. this.$emit('treeSelect', [val], {
  221. selectedNodes: onSelected,
  222. node: {
  223. dataRef: {
  224. props: {
  225. isroot: false,
  226. },
  227. },
  228. },
  229. })
  230. },
  231. // 获取节点全部数据
  232. getAllFindModelCategoryTreeAll() {
  233. this.empty = true
  234. auditMaintainService.getFindModelCategoryTreeAll().then((res) => {
  235. // 存储搜索所需的数据
  236. this.allTreeData = res.data
  237. // 组装数据
  238. const nodeData = [
  239. {
  240. id: '0',
  241. text: '全部分类',
  242. isLeaf: false,
  243. props: {
  244. isroot: true,
  245. },
  246. children: [],
  247. key: '0',
  248. },
  249. ]
  250. if (res.data.length) {
  251. nodeData[0].children = res.data
  252. }
  253. // 根据props下的isEnd越大层级越深 0为最上级节点
  254. // props下的parentId代表父节点id
  255. // 根据上述数据生成多层嵌套的树形结构,该树形结构有多个根节点
  256. const generateTree = (data) => {
  257. const tree = []
  258. const temp = {}
  259. for (let i = 0; i < data.length; i++) {
  260. temp[data[i].id] = data[i]
  261. }
  262. for (let i = 0; i < data.length; i++) {
  263. if (temp[data[i].props.parentId] && data[i].id !== data[i].props.parentId) {
  264. if (!temp[data[i].props.parentId].children) {
  265. temp[data[i].props.parentId].children = []
  266. }
  267. temp[data[i].props.parentId].children.push(data[i])
  268. } else {
  269. tree.push(data[i])
  270. }
  271. }
  272. return tree
  273. }
  274. nodeData[0].children = generateTree(res.data)
  275. this.treeData = nodeData
  276. this.empty = false
  277. this.spinning = false
  278. })
  279. },
  280. // 刷新树节点
  281. refreshNode(nodeId) {
  282. this.key++
  283. this.parentId = nodeId
  284. this.refreshData(this.treeData[0])
  285. this.getAllFindModelCategoryTreeAll()
  286. },
  287. // 刷新树节点
  288. refreshData(treeData) {
  289. if (treeData.id + '' === this.parentId + '') {
  290. return auditMaintainService
  291. .findIamAuditMaintainCategoryTree(treeData.id, treeData.id)
  292. .then((res) => {
  293. treeData.children = res.data
  294. if (res.data.length > 0) {
  295. treeData.isLeaf = false
  296. if (this.expandedKeys.indexOf(treeData.id) === -1) {
  297. this.expandedKeys = new Set(this.expandedKeys.push(treeData.id))
  298. }
  299. } else {
  300. treeData.isLeaf = true
  301. }
  302. return false
  303. })
  304. }
  305. if (treeData.children) {
  306. treeData.children.forEach((item) => {
  307. this.refreshData(item)
  308. })
  309. }
  310. },
  311. // 初始化部门下拉 分级授权获取部门下拉列表 维护权限
  312. initDeptList(formId) {
  313. auditMaintainService.getManagedHierarchyOrg(formId).then((res) => {
  314. res.data.editNodes.forEach((item) => {
  315. this.depOptions.push({
  316. label: item.text,
  317. value: item.id,
  318. text: item.text,
  319. edit: true,
  320. })
  321. })
  322. if (this.managerType !== 'manager') {
  323. // 取编辑和查看节点并集
  324. res.data.viewNodes.forEach((item, index) => {
  325. const node = this.depOptions.find((nodeinfo) => {
  326. return nodeinfo.value === item.id
  327. })
  328. if (!node) {
  329. this.depOptions.push({
  330. label: item.text,
  331. value: item.id,
  332. text: item.text,
  333. edit: false,
  334. })
  335. }
  336. })
  337. }
  338. // 部门下拉框列表值赋值
  339. if (this.depOptions.length > 0) {
  340. this.depvalue = this.depOptions[0].value
  341. // 加载默认值
  342. this.defaultTopNodeId = 'o_' + this.depOptions[0].value
  343. this.defaultTopNodeText = this.depOptions[0].text + this.topNodeText
  344. this.defaultTreeExpandedKeys = ['o_' + this.depOptions[0].value]
  345. this.defaultSelectedKeys = ['o_' + this.depOptions[0].value]
  346. this.edit = this.depOptions[0].edit
  347. // this.initTreeData(this.depOptions[0].value)
  348. this.$emit('depChanged', this.depOptions[0].value, this.depOptions[0])
  349. this.$emit('treeSelect', [this.depOptions[0].value], {
  350. selectedNodes: [
  351. {
  352. data: {
  353. props: {
  354. id: this.depOptions[0].value,
  355. text: this.depOptions[0].text + this.topNodeText,
  356. edit: this.depOptions[0].edit,
  357. },
  358. },
  359. },
  360. ],
  361. node: {
  362. dataRef: {
  363. props: {
  364. isroot: true,
  365. },
  366. },
  367. },
  368. })
  369. } else {
  370. this.defaultTopNodeId = null
  371. this.defaultTopNodeText = null
  372. this.defaultTreeExpandedKeys = []
  373. this.defaultSelectedKeys = []
  374. this.$emit('treeSelect', [9999999], {
  375. selectedNodes: [],
  376. })
  377. this.spinning = false
  378. this.empty = true
  379. }
  380. })
  381. },
  382. /***
  383. * 选中复选框时的事件
  384. */
  385. treeCheck(allKeys, echecked) {
  386. // echecked.checkedNodes 选中的所有节点信息为数组 .data.props 获取详细信息
  387. // echecked.node.dataRef 当前选中的节点信息
  388. if (this.single) {
  389. this.checkedKeys.checked = []
  390. this.checkedKeys.checked = [echecked.node.dataRef.id]
  391. }
  392. this.$emit('checkedKeys', echecked.node.dataRef, echecked.checkedNodes)
  393. },
  394. // 点击树
  395. treeSelect(selectedKeys, info) {
  396. this.checkedKeys = selectedKeys
  397. this.defaultSelectedKeys = selectedKeys
  398. this.allTreeDataKeys = null
  399. this.defaultSelectedKeys = selectedKeys
  400. this.$emit('treeSelect', selectedKeys, info)
  401. },
  402. transformData(data) {
  403. return data.map((d) => {
  404. const { children, ...rest } = d
  405. return {
  406. ...rest,
  407. children: children && this.transformData(children),
  408. scopedSlots: { title: 'title' },
  409. }
  410. })
  411. },
  412. onExpand(expandedKeys) {
  413. // 用户点击展开时,取消自动展开效果
  414. this.expandedKeys = expandedKeys
  415. this.autoExpandParent = false
  416. },
  417. // 点击地址树展开时调用
  418. onLoadData(treeNode) {
  419. let parentId
  420. if (treeNode.dataRef.props.isroot) {
  421. parentId = -1
  422. } else {
  423. parentId = parseInt(treeNode.dataRef.id)
  424. }
  425. return auditMaintainService
  426. .findIamAuditMaintainCategoryTree(parentId, this.depvalue)
  427. .then((res) => {
  428. treeNode.dataRef.children = res.data
  429. // this.setDisabless(res.data)
  430. this.treeData = this.transformData([...this.treeData])
  431. })
  432. },
  433. // 添加是否可点击属性
  434. setDisabless(data) {
  435. return data.map((d) => {
  436. const props = d.props
  437. if (props && props.isEnd === '1') {
  438. // 置灰不可选
  439. d.disabled = true
  440. }
  441. })
  442. },
  443. // 初始化地址树
  444. initTreeData(depId) {
  445. const topDepId = depId === null || depId === undefined ? 0 : depId
  446. auditMaintainService.findIamAuditMaintainCategoryTree(topDepId, topDepId).then((res) => {
  447. // if (res.data) {
  448. // this.defaultSelectedKeys = [res.data[0].id]
  449. // }
  450. // this.mmInitTreeData(res)
  451. this.spinning = false
  452. const treeNode = [
  453. {
  454. id: this.defaultTopNodeId,
  455. text: '全部分类',
  456. isLeaf: false,
  457. props: {
  458. isroot: true,
  459. },
  460. children: [],
  461. key: this.defaultTopNodeId,
  462. },
  463. ]
  464. if (res.data.length) {
  465. treeNode.children = res.data
  466. }
  467. this.treeData = this.transformData(treeNode)
  468. this.expandedKeys = this.defaultTreeExpandedKeys
  469. this.generateList(this.treeData)
  470. this.empty = false
  471. })
  472. },
  473. // 处理搜索用的dataList
  474. generateList(data) {
  475. for (let i = 0; i < data.length; i++) {
  476. const node = data[i]
  477. const key = node.id
  478. const title = node.text
  479. const props = node.props
  480. // 用来判断此几点是否已经配置了用户,需要后台返回标识位进行判断
  481. if (props.showuser) {
  482. data[i].scopedSlots.icon = 'hasuser'
  483. }
  484. this.dataList.push({ key, id: key, title: title, props })
  485. if (node.children) {
  486. this.generateList(node.children)
  487. }
  488. }
  489. },
  490. mmInitTreeData(res) {
  491. this.spinning = false
  492. if (res.data.length) {
  493. this.treeData = this.transformData(res.data)
  494. this.expandedKeys = this.defaultTreeExpandedKeys
  495. this.empty = false
  496. } else {
  497. this.empty = true
  498. }
  499. },
  500. // 刷新树方法
  501. refreshTree() {
  502. this.key++
  503. },
  504. // 组织下拉框change时触发
  505. changedep(value) {
  506. this.key++
  507. if (value.length === 0) {
  508. this.depvalue = 0
  509. this.defaultTreeExpandedKeys = ['0']
  510. this.defaultSelectedKeys = ['0']
  511. this.defaultTopNodeId = '0'
  512. this.defaultTopNodeText = this.topNodeText
  513. } else {
  514. this.depvalue = value[0].oldId
  515. this.defaultTreeExpandedKeys = ['o_' + value[0].oldId]
  516. this.defaultSelectedKeys = ['o_' + value[0].oldId]
  517. this.defaultTopNodeId = 'o_' + value[0].oldId
  518. this.defaultTopNodeText = value[0].text + this.topNodeText
  519. this.edit = true
  520. }
  521. this.initTreeData(this.depvalue)
  522. this.$emit('depChanged', this.depvalue, value[0])
  523. this.$emit(
  524. 'treeSelect',
  525. { id: value[0].oldId },
  526. {
  527. selectedNodes: [
  528. {
  529. data: {
  530. props: {
  531. id: this.defaultTopNodeId,
  532. text: value[0].text + this.topNodeText,
  533. edit: true,
  534. },
  535. },
  536. },
  537. ],
  538. node: {
  539. dataRef: {
  540. props: {
  541. isroot: true,
  542. },
  543. },
  544. },
  545. }
  546. )
  547. },
  548. // 拖拽节点方法
  549. onDrop(info) {
  550. // 被插入节点信息
  551. const dropKey = info.node.eventKey
  552. const dropNode = info.node.dataRef
  553. // 拖拽节点信息
  554. const dragKey = info.dragNode.eventKey
  555. const dragNode = info.dragNode.dataRef
  556. const dropPos = info.node.pos.split('-')
  557. // -1表示之前 0表示合并 1表示之后
  558. const dropPosition = info.dropPosition - Number(dropPos[dropPos.length - 1])
  559. // 分类合并至事项内
  560. if (dropNode.props.isroot && (dropPosition === 1) | (dropPosition === -1)) {
  561. Message.info('不能将分类拖拽至与根节点同层级', 1)
  562. return false
  563. }
  564. const loop = (data, key, callback) => {
  565. data.forEach((item, index, arr) => {
  566. if (item.id === key) {
  567. return callback(item, index, arr)
  568. }
  569. if (item.children) {
  570. return loop(item.children, key, callback)
  571. }
  572. })
  573. }
  574. const data = this.treeData
  575. // Find dragObject
  576. let dragObj
  577. loop(data, dragKey, (item, index, arr) => {
  578. arr.splice(index, 1)
  579. dragObj = item
  580. })
  581. if (!info.dropToGap) {
  582. // Drop on the content
  583. loop(data, dropKey, (item) => {
  584. item.children = item.children || []
  585. // where to insert 示例添加到尾部,可以是随意位置
  586. item.children.push(dragObj)
  587. })
  588. } else if (
  589. (info.node.children || []).length > 0 && // Has children
  590. info.node.expanded && // Is expanded
  591. dropPosition === 1 // On the bottom gap
  592. ) {
  593. loop(data, dropKey, (item) => {
  594. item.children = item.children || []
  595. // where to insert 示例添加到尾部,可以是随意位置
  596. item.children.unshift(dragObj)
  597. })
  598. } else {
  599. let ar
  600. let i
  601. loop(data, dropKey, (item, index, arr) => {
  602. ar = arr
  603. i = index
  604. })
  605. if (dropPosition === -1) {
  606. ar.splice(i, 0, dragObj)
  607. } else {
  608. ar.splice(i + 1, 0, dragObj)
  609. }
  610. }
  611. this.treeData = data
  612. // 拖拽完成,调用接口
  613. const dragParams = {
  614. nodeId: dragNode.id,
  615. targetnodeType: dropNode.props.isroot ? 'root' : 'category', // category/root
  616. targetnodeId: dropNode.id,
  617. position: dropPosition, // -1 0 1 之前 合并 之后
  618. }
  619. auditMaintainService.dragNode(dragParams).then((res) => {
  620. if (!res) {
  621. Message.info(dropNode.text + '节点下存在相同分类编号,拖拽失败')
  622. }
  623. })
  624. },
  625. },
  626. }
  627. </script>
  628. <style module lang="scss">
  629. @use '@/common/design' as *;
  630. .spin {
  631. width: 100%;
  632. line-height: 30;
  633. }
  634. .ywlxtree {
  635. :global(.ant-tree-title) {
  636. display: inline-block;
  637. width: 100%;
  638. overflow: hidden;
  639. text-overflow: ellipsis;
  640. white-space: nowrap;
  641. }
  642. :global(.ant-input-search) {
  643. margin: 8px 0;
  644. overflow: hidden;
  645. }
  646. .active {
  647. color: $primary-color;
  648. }
  649. :global(.ant-select) {
  650. width: 100%;
  651. overflow: hidden;
  652. }
  653. }
  654. .treewrap {
  655. position: relative;
  656. display: flex;
  657. flex-direction: column;
  658. width: 20%;
  659. min-height: 100%;
  660. margin-right: $padding-lg;
  661. transition: width 0.2s;
  662. .fold {
  663. position: absolute;
  664. top: calc(50% - 30px);
  665. right: -15px;
  666. z-index: 2;
  667. width: 15px;
  668. height: 75px;
  669. padding: 0;
  670. border-radius: 0 10px 10px 0;
  671. }
  672. :global(.ant-tree) {
  673. overflow: hidden;
  674. text-overflow: ellipsis;
  675. white-space: nowrap;
  676. }
  677. :global(.ant-card-body) {
  678. background: $white;
  679. }
  680. }
  681. .collapse {
  682. width: 0;
  683. :global(.ant-card-body) {
  684. background: transparent;
  685. :global(.ant-empty) {
  686. display: none;
  687. }
  688. }
  689. }
  690. // 单选样式
  691. .single {
  692. :global .ant-tree-checkbox {
  693. .ant-tree-checkbox-inner {
  694. border-radius: 100px;
  695. &::after {
  696. position: absolute;
  697. top: 3px;
  698. left: 3px;
  699. display: table;
  700. width: 8px;
  701. height: 8px;
  702. content: ' ';
  703. background-color: $primary-color;
  704. border: 0;
  705. border-radius: 8px;
  706. opacity: 0;
  707. transition: all 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
  708. transform: scale(0);
  709. }
  710. }
  711. &.ant-tree-checkbox-checked {
  712. &::after {
  713. position: absolute;
  714. top: 16.67%;
  715. left: 0;
  716. width: 100%;
  717. height: 66.67%;
  718. content: '';
  719. border: 1px solid #1890ff;
  720. border-radius: 50%;
  721. animation: antRadioEffect 0.36s ease-in-out;
  722. animation-fill-mode: both;
  723. }
  724. .ant-tree-checkbox-inner {
  725. background-color: $white;
  726. &::after {
  727. opacity: 1;
  728. transition: all 0.3s cubic-bezier(0.78, 0.14, 0.15, 0.86);
  729. transform: scale(1);
  730. }
  731. }
  732. }
  733. }
  734. }
  735. </style>