index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. <template>
  2. <div class="airport-view">
  3. <div class="airport-header">
  4. <AirportForm :name="name" @form-data-change="formDataChangeHandler" />
  5. <div class="airport-count">
  6. <CountBox
  7. :count-number="tableDataCount.flightCount"
  8. :length="4"
  9. label="今日计划航班数"
  10. />
  11. <CountBox
  12. :count-number="
  13. isDeparture ? finishedCount : tableDataCount.tallyCount
  14. "
  15. :length="4"
  16. label="已完成航班数"
  17. />
  18. <CountBox
  19. :count-number="weightCount"
  20. label="已转载重量KG"
  21. :length="8"
  22. />
  23. </div>
  24. <div class="airport-settings">
  25. <div v-permission="getPermission('count')">
  26. <CommonSwitch v-model:flag="countFlag" label="显示件数" />
  27. </div>
  28. <!-- <div v-permission="getPermission('UTC')">
  29. <CommonSwitch v-model:flag="UTCFlag" label="开启UTC" />
  30. </div> -->
  31. <div v-permission="getPermission('columnSet')">
  32. <ColumnSet
  33. :table-columns="tableColumns"
  34. @checked-submit="columnChecked"
  35. />
  36. </div>
  37. </div>
  38. </div>
  39. <div class="airport-table">
  40. <SimpleTable
  41. ref="tableRef"
  42. :columns="tableColumns"
  43. :data="tableData"
  44. row-key="rowKey"
  45. sequence
  46. highlight-current-row
  47. scrollbar-always-on
  48. :stripe="false"
  49. show-summary
  50. :cache-keys="cacheKeys"
  51. :filter-sort-options="filterSortOptions"
  52. :label-formatter="tableColumnFormatter"
  53. :row-class-name="rowClassName"
  54. :cell-class-name="cellClass"
  55. :column-props="{ formatter: tableDataFormatter }"
  56. @sort-rule-change="sortRuleChangeHandler"
  57. @cell-click="cellClickHandler"
  58. />
  59. </div>
  60. <!-- <div class="table-footer">
  61. <span class="table-footer-count"
  62. >货运航班总数:{{ tableDataCount.freightFlightCount }}</span
  63. >
  64. <span class="table-footer-count"
  65. >货站交接总数:{{ tableDataCount.depotFlightCount }}</span
  66. >
  67. <span v-if="isDeparture" class="table-footer-count"
  68. >已装机总数:{{ tableDataCount.loadCount }}</span
  69. >
  70. <span v-else class="table-footer-count"
  71. >已卸机总数:{{ tableDataCount.unloadCount }}</span
  72. >
  73. </div> -->
  74. </div>
  75. </template>
  76. <script lang="tsx" setup>
  77. import AirportForm from './AirportForm.vue'
  78. import ColumnSet from '@/components/ColumnSet/index.vue'
  79. import CountBox from '../../components/CountBox/index.vue'
  80. import CommonSwitch from '../../components/CommonSwitch/index.vue'
  81. import SimpleTable from '@/components/SimpleTable/index.vue'
  82. import { useTableColumnSet } from '@/hooks/useTableColumnSet'
  83. import { useAirportTable } from './useAirportTable'
  84. import { useTableStyle } from '../../hooks/useTableStyle'
  85. import { useTableCellClick } from '../../hooks/useTableCellClick'
  86. import { useFormatter } from './useFormatter'
  87. import { CommonData } from '~/common'
  88. import { useLoop } from '@/hooks/useLoop'
  89. import { useTableSettingsStore } from '@/store/tableSettings'
  90. import { useFlightState } from './useFlightState'
  91. import { Query } from '@/api/webApi'
  92. import { ElMessage } from 'element-plus'
  93. const props = defineProps({
  94. name: {
  95. type: String,
  96. required: true,
  97. },
  98. })
  99. const isDeparture = props.name.includes('Departure')
  100. const formData: CommonData = reactive({})
  101. const formDataChangeHandler = (data: CommonData) => {
  102. Object.assign(formData, data)
  103. }
  104. const { tableColumns, tableData, getTableData } = useAirportTable(
  105. props.name,
  106. formData
  107. )
  108. const finishedCount = ref(0)
  109. const weightCount = ref(0)
  110. const getWeightCount = async () => {
  111. try {
  112. const { startDate, endDate } = formData
  113. const dataContent = [startDate, endDate]
  114. const {
  115. code,
  116. returnData: { listValues },
  117. message,
  118. } = await Query({
  119. id:
  120. DATACONTENT_ID[
  121. `${
  122. props.name.slice(0, 1).toLowerCase() + props.name.slice(1)
  123. }WeightCount`
  124. ],
  125. dataContent,
  126. })
  127. if (Number(code) !== 0) {
  128. throw new Error(message || '失败')
  129. }
  130. if (!listValues.length) {
  131. ElMessage.info('未查询到重量信息')
  132. weightCount.value = 0
  133. return
  134. }
  135. weightCount.value = listValues[0].weight
  136. } catch (error) {
  137. console.error(error)
  138. }
  139. }
  140. const { getWarningRules } = useFlightState(props.name, tableData, finishedCount)
  141. useLoop(
  142. [
  143. getWeightCount,
  144. getTableData,
  145. // getWarningRules,
  146. ],
  147. 'airport',
  148. [formData]
  149. )
  150. const countFlag = ref(false)
  151. const { tableColumnFormatter, tableDataFormatter } = useFormatter(countFlag)
  152. // const UTCFlag = ref(true)
  153. /* 离港视图默认的排序方式:
  154. * 1.已起飞排在前
  155. * 2.未起飞中已装机在前
  156. * 3.已起飞和未起飞分类中各自按照预计起飞时间排序
  157. */
  158. const defaultSortFunction = (a: CommonData, b: CommonData) => {
  159. const departureTimeCompare = (a: CommonData, b: CommonData) => {
  160. if (a.planDepartureTime) {
  161. if (b.planDepartureTime) {
  162. if (a.planDepartureTime > b.planDepartureTime) {
  163. return 1
  164. } else if (a.planDepartureTime < b.planDepartureTime) {
  165. return -1
  166. } else {
  167. return 0
  168. }
  169. } else {
  170. return -1
  171. }
  172. } else if (b.planDepartureTime) {
  173. return 1
  174. } else {
  175. return 0
  176. }
  177. }
  178. if (a.hasTakenOff === 'Y') {
  179. if (b.hasTakenOff === 'Y') {
  180. return departureTimeCompare(a, b)
  181. } else {
  182. return -1
  183. }
  184. } else if (b.hasTakenOff === 'Y') {
  185. return 1
  186. } else {
  187. if (a.loadPlaneSureTime) {
  188. if (b.loadPlaneSureTime) {
  189. return departureTimeCompare(a, b)
  190. } else {
  191. return -1
  192. }
  193. } else if (b.loadPlaneSureTime) {
  194. return 1
  195. } else {
  196. return departureTimeCompare(a, b)
  197. }
  198. }
  199. }
  200. const filterSortOptions = computed(() => ({
  201. defaultFilterValueMap,
  202. extraFilterValueMap: flightStateFilter,
  203. defaultSortRuleMap: isDeparture
  204. ? undefined
  205. : {
  206. planLandingTime: 'ascending',
  207. },
  208. defaultSortFunction: isDeparture ? defaultSortFunction : undefined,
  209. }))
  210. const sortRuleMap = ref({})
  211. const sortRuleChangeHandler = map => {
  212. sortRuleMap.value = map
  213. }
  214. const { columnChecked } = useTableColumnSet(tableColumns)
  215. const { rowClass, cellClass } = useTableStyle(props.name)
  216. const rowClassName = params => {
  217. const { row, rowIndex } = params
  218. const classes: string[] = []
  219. if (
  220. (row.hasTakenOff === 'Y' || row.hasLanded === 'Y') &&
  221. (['planDepartureTime', 'planLandingTime'].some(
  222. key => sortRuleMap.value[key] === 'ascending'
  223. ) ||
  224. Object.keys(sortRuleMap.value).length === 0) &&
  225. finishedCount.value < tableData.value.length &&
  226. rowIndex === finishedCount.value - 1
  227. ) {
  228. classes.push('underline-red')
  229. }
  230. return `${rowClass(params)} ${classes.join(' ')}`
  231. }
  232. const tableDataCount = computed(() =>
  233. tableData.value.reduce(
  234. (counts: { [x: string]: number }, current) => {
  235. // const preCount = current[isDeparture ? 'preLoad' : 'preUnload']
  236. // if (preCount) {
  237. // counts.waybillCount += Number(String(preCount).split('/')[0])
  238. // counts.goodsCount += Number(String(preCount).split('/')[1])
  239. // }
  240. if (typeof current['allNumber'] === 'number') {
  241. counts.flightCount = current['allNumber']
  242. }
  243. if (current['depotJoinTime'] || current['depotJoinTime_IN']) {
  244. counts.depotFlightCount++
  245. }
  246. const isFreight = tableColumns.value.some(
  247. column => column.groupName === '地服相关' && current[column.columnName]
  248. )
  249. if (isFreight) {
  250. counts.freightFlightCount++
  251. }
  252. if (current['loadPlaneSureTime']) {
  253. counts.loadCount++
  254. }
  255. if (current['unLoadTime']) {
  256. counts.unloadCount++
  257. }
  258. if (current['tallyTime_in']) {
  259. counts.tallyCount++
  260. }
  261. return counts
  262. },
  263. {
  264. // waybillCount: 0,
  265. // goodsCount: 0,
  266. flightCount: 0,
  267. depotFlightCount: 0,
  268. freightFlightCount: 0,
  269. loadCount: 0,
  270. unloadCount: 0,
  271. tallyCount: 0,
  272. }
  273. )
  274. )
  275. const { cellClickHandler } = useTableCellClick(props.name)
  276. const route = useRoute()
  277. const { savedTableFilterValueMap } = useTableSettingsStore()
  278. const defaultFilterValueMap = savedTableFilterValueMap[route.path]
  279. const flightStateFilter = computed<{} | { [x: string]: string[] }>(() => {
  280. switch (formData.flightState) {
  281. case 'hasTakenOff':
  282. return { hasTakenOff: ['Y'] }
  283. case 'hasNotTakenOff':
  284. return { hasTakenOff: ['N'] }
  285. case 'hasLanded':
  286. return { hasLanded: ['Y'] }
  287. case 'hasNotLanded':
  288. return { hasLanded: ['N'] }
  289. case 'canceled':
  290. return { flightState: ['CAN'] }
  291. case 'groundService':
  292. return { groundService: ['Y'] }
  293. default:
  294. return {}
  295. }
  296. })
  297. const cacheKeys = ['IATACode']
  298. const permissionMap = {
  299. DepartureAirport: {
  300. count:
  301. 'number_of_pieces_displayed_in_domestic_departure_terminal_view_button',
  302. UTC: 'turn_on_utc_in_view_of_domestic_departure_terminal_button',
  303. columnSet: 'domestic_departure_terminal_view_column_setting_button',
  304. },
  305. InternationalDepartureAirport: {
  306. count:
  307. 'number_of_pieces_displayed_in_international_departure_terminal_view_button',
  308. UTC: 'international_departure_terminal_view_opens_utc_button',
  309. columnSet: 'international_departure_terminal_view_column_setting_button',
  310. },
  311. ArrivalAirport: {
  312. count:
  313. 'number_of_pieces_displayed_in_domestic_inbound_terminal_view_button',
  314. UTC: 'turn_on_utc_in_view_of_domestic_inbound_terminal_button',
  315. columnSet: 'domestic_inbound_terminal_view_column_setting_button',
  316. },
  317. InternationalArrivalAirport: {
  318. count:
  319. 'number_of_display_pieces_of_international_inbound_terminal_view_button',
  320. UTC: 'the_view_of_international_inbound_terminal_opens_utc_button',
  321. columnSet: 'view_column_setting_of_international_inbound_terminal_button',
  322. },
  323. }
  324. const getPermission = (type?: string) => {
  325. return [permissionMap[props.name][type]]
  326. }
  327. const tableRef = ref<InstanceType<typeof SimpleTable> | null>(null)
  328. const hasSetTableScroll = ref(false)
  329. watch(
  330. [() => formData.startDate, () => formData.endDate],
  331. ([startDate, endDate], [preStartDate, preEndDate]) => {
  332. if (startDate !== preStartDate || endDate !== preEndDate) {
  333. hasSetTableScroll.value = false
  334. }
  335. }
  336. )
  337. watch(tableData, async () => {
  338. await nextTick()
  339. if (hasSetTableScroll.value || !finishedCount.value) {
  340. return
  341. }
  342. if (tableRef.value?.table) {
  343. tableRef.value?.table?.setScrollTop((finishedCount.value - 1) * 50)
  344. }
  345. hasSetTableScroll.value = true
  346. })
  347. </script>
  348. <style lang="scss" scoped>
  349. @import './index.scss';
  350. </style>