CommonUse.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715
  1. <template>
  2. <WorkspaceCard class="work-common" title="常用功能">
  3. <span slot="header-right" class="header-right-set" @click="setCommonFun"><i class="icon-set-img"></i> 设置</span>
  4. <div class="common-lists">
  5. <div class="list-item" v-for="item in commonList" :key="item.id" @click="openLink(item)">
  6. <div class="icon-box-container" v-if="item.icon && item.icon.indexOf('icon-') === 0">
  7. <JyIcon :name="item.icon" classPrefix=""></JyIcon>
  8. </div>
  9. <div v-else class="icon-box-container">
  10. <el-image :src="item.icon" alt="常用功能">
  11. <img slot="error" src="https://www.jianyu360.cn/common-module/public/image/auto.png" />
  12. </el-image>
  13. </div>
  14. <span v-html="item.name.replace('/', '/<br>')" class="item-name"></span>
  15. </div>
  16. <div v-if="commonList && commonList.length < maxCount" class="list-add" @click="setCommonFun">
  17. <span class="icon-add-img"></span>
  18. <span class="add-text">添加常用功能</span>
  19. </div>
  20. </div>
  21. <!-- 设置常用功能dialog -->
  22. <el-dialog
  23. custom-class="fn-dialog"
  24. :visible.sync="dialogShow"
  25. :close-on-click-modal="false"
  26. :show-close="false"
  27. v-if="dialogShow"
  28. center
  29. width="696px">
  30. <SelectorCard @onCancel="changeDialogState(false)" @onConfirm="confirmSaveFn" confirmText="确定">
  31. <div slot="header">常用功能设置</div>
  32. <div class="transfer-content">
  33. <Transfer :maxCount="maxCount" submitKey="id" :left="allFunctions" :right="transferCommonList" @onSave="onTransferSave"></Transfer>
  34. </div>
  35. </SelectorCard>
  36. </el-dialog>
  37. <!-- 改为抽屉式 -->
  38. <DrawerCard customClass="drawer-class" title="常用功能设置" percent="600px" :with-header="false" v-model="drawerShow" @close="onCloseDrawer" @saveData="onSaveDrawer">
  39. <div class="function-drawer-content" ref="drawerScroll" @scroll="handleScroll($event)">
  40. <div class="added-function">
  41. <h3 class="added-title">已添加({{addedList.length}})</h3>
  42. <transition-group class="added-container" name="drag" tag="ul" v-if="addedList && addedList.length > 0">
  43. <li class="added-item" draggable v-for="(item, i) in addedList" :key="item.id" @dragover.prevent @dragstart="onDragstart($event, i)" @dragenter="onDragenter($event, i)" @dragend="onDragend($event, i)">
  44. <div class="icon-box-container">
  45. <el-image :src="item.icon" :alt="item.name">
  46. <img slot="error" src="https://www.jianyu360.cn/common-module/public/image/auto.png" />
  47. </el-image>
  48. </div>
  49. <span v-html="item.name.replace('/', '/<br>')" class="item-name"></span>
  50. <span class="remove-tag" @click.stop="onAddedRemove(item)">-</span>
  51. </li>
  52. </transition-group>
  53. <div v-else class="no-added">暂未设置常用功能</div>
  54. </div>
  55. <div class="classify-function" ref="refContent">
  56. <div class="classify-tab" :class="{'tab-fixed': tabFixed}" ref="tabBox">
  57. <span class="tab-item" :class="{'active': tabActive === index}" v-for="(item, index) in tabNames" :key="item.id" @click="goAnchor(item, index)">{{item.name}}</span>
  58. </div>
  59. <div class="classify-content">
  60. <ul class="outer-container">
  61. <li class="outer-item" :id="level.name" v-for="level in mainFunList" :key="level.id">
  62. <h3 class="outer-item-name">{{ level.name }}</h3>
  63. <ul class="insert-container">
  64. <li class="insert-item" v-for="next in level.children" :key="next.id">
  65. <div class="insert-item-left">
  66. <el-image :src="next.icon" :alt="next.name">
  67. <img slot="error" src="https://www.jianyu360.cn/common-module/public/image/auto.png" />
  68. </el-image>
  69. <span v-html="next.name.replace('<br>', '')"></span>
  70. </div>
  71. <transition name="el-zoom-in-center">
  72. <span v-if="next.status" class="handle-btn remove-btn" @click.stop="onRemoveFun(next)">移除</span>
  73. <span v-else class="handle-btn add-btn" @click.stop="onAddFun(next)">添加</span>
  74. </transition>
  75. </li>
  76. </ul>
  77. </li>
  78. </ul>
  79. </div>
  80. </div>
  81. </div>
  82. </DrawerCard>
  83. </WorkspaceCard>
  84. </template>
  85. <script>
  86. import { JyIcon } from '@jianyu/icon'
  87. import { mapState, mapMutations, mapActions } from 'vuex'
  88. import { Dialog, Image } from 'element-ui'
  89. import WorkspaceCard from '../ui/WorkspaceCard'
  90. import SelectorCard from '@/components/selector/SelectorCard'
  91. import Transfer from '@/components/work-desktop/Transfer'
  92. import { mixinNoPowerMessageTip } from '@/utils/mixins/no-power-message-box'
  93. import { tryCallHooks } from '@jianyu/easy-inject-qiankun'
  94. import { debounce } from '@/utils/globalFunctions'
  95. import DrawerCard from '@/components/drawer/Drawer.vue'
  96. export default {
  97. name: 'CommonUse',
  98. mixins: [mixinNoPowerMessageTip],
  99. components: {
  100. [Dialog.name]: Dialog,
  101. [Image.name]: Image,
  102. WorkspaceCard,
  103. SelectorCard,
  104. JyIcon,
  105. Transfer,
  106. DrawerCard
  107. },
  108. data () {
  109. return {
  110. addedList: [],
  111. mainFunList: [],
  112. dragIndex: '',
  113. enterIndex: '',
  114. tabActive: 0,
  115. tabFixed: false,
  116. isScrollAnchor: true
  117. }
  118. },
  119. computed: {
  120. ...mapState({
  121. maxCount: state => state.workspace.commonUse.maxCount,
  122. dialogShow: state => state.workspace.commonUse.dialogShow,
  123. allFunctions: state => state.workspace.commonUse.allFunctions, // 所有功能
  124. transferCommonList: state => state.workspace.commonUse.transferCommonList,
  125. commonList: state => state.workspace.commonUse.commonList, // 常用功能
  126. mainFunctions: state => state.workspace.commonUse.mainFunctions,
  127. drawerShow: state => state.workspace.commonUse.drawerShow
  128. }),
  129. tabNames () {
  130. return this.mainFunctions.filter(item => item.level === 1)
  131. }
  132. },
  133. watch: {
  134. commonList (val) {
  135. if (val) {
  136. this.addedList = JSON.parse(JSON.stringify(val))
  137. this.formatMainFunList(this.addedList)
  138. }
  139. },
  140. mainFunctions (val) {
  141. if (val) {
  142. this.mainFunList = JSON.parse(JSON.stringify(val))
  143. this.formatMainFunList(this.addedList)
  144. }
  145. }
  146. },
  147. async created () {
  148. await this.getCanUseFunctions()
  149. await this.getAllFunctions({ vm: this })
  150. },
  151. beforeDestroy () {
  152. window.removeEventListener('scroll', this.handleScroll)
  153. },
  154. methods: {
  155. ...mapMutations('workspace/commonUse', [
  156. 'changeDialogState',
  157. 'transferSave',
  158. 'changeDrawerState'
  159. ]),
  160. ...mapActions('workspace/commonUse', [
  161. 'getAllFunctions',
  162. 'getCanUseFunctions',
  163. 'confirmSave'
  164. ]),
  165. // 穿梭框子组件传来的组件
  166. onTransferSave (data) {
  167. this.transferSave(data)
  168. },
  169. openLink (item) {
  170. const { url } = item
  171. if (item.usable) {
  172. tryCallHooks({
  173. fn: () => {
  174. this.$BRACE.methods.open({
  175. route: {
  176. ...item,
  177. link: url
  178. }
  179. })
  180. },
  181. spareFn: () => {
  182. window.open(url)
  183. }
  184. })
  185. } else {
  186. // 判断是否需要自定义弹窗文案
  187. const hasTipInfo = Object.keys(item?.tipInfo || {}).length > 0
  188. if (hasTipInfo) {
  189. // 自定义弹窗文案
  190. const menu = item
  191. // 格式化弹窗配置信息
  192. const dialogParams = {
  193. type: 'tip',
  194. title: menu.tipInfo?.title,
  195. message: menu.tipInfo?.content,
  196. options: Object.assign({
  197. dangerouslyUseHTMLString: true,
  198. customClass: 'custom-message-box',
  199. confirmButtonText: '我知道了',
  200. confirmButtonClass: 'custom-confirm-btn',
  201. showClose: false,
  202. showCancelButton: false,
  203. closeOnClickModal: false,
  204. center: true
  205. }, {
  206. showCancelButton: menu.tipInfo?.isShowCancel,
  207. confirmButtonText: menu.tipInfo?.confirmText
  208. }, menu.tipInfo?.options || {})
  209. }
  210. this.$confirm(dialogParams.message, dialogParams.title, dialogParams.options).then(() => {
  211. // 确认按钮自定义跳转
  212. if (menu.tipInfo?.confirmUrl) {
  213. // 调用工作桌面函数跳转
  214. tryCallHooks({
  215. fn: () => {
  216. this.$BRACE.methods.open({
  217. route: {
  218. link: menu.tipInfo?.confirmUrl,
  219. appType: menu.tipInfo?.appType,
  220. openType: menu.tipInfo?.openType
  221. }
  222. })
  223. },
  224. spareFn: () => {
  225. window.open(menu.tipInfo?.confirmUrl)
  226. }
  227. })
  228. }
  229. }).catch(e => e)
  230. } else {
  231. // 默认文案
  232. this.showNoPowerMessageTip()
  233. }
  234. }
  235. },
  236. confirmSaveFn () {
  237. try {
  238. this.confirmSave()
  239. } catch (error) {
  240. this.$toast(error)
  241. }
  242. },
  243. onDragstart (e, index) {
  244. this.dragIndex = index
  245. const element = e.target
  246. element.classList.add('drag-move-item')
  247. },
  248. onDragenter: debounce(function (e, index) {
  249. e.preventDefault()
  250. if (this.dragIndex !== index) {
  251. const source = this.addedList[this.dragIndex]
  252. this.addedList.splice(this.dragIndex, 1)
  253. this.addedList.splice(index, 0, source)
  254. this.dragIndex = index
  255. const ids = this.addedList.map(v => {
  256. return v.id
  257. })
  258. this.transferSave(ids)
  259. }
  260. }, 200),
  261. onDragend (e, index) {
  262. e.preventDefault()
  263. const element = e.srcElement
  264. element.classList.remove('drag-move-item')
  265. this.$forceUpdate()
  266. },
  267. formatMainFunList (addedList = []) {
  268. this.mainFunList.forEach(v => {
  269. v.children.forEach(t => {
  270. t.status = false
  271. addedList.forEach(s => {
  272. if (s.id === t.id || s.name === t.name) {
  273. t.status = true
  274. }
  275. })
  276. })
  277. })
  278. },
  279. onCloseDrawer () {
  280. this.tabFixed = false
  281. this.tabActive = 0
  282. this.formatMainFunList(this.commonList)
  283. this.changeDrawerState(false)
  284. },
  285. onSaveDrawer () {
  286. this.confirmSaveFn()
  287. },
  288. setCommonFun () {
  289. this.changeDrawerState(true)
  290. this.addedList = JSON.parse(JSON.stringify(this.commonList))
  291. this.formatMainFunList(this.addedList)
  292. },
  293. onRemoveFun (item) {
  294. item.status = false
  295. this.addedList.splice(this.addedList.findIndex(add => add.id === item.id || add.name === item.name), 1)
  296. this.updateMainFunStatus(item)
  297. },
  298. onAddFun (item) {
  299. item.status = true
  300. this.addedList.unshift(item)
  301. this.updateMainFunStatus(item)
  302. },
  303. onAddedRemove (item) {
  304. this.addedList.splice(this.addedList.findIndex(add => add.id === item.id), 1)
  305. this.mainFunList.forEach(v => {
  306. if (v.children) {
  307. v.children.forEach(s => {
  308. if (item.id === s.id || item.name === s.name) {
  309. s.status = false
  310. this.$forceUpdate()
  311. }
  312. })
  313. }
  314. })
  315. const ids = this.addedList.map(v => {
  316. return v.id
  317. })
  318. this.transferSave(ids)
  319. },
  320. goAnchor (item, index) {
  321. this.isScrollAnchor = false
  322. const dom = this.$root.$el.querySelector('#' + item.name)
  323. const offsetTop = this.getOffsetTop(dom)
  324. // qiankun 子应用选择器获取不到document 改为this.$root.$el
  325. const scrollDom = this.$root.$el.querySelector('.function-drawer-content')
  326. // const addTop = this.$root.$el.querySelector('.added-function').offsetHeight
  327. const scrollTop = offsetTop - 70 - 48
  328. scrollDom.scrollTo({
  329. /**
  330. * 抽屉header高度70px, tabs导航栏高度48px, 滚动子元素h3标题高度60px
  331. */
  332. top: scrollTop,
  333. behavior: 'smooth'
  334. })
  335. this.tabActive = index
  336. setTimeout(() => {
  337. this.isScrollAnchor = true
  338. }, 800)
  339. },
  340. handleScroll (e) {
  341. const tabOffsetTop = this.$refs.refContent.getBoundingClientRect().top
  342. this.tabFixed = tabOffsetTop <= 70
  343. if (!this.isScrollAnchor) return
  344. const scrollItems = this.$root.$el.querySelectorAll('.outer-item')
  345. for (let i = scrollItems.length - 1; i >= 0; i--) {
  346. // console.log(e.target.scrollTop, this.getOffsetTop(scrollItems[i]), this.getOffsetTop(scrollItems[0]), 'judge')
  347. const scrollItemTop = this.getOffsetTop(scrollItems[i])
  348. // 判断滚动条滚动距离是否大于当前滚动项可滚动距离
  349. const judge =
  350. e.target.scrollTop >= scrollItemTop
  351. if (judge) {
  352. this.tabActive = i
  353. break
  354. }
  355. }
  356. },
  357. // 获取当前元素的offsetTop
  358. getOffsetTop (obj) {
  359. let offsetTop = 0
  360. while (obj !== window.document.body && obj != null) {
  361. offsetTop += obj.offsetTop
  362. obj = obj.offsetParent
  363. }
  364. return offsetTop
  365. },
  366. updateMainFunStatus (item) {
  367. this.mainFunList.forEach(v => {
  368. if (v.children) {
  369. v.children.forEach(s => {
  370. if (item.id === s.id || item.name === s.name) {
  371. s.status = item.status
  372. this.$forceUpdate()
  373. }
  374. })
  375. }
  376. })
  377. this.formatMainFunList(this.addedList)
  378. const ids = this.addedList.map(v => {
  379. return v.id
  380. })
  381. this.transferSave(ids)
  382. this.$forceUpdate()
  383. }
  384. }
  385. }
  386. </script>
  387. <style lang="scss" scoped>
  388. $main: #2cb7ca;
  389. .drag-move {
  390. transition: transform .3s;
  391. }
  392. ::v-deep{
  393. .fn-dialog{
  394. .el-dialog__header,.el-dialog__body{
  395. padding: 0;
  396. }
  397. }
  398. .transfer-content{
  399. display: flex;
  400. align-items: center;
  401. justify-content: center;
  402. }
  403. .selector-card-header{
  404. margin: 0 0 28px!important;
  405. }
  406. .selector-card.s-card{
  407. width: 100%;
  408. }
  409. .selector-card-content{
  410. display: block!important;
  411. padding: 0 30px;
  412. }
  413. .more-tips{
  414. margin-top: 20px;
  415. font-size: 14px;
  416. line-height: 22px;
  417. text-align: center;
  418. color: #686868;
  419. }
  420. .drawer-class{
  421. background: #F2F2F4;
  422. .el-header{
  423. padding: 26px 30px;
  424. font-size: 18px;
  425. background: #fff;
  426. box-shadow: 0px -1px 0px 0px rgba(0, 0, 0, 0.05) inset;
  427. }
  428. .el-main{
  429. overflow-y: hidden!important;
  430. }
  431. .function-drawer-content{
  432. height: 100%;
  433. overflow-y: scroll;
  434. }
  435. .added-function{
  436. padding: 16px 30px 24px;
  437. background: #fff;
  438. .added-title{
  439. line-height: 24px;
  440. font-size: 16px;
  441. }
  442. .no-added{
  443. padding: 40px;
  444. text-align: center;
  445. font-size: 16px;
  446. color: #686868;
  447. }
  448. .added-container{
  449. display: flex;
  450. flex-wrap: wrap;
  451. }
  452. .added-item{
  453. position: relative;
  454. display: flex;
  455. flex-direction: column;
  456. align-items: center;
  457. width: 104px;
  458. height: fit-content;
  459. margin: 16px 0 0 0;
  460. padding: 8px 0;
  461. text-align: center;
  462. flex-shrink: 0;
  463. border-radius: 8px;
  464. cursor: grabbing;
  465. .item-name{
  466. margin-top: 8px;
  467. line-height: 22px;
  468. font-size: 14px;
  469. color: #1D1D1D;
  470. pointer-events: none;
  471. }
  472. .remove-tag{
  473. position: absolute;
  474. top: 0;
  475. right: 8px;
  476. display: inline-block;
  477. width: 14px;
  478. height: 14px;
  479. line-height: 12px;
  480. border-radius: 50%;
  481. background: #FF3A20;
  482. color: #fff;
  483. font-weight: bold;
  484. cursor: pointer;
  485. font-size: 16px;
  486. }
  487. }
  488. .drag-move-item{
  489. // padding: 8px 0;
  490. border: 1px solid rgba(0, 0, 0, 0.05);
  491. box-shadow: 0px 2px 16px rgba(0, 0, 0, 0.08);
  492. // border-radius: 8px;
  493. .remove-tag{
  494. display: none;
  495. }
  496. }
  497. .drag-init-hide{
  498. transition: 0.01s;
  499. transform: translateX(-9999px);
  500. }
  501. }
  502. .classify-function{
  503. margin-top: 12px;
  504. .classify-tab{
  505. width: 100%;
  506. padding: 0 12px;
  507. background: #fff;
  508. white-space: nowrap;
  509. overflow-x: auto;
  510. border-bottom: 1px solid rgba(0, 0, 0, 0.05);
  511. &::-webkit-scrollbar{
  512. height: 4px;
  513. }
  514. &::-webkit-scrollbar-track {
  515. background-color: #f5f5f5;
  516. }
  517. &::-webkit-scrollbar-thumb {
  518. border-radius: 2px;
  519. background-color: #ECECEC;
  520. opacity: 0.15;
  521. }
  522. }
  523. .tab-fixed{
  524. position: fixed;
  525. top: 70px;
  526. width: 100%;
  527. background: #fff;
  528. z-index: 10;
  529. white-space: nowrap;
  530. overflow-x: auto;
  531. }
  532. .tab-item{
  533. display: inline-block;
  534. // height: 100%;
  535. height: 48px;
  536. line-height: 48px;
  537. padding: 0 20px;
  538. cursor: pointer;
  539. font-size: 16px;
  540. }
  541. .active{
  542. position: relative;
  543. color: $main;
  544. &::after{
  545. position: absolute;
  546. content: '';
  547. width: 32px;
  548. height: 2px;
  549. bottom: 0;
  550. left: 50%;
  551. margin-left: -16px;
  552. background: $main;
  553. }
  554. }
  555. .classify-content{
  556. .outer-container,
  557. .insert-container{
  558. display: flex;
  559. flex-direction: column;
  560. }
  561. .outer-item{
  562. padding-left: 30px;
  563. margin-bottom: 8px;
  564. background: #fff;
  565. &:last-child{
  566. min-height: 100%;
  567. }
  568. }
  569. .outer-item-name{
  570. padding: 24px 0 8px;
  571. font-size: 18px;
  572. line-height: 28px;
  573. font-weight: 700;
  574. color: #1D1D1D;
  575. }
  576. .insert-item{
  577. position: relative;
  578. display: flex;
  579. align-items: center;
  580. justify-content: space-between;
  581. padding: 18px 30px 18px 0;
  582. &::after{
  583. position: absolute;
  584. content: '';
  585. right: 0;
  586. left: 60px;
  587. bottom: 0;
  588. border-bottom: 1px solid rgba(0, 0, 0, 0.05);
  589. }
  590. .el-image{
  591. width: 44px;
  592. height: 44px;
  593. flex-shrink: 0;
  594. }
  595. }
  596. .insert-item-left{
  597. display: flex;
  598. align-items: center;
  599. span{
  600. margin-left: 16px;
  601. font-size: 16px;
  602. line-height: 24px;
  603. }
  604. }
  605. .handle-btn{
  606. width: 72px;
  607. height: 30px;
  608. line-height: 28px;
  609. text-align: center;
  610. background: transparent;
  611. cursor: pointer;
  612. }
  613. .add-btn{
  614. border: 1px solid #E0E0E0;
  615. color: #1D1D1D;
  616. border-radius: 4px;
  617. }
  618. .remove-btn{
  619. border: 0;
  620. font-size: 14px;
  621. color: #FF3A20;
  622. }
  623. }
  624. }
  625. }
  626. }
  627. .icon-box-container {
  628. display: flex;
  629. align-items: center;
  630. justify-content: center;
  631. width: 44px;
  632. height: 44px;
  633. pointer-events: none;
  634. ::before{
  635. content: ''
  636. }
  637. ::v-deep {
  638. .el-image {
  639. width: 100%;
  640. height: 100%;
  641. img {
  642. width: 100%;
  643. height: 100%;
  644. }
  645. }
  646. }
  647. }
  648. .icon-set-img{
  649. display: inline-block;
  650. width: 18px;
  651. height: 18px;
  652. margin-right: 6px;
  653. background: url('~@/assets/images/icon/icon-set.png') no-repeat center center;
  654. background-size: contain;
  655. }
  656. .icon-add-img{
  657. display: inline-block;
  658. width: 44px;
  659. height: 44px;
  660. background: url('~@/assets/images/icon/icon-add.png') no-repeat center center;
  661. background-size: contain;
  662. }
  663. .header-right-set {
  664. display: flex;
  665. align-items: center;
  666. color: $main;
  667. font-size: 14px;
  668. cursor: pointer;
  669. }
  670. .common-lists{
  671. padding: 0 20px;
  672. display: flex;
  673. flex-wrap: wrap;
  674. .list-item,
  675. .list-add{
  676. width: 120px;
  677. padding: 18px 0 24px;
  678. display: flex;
  679. flex-direction: column;
  680. align-items: center;
  681. text-align: center;
  682. cursor: pointer;
  683. }
  684. .list-item{
  685. // flex: 1;
  686. &:hover{
  687. span{
  688. color: $main;
  689. }
  690. }
  691. }
  692. .item-name,.add-text{
  693. margin-top: 10px;
  694. font-size: 14px;
  695. line-height: 20px;
  696. color: #1D1D1D;
  697. @media only screen and (max-width: 1280px) {
  698. font-size: 12px;
  699. }
  700. }
  701. .item-img{
  702. width: 44px;
  703. height: 44px;
  704. }
  705. .add-text{
  706. white-space: nowrap;
  707. color: #686868;
  708. }
  709. }
  710. </style>