index.vue 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018
  1. <!--
  2. * @Author: zk
  3. * @Date: 2022-01-17 10:39:22
  4. * @LastEditTime: 2022-06-28 10:04:17
  5. * @LastEditors: your name
  6. * @Description: 中转进港
  7. -->
  8. <template>
  9. <div class="transfer-in">
  10. <!--功能区-表单-->
  11. <div ref="formWrap" class="terminal-form-wrap">
  12. <el-form ref="form" :inline="true" :model="formData" :rules="rules" class="form">
  13. <div class="form-left">
  14. <el-form-item prop="currentAirport">
  15. <!-- <el-cascader
  16. v-model="formData.currentAirport"
  17. style="width:144px;margin-left:10px"
  18. placeholder="全部机场"
  19. size="small"
  20. :options="currentAirportList"
  21. :props="currentAirportProps"
  22. collapse-tags
  23. clearable
  24. filterable
  25. @change="setCurrentAirport"
  26. /> -->
  27. <el-select v-model="formData.currentAirport" class="input-shadow" size="small" style="width: 100px" filterable default-first-option placeholder="请选择机场" @change="airPortChange">
  28. <el-option v-for="(item, index) in AirportList" :key="index" :label="item.planDepartureApt" :value="item.planDepartureApt" />
  29. </el-select>
  30. </el-form-item>
  31. <el-form-item prop="inboundCarrier">
  32. <el-cascader
  33. v-model="formData.inboundCarrier"
  34. class="input-shadow"
  35. style="width: 150px"
  36. size="small"
  37. :options="carrierProps"
  38. :props="optionProps"
  39. placeholder="进港承运航司"
  40. collapse-tags
  41. clearable
  42. filterable
  43. default-first-option
  44. @change="resetLoopEvent"
  45. />
  46. </el-form-item>
  47. <el-form-item prop="outgoingAirline">
  48. <el-cascader
  49. v-model="formData.outgoingAirline"
  50. class="input-shadow"
  51. style="width: 150px"
  52. size="small"
  53. :options="carrierPropsop"
  54. :props="optionPropser"
  55. placeholder="离港承运航司"
  56. collapse-tags
  57. clearable
  58. filterable
  59. default-first-option
  60. @change="resetLoopEvent"
  61. />
  62. </el-form-item>
  63. <!-- <el-form-item prop="startDate">
  64. <el-date-picker
  65. v-model="formData.startDate"
  66. class="input-shadow"
  67. style="width: 216px"
  68. size="small"
  69. type="date"
  70. value-format="yyyy-MM-dd"
  71. placeholder="开始时间"
  72. @change="startDateChangeHandler"
  73. />
  74. </el-form-item>
  75. <el-form-item prop="endDate">
  76. <el-date-picker
  77. v-model="formData.endDate"
  78. class="input-shadow"
  79. style="width: 216px"
  80. size="small"
  81. type="date"
  82. value-format="yyyy-MM-dd"
  83. placeholder="结束时间"
  84. @change="endDateChangeHandler"
  85. />
  86. </el-form-item> -->
  87. <el-form-item prop="flightDate" label="航班日期">
  88. <el-date-picker
  89. v-model="formData.flightDate"
  90. :clearable="false"
  91. size="small"
  92. style="width: 300px"
  93. type="daterange"
  94. value-format="yyyy-MM-dd"
  95. start-placeholder="开始日期"
  96. end-placeholder="结束日期"
  97. :picker-options="dateRangePickerOptions"
  98. @change="dateChangeHandler"
  99. />
  100. </el-form-item>
  101. <el-form-item>
  102. <div class="box-item">
  103. <p>预计中转数:</p>
  104. <li v-for="(item, index) in orderNum" :key="index" :class="{ 'number-item': !isNaN(item), 'mark-item': isNaN(item) }">
  105. <span v-if="!isNaN(item)">
  106. <i ref="numberItem">0123456789</i>
  107. </span>
  108. <span v-else class="comma">{{ item }}</span>
  109. </li>
  110. </div>
  111. </el-form-item>
  112. </div>
  113. <div class="form-right" @keyup.enter="onSubmit(1)">
  114. <el-form-item prop="search">
  115. <el-popover :value="popoverVisible" placement="bottom" trigger="manual">
  116. <span>请输入航班号(示例:CA1234)或行李牌号(示例:1234567890)</span>
  117. <el-input
  118. slot="reference"
  119. v-model="formData.search"
  120. class="input-shadow"
  121. style="width: 240px"
  122. size="small"
  123. placeholder="请输入内容"
  124. prefix-icon="el-icon-search"
  125. clearable
  126. @focus="popoverVisible = true"
  127. @blur="popoverVisible = false"
  128. />
  129. </el-popover>
  130. </el-form-item>
  131. <el-form-item>
  132. <el-button class="btn-shadow" size="mini" type="primary" @click="onSubmit(1)">搜索</el-button>
  133. </el-form-item>
  134. <el-form-item>
  135. <el-button class="btn-shadow" size="mini" type="primary" @click="changeView">切换视角</el-button>
  136. </el-form-item>
  137. <!-- <el-form-item v-is="['ti_timeIcon']">
  138. <TimeZoneSelector />
  139. </el-form-item> -->
  140. <el-form-item>
  141. <TimeZoneSelector />
  142. </el-form-item>
  143. <!-- <el-form-item v-is="['ti_columnSettings']">
  144. <img class="btn-img btn-shadow" src="@/assets/baggage/ic_setting.png" title="列设置" @click="show" />
  145. </el-form-item> -->
  146. <el-form-item>
  147. <img class="btn-img btn-shadow" src="@/assets/baggage/ic_setting.png" title="列设置" @click="show" />
  148. </el-form-item>
  149. <!-- <el-form-item v-is="['dm_dt_columnSettings']">
  150. <img class="btn-img btn-shadow" src="@/assets/baggage/ic_export.png" title="导出" @click="exportHandler('table', '航站中转进港列表')" />
  151. </el-form-item> -->
  152. <el-form-item>
  153. <img class="btn-img btn-shadow" src="@/assets/baggage/ic_export.png" title="导出" @click="exportHandler('table', '航站中转进港列表')" />
  154. </el-form-item>
  155. </div>
  156. </el-form>
  157. </div>
  158. <!--表格-->
  159. <div v-loading="loading" class="terminal-table" element-loading-text="拼命加载中" element-loading-spinner="el-icon-loading" element-loading-background="rgba(0, 0, 0, 0.8)">
  160. <el-table
  161. ref="table"
  162. class="table"
  163. :data="dealedTableData"
  164. :height="computedTableHeight"
  165. show-summary
  166. :summary-method="summaryMethod"
  167. :span-method="arraySpanMethod"
  168. :header-cell-class-name="headerCellClass"
  169. :row-class-name="tableRowClassName"
  170. :cell-class-name="cellClass"
  171. border
  172. stripe
  173. fit
  174. @cell-click="cellClickHandler"
  175. >
  176. <el-table-column v-for="col in tableColsCopy" :key="col.prop" :prop="col.prop" :label="col.label" :width="col.width" :fixed="col.fixed">
  177. <el-table-column v-for="childCol in col.children" :key="childCol.prop" :prop="childCol.prop" :label="childCol.label" :width="childCol.width" :formatter="tableFormat">
  178. <template #header>
  179. <el-tooltip :content="childCol.desc || childCol.label" placement="top">
  180. <TableHeaderCell
  181. :label="childCol.label"
  182. :filter-options="tableDataFilters[childCol.prop]"
  183. :filter-values.sync="filterValues[childCol.prop]"
  184. :sortable="childCol.sortable"
  185. :sort-rule.sync="tableDataSortRules[childCol.prop]"
  186. />
  187. </el-tooltip>
  188. </template>
  189. </el-table-column>
  190. </el-table-column>
  191. </el-table>
  192. </div>
  193. <!--列设置-->
  194. <Dialog :flag="dialogFlag" class="dialog-check-group">
  195. <div class="dialog-wrapper">
  196. <div class="title">列设置</div>
  197. <div class="content">
  198. <el-tree
  199. :data="tableCols"
  200. :class="colsCheckClass"
  201. show-checkbox
  202. node-key="index"
  203. :default-expand-all="true"
  204. :props="{
  205. label: 'label',
  206. children: 'children',
  207. }"
  208. :default-checked-keys="checkedKeysTemp"
  209. @check="handleCheck"
  210. />
  211. </div>
  212. <div class="foot right t30">
  213. <el-button size="medium" class="r24" type="primary" @click="onCheck">确定</el-button>
  214. <el-button size="medium" @click="hide">取消</el-button>
  215. </div>
  216. </div>
  217. </Dialog>
  218. </div>
  219. </template>
  220. <script>
  221. import Dialog from "@/layout/components/Dialog";
  222. import TimeZoneSelector from "@/components/TimeZoneSelector";
  223. import terminalMixin from "../../mixins/terminal";
  224. import formMixin from "../../mixins/form";
  225. import tableColsMixin from "../../mixins/tableCols";
  226. import timeZoneMixin from "../../mixins/timeZone";
  227. import { getQuery } from "@/api/flight";
  228. import TableHeaderCell from "@/components/TableHeaderCell";
  229. import { setTableFilters, throttledExportToExcel, timeInZone } from "@/utils/table";
  230. import { GeneralDataReception } from "@/api/dataIntegration";
  231. import { parseTime } from "@/utils/index";
  232. import { mapGetters } from "vuex";
  233. export default {
  234. name: "DepartureTerminalView",
  235. components: { Dialog, TimeZoneSelector, TableHeaderCell },
  236. mixins: [terminalMixin, formMixin, tableColsMixin, timeZoneMixin],
  237. data() {
  238. return {
  239. optionProps: {
  240. value: "inAicompanyCode2",
  241. label: "inAicompanyCode2",
  242. },
  243. optionPropser: {
  244. value: "outAicompanyCode2",
  245. label: "outAicompanyCode2",
  246. },
  247. popoverVisible: false,
  248. orderNum: ["0", "0", "0", "0", "0", "0"], // 默认总数
  249. // 初始表头
  250. tableCols: [
  251. {
  252. prop: "arrivalInfo",
  253. label: "进港航班",
  254. width: 180,
  255. fixed: "left",
  256. children: [
  257. {
  258. prop: "preFlightNO",
  259. label: "航班号",
  260. desc: "进港航班编号",
  261. width: 80,
  262. filterable: true,
  263. sortable: true,
  264. },
  265. {
  266. prop: "preFlightDate",
  267. label: "航班日期",
  268. desc: "指航班计划起飞日期(不变的,机票上),不是预计起飞日期(预计起飞时间可能多个),也不是实际起飞日期(实际起飞等于最后预计)",
  269. width: 100,
  270. },
  271. {
  272. prop: "preAirport",
  273. label: "起飞航站",
  274. desc: "指进港航班的起飞机场三字码",
  275. width: 100,
  276. filterable: true,
  277. sortable: true,
  278. },
  279. {
  280. prop: "actualLandingTime",
  281. label: "降落时间",
  282. desc: "根据优先级别显示时间。优先级别:1.实际降落时间,2.预计降落时间,3.计划降落时间",
  283. width: 100,
  284. },
  285. {
  286. prop: "landingBuild",
  287. label: "降落航站楼",
  288. desc: "指航班降落后位于机场的哪个航站楼",
  289. width: 98,
  290. filterable: true,
  291. sortable: true,
  292. },
  293. {
  294. prop: "carousel",
  295. label: "行李转盘",
  296. desc: "指航班到达后行李提取的地方,仅显示最新信息",
  297. width: 100,
  298. filterable: true,
  299. sortable: true,
  300. },
  301. {
  302. prop: "standForLanding",
  303. label: "降落停机位",
  304. desc: "指航班的停机位代码,数据是变化的,仅显示最新信息",
  305. width: 98,
  306. filterable: true,
  307. sortable: true,
  308. },
  309. {
  310. prop: "inTransferBaggageCount",
  311. label: "中转行李数",
  312. desc: "指航班在本航站预计需要中转至对应航班的行李数量",
  313. },
  314. ],
  315. },
  316. {
  317. prop: "departureInfo",
  318. label: "离港航班",
  319. children: [
  320. {
  321. prop: "inTransferredBaggageCount",
  322. label: "已中转行李数",
  323. desc: "指航班在本航站实际已经中转至对应航班的行李数量",
  324. width: 100,
  325. },
  326. {
  327. prop: "flightNO",
  328. label: "航班号",
  329. desc: "指航班编号",
  330. width: 80,
  331. filterable: true,
  332. sortable: true,
  333. },
  334. {
  335. prop: "flightDate",
  336. label: "航班日期",
  337. desc: "指航班计划起飞日期(不变的,机票上),不是预计起飞日期(预计起飞时间可能多个),也不是实际起飞日期(实际起飞等于最后预计)",
  338. width: 100,
  339. },
  340. {
  341. prop: "actualDepartureTime",
  342. label: "起飞时间",
  343. desc: "指航班预计起飞时间,数据是变化的,仅显示最新结果",
  344. width: 100,
  345. },
  346. {
  347. prop: "targetAirport",
  348. label: "目的站",
  349. desc: "指航班执飞航段的目的航站,以航站三字码+航站简称显示",
  350. filterable: true,
  351. sortable: true,
  352. },
  353. {
  354. prop: "departureBuild",
  355. label: "起飞航站楼",
  356. desc: "指航班执飞航段的起飞航站的航站楼",
  357. width: 98,
  358. filterable: true,
  359. sortable: true,
  360. },
  361. {
  362. prop: "bordingGate",
  363. label: "起飞登机口",
  364. desc: "指航班的登机口代码,数据是变化的,仅显示最新信息",
  365. width: 98,
  366. filterable: true,
  367. sortable: true,
  368. },
  369. {
  370. prop: "standForDepartrue",
  371. label: "起飞停机位",
  372. desc: "指航班的停机位代码,数据是变化的,仅显示最新信息",
  373. width: 98,
  374. filterable: true,
  375. sortable: true,
  376. },
  377. // {
  378. // prop: 'outTransferBaggageCount',
  379. // label: '中转进行李数',
  380. // desc: '指其它航班预计中转至本航班的行李数量',
  381. // width: 100
  382. // },
  383. // {
  384. // prop: 'outTransferredBaggageCount',
  385. // label: '已中转进行李数',
  386. // desc: '指其它航班实际已中转至本航班的行李数量',
  387. // width: 120
  388. // },
  389. {
  390. prop: "timeDifference",
  391. label: "转运时间",
  392. desc: "指中转动作完成时间",
  393. },
  394. ],
  395. },
  396. ],
  397. loading: false,
  398. AirportList: [],
  399. carrierProps: [],
  400. carrierPropsop: [],
  401. loopEvent: null,
  402. arrivalCount: 0,
  403. baggageCount: 0,
  404. hasSetTableScroll: false,
  405. spanArr: [],
  406. contactDot: 0,
  407. flag: 0,
  408. table: null,
  409. WarningData: [],
  410. };
  411. },
  412. computed: {
  413. singleDay() {
  414. return this.startDate === this.endDate;
  415. },
  416. ...mapGetters(["timeZone"]),
  417. },
  418. watch: {
  419. dealedTableData: {
  420. handler(val) {
  421. this.spanArr = [];
  422. let contactDot = this.contactDot;
  423. val.forEach((item, index, arr) => {
  424. if (index === 0) {
  425. this.spanArr.push(1);
  426. } else {
  427. if (item["preFlightNO"] === arr[index - 1]["preFlightNO"] && item["preFlightDate"] === arr[index - 1]["preFlightDate"]) {
  428. this.spanArr[contactDot] += 1;
  429. this.spanArr.push(0);
  430. } else {
  431. this.spanArr.push(1);
  432. contactDot = index;
  433. }
  434. }
  435. });
  436. },
  437. deep: true,
  438. },
  439. },
  440. created() {
  441. // this.getAirPortData()
  442. },
  443. mounted() {
  444. this.$refs["form"].validateField("flightDate");
  445. this.getAirPortData();
  446. this.table = this.$refs.table.bodyWrapper;
  447. const that = this;
  448. this.table.addEventListener("scroll", () => {
  449. that.scrollTop = this.table.scrollTop;
  450. });
  451. },
  452. activated() {
  453. this.table.scrollTop = this.scrollTop;
  454. this.getTableData();
  455. this.getWarningData();
  456. this.loopEvent = setInterval(this.getTableData, LOOP_INTERVAL.transferArrivalTable);
  457. // const { startDate, endDate } = this.$route.query
  458. // Object.entries(this.$route.query).forEach(([key, value]) => {
  459. // if ((value ?? '') !== '' && JSON.stringify(value) !== '[]') {
  460. // this.formData[key] = value
  461. // }
  462. // })
  463. // if (startDate !== null && startDate !== undefined) {
  464. // this.formData.flightDate[0] = startDate
  465. // }
  466. // if (endDate !== null && endDate !== undefined) {
  467. // this.formData.flightDate[1] = endDate
  468. // }
  469. },
  470. deactivated() {
  471. if (this.loopEvent) {
  472. clearInterval(this.loopEvent);
  473. this.loopEvent = null;
  474. }
  475. },
  476. beforeDestroy() {
  477. if (this.loopEvent) {
  478. clearInterval(this.loopEvent);
  479. this.loopEvent = null;
  480. }
  481. },
  482. methods: {
  483. async getWarningData() {
  484. try {
  485. const res = await getQuery({
  486. id: DATACONTENT_ID.departureWarningId,
  487. dataContent: [],
  488. });
  489. if (Number(res.code) === 0) {
  490. const { listValues } = res.returnData;
  491. this.WarningData = listValues;
  492. } else {
  493. this.$message.error(res.message);
  494. }
  495. } catch (error) {
  496. this.$message.error("失败");
  497. }
  498. },
  499. resetLoopEvent() {
  500. this.loading = true;
  501. this.hasSetTableScroll = false;
  502. this.loopEvent && clearInterval(this.loopEvent);
  503. this.getTableData();
  504. this.loopEvent = setInterval(this.getTableData, LOOP_INTERVAL.transferArrivalTable);
  505. },
  506. headerCellClass({ row, column }) {
  507. const classes = [];
  508. const rule = this.tableDataSortRules[column.property];
  509. if (rule) {
  510. classes.push(rule);
  511. }
  512. return classes.join(" ");
  513. },
  514. tableRowClassName({ row, rowIndex }) {
  515. const classes = [];
  516. if (row.hasArrived) {
  517. classes.push("bgl-hui");
  518. if (rowIndex === this.arrivalCount - 1) {
  519. classes.push("redBorder");
  520. }
  521. }
  522. return classes.join(" ");
  523. },
  524. changeView() {
  525. // const query = {
  526. // ...this.formData,
  527. // startDate: this.startDate,
  528. // endDate: this.endDate
  529. // }
  530. // delete query.flightDate
  531. // this.$router.replace({
  532. // path: '/transfer/departure',
  533. // query
  534. // })
  535. this.$router.push("/transfer/departure");
  536. },
  537. airPortChange() {
  538. this.getAviationData();
  539. this.upAviationData();
  540. this.resetLoopEvent();
  541. },
  542. dateChangeHandler() {
  543. this.getAviationData();
  544. this.upAviationData();
  545. this.resetLoopEvent();
  546. },
  547. // 选择机场
  548. async getAirPortData() {
  549. try {
  550. const res = await getQuery({
  551. id: DATACONTENT_ID.departureAirId,
  552. dataContent: [],
  553. });
  554. if (Number(res.code) === 0) {
  555. this.AirportList = res.returnData.listValues;
  556. this.formData.currentAirport = "PEK";
  557. this.getAviationData();
  558. this.upAviationData();
  559. this.resetLoopEvent();
  560. } else {
  561. this.$message.error(res.message);
  562. }
  563. } catch (error) {
  564. this.$message.error("失败");
  565. }
  566. },
  567. // 选择航司
  568. async getAviationData() {
  569. try {
  570. const res = await getQuery({
  571. id: DATACONTENT_ID.departureAviJoinId,
  572. dataContent: [this.formData.currentAirport],
  573. });
  574. if (Number(res.code) === 0) {
  575. this.carrierProps = res.returnData.listValues;
  576. } else {
  577. this.$message.error(res.message);
  578. }
  579. } catch (error) {
  580. this.$message.error("失败");
  581. }
  582. },
  583. // 选择航司
  584. async upAviationData() {
  585. try {
  586. const res = await getQuery({
  587. id: DATACONTENT_ID.departureAviLeaveId,
  588. dataContent: [this.formData.currentAirport],
  589. });
  590. if (Number(res.code) === 0) {
  591. this.carrierPropsop = res.returnData.listValues;
  592. } else {
  593. this.$message.error(res.message);
  594. }
  595. } catch (error) {
  596. this.$message.error("失败");
  597. }
  598. },
  599. // 获取表单下拉框数据
  600. // getFormData(params) {
  601. // this.relatedAirportQuery({
  602. // ...params,
  603. // type: 'OUT'
  604. // })
  605. // this.outgoingAirlineQuery(params)
  606. // this.craftTypeQuery(params)
  607. // this.flightAttrQuery(params)
  608. // },
  609. // 获取表格数据
  610. async getTableData() {
  611. if (!this.formData.currentAirport || !this.startDate || !this.endDate) {
  612. return;
  613. }
  614. const arrs1 = [this.formData.inboundCarrier.length === 0 ? "" : this.formData.inboundCarrier[0]];
  615. const arrs2 = [this.formData.outgoingAirline.length === 0 ? "" : this.formData.outgoingAirline[0]];
  616. const arr = [
  617. this.formData.currentAirport,
  618. this.startDate,
  619. this.endDate,
  620. ...arrs1,
  621. ...arrs1,
  622. ...arrs1,
  623. ...arrs2,
  624. ...arrs2,
  625. ...arrs2,
  626. // this.formData.inboundCarrier,
  627. // this.formData.outgoingAirline,
  628. // JSON.stringify(this.formData.inboundCarrier),
  629. // JSON.stringify(this.formData.outgoingAirline),
  630. ];
  631. try {
  632. const res = await getQuery({
  633. id: DATACONTENT_ID.departureTableId,
  634. dataContent: [...arr],
  635. });
  636. if (Number(res.code) === 0) {
  637. this.initTableData(res.returnData.listValues);
  638. } else {
  639. }
  640. this.loading = false;
  641. } catch (error) {
  642. if (this.loopEvent) {
  643. clearInterval(this.loopEvent);
  644. this.loopEvent = null;
  645. }
  646. this.loading = false;
  647. }
  648. },
  649. initTableData(tableData) {
  650. const currentTime = new Date();
  651. const curTime = this.formatTime(currentTime);
  652. this.arrivalCount = 0;
  653. this.baggageCount = 0;
  654. tableData.forEach((item) => {
  655. const o1 = item["inTransferBaggageCount"];
  656. const o2 = item["inTransferredBaggageCount"];
  657. const out1 = o1 != undefined || o1 != null ? o1 : 0;
  658. const out2 = o2 != undefined || o2 != null ? o2 : 0;
  659. if (this.hasArrived(item)) {
  660. this.arrivalCount++;
  661. }
  662. if (item["hasArrived"] && out1 - out2 > 0) {
  663. this.WarningData.forEach((p) => {
  664. const startTime = this.formatTime(timeInZone((p.startDate ?? "").replace("T", " "), this.timeZone), 2);
  665. const endTime = this.formatTime(timeInZone((p.endDate ?? "").replace("T", " "), this.timeZone), 2);
  666. const planTime = this.formatTime(timeInZone((item.actualDepartureTime ?? "").replace("T", " "), this.timeZone), 2);
  667. const capTime = Math.ceil((planTime - curTime) / (1000 * 60));
  668. if (Number(startTime) - Number(curTime) < 0 && Number(endTime) - Number(curTime) > 0) {
  669. if (p.flightNO != "" && p.flightNO == item.flightNO) {
  670. if (capTime - p.warningDuration < 0 && capTime - p.alarmDuration > 0) {
  671. item["warningState"] = 1;
  672. const returnedTarget = Object.assign(item, p);
  673. this.sendLog(returnedTarget);
  674. }
  675. if (capTime - p.alarmDuration < 0) {
  676. item["warningState"] = 2;
  677. const returnedTarget = Object.assign(item, p);
  678. this.sendLog(returnedTarget);
  679. }
  680. } else if (p.flightNO == "" && p.IATACode != "") {
  681. if (item.flightNO.substring(0, 2) == p.IATACode) {
  682. if (capTime - p.warningDuration < 0 && capTime - p.alarmDuration > 0) {
  683. item["warningState"] = 1;
  684. const returnedTarget = Object.assign(item, p);
  685. this.sendLog(returnedTarget);
  686. }
  687. if (capTime - p.alarmDuration < 0) {
  688. item["warningState"] = 2;
  689. const returnedTarget = Object.assign(item, p);
  690. this.sendLog(returnedTarget);
  691. }
  692. }
  693. }
  694. }
  695. });
  696. }
  697. this.baggageCount = this.baggageCount + item.inTransferBaggageCount;
  698. });
  699. this.tableData = this._.sortBy(tableData, ["actualLandingTime", "preFlightNO", "actualDepartureTime", "flightNO"]);
  700. setTableFilters(this.tableData, this.tableDataFilters);
  701. this.toOrderNum(this.baggageCount);
  702. this.$nextTick(() => {
  703. this.setTableScroll();
  704. });
  705. },
  706. formatTime(date, type = 1) {
  707. let time = null;
  708. if (type == 1) {
  709. time = parseTime(date, "{y}-{m}-{d} {h}:{i}:{s}");
  710. } else {
  711. time = date;
  712. }
  713. const newTimt = new Date(time);
  714. return newTimt.getTime();
  715. },
  716. async sendLog(obj) {
  717. try {
  718. const newObj = {
  719. logTime: parseTime(new Date(), "{y}-{m}-{d} {h}:{i}:{s}"),
  720. logInfo: JSON.stringify(obj),
  721. flightNO: obj.flightNO,
  722. flightDate: obj.flightDate,
  723. luggageSN: "",
  724. strategyUseID: obj.alarmStrategyID,
  725. event: 1,
  726. };
  727. await GeneralDataReception({
  728. serviceId: SERVICE_ID.departureScId,
  729. dataContent: JSON.stringify(newObj),
  730. });
  731. } catch (error) {
  732. this.$message.error("失败");
  733. }
  734. },
  735. hasArrived(flight) {
  736. if (flight.actualLandingTime) {
  737. const now = new Date();
  738. const actualLandingTime = new Date(flight.actualLandingTime.replace("T", " "));
  739. flight["hasArrived"] = now > actualLandingTime && !flight["flightCanceled"];
  740. } else {
  741. flight["hasArrived"] = false;
  742. }
  743. return flight["hasArrived"];
  744. },
  745. setTableScroll() {
  746. if (!this.singleDay || this.hasSetTableScroll || this.arrivalCount === 0) {
  747. return;
  748. }
  749. const table = this.$refs["table"].$el;
  750. const scrollParent = table.querySelector(".el-table__body-wrapper");
  751. if (scrollParent.scrollHeight <= scrollParent.offsetHeight) {
  752. return;
  753. }
  754. const lastRow = table.querySelectorAll(".el-table__body tr")[this.arrivalCount - 1];
  755. setTimeout(() => {
  756. const scrollMid = lastRow.offsetTop + lastRow.offsetHeight - scrollParent.offsetHeight / 2;
  757. const scrollMax = scrollParent.scrollHeight - scrollParent.offsetHeight;
  758. if (scrollMid > 0) {
  759. const scrollHeight = Math.min(scrollMid, scrollMax);
  760. scrollParent.scrollTo(0, scrollHeight);
  761. }
  762. }, 0);
  763. this.hasSetTableScroll = true;
  764. },
  765. setNumberTransform() {
  766. const numberItems = this.$refs.numberItem; // 拿到数字的ref,计算元素数量
  767. const numberArr = this.orderNum.filter((item) => !isNaN(item));
  768. // 结合CSS 对数字字符进行滚动,显示订单数量
  769. for (let index = 0; index < numberItems.length; index++) {
  770. const elem = numberItems[index];
  771. elem.style.transform = `translate(-50%, -${numberArr[index] * 10}%)`;
  772. }
  773. },
  774. toOrderNum(num) {
  775. num = num.toString();
  776. if (num.length < 6) {
  777. num = "0" + num; // 如未满八位数,添加"0"补位
  778. this.toOrderNum(num); // 递归添加"0"补位
  779. } else if (num.length >= 6) {
  780. this.orderNum = num.split(""); // 将其便变成数据,渲染至滚动数组
  781. } else {
  782. // 订单总量数字超过八位显示异常
  783. this.$message.warning("总量数字过大");
  784. }
  785. this.setNumberTransform();
  786. },
  787. arraySpanMethod({ row, column, rowIndex, columnIndex }) {
  788. for (let i = 0; i < 7; i++) {
  789. if (columnIndex === i) {
  790. const _row = this.spanArr[rowIndex];
  791. const _col = _row > 0 ? 1 : 0;
  792. return {
  793. rowspan: _row,
  794. colspan: _col,
  795. };
  796. }
  797. }
  798. },
  799. exportHandler(refName, tableName) {
  800. if (this.loading) {
  801. return;
  802. }
  803. const table = this.$refs[refName].$el.cloneNode(true);
  804. const fileName = `${tableName}-${this.currentAirport}-${this.startDate}-${this.endDate}.xlsx`;
  805. throttledExportToExcel(table, tableName, fileName, 2);
  806. },
  807. },
  808. };
  809. </script>
  810. <style lang="scss" scoped>
  811. .terminal-form-wrap {
  812. padding-top: 11px;
  813. padding-left: 5px;
  814. ::v-deep .form {
  815. display: flex;
  816. justify-content: space-between;
  817. .form-left {
  818. flex: 1;
  819. }
  820. .form-right {
  821. flex: 0 1 auto;
  822. }
  823. .el-form-item {
  824. margin-bottom: 0px;
  825. margin-right: 8px;
  826. button,
  827. input,
  828. optgroup,
  829. select,
  830. textarea {
  831. font-family: Helvetica, "Microsoft YaHei";
  832. font-size: 14px;
  833. }
  834. .el-switch__label {
  835. color: #303133;
  836. }
  837. .el-form-item__error {
  838. z-index: 10;
  839. }
  840. }
  841. .btn-img {
  842. position: relative;
  843. top: 6px;
  844. }
  845. }
  846. .box-item {
  847. position: relative;
  848. height: 50px;
  849. font-size: 18px;
  850. line-height: 32px;
  851. text-align: center;
  852. list-style: none;
  853. color: #2d7cff;
  854. writing-mode: vertical-lr;
  855. text-orientation: upright;
  856. /*文字禁止编辑*/
  857. -moz-user-select: none; /*火狐*/
  858. -webkit-user-select: none; /*webkit浏览器*/
  859. -ms-user-select: none; /*IE10*/
  860. -khtml-user-select: none; /*早期浏览器*/
  861. user-select: none;
  862. /* overflow: hidden; */
  863. p {
  864. line-height: 32px;
  865. writing-mode: horizontal-tb !important;
  866. text-orientation: none !important;
  867. /*文字禁止编辑*/
  868. -moz-user-select: none; /*火狐*/
  869. -webkit-user-select: none; /*webkit浏览器*/
  870. -ms-user-select: none; /*IE10*/
  871. -khtml-user-select: none; /*早期浏览器*/
  872. user-select: none;
  873. margin-top: 5px;
  874. }
  875. }
  876. /* 默认逗号设置 */
  877. .mark-item {
  878. width: 10px;
  879. height: 32px;
  880. margin-right: 5px;
  881. line-height: 10px;
  882. font-size: 18px;
  883. position: relative;
  884. & > span {
  885. position: absolute;
  886. width: 100%;
  887. bottom: 0;
  888. writing-mode: vertical-rl;
  889. text-orientation: upright;
  890. }
  891. }
  892. /*滚动数字设置*/
  893. .number-item {
  894. width: 41px;
  895. height: 42px;
  896. /* 背景图片 */
  897. // background: url(/images/text-bg-blue.png) no-repeat center center;
  898. // background-size: 100% 100%;
  899. // background: #ccc;
  900. list-style: none;
  901. margin-right: 5px;
  902. // background:rgba(250,250,250,1);
  903. border-radius: 4px;
  904. border: 3px solid rgb(221, 221, 221);
  905. & > span {
  906. position: relative;
  907. display: inline-block;
  908. margin-right: 10px;
  909. width: 100%;
  910. height: 100%;
  911. writing-mode: vertical-rl;
  912. text-orientation: upright;
  913. overflow: hidden;
  914. & > i {
  915. font-style: normal;
  916. position: absolute;
  917. top: 11px;
  918. left: 50%;
  919. transform: translate(-50%, -1%);
  920. transition: transform 1s ease-in-out;
  921. letter-spacing: 10px;
  922. }
  923. }
  924. }
  925. .number-item:last-child {
  926. margin-right: 0;
  927. }
  928. }
  929. .terminal-table {
  930. width: 100%;
  931. ::v-deep .table {
  932. width: 100%;
  933. .cell {
  934. padding: 0;
  935. text-align: center;
  936. font-size: 14px;
  937. font-family: Helvetica, "Microsoft YaHei";
  938. letter-spacing: 0;
  939. }
  940. .cell-click {
  941. cursor: pointer;
  942. color: #2d7cff;
  943. &.cell-clicked {
  944. color: purple;
  945. }
  946. }
  947. .el-table__header-wrapper,
  948. .el-table__fixed-header-wrapper {
  949. .cell {
  950. font-weight: bold;
  951. color: #101116;
  952. }
  953. .has-gutter {
  954. tr {
  955. .bgl-huang {
  956. background: #fcf0b1;
  957. }
  958. }
  959. }
  960. }
  961. .el-table__body-wrapper,
  962. .el-table__fixed-body-wrapper {
  963. tr.bgl-hui {
  964. background: #d2d6df;
  965. td {
  966. background: #d2d6df;
  967. }
  968. &.redBorder {
  969. position: relative;
  970. &::after {
  971. content: "";
  972. position: absolute;
  973. left: 0;
  974. bottom: 0;
  975. width: 100%;
  976. height: 2px;
  977. background: #e83f82;
  978. }
  979. }
  980. }
  981. }
  982. td.cell-tounLoad {
  983. background: lightcoral !important;
  984. position: relative;
  985. &::after {
  986. content: "";
  987. display: block;
  988. width: 100%;
  989. height: 100%;
  990. position: absolute;
  991. top: 0;
  992. left: 0;
  993. border: 2px dashed red;
  994. }
  995. }
  996. td.cell-tounLoadNew {
  997. background: #fcf0b1 !important;
  998. position: relative;
  999. &::after {
  1000. content: "";
  1001. display: block;
  1002. width: 100%;
  1003. height: 100%;
  1004. position: absolute;
  1005. top: 0;
  1006. left: 0;
  1007. border: 2px dashed #e28913;
  1008. }
  1009. }
  1010. .el-table__cell.is-hidden > * {
  1011. visibility: visible;
  1012. }
  1013. }
  1014. }
  1015. </style>