123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281 |
- <!--
- * @Author: your name
- * @Date: 2022-01-17 10:39:22
- * @LastEditTime: 2022-08-12 19:14:09
- * @LastEditors: your name
- * @Description: 行李视图
- -->
- <template>
- <div class="baggage-view">
- <div
- class="part1"
- :style="{ height: basicInfoHeight }"
- >
- <div class="title">
- <span>行李基本信息</span>
- <el-radio-group
- v-model="infoBtn"
- class="radioBtn"
- size="mini"
- fill="#FFFFFF"
- text-color="#28344D"
- >
- <el-radio-button
- v-for="item in infoRadios"
- :key="item"
- :label="item"
- />
- </el-radio-group>
- <!-- <BackButton /> -->
- </div>
- <div
- v-show="basicInfoOpen"
- class="part1_info"
- >
- <el-row :gutter="12">
- <el-col
- v-for="(item, index) in baggageBasicInfoCols"
- :key="index"
- :xl="[0, 2, 4].includes(index % 7) ? 4 : 3"
- :sm="6"
- :xs="6"
- >
- <span class="label">{{ item.label }}:</span>
- <span
- class="content"
- :class="{
- click: item.prop === 'compensationSign' && baggageBasicInfo[item.prop]
- }"
- :title="formattedBaggageInfo(item.prop)"
- @click="baggageBasicInfoClickHandler(item.prop)"
- >{{ formattedBaggageInfo(item.prop) }}</span
- >
- </el-col>
- </el-row>
- </div>
- <div
- class="button-toggle"
- @click="basicInfoToggle"
- >
- <i :class="basicInfoOpen ? 'el-icon-caret-top' : 'el-icon-caret-bottom'" />
- </div>
- </div>
- <div
- v-show="infoBtn === infoRadios[0]"
- class="part2"
- :style="{ height: trackListHeight }"
- >
- <div class="part2_info">
- <div class="title">行李跟踪信息</div>
- <div class="type normal">
- {{ baggageBasicInfo.BagStatus }}
- </div>
- <div class="airline">
- <el-select
- v-model="selectedAirline"
- size="mini"
- class="airline-select"
- >
- <el-option
- v-for="airline in airlineList"
- :key="airline.value"
- :value="airline.value"
- :label="airline.label"
- />
- </el-select>
- </div>
- <div class="baggage-track-chart">
- <div class="step-line">
- <div
- v-for="(line, index) in 6"
- :key="index"
- :class="['step-line-segment', { 'step-line-active': activeStepLine(index) }]"
- />
- </div>
- <div
- v-for="(item, index) in stepNodes"
- :key="index"
- :class="{ 'step-item': true, 'active-item': item.status }"
- >
- <div class="step-circle">
- <span class="step-name">{{ item.nodeName }}</span>
- </div>
- <div class="step-info">
- <div :class="statusClasses(item.status)">{{ item.status }}</div>
- <span class="step-time">{{ item.processingTime }}</span>
- <div class="step-location">{{ item.locationId }}</div>
- </div>
- </div>
- </div>
- </div>
- <div class="btns">
- <img
- class="btn-square btn-shadow"
- src="@/assets/baggage/ic_export.png"
- title="导出"
- @click="exportHandler('table', '行李节点列表')"
- />
- <img
- class="btn-square btn-shadow"
- src="@/assets/baggage/ic_setting.png"
- title="列设置"
- @click="show"
- />
- </div>
- <div
- class="button-toggle"
- @click="trackListToggle"
- >
- <i :class="trackListOpen ? 'el-icon-caret-top' : 'el-icon-caret-bottom'" />
- </div>
- </div>
- <div
- v-show="infoBtn == infoRadios[0]"
- class="part3"
- :style="{
- height: `calc(100vh - 80px - ${basicInfoHeight} - ${trackListHeight} - 3 * 8px - 20px)`
- }"
- >
- <el-table
- ref="table"
- :data="baggageTableData"
- height="100%"
- size="mini"
- border
- fit
- :header-cell-class-name="headerCellClass"
- :header-cell-style="{ color: '#101116' }"
- :cell-class-name="cellClass"
- :span-method="tableSpanMethod"
- @cell-click="cellClickHandler"
- >
- <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
- :fixed="item.fixed"
- >
- <template slot="header">
- <div class="cell-content">{{ item.name }}</div>
- </template>
- <template slot-scope="scope">
- <div class="cell-content">{{ scope.row[item.prop] }}</div>
- </template>
- </el-table-column>
- </el-table>
- </div>
- <div
- v-show="infoBtn === infoRadios[1]"
- class="part4"
- :style="{
- height: `calc(100vh - 80px - ${basicInfoHeight} - 2 * 8px - 20px)`
- }"
- >
- <header class="head">
- <div class="title">行李跟踪信息</div>
- <div class="btns">
- <img
- class="btn-square btn-shadow"
- src="@/assets/baggage/ic_export.png"
- title="导出"
- @click="exportMessageToExcel"
- />
- </div>
- </header>
- <main class="main">
- <template v-if="messageList.length">
- <el-row
- :gutter="24"
- type="flex"
- >
- <el-col
- v-for="(message, index) in messageList"
- :key="index"
- :span="6"
- >
- <div class="card">
- <div class="message-date">{{ message.date }}</div>
- <div class="message-content">
- {{ message.dataContent.replaceAll(/[\r\n]{2,}/g, '\n').replaceAll('\\', '') }}
- </div>
- </div>
- </el-col>
- </el-row>
- </template>
- <template v-else>
- <el-empty
- :image-size="1"
- description="暂无数据"
- />
- </template>
- </main>
- </div>
- <!--列设置-->
- <Dialog
- :flag="dialogFlag"
- class="dialog-check-group"
- >
- <div class="dialog-wrapper">
- <div class="title">列设置</div>
- <div class="content">
- <el-tree
- ref="columnSetTree"
- :data="tableCols"
- :class="colsCheckClass"
- show-checkbox
- node-key="index"
- :default-expand-all="true"
- :props="{
- label: 'name',
- children: 'children'
- }"
- :default-checked-keys="checkedKeysTemp"
- @check="handleCheck"
- />
- </div>
- <div class="foot right t30">
- <el-button
- size="medium"
- class="r24"
- type="primary"
- @click="onCheck('baggageTableData')"
- >确定</el-button
- >
- <el-button
- size="medium"
- @click="hide"
- >取消</el-button
- >
- </div>
- </div>
- </Dialog>
- </div>
- </template>
- <script>
- // import BackButton from '@/components/BackButton'
- import Dialog from '@/layout/components/Dialog/index.vue'
- import { myQuery } from '@/api/dataIntegration'
- import { BaggageMessageQuery } from '@/api/flight'
- import tableColsMixin from '../../mixins/tableCols'
- import { throttledExportToExcel } from '@/utils/table'
- import * as XLSX from 'xlsx'
- import XLSX_STYLE from 'xlsx-style'
- import FileSaver from 'file-saver'
- import { mapGetters } from 'vuex'
- export default {
- name: 'BaggageView',
- components: {
- // BackButton,
- Dialog
- },
- mixins: [tableColsMixin],
- data() {
- return {
- queryData: {},
- airlineList: [],
- selectedAirline: '',
- debounceTime: 300,
- baggageBasicInfoCols: [
- {
- label: '行李牌号',
- prop: 'bagNo'
- },
- {
- label: '航班号',
- prop: 'flightNO'
- },
- {
- label: '特殊行李类型',
- prop: 'specialType'
- },
- {
- label: 'PNR编号',
- prop: 'PNR'
- },
- {
- label: '旅客',
- prop: 'name'
- },
- {
- label: '装载序列号',
- prop: 'loadSequenceIndex'
- },
- {
- label: '总件数',
- prop: 'totalNumber'
- },
- {
- label: '总重量',
- prop: 'totalWeight'
- },
- {
- label: '尺寸',
- prop: 'size'
- },
- {
- label: '常旅客号',
- prop: 'frequentFlyerNumber'
- },
- {
- label: '常旅客级别',
- prop: 'frequentFlyerClass'
- },
- {
- label: '取消值机',
- prop: 'whetherToCancelTheCheckIn'
- },
- {
- label: '是否可装载',
- prop: 'isItLoadable'
- },
- {
- label: '是否可运输',
- prop: 'isItTransportable'
- },
- {
- label: '行李激活状态',
- prop: 'activeState'
- },
- {
- label: '无BSM状态',
- prop: 'noBSM'
- },
- {
- label: '中转进航班',
- prop: 'inFlightNo'
- },
- {
- label: '中转出航班',
- prop: 'transferFlightNo'
- },
- {
- label: '速运标记',
- prop: 'expressSign'
- },
- {
- label: '破损标记',
- prop: 'brokenSign'
- },
- {
- label: '投诉标记',
- prop: 'complaintSign'
- },
- {
- label: '赔偿标记',
- prop: 'compensationSign'
- },
- {
- label: '异常状态',
- prop: 'bagExcType'
- },
- {
- label: '企业或团队名称',
- prop: 'teamOrGroup'
- }
- ],
- baggageBasicInfo: {},
- infoBtn: '',
- infoRadios: ['跟踪信息', '跟踪报文'],
- messageList: [],
- stepNodes: [],
- tableCols: [
- { name: '航班号', prop: 'flightNO', fixed: true },
- { name: '航班日期', prop: 'flightDate', width: 95, fixed: true },
- { name: '起飞航站\n起飞时间', prop: 'departureInfo', width: 100 },
- { name: '目的航站\n降落时间', prop: 'landingInfo', width: 100 },
- { name: '旅客舱位', prop: 'passengerCompartment', width: 70 },
- { name: '旅客座位号', prop: 'passengerSeatNumber' },
- { name: '值机序号', prop: 'passengerCheckInNumber', width: 70 },
- { name: '节点标识', prop: 'nodeCode', width: 100 },
- { name: '节点名称', prop: 'nodeName', width: 70 },
- { name: '位置标识', prop: 'locationCode' },
- { name: '位置描述', prop: 'locationRemark' },
- { name: '读取时间', prop: 'dealTime', width: 158 },
- { name: '结果', prop: 'status', width: 60 },
- { name: '次级代码', prop: 'secondaryCode', width: 70 },
- { name: '操作人', prop: 'AgentCode', width: 90 },
- { name: '设备ID', prop: 'DeviceCode' },
- { name: '发往位置', prop: 'toLocation', width: 70 },
- { name: '发往位置描述', prop: 'toLocationMark', width: 100 },
- { name: '装载序号', prop: 'LoadSN', width: 70 },
- { name: '容器编号', prop: 'U_Device_ID', width: 110 },
- { name: '数据来源', prop: 'dataSource' }
- ],
- baggageTableData: [],
- spanArr: [],
- pos: 0,
- queryLoop: null,
- queryTrackLoop: null,
- basicInfoOpen: true,
- trackListOpen: false
- }
- },
- computed: {
- ...mapGetters(['sidebar']),
- activeStepLine() {
- return function (index) {
- return this.stepNodes[index].status && this.stepNodes[index + 1].status
- }
- },
- statusClasses() {
- return function (status) {
- const classes = ['step-status']
- if (typeof status === 'string') {
- if (status.includes('正常') || status.includes('通过')) {
- classes.push('step-status-normal')
- } else {
- classes.push('step-status-abnormal')
- }
- }
- return classes
- }
- },
- formattedBaggageInfo() {
- return function (prop) {
- const value = this.baggageBasicInfo[prop]
- if ((value ?? '') === '') {
- return ''
- } else {
- switch (prop) {
- case 'transitSign':
- return Number(value) === 0 ? '非中转' : '中转'
- case 'activeState':
- return Number(value) === 0 ? '未激活' : '激活'
- case 'whetherToCancelTheCheckIn':
- return Number(value) === 1 ? '取消' : ''
- case 'isItLoadable':
- case 'isItTransportable':
- case 'noBSM':
- case 'expressSign':
- case 'brokenSign':
- case 'complaintSign':
- // case 'compensationSign':
- return Number(value) === 1 || value === 'Y' ? '是' : '否'
- default:
- return value
- }
- }
- }
- },
- basicInfoHeight() {
- return this.basicInfoOpen ? '220px' : '68px'
- },
- trackListHeight() {
- return this.trackListOpen ? '176px' : '81px'
- }
- },
- watch: {
- infoBtn: {
- handler(val) {
- this.stopLoopAll()
- if (val === this.infoRadios[0]) {
- if (this.selectedAirline) {
- this.startQueryTrack()
- }
- this.startQueryDetails()
- } else if (val === this.infoRadios[1]) {
- this.startQueryMessage()
- }
- },
- immediate: true
- },
- selectedAirline() {
- this.stopQueryTrack()
- this.startQueryTrack()
- }
- },
- created() {
- this.resetStepNodes()
- const { flightNO, flightDate, bagSN } = this.$route.query
- if (flightNO && flightDate && bagSN) {
- this.queryData = { flightNO, flightDate, bagSN }
- this.queryBasicInfo()
- this.queryAirline()
- this.infoBtn = this.infoRadios[0]
- } else {
- this.$router.push('/')
- }
- },
- activated() {
- this.resizeHandler()
- this.debouncedResizeHandler = this._.debounce(this.resizeHandler, this.debounceTime)
- window.addEventListener('resize', this.debouncedResizeHandler)
- },
- updated() {
- this.resizeHandler()
- },
- deactivated() {
- this.stopLoopAll()
- window.removeEventListener('resize', this.debouncedResizeHandler)
- },
- methods: {
- basicInfoToggle() {
- this.basicInfoOpen = !this.basicInfoOpen
- },
- trackListToggle() {
- this.trackListOpen = !this.trackListOpen
- },
- resizeHandler() {
- this.$refs['table']?.doLayout()
- },
- baggageBasicInfoClickHandler(prop) {
- if (prop !== 'compensationSign' || !this.baggageBasicInfo[prop]) {
- return
- }
- this.$store.dispatch('app/setAbnormalBaggageQueryParams', {
- flightNO: this.queryData.flightNO,
- flightDate: this.queryData.flightDate,
- bagSN: this.queryData.bagSN,
- fileNumber: this.baggageBasicInfo[prop]
- })
- this.$store.dispatch('app/toggleAbnormalBaggageDialogFlag', true)
- },
- startQueryDetails() {
- this.queryDetails()
- this.queryLoop = setInterval(this.queryDetails.bind(this), LOOP_INTERVAL.baggageDetails)
- },
- startQueryTrack() {
- this.queryTrack()
- this.queryTrackLoop = setInterval(this.queryTrack.bind(this), LOOP_INTERVAL.baggageTrack)
- },
- startQueryMessage() {
- this.queryMessage()
- this.queryLoop = setInterval(this.queryMessage.bind(this), LOOP_INTERVAL.baggageMessage)
- },
- stopQueryTrack() {
- this.queryTrackLoop && clearInterval(this.queryTrackLoop)
- this.queryTrackLoop = null
- },
- stopLoopAll() {
- this.queryLoop && clearInterval(this.queryLoop)
- this.queryLoop = null
- this.stopQueryTrack()
- },
- resetStepNodes() {
- this.stepNodes = [
- {
- nodeCode: 'CHECKIN',
- nodeName: '值机'
- },
- {
- nodeCode: 'SECURITY',
- nodeName: '安检'
- },
- {
- nodeCode: 'SORT',
- nodeName: '分拣'
- },
- {
- nodeCode: 'LOAD',
- nodeName: '装车'
- },
- {
- nodeCode: 'INFL',
- nodeName: '装机'
- },
- {
- nodeCode: 'UNLOAD',
- nodeName: '卸机'
- },
- {
- nodeCode: 'ARRIVED',
- nodeName: '到达'
- }
- ]
- },
- initTableData(tableData) {
- const spanArr = []
- let pos = 0
- for (let i = 0; i < tableData.length; i++) {
- if (i === 0) {
- spanArr.push(1)
- } else {
- if (
- tableData[i]['flightNO'] === tableData[i - 1]['flightNO'] &&
- tableData[i]['flightDate'] === tableData[i - 1]['flightDate'] &&
- tableData[i]['departureAirport'] === tableData[i - 1]['departureAirport'] &&
- tableData[i]['landingAirport'] === tableData[i - 1]['landingAirport']
- ) {
- spanArr[pos] += 1
- spanArr.push(0)
- } else {
- spanArr.push(1)
- pos = i
- }
- }
- }
- this.spanArr = spanArr
- this.pos = pos
- },
- headerCellClass({ row, column, rowIndex, columnIndex }) {
- if (['departureInfo', 'landingInfo'].includes(column.property)) {
- return 'pre-line'
- }
- },
- cellClass({ row, column, rowIndex, columnIndex }) {
- const classes = []
- if (
- ['flightNO', 'U_Device_ID'].includes(column.property) &&
- row[column.property] &&
- row[column.property] !== 'FBULK'
- ) {
- classes.push('cell-click')
- }
- if (['departureInfo', 'landingInfo'].includes(column.property)) {
- classes.push('pre-line')
- }
- return classes.join(' ')
- },
- cellClickHandler(row, column, cell, event) {
- if (row[column.property] && row[column.property] !== 'FBULK') {
- switch (column.property) {
- case 'flightNO':
- this.$router.push({
- path: `${this.$route.path.split('/').slice(0, -1).join('/')}/flightView`,
- query: {
- flightNO: row.flightNO,
- flightDate: row.flightDate
- }
- })
- break
- case 'U_Device_ID':
- this.$router.push({
- path: `${this.$route.path.split('/').slice(0, -1).join('/')}/containerView`,
- query: {
- flightNO: row.flightNO,
- flightDate: row.flightDate,
- departureAirport: row.departureAirport,
- landingAirport: row.landingAirport,
- containerID: row.U_Device_ID
- }
- })
- break
- default:
- break
- }
- }
- },
- tableSpanMethod({ row, column, rowIndex, columnIndex }) {
- if (['flightNO', 'flightDate', 'departureInfo', 'landingInfo'].includes(column['property'])) {
- const _row = this.spanArr[rowIndex]
- const _col = _row > 0 ? 1 : 0
- return {
- rowspan: _row,
- colspan: _col
- }
- }
- },
- exportHandler(refName, tableName) {
- const table = this.$refs[refName].$el.cloneNode(true)
- const { bagSN, flightNO, flightDate } = this.queryData
- const fileName = `${tableName}-${bagSN}-${flightNO}-${flightDate}.xlsx`
- throttledExportToExcel(table, tableName, fileName)
- },
- exportMessageToExcel() {
- const xlsxDatas = [['Date & Time', 'Message']]
- xlsxDatas.push(
- ...this.messageList.map(message => [
- message.date,
- message.dataContent.replaceAll(/[\r\n]{2,}/g, '\n').replaceAll('\\', '')
- ])
- )
- const columnWidths = []
- xlsxDatas.forEach(row => {
- // 计算每一列宽度,考虑换行
- row.forEach((cell, columnIndex) => {
- const cellWidth = Math.max(
- ...cell
- .toString()
- .split('\n')
- .map(cellRow =>
- cellRow.split('').reduce((pre, curr) => {
- const letterSize = curr.charCodeAt(0) > 255 ? 2 : 1
- return pre + letterSize
- }, 0)
- )
- )
- if ((!columnWidths[columnIndex] && cellWidth > 0) || cellWidth > columnWidths[columnIndex]) {
- columnWidths[columnIndex] = cellWidth
- }
- })
- })
- // 生成表格数据
- const sheet = XLSX.utils.aoa_to_sheet(xlsxDatas)
- // 添加列宽度
- sheet['!cols'] = columnWidths.map(width => ({
- wch: width + 2
- }))
- // 表格对齐、添加边框
- const borderStyle = {
- style: 'medium',
- color: {
- rgb: 'FFFFFF'
- }
- }
- const reg = /^[A-Z]+([\d]+$)/
- for (const key in sheet) {
- const match = reg.test(key)
- if (match) {
- const rowIndex = reg.exec(key)[1]
- let cellStyle = {
- alignment: {
- horizontal: 'center',
- vertical: 'center',
- wrapText: true
- }
- }
- if (Number(rowIndex) === 1) {
- cellStyle = {
- ...cellStyle,
- border: {
- top: borderStyle,
- right: borderStyle,
- bottom: borderStyle,
- left: borderStyle
- },
- font: {
- color: {
- rgb: 'FFFFFF'
- }
- },
- fill: {
- fgColor: {
- rgb: '3366FF'
- }
- }
- }
- } else {
- cellStyle.alignment.horizontal = 'left'
- }
- sheet[key].s = cellStyle
- }
- }
- // 表格数据转换
- const workBook = XLSX.utils.book_new()
- XLSX.utils.book_append_sheet(workBook, sheet, '行李原始报文')
- const tableWrite = XLSX_STYLE.write(workBook, {
- bookType: 'xlsx',
- bookSST: true,
- type: 'buffer',
- cellStyles: true
- })
- // 下载表格
- const { bagSN, flightNO, flightDate } = this.queryData
- const fileName = `行李原始报文-${bagSN}-${flightNO}-${flightDate}.xlsx`
- FileSaver.saveAs(new Blob([tableWrite], { type: 'application/octet-stream' }), fileName)
- },
- // 行李详情基础信息
- queryBaggageBasicInfo(dataContent) {
- return myQuery(DATACONTENT_ID.baggageBasicInfo, ...dataContent)
- },
- // 行李航段
- queryBaggageAirline(dataContent) {
- return myQuery(DATACONTENT_ID.baggageAirline, ...dataContent)
- },
- // 行李详情追踪链
- queryBaggageTrack(dataContent) {
- return myQuery(DATACONTENT_ID.baggageTrack, ...dataContent)
- },
- // 行李详情表格
- queryBaggageDetails(dataContent) {
- return myQuery(DATACONTENT_ID.baggageDetails, ...dataContent)
- },
- // 原始报文
- async queryBaggageMessage(dataContent) {
- try {
- const { code, returnData, message } = await BaggageMessageQuery({
- id: DATACONTENT_ID.baggageMessage,
- dataContent
- })
- if (Number(code) === 0) {
- return returnData.listValues
- } else {
- this.$message.error(message ?? '失败')
- }
- } catch (error) {
- this.$message.error('失败')
- }
- },
- async queryBasicInfo(queryData = this.queryData) {
- const { flightNO, flightDate, bagSN } = queryData
- const dataContent = [flightNO, flightDate, bagSN]
- try {
- const baggageBasicInfo = await this.queryBaggageBasicInfo(dataContent)
- if (baggageBasicInfo.length) {
- baggageBasicInfo[0].flightNO = flightNO
- this.baggageBasicInfo = baggageBasicInfo[0]
- }
- } catch (error) {
- this.$message.error('失败')
- }
- },
- async queryDetails(queryData = this.queryData) {
- function setDataSource(item) {
- if (item['b_type'] !== 'BSM') {
- const resourceCode = item['resourceFile']?.slice(-4)
- switch (resourceCode) {
- case '0100':
- if (
- (item['DeviceCode'] && item['DeviceCode'].toUpperCase() === 'STARHUB') ||
- (!item['DeviceCode'] && !['LOAD', 'INFL'].includes(item['nodeCode']))
- ) {
- item['dataSource'] = '星盟'
- } else {
- item['dataSource'] = 'BRS'
- }
- break
- case '0101':
- item['dataSource'] = 'RFID'
- break
- case '0102':
- item['dataSource'] = '首都机场'
- break
- default:
- break
- }
- }
- }
- const { flightNO, flightDate, bagSN } = queryData
- const dataContent = [flightNO, flightDate, bagSN]
- try {
- const baggageDetails = await this.queryBaggageDetails(new Array(6).fill(dataContent).flat())
- this.baggageTableData = baggageDetails.map((item, index) => {
- if (item['dealTime']) {
- item['dealTime'] = item['dealTime'].replace('T', ' ')
- }
- item['departureInfo'] = `${item['departureAirport']}\n${
- item['departureTime'] ? item['departureTime'].replace('T', '\n') : ''
- }`
- item['landingInfo'] = `${item['landingAirport']}\n${
- item['landingTime'] ? item['landingTime'].replace('T', '\n') : ''
- }`
- setDataSource(item)
- return item
- })
- this.initTableData(this.baggageTableData)
- } catch (error) {
- this.$message.error('失败')
- }
- },
- async queryAirline(queryData = this.queryData) {
- const { flightNO, flightDate, bagSN } = queryData
- const dataContent = [flightNO, flightDate, bagSN]
- try {
- const result = await this.queryBaggageAirline(dataContent)
- this.airlineList = result.map(({ flightNO, flightDate, departureAirport, arriveAirport, luggageSN }) => ({
- label: `${departureAirport}-${arriveAirport}`,
- value: `${flightNO},${flightDate},${luggageSN}`,
- flightNO,
- flightDate
- }))
- if (this.airlineList.length) {
- let currentIndex = this.airlineList.findIndex(
- ({ flightNO, flightDate }) => flightNO === queryData.flightNO && flightDate === queryData.flightDate
- )
- currentIndex = currentIndex > -1 ? currentIndex : 0
- this.selectedAirline = this.airlineList[currentIndex].value
- } else {
- this.selectedAirline = ''
- }
- } catch (error) {
- this.$message.error('失败')
- }
- },
- async queryTrack() {
- function isSameStep(code1, code2) {
- const sameStepCodes = ['ARRIVED', 'TRANSFER']
- return sameStepCodes.includes(code1) && sameStepCodes.includes(code2)
- }
- try {
- const result = await this.queryBaggageTrack(this.selectedAirline.split(','))
- this.resetStepNodes()
- result.forEach(({ nodeCode, nodeName, processingTime, locationId, status }) => {
- const replaceIndex = this.stepNodes.findIndex(
- stepNode => stepNode.nodeCode === nodeCode || isSameStep(stepNode.nodeCode, nodeCode)
- )
- if (replaceIndex > -1) {
- this.stepNodes.splice(replaceIndex, 1, {
- nodeCode,
- nodeName,
- processingTime: processingTime?.replace('T', '\n'),
- locationId,
- status
- })
- }
- })
- } catch (error) {
- this.$message.error('失败')
- }
- },
- async queryMessage(queryData = this.queryData) {
- const { flightNO, flightDate, bagSN } = queryData
- const dataContent = [flightNO, flightDate, bagSN]
- try {
- const result = await this.queryBaggageMessage(dataContent)
- const messageList = result.reduce((list, message, currentIndex, arr) => {
- const messageObject = typeof message === 'string' ? JSON.parse(message) : message
- // 确保是当前行李的报文
- const isCorrectBaggage = messageObject.dataContent.match(/\.N\/([0-9]{10})/)?.[1] === bagSN
- // 相同报文去重
- const index = arr.findIndex(testMessage => {
- const testMessageObject = typeof testMessage === 'string' ? JSON.parse(testMessage) : testMessage
- return (
- messageObject.dataContent === testMessageObject.dataContent &&
- messageObject.ssid === testMessageObject.ssid
- )
- })
- if (isCorrectBaggage && currentIndex === index) {
- return [...list, messageObject]
- } else {
- return list
- }
- }, [])
- this.messageList = this._.sortBy(messageList, 'ssid')
- } catch (error) {
- this.$message.error('失败')
- }
- }
- }
- }
- </script>
- <style
- lang="scss"
- scoped
- >
- .baggage-view {
- width: 100%;
- height: calc(100vh - 80px);
- overflow: hidden;
- background: #dfe3ea;
- padding: 8px 8px 0;
- .part1 {
- width: 100%;
- // height: 232px;
- background: #041741;
- padding: 16px 30px;
- overflow: hidden;
- position: relative;
- ::v-deep .title {
- font-size: 18px;
- font-weight: bold;
- color: #ffffff;
- display: flex;
- flex-direction: row;
- align-items: center;
- .radioBtn {
- margin-left: 32px;
- padding: 5px;
- background: #000d2a;
- .el-radio-button__inner {
- background: #000d2a;
- color: #fff;
- border: none;
- font-weight: bold;
- }
- .el-radio-button:first-child .el-radio-button__inner {
- border: none;
- }
- }
- .btn-back {
- color: #ffffff;
- }
- }
- .part1_info {
- width: 100%;
- color: #fff;
- font-size: 14px;
- font-weight: 400;
- color: #ffffff;
- > .el-row > .el-col {
- height: 38px;
- line-height: 38px;
- display: flex;
- .label {
- flex-basis: 126px;
- text-align: right;
- }
- .content {
- flex: 1;
- margin: 0;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- &.click {
- text-decoration: underline;
- cursor: pointer;
- }
- }
- }
- }
- }
- .part2 {
- margin: 8px 0;
- width: 100%;
- padding: 24px 30px 28px;
- overflow: hidden;
- background: #ffffff;
- display: flex;
- flex-direction: row;
- justify-content: space-between;
- align-items: flex-start;
- position: relative;
- .part2_info {
- flex: 1;
- display: flex;
- flex-direction: row;
- justify-content: flex-start;
- align-items: flex-start;
- line-height: 42px;
- .title {
- width: 120px;
- font-size: 18px;
- font-weight: bold;
- color: #303133;
- margin-right: 20px;
- }
- .type {
- font-size: 18px;
- font-weight: bold;
- margin-right: 20px;
- .warn {
- color: #df3559;
- }
- .normal {
- color: #519f6b;
- }
- }
- .airline {
- width: 120px;
- margin-right: 20px;
- }
- .baggage-track-chart {
- flex: 1;
- height: 124px;
- max-width: 1280px;
- position: relative;
- display: flex;
- flex-direction: row;
- justify-content: space-between;
- width: 100%;
- }
- .step-line {
- width: calc(100% - 80px);
- height: 10px;
- position: absolute;
- top: 16px;
- right: 0;
- left: 0;
- margin: auto;
- display: flex;
- .step-line-segment {
- width: calc(100% / 6);
- height: 100%;
- background: #afb4bf;
- &.step-line-active {
- background: #2d67e3;
- }
- }
- }
- .step-item {
- width: 80px;
- height: 100%;
- text-align: center;
- font-size: 14px;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: flex-start;
- z-index: 1;
- font-family: Helvetica, 'Microsoft Yahei';
- .step-circle {
- width: 42px;
- height: 42px;
- border-radius: 50%;
- background: #aaacb2;
- .step-name {
- color: #ffffff;
- font-size: 14px;
- font-weight: bold;
- }
- }
- .step-info {
- margin-top: 15px;
- color: #101116;
- line-height: 22px;
- .step-status {
- &-normal {
- color: #4ab36f;
- }
- &-abnormal {
- color: #e9af4b;
- }
- }
- .step-time {
- white-space: pre-line;
- font-size: 12px;
- line-height: 20px;
- }
- }
- &.active-item .step-circle {
- background: #2d67e3;
- }
- }
- }
- .btns {
- margin-top: 6px;
- }
- }
- .part3 {
- width: 100%;
- // header-80px、part1-232px、part2-128px、间隙3*8px、底部44px
- // height: calc(100vh - 80px - 232px - 128px - 3 * 8px - 44px);
- background: #ffffff;
- ::v-deep .el-table {
- width: 100%;
- // &.el-table--striped {
- // .el-table__body tr.el-table__row--striped td.el-table__cell,
- // .el-table__header .el-table__cell {
- // background: #ffffff;
- // }
- // }
- .el-table__cell {
- // background: #f0f3f7;
- padding: 0;
- &.cell-click {
- cursor: pointer;
- .cell {
- color: #2d7cff;
- }
- }
- .cell {
- padding: 0;
- word-spacing: 0;
- font-size: 14px;
- font-family: Helvetica, 'Microsoft YaHei';
- font-weight: 400;
- color: #303133;
- width: 100% !important;
- .cell-content {
- padding: 6px 0;
- }
- }
- }
- .el-table__body .el-table__cell .cell {
- padding: 6px 10px;
- .cell-content {
- display: inline;
- padding: 0;
- }
- }
- }
- }
- .part4 {
- width: 100%;
- // height: calc(100vh - 80px - 232px - 2 * 8px - 44px);
- .head {
- padding: 16px 24px 11px 30px;
- background: transparent;
- display: flex;
- justify-content: space-between;
- .title {
- line-height: 30px;
- font-size: 18px;
- font-weight: bold;
- color: #303133;
- }
- }
- .main {
- height: calc(100% - 57px);
- overflow-y: auto;
- overflow-x: hidden;
- ::v-deep .el-row {
- flex-wrap: wrap;
- .card {
- width: 100%;
- min-height: 440px;
- padding: 20px;
- background: #ffffff;
- box-shadow: 0px 3px 2px 0px rgba(0, 0, 0, 0.29);
- margin-bottom: 24px;
- > .message-date {
- width: 180px;
- height: 26px;
- line-height: 14px;
- font-size: 14px;
- font-family: Helvetica;
- color: #afb4bf;
- border-bottom: 1px solid #afb4bf;
- margin-bottom: 18px;
- }
- > .message-content {
- white-space: pre-line;
- line-height: 24px;
- font-size: 14px;
- color: #303133;
- word-break: break-all;
- }
- }
- }
- }
- }
- .btns {
- height: 30px;
- display: flex;
- .btn-square {
- margin-left: 10px;
- width: 30px;
- }
- }
- .button-toggle {
- position: absolute;
- bottom: 0;
- left: 50%;
- transform: translateX(-50%);
- z-index: 1000;
- width: 20px;
- height: 15px;
- border-radius: 4px;
- background-color: #2d67e3;
- color: #ffffff;
- cursor: pointer;
- text-align: center;
- }
- }
- </style>
- <style
- scoped
- lang="scss"
- >
- ::v-deep .baggage-view {
- .el-popover {
- &.popover-dark {
- background: #303133;
- color: #ffffff;
- border: none;
- }
- .pre-line {
- white-space: pre-line;
- }
- }
- .el-popper[x-placement^='top'].popover-dark .popper__arrow::after {
- border-top-color: #303133;
- }
- .el-popper[x-placement^='right'].popover-dark .popper__arrow::after {
- border-right-color: #303133;
- }
- .el-popper[x-placement^='bottom'].popover-dark .popper__arrow::after {
- border-bottom-color: #303133;
- }
- .el-popper[x-placement^='left'].popover-dark .popper__arrow::after {
- border-left-color: #303133;
- }
- }
- </style>
|