图书馆综合管理系统
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

666 lines
22 KiB

6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
  1. <template>
  2. <div class="app-container">
  3. <div class="venue-header">
  4. <h4 @click="handleToGrids"><i class="iconfont icon-shuju" />书架总览</h4>
  5. <span class="bookshelf-area">{{ floorName }} - {{ regionName }}</span>
  6. <p><i class="iconfont icon-gongsi" />{{ user.fonds.fondsName }}</p>
  7. </div>
  8. <div class="venue-content">
  9. <crudOperation :permission="permission">
  10. <template v-slot:middle>
  11. <el-select v-model="layerVal" clearable size="small" placeholder="楼层" class="filter-item" style="width: 100px; margin-right: 20px;">
  12. <el-option v-for="item in layerOptions" :key="item.id" :label="item.name" :value="item.id" />
  13. </el-select>
  14. <el-button v-permission="permission.add" size="mini" @click="crud.toAdd">
  15. <i class="iconfont icon-shengchengpandiandan" />
  16. 书架盘点
  17. </el-button>
  18. </template>
  19. <template v-slot:right>
  20. <el-button :loading="crud.downloadLoading" size="mini" @click="doExport(crud.selections)">
  21. <i class="iconfont icon-daochu" />
  22. 导出
  23. </el-button>
  24. </template>
  25. </crudOperation>
  26. <div class="venue-left">
  27. <div class="container-right tab-content">
  28. <span class="right-top-line" />
  29. <span class="left-bottom-line" />
  30. <ul class="tab-nav">
  31. <li v-for="(item,index) in tabListData" :key="index" :class="{ 'active-tab-nav': tabIndex == index }" @click="changeActiveTab(index)">{{ item.name }}<i /></li>
  32. <!-- 最右侧装饰img -->
  33. <span class="tab-right-img" />
  34. </ul>
  35. <div class="tag-info">
  36. <p class="tag-sort">错序<i class="iconfont icon-zhuangtai2" />1</p>
  37. <p class="tag-place">错架<i class="iconfont icon-zhuangtai2" />1</p>
  38. <p class="tag-in">在架<i class="iconfont icon-zhuangtai2" />20</p>
  39. </div>
  40. <!-- </div> -->
  41. <div class="shelf-top">
  42. <p v-for="(item,index) in rackNum" :key="index" :style="{width: `calc(${'100%/' + rackNum} - 4px )`}"><span>{{ index+1 + '架' }}</span></p>
  43. </div>
  44. <ul v-loading="listLoading" class="data-shelf-row">
  45. <!-- :class="{ active: i === cellIndex }" -->
  46. <li
  47. v-for="(cell,i) in booShelfGrid"
  48. :key="i"
  49. class="data-shelf-cell"
  50. :style="cellStyle"
  51. @dblclick="handleCellCurrent(cell,i)"
  52. @mouseenter="showPopover(i)"
  53. @mouseleave="hidePopover"
  54. >
  55. <!-- <span class="cell-name">{{ removeAreaPrefix(cell.gridName) }}</span> -->
  56. <div class="tag-info">
  57. <p class="tag-sort"><i class="iconfont icon-zhuangtai2" />1</p>
  58. <p class="tag-place"><i class="iconfont icon-zhuangtai2" />1</p>
  59. <p class="tag-in"><i class="iconfont icon-zhuangtai2" />20</p>
  60. </div>
  61. <el-popover
  62. v-if="popoverIndex === i"
  63. ref="popover"
  64. :visible="popoverVisible[i]"
  65. width="400"
  66. :style="popoverStyles[i]"
  67. trigger="manual"
  68. >
  69. <div slot="reference" class="popover-content">
  70. <div class="tooltip-top">
  71. <h4>层位概况</h4>
  72. <i class="update-time">2024-11-28 09:46</i>
  73. </div>
  74. <ul>
  75. <li><p>层位</p><em class="percentage"><i style="color: #fff;">{{ removeAreaPrefix(cell.gridName) }}</i></em></li>
  76. <li><p>在架</p><em><i>15000</i></em></li>
  77. <li><p>错架</p><em><i>300</i></em> <em class="percentage">2.00%</em></li>
  78. <li><p>错序</p><em><i>0</i></em><em class="percentage">0.00%</em></li>
  79. </ul>
  80. </div>
  81. </el-popover>
  82. </li>
  83. </ul>
  84. </div>
  85. </div>
  86. <div class="venue-right">
  87. <div class="lib-right-item lib-info">
  88. <h4>本架概况</h4>
  89. <ul class="data-right-list">
  90. <li><p>书架</p><span><i>001</i></span></li>
  91. <li><p>规格</p><span><i>双面 6 x 5</i></span></li>
  92. </ul>
  93. </div>
  94. <div class="lib-right-item">
  95. <h4>本架盘点概况</h4>
  96. <div class="refresh-date">2024-11-28 09:46</div>
  97. <ul class="data-right-list">
  98. <li><p>在架</p><span><i>15000</i></span></li>
  99. <li><p>错架</p><span><i>300</i></span> <span class="percentage">2.00%</span></li>
  100. <li><p>错序</p><span><i>0</i></span><span class="percentage">0.00%</span></li>
  101. </ul>
  102. </div>
  103. </div>
  104. </div>
  105. <!-- form -->
  106. <el-dialog append-to-body :close-on-click-modal="false" :modal-append-to-body="false" :before-close="crud.cancelCU" :visible="crud.status.cu > 0" :title="crud.status.title">
  107. <span class="dialog-right-top" />
  108. <span class="dialog-left-bottom" />
  109. <div class="setting-dialog">
  110. <el-form ref="form" :inline="true" :model="form" :rules="rules" size="small" label-width="80px">
  111. <el-form-item label="盘点单号" prop="taskName">
  112. <el-input v-model="form.taskName" />
  113. </el-form-item>
  114. <el-form-item label="盘点类型" prop="taskType">
  115. <el-input v-model="form.taskType" />
  116. </el-form-item>
  117. <el-form-item label="目标位置" prop="location">
  118. <el-input v-model="form.location" />
  119. </el-form-item>
  120. <el-form-item label="目标数量" prop="number">
  121. <el-input v-model="form.number" />
  122. </el-form-item>
  123. <el-row>
  124. <el-form-item label="备注" prop="remark">
  125. <el-input v-model="form.remark" type="textarea" style="width: 572px;" :rows="4" />
  126. </el-form-item>
  127. </el-row>
  128. </el-form>
  129. <div slot="footer" class="dialog-footer">
  130. <el-button type="text" @click="crud.cancelCU">取消</el-button>
  131. <el-button :loading="crud.status.cu === 2" type="primary" @click="crud.submitCU">保存</el-button>
  132. </div>
  133. </div>
  134. </el-dialog>
  135. </div>
  136. </template>
  137. <script>
  138. import { FetchInitShelfGridByShelfId, FetchBookShelfDetails } from '@/api/shelf/index'
  139. import crudRegion from '@/api/area/index'
  140. import CRUD, { presenter, header, form, crud } from '@crud/crud'
  141. import crudOperation from '@crud/CRUD.operation'
  142. import { mapGetters } from 'vuex'
  143. const defaultForm = { id: null, taskType: null, taskName: null, location: null, number: null, remark: null }
  144. export default {
  145. name: 'DataScreening',
  146. components: { crudOperation },
  147. cruds() {
  148. return CRUD({ title: '架位总览', url: 'api/libraryRegion/initLibraryRegionList', crudMethod: { ...crudRegion }, sort: [], optShow: {
  149. add: false,
  150. edit: false,
  151. del: false,
  152. download: false,
  153. group: false,
  154. reset: false
  155. },
  156. queryOnPresenterCreated: false
  157. })
  158. },
  159. mixins: [presenter(), header(), form(defaultForm), crud()],
  160. data() {
  161. const _this = this
  162. return {
  163. listLoading: false,
  164. tabIndex: 0,
  165. floorName: null,
  166. regionName: null,
  167. rowType: null,
  168. bookShelfDetails: null,
  169. booShelfGrid: null,
  170. cellInfo: {
  171. gridName: null,
  172. startSortmark: null,
  173. endSortmark: null,
  174. cameraId: null
  175. },
  176. callNumVisible: false,
  177. layerNum: 0,
  178. rackNum: 0,
  179. swiperActiveIndex: 0,
  180. cellIndex: null,
  181. swiperOptionContent: {
  182. slidesPerView: 'auto',
  183. on: {
  184. slideChangeTransitionStart: function() {
  185. _this.cellIndex = null
  186. _this.swiperActiveIndex = this.activeIndex
  187. console.log('activeIndexffff', this.swiperActiveIndex)
  188. _this.swiperTitle.slideTo(this.activeIndex, 500, false)
  189. }
  190. }
  191. },
  192. swiperOptionTitle: {
  193. slidesPerView: 'auto',
  194. freeMode: true
  195. },
  196. layerVal: '001排',
  197. layerOptions: [{ id: 1, name: '001排' }],
  198. tabListData: [],
  199. permission: {
  200. add: ['admin', 'floor:add'],
  201. edit: ['admin', 'floor:edit'],
  202. del: ['admin', 'floor:del']
  203. },
  204. rules: {
  205. taskName: [
  206. { required: true, message: '请输入盘点单号', trigger: 'blur' }
  207. ],
  208. taskType: [
  209. { required: true, message: '请输入盘点类型', trigger: 'blur' }
  210. ],
  211. location: [
  212. { required: true, message: '请输入目标位置', trigger: 'blur' }
  213. ],
  214. number: [
  215. { required: true, message: '请输入目标数量', trigger: 'blur' }
  216. ]
  217. },
  218. popoverIndex: null,
  219. popoverVisible: [],
  220. popoverStyles: []
  221. }
  222. },
  223. computed: {
  224. ...mapGetters([
  225. 'user',
  226. 'baseApi'
  227. ]),
  228. swiperContent() {
  229. return this.$refs.swiperContent.$el.swiper
  230. },
  231. swiperTitle() {
  232. return this.$refs.swiperTitle.$el.swiper
  233. },
  234. cellStyle: function() {
  235. // const h = '100%/' + this.layerNum
  236. // const w = '100%/' + this.rackNum
  237. const h = '76px'
  238. const w = '100%/' + this.rackNum
  239. return { width: `calc(${w} )`, height: `calc(${h})` }
  240. }
  241. },
  242. async created() {
  243. if (localStorage.getItem('dataScreenRegion')) {
  244. const dataScreenRegion = JSON.parse(localStorage.getItem('dataScreenRegion'))
  245. this.floorName = dataScreenRegion.floorName
  246. this.regionName = dataScreenRegion.regionName
  247. this.rowType = dataScreenRegion.rowType
  248. // 单面/双面
  249. this.tabListData = dataScreenRegion.rowType === 1
  250. ? dataScreenRegion.toward === 1
  251. ? [{ name: 'A面' }]
  252. : [{ name: 'B面' }]
  253. : [{ name: 'A面' }, { name: 'B面' }]
  254. FetchBookShelfDetails({ 'shelfId': dataScreenRegion.id }).then(res => {
  255. this
  256. this.layerNum = res.shelfFloor
  257. this.rackNum = res.shelfShelf
  258. this.bookShelfDetails = res
  259. this.getInitShelfGridByShelfId(this.bookShelfDetails.toward)
  260. }).catch(() => {
  261. })
  262. }
  263. },
  264. methods: {
  265. [CRUD.HOOK.beforeRefresh]() {
  266. },
  267. [CRUD.HOOK.afterRefresh](crud) {
  268. },
  269. // 提交前的验证
  270. [CRUD.HOOK.afterValidateCU](crud) {
  271. return true
  272. },
  273. removeAreaPrefix(gridNames) {
  274. const index = gridNames.indexOf('区')
  275. if (index !== -1) {
  276. return gridNames.substring(index + 1)
  277. }
  278. return gridNames
  279. },
  280. getInitShelfGridByShelfId(toward) {
  281. this.listLoading = true
  282. // rowType 1 单 2 双
  283. // toward 1 A面 2 B面
  284. // shelfType 1 '始终最左边为第1架(S型排架)'
  285. // shelfType 2 'A面最左为第1架(B面最左为最后1架)'
  286. // shelfType 3 'B面最左为第1架(A面最左为最后1架)'
  287. // floorType 1 '最顶层为第一层(从上至下)'
  288. // floorType 2 '最底层为第一层(从下至上)'
  289. FetchInitShelfGridByShelfId({ 'shelfId': this.bookShelfDetails.id, 'toward': toward }).then(res => {
  290. const sortFunction = toward === 1 ? {
  291. 1: { 1: 'sortBookshelvesLeftTop', 2: 'sortBookshelvesLeftBottom' },
  292. 2: { 1: 'sortBookshelvesLeftTop', 2: 'sortBookshelvesLeftBottom' },
  293. 3: { 1: 'sortBookshelvesRightTop', 2: 'sortBookshelvesRightBottom' }
  294. } : {
  295. 1: { 1: 'sortBookshelvesLeftTop', 2: 'sortBookshelvesLeftBottom' },
  296. 2: { 1: 'sortBookshelvesRightTop', 2: 'sortBookshelvesRightBottom' },
  297. 3: { 1: 'sortBookshelvesLeftTop', 2: 'sortBookshelvesLeftBottom' }
  298. }
  299. const shelfType = this.bookShelfDetails.shelfType
  300. const floorType = this.bookShelfDetails.floorType
  301. const sortMethod = sortFunction[shelfType][floorType]
  302. this.booShelfGrid = this[sortMethod](res)
  303. this.popoverVisible = Array(this.booShelfGrid.length).fill(false)
  304. setTimeout(() => {
  305. this.listLoading = false
  306. }, 1000)
  307. }).catch(() => {
  308. })
  309. },
  310. // 最左为第一架, 最顶层为第一层 从上往下
  311. sortBookshelvesLeftTop(data) {
  312. const sortedData = []
  313. const maxFloor = Math.max(...data.map(item => parseInt(item.gridFloor)))
  314. const maxShelf = Math.max(...data.map(item => parseInt(item.gridShelf.slice(-1))))
  315. for (let i = 1; i <= maxFloor; i++) {
  316. for (let j = 1; j <= maxShelf; j++) {
  317. const currentShelf = data.find(item => parseInt(item.gridFloor) === i && parseInt(item.gridShelf.slice(-1)) === j)
  318. if (currentShelf) {
  319. sortedData.push(currentShelf)
  320. }
  321. }
  322. }
  323. return sortedData
  324. },
  325. // 最右为第一架,最左为最后一架, 最顶层为第一层 从上往下
  326. sortBookshelvesRightTop(data) {
  327. const sortedData = []
  328. // 获取最大的楼层数
  329. const maxFloor = Math.max(...data.map(item => parseInt(item.gridFloor)))
  330. const maxShelf = Math.max(...data.map(item => parseInt(item.gridShelf.match(/\d+$/)[0])))
  331. for (let i = 1; i <= maxFloor; i++) {
  332. // 从最大的书架层数开始,向下排序
  333. for (let j = maxShelf; j >= 1; j--) {
  334. const currentShelf = data.find(item => parseInt(item.gridFloor) === i && parseInt(item.gridShelf.match(/\d+$/)[0]) === j)
  335. if (currentShelf) {
  336. sortedData.push(currentShelf)
  337. }
  338. }
  339. }
  340. return sortedData
  341. },
  342. // 最左为第一架, 最底层为第一层 从下往上
  343. sortBookshelvesLeftBottom(data) {
  344. const sortedData = []
  345. // 获取最大的楼层数
  346. const maxFloor = Math.max(...data.map(item => parseInt(item.gridFloor)))
  347. // 获取最大的书架层数
  348. const maxShelf = Math.max(...data.map(item => parseInt(item.gridShelf.slice(-1))))
  349. for (let i = maxFloor; i >= 1; i--) {
  350. for (let j = 1; j <= maxShelf; j++) {
  351. const currentShelf = data.find(item => parseInt(item.gridFloor) === i && parseInt(item.gridShelf.slice(-1)) === j)
  352. if (currentShelf) {
  353. sortedData.push(currentShelf)
  354. }
  355. }
  356. }
  357. return sortedData
  358. },
  359. // 最左为最后一架, 最底层为第一层 从下往上
  360. sortBookshelvesRightBottom(data) {
  361. const sortedData = []
  362. // 获取最大的楼层数
  363. const maxFloor = Math.max(...data.map(item => parseInt(item.gridFloor)))
  364. const maxShelfPerFloor = data.map(item => parseInt(item.gridShelf.match(/\d+$/)[0]))
  365. .reduce((acc, curr, index, arr) => {
  366. const floor = parseInt(data[index].gridFloor)
  367. if (!acc[floor]) acc[floor] = 1
  368. if (acc[floor] < curr) acc[floor] = curr
  369. return acc
  370. }, {})
  371. // 从最大的楼层开始向下遍历
  372. for (let i = maxFloor; i >= 1; i--) {
  373. // 从最大的书架编号开始向左遍历
  374. for (let j = maxShelfPerFloor[i] || 1; j >= 1; j--) {
  375. const currentShelf = data.find(item => parseInt(item.gridFloor) === i && parseInt(item.gridShelf.match(/\d+$/)[0]) === j)
  376. if (currentShelf) {
  377. sortedData.push(currentShelf)
  378. }
  379. }
  380. }
  381. return sortedData
  382. },
  383. changeActiveTab(index) {
  384. this.tabIndex = index
  385. this.cellIndex = null
  386. this.getInitShelfGridByShelfId(index + 1)
  387. },
  388. handleCellCurrent(item, index) {
  389. console.log('index', index)
  390. console.log('item', item)
  391. this.cellIndex = index
  392. this.cellInfo = {
  393. id: item.id,
  394. gridName: item.gridName,
  395. gridRow: item.gridRow,
  396. gridShelf: item.gridShelf,
  397. shelfId: item.shelfId,
  398. floorName: this.floorName,
  399. regionName: this.regionName,
  400. rowType: this.rowType,
  401. toward: item.toward
  402. }
  403. this.handleToGrids(this.cellInfo)
  404. },
  405. handleToGrids(data) {
  406. this.$router.push({ path: '/dataScreening/gird' })
  407. localStorage.setItem('dataScreenShelf', JSON.stringify(data))
  408. },
  409. showPopover(index) {
  410. this.popoverIndex = index
  411. if (!this.popoverVisible[index]) {
  412. this.$set(this.popoverVisible, index, true)
  413. }
  414. const lastColumnIndexes = []
  415. const secondLastColumnIndexes = []
  416. for (let i = 0; i < this.booShelfGrid.length; i++) {
  417. const columnIndex = i % this.rackNum
  418. // 如果是最后一列(第5列)
  419. if (columnIndex === this.rackNum - 1) {
  420. lastColumnIndexes.push(i)
  421. // 更新最后一列的样式
  422. // this.$set(this.popoverStyles, i, { position: 'absolute', left: '0', top: '20px' })
  423. }
  424. // 如果是倒数第二列(第4列)
  425. if (columnIndex === this.rackNum - 2) {
  426. secondLastColumnIndexes.push(i)
  427. // 更新倒数第二列的样式
  428. // this.$set(this.popoverStyles, i, { position: 'absolute', left: '-20px', top: '20px' })
  429. }
  430. }
  431. },
  432. hidePopover() {
  433. this.popoverIndex = null
  434. // 隐藏所有的popover
  435. this.popoverVisible.forEach((isVisible, index) => {
  436. if (isVisible) {
  437. this.$set(this.popoverVisible, index, false)
  438. }
  439. })
  440. }
  441. }
  442. }
  443. </script>
  444. <style lang="scss" scoped>
  445. .container-right{
  446. min-height: calc(100vh - 232px) !important;
  447. }
  448. .venue-content{
  449. position: relative;
  450. }
  451. .crud-opts{
  452. position: absolute;
  453. right: 20px;
  454. top: 10px;
  455. }
  456. .venue-left{
  457. flex: 1;
  458. margin-right: 0 !important;
  459. .venue-preview{
  460. height: 633px !important;
  461. }
  462. }
  463. .venue-right{
  464. display: flex;
  465. flex-direction: column;
  466. width: 400px;
  467. padding: 50px 10px 20px 10px !important;
  468. .lib-right-item{
  469. position: relative;
  470. padding-bottom: 10px;
  471. margin-bottom: 10px;
  472. border: 1px solid #E8F2FF;
  473. border-radius: 4px;
  474. h4{
  475. padding: 6px 10px;
  476. background-color: #E8F2FF;
  477. color: #000;
  478. line-height: 30px;
  479. border-bottom: 1px solid #edeff3;
  480. }
  481. .refresh-date{
  482. position: absolute;
  483. right: 14px;
  484. top: 10px;
  485. font-size: 12px;
  486. line-height: 30px;
  487. }
  488. }
  489. }
  490. .data-right-list {
  491. padding-top: 10px;
  492. li{
  493. display: flex;
  494. justify-content: flex-start;
  495. align-items: center;
  496. line-height: 36px;
  497. p{
  498. width: 80px;
  499. font-weight: bold;
  500. text-align: right;
  501. }
  502. span{
  503. width: 140px;
  504. display: block;
  505. text-align: right;
  506. i{
  507. font-style: normal;
  508. font-weight: bold;
  509. padding: 0 10px;
  510. color: #0348f3;
  511. }
  512. &.percentage{
  513. width: auto;
  514. }
  515. }
  516. }
  517. }
  518. .tag-info{
  519. position: absolute;
  520. right: 20px;
  521. top: 8px;
  522. p{
  523. margin-left: 20px;
  524. }
  525. }
  526. .shelf-top{
  527. display: flex;
  528. justify-content: space-around;
  529. align-items: center;
  530. text-align: center;
  531. margin-top: 20px;
  532. p{
  533. font-size: 14px;
  534. color: #fff;
  535. height: 36px;
  536. line-height: 30px;
  537. background: url('~@/assets/images/shelf04.png') no-repeat center top;
  538. background-size: auto 100%;
  539. }
  540. }
  541. .data-shelf-row{
  542. display: flex;
  543. flex: 1;
  544. flex-wrap: wrap;
  545. text-align: center;
  546. // margin-top: -2px;
  547. // padding-top: 40px;
  548. .data-shelf-cell{
  549. position: relative;
  550. font-size: 14px;
  551. color: #0C0E1E;
  552. background: url('~@/assets/images/shelf02.png') repeat-x left top;
  553. background-size: 20% 100%;
  554. border-radius: 3px;
  555. cursor: pointer;
  556. .tag-info{
  557. right: 12px;
  558. top: 44px;
  559. p{
  560. margin-left: 10px;
  561. }
  562. }
  563. &::before{
  564. content: "";
  565. position: absolute;
  566. left: 0;
  567. top: 0;
  568. width: 6px;
  569. height: 76px;
  570. background: url('~@/assets/images/shelf01.png') no-repeat left top;
  571. background-size: 100% 100%;
  572. }
  573. &::after{
  574. content: "";
  575. position: absolute;
  576. right: -4px;
  577. top: 0;
  578. width: 6px;
  579. height: 76px;
  580. background: url('~@/assets/images/shelf01.png') no-repeat left top;
  581. background-size: 100% 100%;
  582. }
  583. .cell-name{
  584. display: block;
  585. width: 100%;
  586. line-height: 76px;
  587. }
  588. &.active{
  589. color: #fff;
  590. background-color: #0348F3;
  591. }
  592. }
  593. }
  594. ::v-deep .data-shelf-row span.el-popover__reference-wrapper{
  595. position: absolute !important;
  596. left: 60% !important;
  597. top: 48px !important;
  598. width: 300px;
  599. height: 210px;
  600. background:rgba(0,0,0,.8);
  601. color: #fff;
  602. border-radius: 6px;
  603. z-index: 99999999;
  604. .popover-content{
  605. .tooltip-top{
  606. display: flex;
  607. justify-content: space-between;
  608. align-items: center;
  609. height: 40px;
  610. line-height: 40px;
  611. padding: 0 10px;
  612. border-bottom: 1px solid #fff;
  613. }
  614. .tooltip-top i{
  615. font-style: normal;
  616. font-size: 12px;
  617. }
  618. ul{
  619. padding: 10px;
  620. }
  621. ul li{
  622. display: flex;
  623. justify-content: flex-start;
  624. align-items: center;
  625. line-height: 36px;
  626. font-style: normal;
  627. }
  628. ul li p{
  629. width: 80px;
  630. font-weight: bold;
  631. text-align: right;
  632. }
  633. ul li em{
  634. width: 100px;
  635. display: block;
  636. text-align: right;
  637. font-style: normal;
  638. }
  639. ul li i{
  640. font-style: normal;
  641. font-weight: bold;
  642. padding: 0 10px;
  643. color: #0348f3;
  644. }
  645. ul li em.percentage{
  646. width: auto;
  647. }
  648. }
  649. }
  650. </style>