12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151 |
- <!--
- * @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('\\', '') }} -->
- {{ 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/temp'
- import { BaggageMessageQuery } from '@/api/temp'
- 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(SERVICE_ID.baggageBasicInfo, ...dataContent)
- },
- // 行李航段
- queryBaggageAirline (dataContent) {
- return myQuery(SERVICE_ID.baggageAirline, ...dataContent)
- },
- // 行李详情追踪链
- queryBaggageTrack (dataContent) {
- return myQuery(SERVICE_ID.baggageTrack, ...dataContent)
- },
- // 行李详情表格
- queryBaggageDetails (dataContent) {
- return myQuery(SERVICE_ID.baggageDetails, ...dataContent)
- },
- // 原始报文
- async queryBaggageMessage (dataContent) {
- try {
- const { code, returnData, message } = await BaggageMessageQuery({
- id: SERVICE_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;
- max-height: 152px;
- overflow-x: hidden;
- overflow-y: auto;
- > .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>
|