Browse Source

1月9号提出问题2-5修改

zhongxiaoyu 2 years ago
parent
commit
1b1994f593

+ 41 - 8
src/components/TableHeaderCell/index.vue

@@ -6,7 +6,8 @@
         'el-table-v2__header-cell-text',
         'el-table__header-cell-text',
         {
-          'table-header-cell-space-between': (filterable && filterStyle === 'arrow') || sortable,
+          'table-header-cell-space-between':
+            (filterable && filterStyle === 'arrow') || sortable,
         },
       ]"
     >
@@ -23,12 +24,18 @@
       <template v-else>
         <span style="flex: 1">{{ `${desc ? '*' : ''}${label}` }}</span>
       </template>
-      <div v-if="(filterable && filterStyle === 'arrow') || sortable" class="button-wrapper">
+      <div
+        v-if="(filterable && filterStyle === 'arrow') || sortable"
+        class="button-wrapper"
+      >
         <div
           v-if="filterable && filterStyle === 'arrow'"
           ref="buttonRef"
           v-click-outside="clickOutsideHandler"
-          :class="['filter-arrow', { 'arrow-active': active, 'arrow-expand': expand }]"
+          :class="[
+            'filter-arrow',
+            { 'arrow-active': active, 'arrow-expand': expand },
+          ]"
         >
           <el-icon>
             <CaretBottom />
@@ -53,6 +60,10 @@
         @show="expand = true"
         @hide="expand = false"
       >
+        <el-button-group size="small" type="default" class="select-buttons">
+          <el-button @click="selectAll">全选</el-button>
+          <el-button @click="selectReverse">反选</el-button>
+        </el-button-group>
         <el-select
           v-model="selections"
           size="default"
@@ -63,11 +74,6 @@
           collapse-tags
           clearable
           :teleported="false"
-          @change="
-            newVal => {
-              emit('update:filterValues', newVal)
-            }
-          "
         >
           <el-option
             v-for="(option, index) in filterOptions"
@@ -126,6 +132,26 @@ watchEffect(() => {
     selections.value = props.filterValues
   }
 })
+watchEffect(() => {
+   emit('update:filterValues', selections.value)
+})
+const selectAll = () => {
+  selections.value.push(...props.filterOptions!.reduce((pre:string[], { value }) => {
+    if (!selections.value.includes(value)) {
+      pre.push(value)
+    }
+    return pre
+  }, []))
+}
+const selectReverse = () => {
+  selections.value = props.filterOptions!.reduce((pre: string[], { value }) => {
+    if (!selections.value.includes(value)) {
+      pre.push(value)
+    }
+    return pre
+  }, [])
+}
+
 const buttonRef = ref()
 const popoverRef = ref()
 const clickOutsideHandler = () => {
@@ -211,4 +237,11 @@ const sortChange = () => {
 .el-select-dropdown__item.hover {
   background: #d2d6df;
 }
+
+.select-buttons {
+  margin-bottom: 10px;
+  .el-button {
+    margin-right: 10px;
+  }
+}
 </style>

+ 27 - 10
src/hooks/useTableFilterAndSort.ts

@@ -2,11 +2,17 @@ import { Ref } from 'vue'
 import _ from 'lodash'
 import { CommonData, CommonTableColumn, MaybeRef } from '~/common'
 
+interface Options {
+  defaultFilterValueMap?: { [x: string]: string[] } // 默认筛选条件
+  extraFilterValueMap?: MaybeRef<{ [x: string]: string[] }> // 表头之外的额外筛选条件
+  defaultSortRuleMap?: { [x: string]: string } // 默认排序
+  extraSortRuleMap?: MaybeRef<{ [x: string]: string }> // 表头之外的额外排序条件
+}
+
 export function useTableFilterAndSort(
   tableColumns: Ref<CommonTableColumn[]>,
   tableData: Ref<CommonData[]>,
-  defaultFilterValueMap: MaybeRef<{ [x: string]: string[] }> = {},
-  defaultSortRuleMap: MaybeRef<{ [x: string]: string }> = {}
+  options: Options = {}
 ) {
   watch([tableColumns, tableData], ([columns, records]) => {
     const tempSets = {}
@@ -23,7 +29,7 @@ export function useTableFilterAndSort(
     Object.keys(tempSets).forEach(key => {
       filterOptionMap[key] = _.orderBy(
         [...tempSets[key]].map(value => ({
-          text: value,
+          label: value,
           value,
         })),
         o => o.value
@@ -31,17 +37,28 @@ export function useTableFilterAndSort(
     })
   })
 
-  const filterOptionMap = reactive({})
-  const filterValueMap = reactive({})
-  const mergedFilterValueMap = computed<{ [x: string]: string[] }>(() => ({
-    ...unref(defaultFilterValueMap),
+  const {
+    defaultFilterValueMap = {},
+    extraFilterValueMap = {},
+    defaultSortRuleMap = {},
+    extraSortRuleMap = {},
+  } = options
+
+  const filterOptionMap = reactive<{
+    [x: string]: { label: string; value: string }[]
+  }>({})
+  const filterValueMap = reactive(defaultFilterValueMap)
+  const mergedFilterValueMap = computed(() => ({
+    ...unref(extraFilterValueMap),
     ...filterValueMap,
   }))
-  const sortRuleMap = reactive({})
-  const mergedSortRuleMap = computed<{ [x: string]: string }>(() => ({
-    ...unref(defaultSortRuleMap),
+
+  const sortRuleMap = reactive(defaultSortRuleMap)
+  const mergedSortRuleMap = computed(() => ({
+    ...unref(extraSortRuleMap),
     ...sortRuleMap,
   }))
+
   const dealedTableData = computed(() => {
     const filtered = tableData.value.filter(item => {
       let flag = true

+ 43 - 0
src/store/tableSettings.ts

@@ -0,0 +1,43 @@
+import { defineStore } from 'pinia'
+
+interface FilterValues {
+  [x: string]: string[]
+}
+
+export const useTableSettingsStore = defineStore('tableSettings', () => {
+  const route = useRoute()
+
+  const savedColumnKeysMap = ref<{ [fullTableName: string]: string[] }>(
+    JSON.parse(localStorage.getItem('savedColumnKeysMap') ?? '{}')
+  )
+  const saveColumnKeys = (columnKeys: string[] = [], tableName?: string) => {
+    const fullTableName = route.path + (tableName ? `/${tableName}` : '')
+    savedColumnKeysMap.value[fullTableName] = columnKeys
+    localStorage.setItem(
+      'savedColumnKeysMap',
+      JSON.stringify(savedColumnKeysMap.value)
+    )
+  }
+
+  const savedTableFilterValueMap = ref<{
+    [fullTableName: string]: FilterValues
+  }>(JSON.parse(localStorage.getItem('savedTableFilterValueMap') ?? '{}'))
+  const saveTableFilterValues = (
+    filterValues: FilterValues,
+    tableName?: string
+  ) => {
+    const fullTableName = route.path + (tableName ? `/${tableName}` : '')
+    savedTableFilterValueMap.value[fullTableName] = filterValues
+    localStorage.setItem(
+      'savedTableFilterValueMap',
+      JSON.stringify(savedTableFilterValueMap.value)
+    )
+  }
+
+  return {
+    savedColumnKeysMap,
+    saveColumnKeys,
+    savedTableFilterValueMap,
+    saveTableFilterValues,
+  }
+})

+ 2 - 2
src/views/realTime/components/AirportView/AirportForm.vue

@@ -38,7 +38,7 @@
         />
       </el-select>
     </el-form-item>
-    <el-form-item :prop="formData.flightWarning" style="width: 104px">
+    <!-- <el-form-item :prop="formData.flightWarning" style="width: 104px">
       <el-select
         v-model="formData.flightWarning"
         size="default"
@@ -51,7 +51,7 @@
           :value="option.value"
         />
       </el-select>
-    </el-form-item>
+    </el-form-item> -->
     <el-form-item
       v-if="name.includes('International')"
       :prop="formData.waybillType"

+ 65 - 26
src/views/realTime/components/AirportView/index.vue

@@ -17,9 +17,9 @@
         <div v-permission="getPermission('count')">
           <CommonSwitch v-model:flag="countFlag" label="显示件数" />
         </div>
-        <div v-permission="getPermission('UTC')">
+        <!-- <div v-permission="getPermission('UTC')">
           <CommonSwitch v-model:flag="UTCFlag" label="开启UTC" />
-        </div>
+        </div> -->
         <div v-permission="getPermission('columnSet')">
           <ColumnSet
             :table-columns="tableColumns"
@@ -86,8 +86,14 @@ import { useTableFilterAndSort } from '@/hooks/useTableFilterAndSort'
 import { useFormatter } from './useFormatter'
 import { ElTableV2, RowEventHandlers, TableV2Instance } from 'element-plus'
 import { CommonData } from '~/common'
-import type { HeaderRenderProps, CellRenderProps, RowClassGetter, ScrollParams } from '../../type'
+import type {
+  HeaderRenderProps,
+  CellRenderProps,
+  RowClassGetter,
+  ScrollParams,
+} from '../../type'
 import { useLoop } from '@/hooks/useLoop'
+import { useTableSettingsStore } from '@/store/tableSettings'
 
 const props = defineProps({
   name: {
@@ -108,8 +114,18 @@ const { tableColumns, tableData, getTableData } = useAirportTable(
   formData
 )
 
-const customRendererColumns = computed(() =>
-  tableColumns.value.map(column => ({
+const customRendererColumns = computed(() => [
+  {
+    key: 'rowNO',
+    width: 33,
+    title: '序号',
+    cellRenderer: ({ rowIndex }: CellRenderProps) => (
+      <div class="el-table-v2__cell-text">{rowIndex + 1}</div>
+    ),
+    align: 'center',
+    fixed: isDeparture,
+  },
+  ...tableColumns.value.map(column => ({
     ...column,
     headerCellRenderer: ({column}: HeaderRenderProps) => (
       <TableHeaderCell
@@ -139,8 +155,8 @@ const customRendererColumns = computed(() =>
         }
       </>
     ),
-  }))
-)
+  })),
+])
 
 const countFlag = ref(true)
 const { tableColumnFormatter, tableDataFormatter } = useFormatter(countFlag)
@@ -154,16 +170,19 @@ const cellPropsGetter = params => ({
   class: cellClassV2(params),
 })
 const dealedCount = ref(0)
-const rowClass: RowClassGetter = (params) => {
+const rowClass: RowClassGetter = params => {
   const { rowData, rowIndex } = params
   const classes: string[] = []
   if (rowData.hasTakenOff === 'Y' || rowData.hasLanded === 'Y') {
     classes.push('bg-gray')
-    if (dealedCount.value < tableData.value.length && rowIndex === dealedCount.value - 1) {
+    if (
+      dealedCount.value < tableData.value.length &&
+      rowIndex === dealedCount.value - 1
+    ) {
       classes.push('underline-red')
     }
   }
-  if (selectedRowKey.value && params.rowData.rowKey === selectedRowKey.value) {
+  if (selectedRowKey.value && rowData.rowKey === selectedRowKey.value) {
     classes.push('is-selected')
   }
 
@@ -173,10 +192,10 @@ const selectedRowKey = ref('')
 watch(formData, () => {
   selectedRowKey.value = ''
 })
-const rowEventHandlers:RowEventHandlers = {
-  onClick: (params) => {
+const rowEventHandlers: RowEventHandlers = {
+  onClick: params => {
     selectedRowKey.value = params.rowKey as string
-  }
+  },
 }
 
 const tableDataCount = computed(() =>
@@ -216,6 +235,12 @@ const tableDataCount = computed(() =>
 
 const { cellClickHandlerV2 } = useTableCellClick(props.name)
 
+const route = useRoute()
+const {
+  savedTableFilterValueMap,
+  saveTableFilterValues,
+} = useTableSettingsStore()
+const defaultFilterValueMap = savedTableFilterValueMap[route.path]
 const flightStateFilter = computed<{} | { [x: string]: string[] }>(() => {
   switch (formData.flightState) {
     case 'hasTakenOff':
@@ -237,12 +262,23 @@ const {
   filterValueMap,
   sortRuleMap,
   dealedTableData,
-} = useTableFilterAndSort(
-  tableColumns,
-  tableData,
-  flightStateFilter,
-  { [props.name.includes('Departure') ? 'planDepartureTime' : 'planLandingTime']: 'ascending' }
-)
+} = useTableFilterAndSort(tableColumns, tableData, {
+  defaultFilterValueMap,
+  extraFilterValueMap: flightStateFilter,
+  extraSortRuleMap: {
+    [props.name.includes('Departure')
+      ? 'planDepartureTime'
+      : 'planLandingTime']: 'ascending',
+  },
+})
+const columnsShouldCache = ['IATACode']
+watch(filterValueMap, map => {
+  const values: { [x: string]: string[] } = {}
+  columnsShouldCache.forEach(columnName => {
+    values[columnName] = map[columnName]
+  })
+  saveTableFilterValues(values)
+})
 
 const permissionMap = {
   DepartureAirport: {
@@ -276,7 +312,10 @@ const getPermission = (type?: string) => {
 
 const hasSetTableScroll = ref(false)
 watch(formData, (newData, oldData) => {
-  if (newData.startDate !== oldData.startDate || newData.endDate !== oldData.endDate) {
+  if (
+    newData.startDate !== oldData.startDate ||
+    newData.endDate !== oldData.endDate
+  ) {
     hasSetTableScroll.value = false
   }
 })
@@ -329,11 +368,11 @@ const tableScrollHandler = ({ scrollLeft, scrollTop }: ScrollParams) => {
 onActivated(() => {
   const { x, y } = scrollPosition
   if (x > 0 || y > 0) {
-  visibility.value = 'hidden'
-  tableRef.value?.scrollTo({ scrollLeft: 0, scrollTop: 0 })
-  // 不加延迟的话横向滚动会出错
-  // 等待滚动完成再显示,一定要使用visibility,使用v-show或者说display: none一样会变空白
-  setTimeout(() => {
+    visibility.value = 'hidden'
+    tableRef.value?.scrollTo({ scrollLeft: 0, scrollTop: 0 })
+    // 不加延迟的话横向滚动会出错
+    // 等待滚动完成再显示,一定要使用visibility,使用v-show或者说display: none一样会变空白
+    setTimeout(() => {
       tableRef.value?.scrollTo({
         scrollLeft: x,
         scrollTop: y,
@@ -341,7 +380,7 @@ onActivated(() => {
       visibility.value = 'visible'
     }, 0)
   }
-  })
+})
 </script>
 <style lang="scss" scoped>
 @import './index.scss';

+ 29 - 7
src/views/realTime/components/ColumnSet/index.vue

@@ -56,20 +56,26 @@ import Dialog from '@/components/dialog/index.vue'
 import { PropType } from 'vue'
 import { CommonTableColumn } from '~/common'
 import { tableColumnGroup } from '../../type'
+import { useTableSettingsStore } from '@/store/tableSettings'
+
+const simpleClone = (obj: any) => JSON.parse(JSON.stringify(obj))
 
 const props = defineProps({
+  name: {
+    type: String,
+  },
   tableColumns: {
     type: Array as PropType<CommonTableColumn[]>,
     required: true,
   },
 })
 
+const emits = defineEmits(['checkedSubmit'])
+
 const needShowColumns = computed(() =>
   props.tableColumns.filter(column => column.needShow)
 )
 
-const emits = defineEmits(['checkedSubmit'])
-
 const inGroup = computed(() => {
   return (
     'groupName' in
@@ -77,8 +83,6 @@ const inGroup = computed(() => {
   )
 })
 
-const simpleClone = (obj: any) => JSON.parse(JSON.stringify(obj))
-
 const dialogFlag = ref(false)
 const dialogShow = () => {
   tempGroups.value = simpleClone(checkedGroups.value)
@@ -91,10 +95,18 @@ const dialogHide = () => {
 const submitHandler = () => {
   checkedGroups.value = simpleClone(tempGroups.value)
   checkedKeys.value = simpleClone(tempKeys.value)
-  emits('checkedSubmit', checkedColumnKeys.value)
+  checkedSubmit()
   dialogHide()
 }
 
+const { savedColumnKeysMap, saveColumnKeys } = useTableSettingsStore()
+const route = useRoute()
+
+const checkedSubmit = () => {
+  emits('checkedSubmit', checkedColumnKeys.value)
+  saveColumnKeys(checkedColumnKeys.value)
+}
+
 const columnGroups = computed(() => {
   if (inGroup.value) {
     return needShowColumns.value.reduce((pre: tableColumnGroup[], curr) => {
@@ -132,7 +144,17 @@ const checkedColumnKeys = computed<string[]>(() => {
     return checkedKeys.value
   }
 })
-watch(needShowColumns, columns => {
+
+const fullTableName = route.path + (props.name ? `/${props.name}` : '')
+
+watch(needShowColumns, defaultColumns => {
+  const savedColumnKeys = savedColumnKeysMap[fullTableName]
+  const columns = savedColumnKeys
+    ? defaultColumns.filter(column =>
+        savedColumnKeys.includes(column.columnName)
+      )
+    : defaultColumns
+
   if (inGroup.value) {
     checkedGroups.value = {}
     columns.forEach(({ columnName, groupName }) => {
@@ -148,7 +170,7 @@ watch(needShowColumns, columns => {
   } else {
     checkedKeys.value = columns.map(({ columnName }) => columnName)
   }
-  emits('checkedSubmit', checkedColumnKeys.value)
+  checkedSubmit()
 })
 </script>
 

+ 1 - 1
src/views/realTime/components/FlightView/index.vue

@@ -39,7 +39,7 @@
     </div>
     <div class="waybill-list-wrapper">
       <div class="waybill-list-header">
-        <CommonSwitch v-model:flag="UTCFlag" label="开启UTC" />
+        <!-- <CommonSwitch v-model:flag="UTCFlag" label="开启UTC" /> -->
         <!-- <el-button
           class="button-sqaure"
           :icon="Refresh"

+ 1 - 3
src/views/realTime/hooks/useTableColumnSet.ts

@@ -1,9 +1,7 @@
 import { Ref } from 'vue'
 import { CommonTableColumn } from '~/common'
 
-export function useTableColumnSet(
-  tableColumns: Ref<CommonTableColumn[]>
-) {
+export function useTableColumnSet(tableColumns: Ref<CommonTableColumn[]>) {
   const filterColumnKeys = ref<string[]>([])
   const filteredColumns = ref<CommonTableColumn[]>([])
   watchEffect(() => {