index.vue 26 KB

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