Detail.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580
  1. <template>
  2. <div>
  3. <a-card :bordered="false" :loading="loading" v-show="visible" class="card" :title="modalTitle">
  4. <a-row :gutter="48" slot="extra">
  5. <a-col :md="48" :sm="48">
  6. <span class="table-page-search-submitButtons" style="float: right">
  7. <a-button style="margin-left: 8px" @click="handleCancel">返回</a-button>
  8. </span>
  9. </a-col>
  10. </a-row>
  11. <a-layout>
  12. <a-layout-content style="background-color: rgb(255, 255, 255)">
  13. <a-divider orientation="left">报修详情</a-divider>
  14. <detail-list title="" :col="3">
  15. <detail-list-item term="报修单号">{{ model.no }}</detail-list-item>
  16. <detail-list-item term="设备编号">{{ model.sbNo }}</detail-list-item>
  17. <detail-list-item term="设备名称">{{ model.sbName }}</detail-list-item>
  18. <!-- <detail-list-item term="预留维修时间">{{ model.limitHours }}</detail-list-item> -->
  19. <detail-list-item term="使用位置">{{ model.sbCph }}</detail-list-item>
  20. <!--<detail-list-item term="部件名称">{{ model.partName }}</detail-list-item>-->
  21. <detail-list-item term="工单类别">{{ BaseTool.Object.getField(planFlagMap, model.category) }}</detail-list-item>
  22. <!-- <detail-list-item term="是否停机">{{ BaseTool.Object.getField(needStopMap,model.needStop) }}</detail-list-item>-->
  23. <detail-list-item term="报修人">{{ model.actualUser }}</detail-list-item>
  24. <detail-list-item term="报修来源">{{ BaseTool.Object.getField(this.sourceMap, model.source)
  25. }}</detail-list-item>
  26. <!-- <detail-list-item term="紧急等级"><badge :text="BaseTool.Object.getField(levelMap,model.level)" :status="DictCache.COLOR.REPAIR_APPLICATION_FORM_LEVEL[model.applicationLevel]"/></detail-list-item>-->
  27. <detail-list-item term="报修时间">{{ model.applyTime }}</detail-list-item>
  28. <detail-list-item term="报修状态">
  29. <badge :text="BaseTool.Object.getField(statusMap, model.status)"
  30. :status="DictCache.COLOR.REPAIR_APPLICATION_FORM_STATUS[model.status]" />
  31. </detail-list-item>
  32. <detail-list-item term="要求时间">{{ model.limitHours }}小时</detail-list-item>
  33. <detail-list-item term="要求日期">{{ model.limitDate }}</detail-list-item>
  34. </detail-list>
  35. <detail-list title="" :col="1">
  36. <!--<detail-list-item term="故障描述">{{ BaseTool.Object.getField(this.descripitionMap, model.content) }}</detail-list-item>-->
  37. <detail-list-item term="故障描述">{{ model.content }}</detail-list-item>
  38. </detail-list>
  39. <title-divider title="报修图片" width="90px"></title-divider>
  40. <detail-list title="" :col="1">
  41. <detail-list-item term="" v-if="model.applicationFileList != null && model.applicationFileList.length > 0">
  42. <viewer :images="model.applicationFileList" @inited="inited" ref="viewer" :index="1">
  43. <img v-for="item in model.applicationFileList" :src="item.url" :key="item.id" class="image">
  44. </viewer>
  45. </detail-list-item>
  46. <detail-list-item term=""
  47. v-if="model.applicationFileList == null || model.applicationFileList.length === 0">
  48. 暂无
  49. </detail-list-item>
  50. </detail-list>
  51. <a-divider orientation="left">维修详情</a-divider>
  52. <detail-list title="" :col="3">
  53. <!-- <detail-list-item term="故障类别">{{ model.repairErrorTypeName }}</detail-list-item>-->
  54. <detail-list-item term="维修开始时间">{{ model.repairStartTime }}</detail-list-item>
  55. <detail-list-item term="维修结束时间">{{ model.repairEndTime }}</detail-list-item>
  56. <detail-list-item term="维修耗时">{{ model.repairMinutes }}小时</detail-list-item>
  57. <detail-list-item term="维修人员">{{ model.repairUserName }}</detail-list-item>
  58. <!--<detail-list-item term="维修次数">{{ model.repairTimes }}</detail-list-item>-->
  59. </detail-list>
  60. <detail-list title="" :col="1">
  61. <detail-list-item term="维修描述">{{ model.repairContent }}</detail-list-item>
  62. </detail-list>
  63. <title-divider title="维修图片" width="90px"></title-divider>
  64. <detail-list title="" :col="1">
  65. <detail-list-item term="" v-if="model.repairFileList != null && model.repairFileList.length > 0">
  66. <viewer :images="model.repairFileList" @inited="inited" ref="viewer" :index="1">
  67. <img v-for="item in model.repairFileList" :src="item.url" :key="item.id" class="image">
  68. </viewer>
  69. </detail-list-item>
  70. <detail-list-item term="" v-if="model.repairFileList == null || model.repairFileList.length === 0">
  71. 暂无
  72. </detail-list-item>
  73. </detail-list>
  74. <a-divider v-if="dispatchList != null" orientation="left">转派详情</a-divider>
  75. <detail-list v-for="(item, index) in dispatchList" title="" :key="index" :col="3">
  76. <detail-list-item term="转派人">{{ item.username }}</detail-list-item>
  77. <detail-list-item term="转派时间">{{ item.time }}</detail-list-item>
  78. <detail-list-item term="转派备注">{{ item.remark }}</detail-list-item>
  79. <detail-list-item term="审批状态" v-if="item.type === 'transfer'">
  80. <badge :text="getTransferStatusText(item.status)" :status="getTransferBadgeStatus(item.status)" />
  81. </detail-list-item>
  82. <detail-list-item v-if="item.approverName" term="审批人">{{ item.approverName }}</detail-list-item>
  83. <detail-list-item v-if="item.approveTime" term="审批时间">{{ item.approveTime }}</detail-list-item>
  84. <detail-list-item v-if="item.approveRemark" term="审批意见">{{ item.approveRemark }}</detail-list-item>
  85. </detail-list>
  86. <a-divider orientation="left">审核详情</a-divider>
  87. <detail-list title="" :col="3">
  88. <detail-list-item term="审核开始时间">{{ model.checkStartTime }}</detail-list-item>
  89. <detail-list-item term="审核结束时间">{{ model.checkEndTime }}</detail-list-item>
  90. <detail-list-item term="审核人员">{{ model.checkUserName }}</detail-list-item>
  91. <detail-list-item term="审核描述">{{ model.checkContent }}</detail-list-item>
  92. </detail-list>
  93. <detail-list title="审核图片:" :col="6">
  94. <upload-image-detail :images-list="model.checkFileList" />
  95. </detail-list>
  96. </a-layout-content>
  97. <a-layout-sider style="background-color: rgb(255, 255, 255)">
  98. <div style="margin-top: 30px;margin-left: 30px;">
  99. <a-steps progress-dot :current="6" direction="vertical">
  100. <a-step title="报修时间:" :description="'' + model.applyTime ? model.applyTime : ''" />
  101. <a-step title="维修开始时间:" :description="'' + model.repairStartTime ? model.repairStartTime : ''" />
  102. <a-step title="维修结束时间:" :description="'' + model.repairEndTime ? model.repairEndTime : ''" />
  103. <a-step title="审核开始时间:" :description="'' + model.checkStartTime ? model.checkStartTime : ''" />
  104. <a-step title="审核结束时间:" :description="'' + model.checkEndTime ? model.checkEndTime : ''" />
  105. </a-steps>
  106. </div>
  107. </a-layout-sider>
  108. </a-layout>
  109. <!-- <title-divider title="配件清单" width="90px"></title-divider>
  110. <a-table :data-source="dataSpare" :columns="columnsSpare" tableLayout="auto" rowKey="id">
  111. </a-table>-->
  112. <title-divider title="委外记录" width="90px"></title-divider>
  113. <a-table :data-source="dataFee" :columns="columnsFee" tableLayout="auto" rowKey="id">
  114. <span slot="action" slot-scope="record">
  115. <template>
  116. <a @click="handleViewFee(record)">查看</a>
  117. </template>
  118. </span>
  119. </a-table>
  120. <!--<title-divider title="维修报告" width="90px"></title-divider>
  121. <a-table :data-source="dataReason" :columns="columnsReason" tableLayout="fixed" rowKey="id">
  122. <span slot="action" slot-scope="record">
  123. <template>
  124. <a @click="handleViewReason(record)">查看</a>
  125. </template>
  126. </span>
  127. </a-table> -->
  128. </a-card>
  129. <check-form ref="checkForm" @ok="handleOk" />
  130. <fee-base-form ref="feeForm" @ok="handleOk" />
  131. <reason-base-form ref="reasonForm" @ok="handleOk" />
  132. <finish-form ref="finishForm" @ok="handleOk" />
  133. <dispatch-form ref="dispatchForm" @ok="handleCancel" />
  134. <fee-detail ref="feeDetail" @ok="handleOk" />
  135. <reason-detail ref="reasonDetail" @ok="handleOk" />
  136. </div>
  137. </template>
  138. <script>
  139. import DetailList from '@/components/tools/DetailList'
  140. import { fetchRepairApplicationForm, approve, receive } from '@/api/repair/application-form'
  141. import CheckForm from './CheckForm'
  142. import FinishForm from './FinishForm'
  143. import DispatchForm from './DispatchForm'
  144. import SparePartUsedSelectTable from '@/views/sqarepartmanage/sparepartused/modules/SparePartUsedSelectTable'
  145. import SparePickFormSelectTable from '@/views/store/sparepickform/modules/SparePickFormSelectTable'
  146. import { selectSparePartUsedListByRepairId } from '@/api/sqarepartmanage/sparepartused'
  147. import { selectRepairProjectListByRepairId } from '@/api/repair/repairprojectrelation'
  148. import FeeBaseForm from '@/views/repair/fee/modules/BaseForm'
  149. import ReasonBaseForm from '@/views/repair/repair-reason/modules/BaseForm'
  150. import FeeDetail from '@/views/repair/fee/modules/Detail'
  151. import ReasonDetail from '@/views/repair/repair-reason/modules/Detail'
  152. import { deleteRepairFees, fetchRepairFee, queryRepairFee } from '@/api/repair/fee'
  153. import { deleteRepairReasons, fetchRepairReason, queryRepairReason } from '@/api/repair/repair-reason'
  154. const DetailListItem = DetailList.Item
  155. export default {
  156. name: 'RepairApplicationFormDetail',
  157. components: {
  158. CheckForm,
  159. DetailList,
  160. DetailListItem,
  161. FinishForm,
  162. FeeDetail,
  163. ReasonDetail,
  164. FeeBaseForm,
  165. ReasonBaseForm,
  166. DispatchForm,
  167. SparePartUsedSelectTable,
  168. SparePickFormSelectTable,
  169. },
  170. data() {
  171. return {
  172. confirmLoading: false,
  173. mdl: {},
  174. modalTitle: null,
  175. needStopMap: {},
  176. planFlagMap: {},
  177. dispatchList: [],
  178. activeKey: 'a',
  179. visible: false,
  180. loading: false,
  181. // 下拉框map
  182. sourceMap: {},
  183. levelMap: {},
  184. descripitionMap: {},
  185. statusMap: {},
  186. typeMap: {},
  187. typeReasonMap: {},
  188. repairProjectMap: {},
  189. repairTechnologyMap: {},
  190. data: [],
  191. dataSpare: [],
  192. dataFee: [],
  193. dataReason: [],
  194. // 表头
  195. columns: [
  196. {
  197. title: '序号',
  198. dataIndex: 'index',
  199. customRender: (text, record, index) => {
  200. return `${index + 1}`
  201. },
  202. },
  203. {
  204. title: '编码',
  205. dataIndex: 'no',
  206. },
  207. {
  208. title: '名称',
  209. dataIndex: 'name',
  210. },
  211. {
  212. title: '维修类别',
  213. dataIndex: 'type',
  214. customRender: (text, record, index) => {
  215. return this.BaseTool.Object.getField(this.repairProjectMap, text)
  216. },
  217. },
  218. {
  219. title: '维修工艺',
  220. dataIndex: 'technology',
  221. customRender: (text, record, index) => {
  222. return this.BaseTool.Object.getField(this.repairTechnologyMap, text)
  223. },
  224. },
  225. {
  226. title: '标准工时',
  227. dataIndex: 'standardHours',
  228. },
  229. {
  230. title: '标准费用',
  231. dataIndex: 'standardMoney',
  232. },
  233. {
  234. title: '考核工时',
  235. dataIndex: 'checkHours',
  236. },
  237. ],
  238. columnsSpare: [
  239. {
  240. title: '序号',
  241. dataIndex: 'index',
  242. customRender: (text, record, index) => {
  243. return `${index + 1}`
  244. },
  245. },
  246. {
  247. title: '备件名称',
  248. dataIndex: 'spareId',
  249. customRender: (text, record, index) => {
  250. return record.spareName
  251. },
  252. },
  253. {
  254. title: '数量',
  255. dataIndex: 'num',
  256. },
  257. {
  258. title: '价格',
  259. dataIndex: 'price',
  260. },
  261. {
  262. title: '总价',
  263. dataIndex: 'totalPrice',
  264. },
  265. ],
  266. columnsFee: [
  267. {
  268. title: '序号',
  269. dataIndex: 'index',
  270. customRender: (text, record, index) => {
  271. return `${index + 1}`
  272. },
  273. },
  274. {
  275. title: '费用金额',
  276. dataIndex: 'fee',
  277. customRender: (text, record, index) => {
  278. return this.BaseTool.Amount.formatter(text)
  279. },
  280. },
  281. {
  282. title: '费用类别',
  283. dataIndex: 'type',
  284. customRender: (text, record, index) => {
  285. return this.BaseTool.Object.getField(this.typeMap, text)
  286. },
  287. },
  288. {
  289. title: '费用原因',
  290. dataIndex: 'reason',
  291. },
  292. {
  293. title: '费用描述',
  294. dataIndex: 'descripition',
  295. },
  296. {
  297. title: '备注',
  298. dataIndex: 'remark',
  299. },
  300. ],
  301. columnsReason: [
  302. {
  303. title: '序号',
  304. dataIndex: 'index',
  305. width: '70',
  306. customRender: (text, record, index) => {
  307. return `${index + 1}`
  308. },
  309. },
  310. {
  311. title: '分析时间',
  312. dataIndex: 'analyzeTime',
  313. width: '200px',
  314. },
  315. {
  316. title: '问题描述',
  317. dataIndex: 'problemDesc',
  318. ellipsis: true,
  319. width: '200px',
  320. },
  321. {
  322. title: '维修报告',
  323. dataIndex: 'reasonAnalysis',
  324. ellipsis: true,
  325. width: '200px',
  326. },
  327. {
  328. title: '改进措施类别',
  329. dataIndex: 'improveMeasure',
  330. ellipsis: true,
  331. width: '200px',
  332. customRender: (text, record, index) => {
  333. return this.BaseTool.Object.getField(this.typeReasonMap, text)
  334. },
  335. },
  336. {
  337. title: '操作',
  338. key: 'action',
  339. width: '200px',
  340. align: 'center',
  341. scopedSlots: { customRender: 'action' },
  342. },
  343. ],
  344. model: {
  345. id: null,
  346. sbId: null,
  347. partId: null,
  348. repairUserId: null,
  349. needStop: null,
  350. category: null,
  351. no: null,
  352. source: null,
  353. applyTime: null,
  354. level: null,
  355. limitHours: null,
  356. limitDate: null,
  357. content: null,
  358. status: null,
  359. remark: null,
  360. updateTime: null,
  361. createdUserId: null,
  362. updateUserId: null,
  363. createdUserName: null,
  364. sbName: null,
  365. partName: null,
  366. updateUserName: null,
  367. repairFormVO: null,
  368. repairCheckVO: null,
  369. },
  370. }
  371. },
  372. created() {
  373. // 下拉框map
  374. this.sourceMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.REPAIR_APPLICATION_FORM_SOURCE)
  375. this.levelMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.REPAIR_APPLICATION_FORM_LEVEL)
  376. this.statusMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.REPAIR_APPLICATION_FORM_STATUS)
  377. this.statusRepairMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.REPAIR_FORM_STATUS)
  378. this.statusCheckMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.REPAIR_CHECK_STATUS)
  379. this.needStopMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.YES_NO)
  380. this.planFlagMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.REPAIR_APPLICATION_FORM_CATEGORY)
  381. this.repairProjectMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.REPAIR_PROJECT_TYPE)
  382. this.repairTechnologyMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.REPAIR_TECHNOLOGY_TYPE)
  383. this.descripitionMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.REPAIR_QUESTION)
  384. this.typeMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.REPAIR_FEE_TYPE)
  385. this.typeReasonMap = this.DictCache.getLabelByValueMapByType(this.DictCache.TYPE.REPAIR_REASON_TYPE)
  386. },
  387. methods: {
  388. base(record) {
  389. this.visible = true
  390. this.modalTitle = '详情'
  391. this.model = record
  392. this.dispatchList = JSON.parse(record.repairDispatchList)
  393. this.init()
  394. },
  395. init() {
  396. selectRepairProjectListByRepairId({ id: this.model.id }).then((res) => {
  397. this.data = res.data
  398. })
  399. selectSparePartUsedListByRepairId({ id: this.model.id }).then((res) => {
  400. this.dataSpare = res.data
  401. })
  402. queryRepairFee({ repairId: this.model.id }).then((res) => {
  403. this.dataFee = res.data
  404. })
  405. queryRepairReason({ repairId: this.model.id }).then((res) => {
  406. this.dataReason = res.data
  407. })
  408. },
  409. handleCancel() {
  410. this.visible = false
  411. this.confirmLoading = false
  412. this.$emit('ok')
  413. },
  414. receive() {
  415. receive(this.model).then(() => {
  416. this.$message.info('任务接收成功,请及时维修')
  417. this.handleOk()
  418. })
  419. },
  420. batchDeleteFee(id) {
  421. let ids = []
  422. if (this.BaseTool.String.isBlank(id)) {
  423. const length = this.selectedRows.length
  424. if (length === 0) {
  425. this.$message.info('请选择要删除的记录')
  426. return
  427. }
  428. ids = this.selectedRows.map((item) => item.id)
  429. } else {
  430. ids = [id]
  431. }
  432. deleteRepairFees(ids).then((res) => {
  433. this.$message.info('删除成功')
  434. this.handleOk()
  435. this.$refs.table.clearSelected()
  436. })
  437. },
  438. handleAddFee() {
  439. const modal = this.$refs.feeForm
  440. modal.base(null, this.model)
  441. },
  442. handleEditFee(record) {
  443. fetchRepairFee({ id: record.id }).then((res) => {
  444. const modal = this.$refs.feeForm
  445. modal.base(res.data, this.model)
  446. })
  447. },
  448. handleViewFee(record) {
  449. fetchRepairFee({ id: record.id }).then((res) => {
  450. const modal = this.$refs.feeDetail
  451. modal.base(res.data)
  452. })
  453. },
  454. batchDeleteReason(id) {
  455. let ids = []
  456. if (this.BaseTool.String.isBlank(id)) {
  457. const length = this.selectedRows.length
  458. if (length === 0) {
  459. this.$message.info('请选择要删除的记录')
  460. return
  461. }
  462. ids = this.selectedRows.map((item) => item.id)
  463. } else {
  464. ids = [id]
  465. }
  466. deleteRepairReasons(ids).then((res) => {
  467. this.$message.info('删除成功')
  468. this.handleOk()
  469. this.$refs.table.clearSelected()
  470. })
  471. },
  472. handleAddReason() {
  473. const modal = this.$refs.reasonForm
  474. this.visible = false
  475. modal.base(null, this.model)
  476. },
  477. handleEditReason(record) {
  478. fetchRepairReason({ id: record.id }).then((res) => {
  479. const modal = this.$refs.reasonForm
  480. this.visible = false
  481. modal.base(res.data, this.model)
  482. })
  483. },
  484. handleViewReason(record) {
  485. fetchRepairReason({ id: record.id }).then((res) => {
  486. const modal = this.$refs.reasonDetail
  487. modal.base(res.data)
  488. })
  489. },
  490. handleApprove() {
  491. approve(this.model).then(() => {
  492. this.$message.info('操作成功')
  493. this.handleOk()
  494. })
  495. },
  496. handleReturn() {
  497. const modal = this.$refs.checkForm
  498. modal.base(this.model)
  499. },
  500. handleOk() {
  501. this.loading = true
  502. fetchRepairApplicationForm({ id: this.model.id }).then((res) => {
  503. this.loading = false
  504. this.model = res.data
  505. this.visible = true
  506. this.dispatchList = JSON.parse(this.model.repairDispatchList)
  507. this.init()
  508. })
  509. },
  510. handleFinish() {
  511. const modal = this.$refs.finishForm
  512. modal.base(this.model)
  513. },
  514. handleSpareSelect() {
  515. this.$refs.spareSelectModal.base()
  516. },
  517. handleDispatch() {
  518. const modal = this.$refs.dispatchForm
  519. modal.base(this.model)
  520. },
  521. changeTab(activeKey) {
  522. this.activeKey = activeKey
  523. if (this.activeKey === 'a' && this.BaseTool.Object.isNotBlank(this.$refs.sparePartUsedSelectTable)) {
  524. const modal = this.$refs.sparePartUsedSelectTable
  525. modal.handleOk()
  526. return
  527. }
  528. if (this.activeKey === 'b' && this.BaseTool.Object.isNotBlank(this.$refs.sparePickFormSelectTable)) {
  529. const modal = this.$refs.sparePickFormSelectTable
  530. modal.handleOk()
  531. }
  532. },
  533. inited(viewer) {
  534. this.$viewer = viewer
  535. },
  536. // 转派记录审批状态文字:pending-待审批 approved-已通过 rejected-已驳回;老数据无 status 字段时按已通过展示(早期转派无审批流程)
  537. getTransferStatusText(status) {
  538. if (status === 'pending') return '待审批'
  539. if (status === 'rejected') return '已驳回'
  540. return '已通过'
  541. },
  542. getTransferBadgeStatus(status) {
  543. if (status === 'pending') return 'warning'
  544. if (status === 'rejected') return 'error'
  545. return 'success'
  546. },
  547. },
  548. }
  549. </script>
  550. <style scoped>
  551. /* For demo */
  552. .ant-carousel {
  553. width: 300px;
  554. height: 300px;
  555. }
  556. .ant-carousel>>>.slick-slide {
  557. text-align: center;
  558. height: 300px;
  559. line-height: 300px;
  560. overflow: hidden;
  561. }
  562. .ant-carousel>>>.slick-slide h3 {
  563. color: #fff;
  564. }
  565. .image {
  566. width: calc(20% - 10px);
  567. cursor: pointer;
  568. margin: 5px;
  569. display: inline-block;
  570. }
  571. </style>