index.vue 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891
  1. <!--
  2. * @Author: your name
  3. * @Date: 2022-01-17 10:39:22
  4. * @LastEditTime: 2022-06-30 09:46:18
  5. * @LastEditors: your name
  6. * @Description: 行李视图
  7. -->
  8. <template>
  9. <div class="baggage-view">
  10. <div ref="basicInfo" class="part1">
  11. <div class="title">
  12. <span>行李基本信息</span>
  13. <el-radio-group v-model="infoBtn" class="radioBtn" size="mini" fill="#FFFFFF" text-color="#28344D">
  14. <el-radio-button v-for="item in infoRadios" :key="item" :label="item" />
  15. </el-radio-group>
  16. </div>
  17. <div class="part1_info">
  18. <el-row :gutter="12">
  19. <el-col v-for="(item, index) in baggageBasicInfoCols" :key="index" :xl="[1, 4, 5].includes(index % 7) ? 4 : 3" :sm="6" :xs="6">
  20. <span class="label">{{ item.label }}:</span><span class="content" :title="formattedBaggageInfo(item.prop)">{{ formattedBaggageInfo(item.prop) }}</span>
  21. </el-col>
  22. </el-row>
  23. </div>
  24. </div>
  25. <div v-show="infoBtn === infoRadios[0]" class="part2">
  26. <div class="part2_info">
  27. <div style="width: 120px" class="title">行李跟踪信息</div>
  28. <div class="type normal">
  29. {{ baggageBasicInfo.BagStatus }}
  30. </div>
  31. <div class="step">
  32. <div class="baggage-track-chart">
  33. <div class="stepLine">
  34. <div :style="{ width: lineWidth }" class="stepLineBlue" />
  35. </div>
  36. <!-- <el-popover
  37. v-for="(item, index) in stepData"
  38. :key="index"
  39. :ref="'popover' + index"
  40. :value="popoverVisible(item)"
  41. :open-delay="500"
  42. placement="left-end"
  43. popper-class="popover-dark"
  44. trigger="manual"
  45. >
  46. <div class="pre-line">{{ messageTooltip(item.resourceFile) }}</div>
  47. <div
  48. slot="reference"
  49. :class="{ 'stepItem': true, activeItem: item.DealTime }"
  50. @mouseenter="itemMouseEnterHandler(item)"
  51. @mouseleave="itemMouseLeaveHandler(item)"
  52. >
  53. <span class="head">
  54. <span>{{ item.NodeNameEN }}</span>
  55. </span>
  56. <span>{{ item.DealTime }}</span>
  57. </div>
  58. </el-popover> -->
  59. <div v-for="(item, index) in stepData" :key="index" :class="{ 'stepItem': true, activeItem: item.DealTime }" @mouseenter="itemMouseEnterHandler(item)" @mouseleave="itemMouseLeaveHandler(item)">
  60. <span class="head">
  61. <!-- {{ item.airPort }} -->
  62. <!-- <span v-if="item.airPort && item.nodeName !== ''">-</span> -->
  63. <span>{{ item.NodeNameEN }}</span>
  64. </span>
  65. <span>{{ item.DealTime }}</span>
  66. <!-- <span>{{ item.time }}</span> -->
  67. </div>
  68. </div>
  69. </div>
  70. </div>
  71. <div class="btns">
  72. <img class="btn-square btn-shadow" src="../../../../assets/baggage/ic_export.png">
  73. <img class="btn-square btn-shadow" src="../../../../assets/baggage/ic_setting.png" @click="show">
  74. </div>
  75. </div>
  76. <div v-show="infoBtn == infoRadios[0]" class="part3" :style="{
  77. 'height': `calc(100vh - 80px - ${basicInfoHeight}px - 128px - 3 * 8px - 44px)`
  78. }">
  79. <!-- <el-popover
  80. trigger="hover"
  81. placement="top-start"
  82. popper-class="popover-dark"
  83. :visible-arrow="false"
  84. :disabled="!messageTooltipVisible"
  85. >
  86. <div class="pre-line">{{ messageTooltip }}</div> -->
  87. <el-table ref="table" :data="baggageTableData" :height="`calc(100vh - 80px - ${basicInfoHeight}px - 128px - 3 * 8px - 44px)`" size="mini" border fit :header-cell-class-name="headerCellClass" :header-cell-style="{ color: '#101116' }" :cell-class-name="cellClass" :span-method="tableSpanMethod" @cell-mouse-enter="cellMouseEnterHandler" @cell-mouse-leave="cellMouseLeaveHandler" @cell-click="cellClickHandler">
  88. <el-table-column v-for="item in tableColsCopy" :key="item.index" :prop="item.prop" :label="item.name" :align="item.align || 'center'" :width="item.width" show-overflow-tooltip>
  89. <template slot="header">
  90. <div class="cell-content">{{ item.name }}</div>
  91. </template>
  92. <template slot-scope="scope">
  93. <div class="cell-content">{{ scope.row[item.prop] }}</div>
  94. </template>
  95. </el-table-column>
  96. </el-table>
  97. <!-- </el-popover> -->
  98. </div>
  99. <div v-show="infoBtn === infoRadios[1]" class="part4" :style="{
  100. 'height': `calc(100vh - 80px - ${basicInfoHeight}px - 2 * 8px - 44px)`
  101. }">
  102. <header class="head">
  103. <div class="title">行李跟踪信息</div>
  104. <div class="btns">
  105. <!-- <img
  106. class="btn-square"
  107. src="../../../../assets/baggage/ic_export.png"
  108. >
  109. <img
  110. class="btn-square"
  111. src="../../../../assets/baggage/ic_setting.png"
  112. @click="show"
  113. > -->
  114. </div>
  115. </header>
  116. <main class="main">
  117. <template v-if="messageList.length">
  118. <el-row :gutter="24" type="flex">
  119. <el-col v-for="(message, index) in messageList" :key="index" :span="6">
  120. <div class="card">
  121. <div class="message-date">{{ message.date + ' UTC' }}</div>
  122. <div class="message-content">
  123. {{ message.dataContent.replaceAll(/[\r\n]{2,}/g, '\n') }}
  124. <!-- BSM <br>
  125. .V/1LHRB <br>
  126. .F/XX1640/08APR/PEK/Y <br>
  127. .O/ZZ941/08APR/DXB/E <br>
  128. .N/0666826758001 <br>
  129. .D/SELF//08APR/110023L//PEK30113 <br>
  130. .S/N/32L/C/030//Y/I <br>
  131. .W/K/l/0 <br>
  132. .P/1CUI/DI ENDBSM<br> -->
  133. </div>
  134. </div>
  135. </el-col>
  136. </el-row>
  137. </template>
  138. <template v-else>
  139. <el-empty :image-size="1" description="暂无数据" />
  140. </template>
  141. </main>
  142. </div>
  143. <!--列设置-->
  144. <Dialog :flag="dialogFlag" class="dialog-check-cols">
  145. <div class="col-dialog">
  146. <div class="title">列设置</div>
  147. <div class="content">
  148. <el-tree :data="tableCols" :class="colsCheckClass" show-checkbox node-key="index" :default-expand-all="true" :props="{
  149. label: 'name',
  150. children: 'children',
  151. }" :default-checked-keys="checkedKeysTemp" @check="handleCheck" />
  152. </div>
  153. <div class="foot right t30">
  154. <el-button size="medium" class="r24" type="primary" @click="onCheck">确定</el-button>
  155. <el-button size="medium" @click="hide">取消</el-button>
  156. </div>
  157. </div>
  158. </Dialog>
  159. </div>
  160. </template>
  161. <script>
  162. import Dialog from '@/layout/components/Dialog/index.vue'
  163. import { queryMap, myQuery } from '@/api/dataIntegration'
  164. import tableColsMixin from '../../mixins/tableCols'
  165. export default {
  166. name: 'BaggageView',
  167. components: {
  168. Dialog
  169. },
  170. mixins: [tableColsMixin],
  171. data () {
  172. return {
  173. departureAirport: '',
  174. landingAirport: '',
  175. queryData: {},
  176. basicInfoHeight: 0,
  177. baggageBasicInfoCols: [
  178. {
  179. label: '行李牌号',
  180. prop: 'bagNo'
  181. },
  182. {
  183. label: '航班号',
  184. prop: 'FlightNO'
  185. },
  186. {
  187. label: '企业或团队名称',
  188. prop: 'teamOrGroup'
  189. },
  190. {
  191. label: '值机位置',
  192. prop: 'checkInLocation'
  193. },
  194. {
  195. label: '特殊行李类型',
  196. prop: 'specialType'
  197. },
  198. {
  199. label: 'PNR编号',
  200. prop: 'PNR'
  201. },
  202. {
  203. label: '旅客姓名大写拼音',
  204. prop: 'name'
  205. },
  206. {
  207. label: '装载序列号',
  208. prop: 'loadSequenceIndex'
  209. },
  210. {
  211. label: '总件数',
  212. prop: 'totalNumber'
  213. },
  214. {
  215. label: '总重量',
  216. prop: 'totalWeight'
  217. },
  218. {
  219. label: '尺寸',
  220. prop: 'size'
  221. },
  222. {
  223. label: '外部特征描述',
  224. prop: 'externalCharacterization'
  225. },
  226. {
  227. label: '常旅客号',
  228. prop: 'frequentFlyerNumber'
  229. },
  230. {
  231. label: '常旅客级别',
  232. prop: 'frequentFlyerClass'
  233. },
  234. {
  235. label: '是否取消值机',
  236. prop: 'whetherToCancelTheCheckIn'
  237. },
  238. {
  239. label: '是否可装载',
  240. prop: 'isItLoadable'
  241. },
  242. {
  243. label: '是否可运输',
  244. prop: 'isItTransportable'
  245. },
  246. {
  247. label: '行李激活状态',
  248. prop: 'activeState'
  249. },
  250. {
  251. label: '无BSM状态',
  252. prop: 'noBSM'
  253. },
  254. {
  255. label: '中转标记',
  256. prop: 'transitSign'
  257. },
  258. {
  259. label: '速运标记',
  260. prop: 'expressSign'
  261. },
  262. {
  263. label: '破损标记',
  264. prop: 'brokenSign'
  265. },
  266. {
  267. label: '投诉标记',
  268. prop: 'complaintSign'
  269. },
  270. {
  271. label: '赔偿标记',
  272. prop: 'compensationSign'
  273. },
  274. {
  275. label: '异常状态',
  276. prop: 'bagExcType'
  277. }
  278. ],
  279. baggageBasicInfo: {},
  280. dialogVisibledele: false,
  281. active: 2,
  282. infoBtn: '跟踪信息',
  283. infoRadios: ['跟踪信息', '跟踪报文'],
  284. messageList: [
  285. // {
  286. // content: `BSM
  287. // .V/1LHRB
  288. // .F/XX1640/08APR/PEK/Y
  289. // .O/ZZ941/08APR/DXB/E
  290. // .N/0666826758001
  291. // .D/SELF//08APR/110023L//PEK30113
  292. // .S/N/32L/C/030//Y/I
  293. // .W/K/l/0
  294. // .P/1CUI/DI ENDBSM`,
  295. // date: '2022-04-25 12:42:38:00'
  296. // }
  297. ],
  298. // messageTooltipList: [],
  299. checkList: [],
  300. stepData: new Array(9).fill({}),
  301. tableCols: [
  302. {
  303. name: '航班号',
  304. prop: 'flightNo'
  305. },
  306. { name: '航班日期', prop: 'flightDate', width: 100 },
  307. {
  308. name: '起飞航站\n预计起飞时间',
  309. prop: 'departureAirport',
  310. width: 111
  311. },
  312. {
  313. name: '目的航站\n预计降落时间',
  314. prop: 'landingAirport',
  315. sortable: 'custom',
  316. width: 111
  317. },
  318. { name: '旅客仓位', prop: 'passengerCompartment', width: 70 },
  319. { name: '旅客座位号', prop: 'passengerSeatNumber' },
  320. { name: '值机序号', prop: 'passengerCheckInNumber', width: 70 },
  321. { name: '节点标识', prop: 'nodeCode', width: 100 },
  322. { name: '节点名称', prop: 'nodeName' },
  323. { name: '位置标识', prop: 'locationCode' },
  324. // { name: '位置码', prop: '', },
  325. { name: '位置描述', prop: 'locationRemark' },
  326. { name: '读取时间', prop: 'dealTime', width: 158 },
  327. { name: '结果', prop: 'status' },
  328. { name: '次级代码', prop: 'secondaryCode', width: 70 },
  329. { name: '操作人', prop: 'AgentCode', width: 100 },
  330. { name: '设备ID', prop: 'DeviceCode' },
  331. { name: '发往位置', prop: 'toLocation' },
  332. { name: '发往位置描述', prop: 'toLocationMark', width: 110 },
  333. { name: '装载序号', prop: 'LoadSN' },
  334. { name: '容器编号', prop: 'U_Device_ID', width: 100 }
  335. ],
  336. baggageTableData: [],
  337. spanArr: [],
  338. pos: 0,
  339. hoveredRow: null,
  340. loopEvent: null,
  341. queryMessageLoop: null
  342. }
  343. },
  344. computed: {
  345. lineWidth () {
  346. for (let i = this.stepData.length - 1; i > -1; i--) {
  347. if (this.stepData[i].DealTime) {
  348. return (i * 100) / (this.stepData.length - 1) + '%'
  349. }
  350. }
  351. return 0
  352. },
  353. // messageTooltip() {
  354. // return function (resourceFile) {
  355. // const message = this.messageTooltipList.find(message => message.resourceFile === resourceFile)
  356. // return message ? `${message.date}\n${message.dataContent.replaceAll(/[\r\n]{2,}/g, '\n')}` : ''
  357. // }
  358. // },
  359. // popoverVisible() {
  360. // return function (item) {
  361. // return (
  362. // (item.hover || item.tableHover) &&
  363. // this.messageTooltipList.some(message => message.resourceFile === item.resourceFile)
  364. // )
  365. // }
  366. // },
  367. formattedBaggageInfo () {
  368. return function (prop) {
  369. const value = this.baggageBasicInfo[prop]
  370. if ((value ?? '') === '') {
  371. return ''
  372. } else if (prop === 'transitSign') {
  373. return Number(value) === 1 ? '中转' : '非中转'
  374. } else if (
  375. [
  376. 'whetherToCancelTheCheckIn',
  377. 'isItLoadable',
  378. 'isItTransportable',
  379. 'activeState',
  380. 'noBSM',
  381. 'expressSign',
  382. 'brokenSign',
  383. 'complaintSign',
  384. 'compensationSign',
  385. 'bagExcType'
  386. ].includes(prop)
  387. ) {
  388. return Number(value) === 1 || String(value) === 'Y' ? '是' : '否'
  389. } else {
  390. return value
  391. }
  392. }
  393. }
  394. },
  395. watch: {
  396. infoBtn (val) {
  397. const that = this
  398. if (val === '跟踪报文') {
  399. clearInterval(this.loopEvent)
  400. this.loopEvent = null
  401. this.baggageMessageQuery()
  402. this.queryMessageLoop = setInterval(function () {
  403. that.baggageMessageQuery()
  404. }, 5000)
  405. } else {
  406. clearInterval(this.queryMessageLoop)
  407. this.queryMessageLoop = null
  408. this.queryBaggageAll()
  409. this.loopEvent = setInterval(function () {
  410. that.queryBaggageAll()
  411. }, 3000)
  412. }
  413. },
  414. hoveredRow: {
  415. handler (row) {
  416. this.stepData.forEach(item => {
  417. item.tableHover = row && item.resourceFile === row.resourceFile
  418. })
  419. },
  420. deep: true
  421. }
  422. },
  423. mounted () {
  424. this.queryData = this._.cloneDeep(this.$route.query)
  425. // console.log(this.queryData)
  426. const that = this
  427. this.queryBaggageAll()
  428. this.loopEvent = setInterval(function () {
  429. that.queryBaggageAll()
  430. }, 3000)
  431. },
  432. updated () {
  433. this.basicInfoHeight = this.$refs['basicInfo'].offsetHeight
  434. this.$refs['table']?.doLayout()
  435. },
  436. beforeDestroy () {
  437. clearInterval(this.loopEvent)
  438. this.loopEvent = null
  439. clearInterval(this.queryMessageLoop)
  440. this.queryMessageLoop = null
  441. },
  442. methods: {
  443. // objectSpanMethod({ row, column, rowIndex, columnIndex }) {
  444. // if (columnIndex < 4) {
  445. // const _row = this.spanArr[rowIndex]
  446. // const _col = _row > 0 ? 1 : 0
  447. // return {
  448. // rowspan: _row,
  449. // colspan: _col
  450. // }
  451. // }
  452. // },
  453. initTableData (tableData) {
  454. const spanArr = []
  455. let pos = 0
  456. for (let i = 0; i < tableData.length; i++) {
  457. if (i === 0) {
  458. spanArr.push(1)
  459. } else {
  460. if (
  461. tableData[i]['flightNo'] === tableData[i - 1]['flightNo'] &&
  462. tableData[i]['flightDate'] === tableData[i - 1]['flightDate'] &&
  463. tableData[i]['departureAirport'] === tableData[i - 1]['departureAirport'] &&
  464. tableData[i]['landingAirport'] === tableData[i - 1]['landingAirport']
  465. ) {
  466. spanArr[pos] += 1
  467. spanArr.push(0)
  468. } else {
  469. spanArr.push(1)
  470. pos = i
  471. }
  472. }
  473. }
  474. this.spanArr = spanArr
  475. this.pos = pos
  476. },
  477. headerCellClass ({ row, column, rowIndex, columnIndex }) {
  478. if (['departureAirport', 'landingAirport'].includes(column.property)) {
  479. return 'pre-line'
  480. }
  481. },
  482. cellClass ({ row, column, rowIndex, columnIndex }) {
  483. const classes = []
  484. if (column.property === 'flightNo') {
  485. classes.push('cell-click')
  486. }
  487. if (['departureAirport', 'landingAirport'].includes(column.property)) {
  488. classes.push('pre-line')
  489. }
  490. return classes.join(' ')
  491. },
  492. cellClickHandler (row, column, cell, event) {
  493. switch (column.property) {
  494. case 'flightNo':
  495. this.$router.push({
  496. path: `/${this.$route.path.split('/').slice(1, -1).join('/')}/flightView`,
  497. query: {
  498. FlightNO: row.flightNo,
  499. FlightDate: row.flightDate
  500. }
  501. })
  502. break
  503. default:
  504. break
  505. }
  506. },
  507. tableSpanMethod ({ row, column, rowIndex, columnIndex }) {
  508. if (['flightNo', 'flightDate', 'departureAirport', 'landingAirport'].includes(column['property'])) {
  509. const _row = this.spanArr[rowIndex]
  510. const _col = _row > 0 ? 1 : 0
  511. return {
  512. rowspan: _row,
  513. colspan: _col
  514. }
  515. }
  516. },
  517. itemMouseEnterHandler (item) {
  518. if (item.resourceFile) {
  519. // this.checkBaggageMessage(item.resourceFile)
  520. item.hover = true
  521. }
  522. },
  523. itemMouseLeaveHandler (item) {
  524. item.hover = false
  525. },
  526. cellMouseEnterHandler (row, column, cell, event) {
  527. // if (row?.resourceFile) {
  528. // this.checkBaggageMessage(row.resourceFile)
  529. // }
  530. this.hoveredRow = row
  531. },
  532. cellMouseLeaveHandler () {
  533. // this.hoveredRow = null
  534. },
  535. async checkBaggageMessage (resourceFile) {
  536. if (!this.messageTooltipList.some(message => message.resourceFile === resourceFile)) {
  537. const result = await this.queryMessage([resourceFile])
  538. this.messageTooltipList.push({
  539. ...result[0],
  540. resourceFile
  541. })
  542. }
  543. },
  544. // 行李详情基础信息
  545. queryBaggageBasicInfo (dataContent) {
  546. return myQuery(queryMap.baggageBasicInfoByID, ...dataContent)
  547. },
  548. // 行李详情追踪链
  549. queryBaggageTrack (dataContent) {
  550. return myQuery(queryMap.baggageTrackByID, ...dataContent)
  551. },
  552. // 行李详情表格
  553. queryBaggageDetails (dataContent) {
  554. return myQuery(queryMap.baggageDetailsByID, ...dataContent)
  555. },
  556. // 原始报文
  557. queryMessage (dataContent) {
  558. return myQuery(queryMap.message, ...dataContent)
  559. },
  560. async queryBaggageAll (queryData = this.queryData) {
  561. const { FlightNO, FlightDate, BagSN } = queryData
  562. const dataContent = [FlightNO, FlightDate, BagSN]
  563. try {
  564. const [
  565. baggageBasicInfo,
  566. // baggageTrack,
  567. baggageDetails
  568. ] = await Promise.all([
  569. this.queryBaggageBasicInfo(dataContent),
  570. // this.queryBaggageTrack(new Array(2).fill(dataContent).flat()),
  571. this.queryBaggageDetails(new Array(6).fill(dataContent).flat())
  572. ])
  573. if (baggageBasicInfo.length) {
  574. baggageBasicInfo[0].FlightNO = FlightNO
  575. this.baggageBasicInfo = baggageBasicInfo[0]
  576. }
  577. this.baggageTableData = baggageDetails.map((item, index) => {
  578. const { hover, tableHover } = this.stepData[index] ?? {}
  579. this.stepData.splice(index, 1, {
  580. NodeNameEN: item.nodeCode,
  581. DealTime: item.dealTime.replace('T', '\n'),
  582. resourceFile: item.resourceFile,
  583. hover: !!hover,
  584. tableHover: !!tableHover
  585. })
  586. if (item['dealTime'].split('T').length > 1) {
  587. item['dealTime'] = item['dealTime'].replace('T', ' ')
  588. }
  589. item['departureAirport'] = `${item['departureAirport']}\n${item['departureTime'].replace('T', '\n')}`
  590. item['landingAirport'] = `${item['landingAirport']}\n${item['landingTime'].replace('T', '\n')}`
  591. return item
  592. })
  593. this.initTableData(this.baggageTableData)
  594. } catch (error) {
  595. console.log('错误', error)
  596. }
  597. },
  598. async baggageMessageQuery () {
  599. const { FlightNO, FlightDate, BagSN } = this.queryData
  600. const dataContent = [FlightNO, FlightDate, BagSN]
  601. try {
  602. const result = await this.queryMessage(dataContent)
  603. this.messageList = result.map(message => {
  604. message.dataContent = JSON.parse(message.dataContent).dataContent
  605. return message
  606. })
  607. } catch (error) {
  608. console.log('出错了', error)
  609. }
  610. }
  611. }
  612. }
  613. </script>
  614. <style lang="scss">
  615. .radioBtn {
  616. padding: 5px;
  617. background: #000d2a;
  618. .el-radio-button__inner {
  619. background: #000d2a;
  620. color: #fff;
  621. border: none;
  622. font-weight: bold;
  623. }
  624. .el-radio-button:first-child .el-radio-button__inner {
  625. border: none;
  626. }
  627. }
  628. </style>
  629. <style lang="scss" scoped>
  630. .baggage-view {
  631. width: 100%;
  632. height: calc(100vh - 81px);
  633. overflow: hidden;
  634. background: #dfe3ea;
  635. padding: 8px 8px 0;
  636. .part1 {
  637. width: 100%;
  638. // height: 232px;
  639. background: #041741;
  640. padding: 16px 30px;
  641. .title {
  642. font-size: 18px;
  643. font-weight: bold;
  644. color: #ffffff;
  645. width: 320px;
  646. display: flex;
  647. flex-direction: row;
  648. justify-content: space-between;
  649. align-items: center;
  650. }
  651. .part1_info {
  652. width: 100%;
  653. color: #fff;
  654. font-size: 14px;
  655. font-weight: 400;
  656. color: #ffffff;
  657. > .el-row > .el-col {
  658. height: 38px;
  659. line-height: 38px;
  660. display: flex;
  661. .label {
  662. flex-basis: 126px;
  663. text-align: right;
  664. }
  665. .content {
  666. flex: 1;
  667. margin: 0;
  668. white-space: nowrap;
  669. overflow: hidden;
  670. text-overflow: ellipsis;
  671. }
  672. }
  673. }
  674. }
  675. .part2 {
  676. margin: 8px 0;
  677. width: 100%;
  678. padding: 24px 30px;
  679. background: #ffffff;
  680. display: flex;
  681. flex-direction: row;
  682. justify-content: space-between;
  683. align-items: center;
  684. .part2_info {
  685. flex: 1;
  686. display: flex;
  687. flex-direction: row;
  688. justify-content: flex-start;
  689. align-items: center;
  690. .title {
  691. font-size: 18px;
  692. font-weight: bold;
  693. color: #303133;
  694. margin-right: 20px;
  695. }
  696. .type {
  697. font-size: 18px;
  698. font-weight: bold;
  699. margin-right: 20px;
  700. }
  701. .warn {
  702. color: #df3559;
  703. }
  704. .normal {
  705. color: #519f6b;
  706. }
  707. .step {
  708. flex: 1;
  709. height: 80px;
  710. max-width: 1430px;
  711. position: relative;
  712. .baggage-track-chart {
  713. display: flex;
  714. flex-direction: row;
  715. justify-content: space-between;
  716. align-items: center;
  717. width: 100%;
  718. overflow-x: scroll;
  719. overflow-y: hidden;
  720. }
  721. .stepLine {
  722. width: 100%;
  723. height: 20px;
  724. background: #afb4bf;
  725. position: absolute;
  726. top: 50%;
  727. margin-top: -10px;
  728. border-radius: 10px;
  729. .stepLineBlue {
  730. position: absolute;
  731. height: 100%;
  732. background: #041741;
  733. border-radius: 10px;
  734. }
  735. }
  736. .stepItem {
  737. width: 80px;
  738. height: 80px;
  739. background: #afb4bf;
  740. border-radius: 50%;
  741. text-align: center;
  742. font-weight: bold;
  743. color: #ffffff;
  744. font-size: 12px;
  745. display: flex;
  746. flex-direction: column;
  747. align-content: space-around;
  748. align-items: center;
  749. // padding-top: 19px;
  750. justify-content: center;
  751. z-index: 1;
  752. .head {
  753. font-size: 14px;
  754. }
  755. }
  756. .activeItem {
  757. background: #041741;
  758. }
  759. }
  760. }
  761. }
  762. .part3 {
  763. width: 100%;
  764. // header-80px、part1-232px、part2-128px、间隙3*8px、底部44px
  765. // height: calc(100vh - 80px - 232px - 128px - 3 * 8px - 44px);
  766. background: #ffffff;
  767. ::v-deep .el-table {
  768. width: 100%;
  769. // &.el-table--striped {
  770. // .el-table__body tr.el-table__row--striped td.el-table__cell,
  771. // .el-table__header .el-table__cell {
  772. // background: #ffffff;
  773. // }
  774. // }
  775. .el-table__cell {
  776. // background: #f0f3f7;
  777. padding: 0;
  778. &.cell-click {
  779. cursor: pointer;
  780. .cell {
  781. color: #2d7cff;
  782. }
  783. }
  784. .cell {
  785. padding: 0;
  786. word-spacing: 0;
  787. font-size: 14px;
  788. font-family: Helvetica, "Microsoft YaHei";
  789. font-weight: 400;
  790. color: #303133;
  791. .cell-content {
  792. padding: 6px 0;
  793. }
  794. }
  795. }
  796. .el-table__body .el-table__cell .cell {
  797. padding: 6px 10px;
  798. .cell-content {
  799. display: inline;
  800. padding: 0;
  801. }
  802. }
  803. }
  804. }
  805. .part4 {
  806. width: 100%;
  807. // height: calc(100vh - 80px - 232px - 2 * 8px - 44px);
  808. .head {
  809. padding: 16px 24px 11px 30px;
  810. background: transparent;
  811. display: flex;
  812. justify-content: space-between;
  813. .title {
  814. line-height: 30px;
  815. font-size: 18px;
  816. font-weight: bold;
  817. color: #303133;
  818. }
  819. }
  820. .main {
  821. height: calc(100% - 57px);
  822. overflow-y: auto;
  823. overflow-x: hidden;
  824. ::v-deep .el-row {
  825. flex-wrap: wrap;
  826. .card {
  827. width: 100%;
  828. min-height: 440px;
  829. padding: 20px;
  830. background: #ffffff;
  831. box-shadow: 0px 3px 2px 0px rgba(0, 0, 0, 0.29);
  832. margin-bottom: 24px;
  833. > .message-date {
  834. width: 180px;
  835. height: 26px;
  836. line-height: 14px;
  837. font-size: 14px;
  838. font-family: Helvetica;
  839. color: #afb4bf;
  840. border-bottom: 1px solid #afb4bf;
  841. margin-bottom: 18px;
  842. }
  843. > .message-content {
  844. white-space: pre-line;
  845. line-height: 24px;
  846. font-size: 14px;
  847. color: #303133;
  848. word-break: break-all;
  849. }
  850. }
  851. }
  852. }
  853. }
  854. .btns {
  855. height: 30px;
  856. display: flex;
  857. .btn-square {
  858. margin-left: 10px;
  859. width: 30px;
  860. }
  861. }
  862. }
  863. </style>
  864. <style lang="scss">
  865. .el-popover {
  866. &.popover-dark {
  867. background: #303133;
  868. color: #ffffff;
  869. border: none;
  870. }
  871. .pre-line {
  872. white-space: pre-line;
  873. }
  874. }
  875. .el-popper[x-placement^="top"].popover-dark .popper__arrow::after {
  876. border-top-color: #303133;
  877. }
  878. .el-popper[x-placement^="right"].popover-dark .popper__arrow::after {
  879. border-right-color: #303133;
  880. }
  881. .el-popper[x-placement^="bottom"].popover-dark .popper__arrow::after {
  882. border-bottom-color: #303133;
  883. }
  884. .el-popper[x-placement^="left"].popover-dark .popper__arrow::after {
  885. border-left-color: #303133;
  886. }
  887. </style>