Răsfoiți Sursa

feat: 修改username相关功能

zhouyuhao 9 luni în urmă
părinte
comite
03c77ad0e5

+ 33 - 16
src/components/NotificationMessageCard/src/components/EventCard.vue

@@ -1,6 +1,7 @@
 <script setup lang="ts">
 import { transportationMode } from '@/components/transportationMode'
 import { useRouter } from 'vue-router'
+import { getTimezone } from '@/utils/tools'
 
 const router = useRouter()
 
@@ -15,14 +16,15 @@ interface EventCardPropsData {
   location: string
   timezone?: string // 时区
   time: string
-  previous?: string
+  timeLabel: string
+  previous?: Array<string>
   info?: {
     route?: []
-    etdChangeNum?: number
-    etaChangeNum?: number
+    etdOrdeparturNum?: number
+    etaOrarrivalNum?: number
     time: string
-    departureDelayNum?: number
-    arrivalDelayNum?: number
+    timeLabel: string
+    delayTimeTip: string
     timezone?: string // 时区
     leg?: []
   }
@@ -61,17 +63,17 @@ const handleSeeAll = (data: any) => {
       </div>
       <div
         class="more-tips"
-        v-if="data.type === 'delay' && (data.info.departureDelayNum || data.info.arrivalDelayNum)"
+        v-if="data.type === 'delay' && (data.info.etdOrdeparturNum || data.info.etaOrarrivalNum)"
       >
         <div>
-          <span v-if="data.info.departureDelayNum"
-            >Departure Delay ({{ data.info.departureDelayNum }})</span
+          <span v-if="data.info.etdOrdeparturNum"
+            >Departure Delay ({{ data.info.etdOrdeparturNum }})</span
           >
-          <span v-if="data.info.departureDelayNum && data.info.arrivalDelayNum">
+          <span v-if="data.info.etdOrdeparturNum && data.info.etaOrarrivalNum">
             &nbsp;&nbsp;|&nbsp;&nbsp;</span
           >
-          <span v-if="data.info.arrivalDelayNum">
-            Arrival Delay ({{ data.info.arrivalDelayNum }})
+          <span v-if="data.info.etaOrarrivalNum">
+            Arrival Delay ({{ data.info.etaOrarrivalNum }})
           </span>
         </div>
         <el-button @click="handleSeeAll(data)" class="see-all-icon el-button--text">
@@ -82,14 +84,18 @@ const handleSeeAll = (data: any) => {
 
       <div
         class="more-tips"
-        v-if="data.type === 'change' && (data.info.etdChangeNum || data.info.etaChangeNum)"
+        v-if="data.type === 'change' && (data.info.etdOrdeparturNum || data.info.etaOrarrivalNum)"
       >
         <div>
-          <span v-if="data.info.etdChangeNum">ETD Change ({{ data.info.etdChangeNum }})</span>
-          <span v-if="data.info.etdChangeNum && data.info.etaChangeNum">
+          <span v-if="data.info.etdOrdeparturNum"
+            >ETD Change ({{ data.info.etdOrdeparturNum }})</span
+          >
+          <span v-if="data.info.etdOrdeparturNum && data.info.etaOrarrivalNum">
             &nbsp;&nbsp;|&nbsp;&nbsp;</span
           >
-          <span v-if="data.info.etaChangeNum"> ETA Change ({{ data.info.etaChangeNum }}) </span>
+          <span v-if="data.info.etaOrarrivalNum">
+            ETA Change ({{ data.info.etaOrarrivalNum }})
+          </span>
         </div>
         <el-button @click="handleSeeAll(data)" class="see-all-icon el-button--text">
           See All
@@ -115,19 +121,30 @@ const handleSeeAll = (data: any) => {
       </div>
       <div class="route" v-if="data?.info?.route?.length > 0">
         <span class="font_family icon-icon_route_b"></span>
-        <span></span>
+        <span>Route:&nbsp;</span>
         <template v-for="(item, index) in data.info.route" :key="index">
           <span>{{ item }}</span
           ><span style="margin: 0 3px" v-if="index !== data.info.route.length - 1">→</span>
         </template>
       </div>
+      <!-- change多程情况中的Leg-->
+      <div class="location" v-if="data?.info?.leg?.length > 0">
+        <span class="font_family icon-icon_location_b"></span>
+        <span>Current Leg:&nbsp;</span>
+        <template v-for="(item, index) in data.info.leg" :key="index">
+          <span>{{ item }}</span
+          ><span style="margin: 0 3px" v-if="index !== data.info.leg.length - 1">→</span>
+        </template>
+      </div>
       <div class="location" v-if="data.location">
         <span class="font_family icon-icon_location_b"></span>
         <span>{{ data.location }}</span>
       </div>
       <div class="delay-time" v-if="data.type === 'delay' && data.info?.time">
         <span class="font_family icon-icon_delay_b"></span>
+        <span>{{ data.info.timeLabel }}</span>
         <span>{{ data.info.time }}</span>
+        <span>{{ getTimezone(data.info.timezone) }}</span>
       </div>
       <div class="change-time" v-if="data.type === 'change' && data.info?.time">
         <span style="margin-left: 1px" class="font_family icon-icon_time_b"></span>

+ 9 - 1
src/components/NotificationMessageCard/src/components/FeatureUpdateCard.vue

@@ -23,7 +23,7 @@ const props = defineProps<{
         <div class="title">
           <!-- <span class="font_family icon-icon_password_b"></span> -->
           <img style="margin-right: 5px" src="../images/icon_publish.png" alt="" />
-          <span>{{ data.header }}</span>
+          <span class="gradient-text">{{ data.header }}</span>
         </div>
         <div class="content-text">
           <span>{{ data.content }}</span>
@@ -81,6 +81,14 @@ const props = defineProps<{
         display: inline-block;
         font-weight: 700;
       }
+      .gradient-text {
+        background: linear-gradient(90deg, #dc6c6d 0%, #7959c8 46%, #ed6d00 100%);
+        background-clip: text;
+        -webkit-background-clip: text;
+        color: transparent;
+        font-size: 14px;
+        font-weight: bold;
+      }
       .font_family {
         margin-right: 8px;
       }

+ 4 - 1
src/components/ScoringGrade/src/ScoringGrade.vue

@@ -14,6 +14,9 @@ import happyPng from '../image/score_happy.png'
 import happyPng2 from '../image/happy_2.png'
 import normalPng from '../image/score_normal.png'
 import submitsucessful from '../image/submit_successful.png'
+import { useUserStore } from '@/stores/modules/user'
+
+const userStore = useUserStore()
 
 // const isShow = ref(true)
 const visible = ref(false)
@@ -202,7 +205,7 @@ const changeSmileRadio = (val: any) => {
 }
 // 提交details
 const submitDetails = (val: any) => {
-  const username = localStorage.getItem('account') ? localStorage.getItem('account') : ''
+  const username = userStore.userName
   if (angryCheckbox.value.length) {
     $api
       .scoringgrade({

+ 3 - 3
src/router/index.ts

@@ -109,10 +109,10 @@ const router = createRouter({
 // * 路由拦截 beforeEach
 router.beforeEach(async (to, from, next) => {
   useBreadCrumb().setRouteList(to)
+  const userStore = useUserStore()
   // 如果手动跳转登录页,清除登录信息
   if (to.path === '/login') {
-    if (localStorage.getItem('username')) {
-      const userStore = useUserStore()
+    if (userStore.userInfo?.uname) {
       await userStore.logout()
     }
     sessionStorage.removeItem('trackingTablePageInfo')
@@ -122,7 +122,7 @@ router.beforeEach(async (to, from, next) => {
   // 未登录白名单
   const whiteList = ['/login', '/public-tracking', '/public-tracking/detail', '/reset-password']
   // 判断是否登录
-  if (!whiteList.includes(to.path) && !localStorage.getItem('username')) {
+  if (!whiteList.includes(to.path) && !userStore.userInfo?.uname) {
     const userStore = useUserStore()
     await userStore.logout()
     if (whiteList.includes(from.path)) {

+ 27 - 8
src/stores/modules/user.ts

@@ -1,33 +1,52 @@
 import { defineStore } from 'pinia'
 import { useVisitedRowState } from './visitedRow'
 
+interface UserInfo {
+  uname: string
+  first_name: string
+  last_name: string
+  user_type: string
+  email: string
+  expire_day: number
+  date_format: string
+  numbers_format: string
+}
 interface UserState {
-  username: string
+  userInfo: UserInfo
   isFirstLogin: boolean
 }
 export const useUserStore = defineStore('user', {
   state: (): UserState => ({
-    username: localStorage.getItem('username') || '',
+    userInfo: JSON.parse(localStorage.getItem('userInfo') || '{}'),
     isFirstLogin: localStorage.getItem('isFirstLogin')
       ? JSON.parse(localStorage.getItem('isFirstLogin'))
       : false
   }),
-  getters: {},
+  getters: {
+    userName(state) {
+      if (state.userInfo.first_name && state.userInfo.last_name) {
+        return `${state.userInfo.first_name} ${state.userInfo.last_name}`
+      } else {
+        return state.userInfo.uname || ''
+      }
+    }
+  },
   actions: {
-    setUsername(username: any, isFirstLogin?: boolean) {
-      localStorage.setItem('username', username)
-      this.username = username
+    setUserInfo(userInfo: any, isFirstLogin?: boolean) {
+      localStorage.setItem('userInfo', JSON.stringify(userInfo))
+      this.userInfo = userInfo
       if (isFirstLogin !== undefined) {
         localStorage.setItem('isFirstLogin', JSON.stringify(isFirstLogin))
         this.isFirstLogin = isFirstLogin
       }
     },
+
     async logout(isNeedLogout: boolean = true) {
       if (isNeedLogout) {
         await $api.logout().then(() => {})
       }
-      localStorage.removeItem('username')
-      this.username = ''
+      localStorage.removeItem('userInfo')
+      this.userInfo = {}
       if (localStorage.getItem('isFirstLogin')) {
         localStorage.removeItem('isFirstLogin')
       }

+ 16 - 5
src/utils/tools.ts

@@ -9,17 +9,28 @@ export const formatTimezone = (time: string, timezone?: string) => {
     if (!timezone) {
       return formattedTime
     }
-    let gmtOffset = ''
+    let utcOffset = ''
     const timeZoneOffset = moment.tz(`${moment().year()}-01-01`, timezone).format('Z')
-    // 替换 "+07:00" 为 "GMT+07"
-    gmtOffset = `(GMT${timeZoneOffset.slice(0, 3)})`
-    return `${formattedTime} ${gmtOffset}`
+    // 替换 "+07:00" 为 "UTC+07"
+    utcOffset = `(UTC${timeZoneOffset.slice(0, 3)})`
+    return `${formattedTime} ${utcOffset}`
   } else {
     formattedTime = moment(time).format(formatString)
     return formattedTime
   }
 }
 
+/**
+ * 返回传入地区的UTC时区格式化
+ * @param timezone
+ * @returns
+ */
+export const getTimezone = (timezone: string): string => {
+  if (timezone) return ''
+  const offset = moment.tz(`${moment().year()}-01-01`, timezone).format('Z')
+  return `UTC${offset.slice(0, 3)}`
+}
+
 export const formatTimezoneByUTCorGMT = (time: string, timezone: string) => {
   if (!time) return '--'
   let formattedTime = ''
@@ -53,7 +64,7 @@ export const isEuropean = () => {
  * @param digits - 小数位数
  * @param isEuropean - 是否为欧洲地区
  */
-export const formatNumber = (number: number, digits: number, isEuropean?: boolean): string => {
+export const formatNumber = (number: number, digits: number = 2, isEuropean?: boolean): string => {
   const userLanguage = isEuropean ? 'de-DE' : 'zh-CN'
 
   // 设置数字格式化的选项

+ 6 - 1
src/views/Booking/src/components/BookingDetail/src/components/ContainersView.vue

@@ -2,7 +2,7 @@
 import { type VxeGridInstance, type VxeGridProps } from 'vxe-table'
 // import { autoWidth } from '@/utils/table'
 import { useRowClickStyle } from '@/hooks/rowClickStyle'
-import { formatTimezone } from '@/utils/tools'
+import { formatTimezone, formatNumber } from '@/utils/tools'
 
 const props = defineProps({
   data: Object
@@ -40,6 +40,11 @@ const handleColumns = (columns: any) => {
         ...curColumn,
         formatter: ({ cellValue }: any) => formatTimezone(cellValue)
       }
+    } else if (item.formatter === 'number') {
+      curColumn = {
+        ...curColumn,
+        formatter: ({ cellValue }: any) => formatNumber(Number(cellValue), item?.digits)
+      }
     }
     return curColumn
   })

+ 6 - 1
src/views/Booking/src/components/BookingTable/src/BookingTable.vue

@@ -9,7 +9,7 @@ import { useRouter } from 'vue-router'
 import { transportationMode } from '@/components/transportationMode'
 import { useThemeStore } from '@/stores/modules/theme'
 import { useVisitedRowState } from '@/stores/modules/visitedRow'
-import { formatTimezone } from '@/utils/tools'
+import { formatTimezone, formatNumber } from '@/utils/tools'
 
 const visitedRowState = useVisitedRowState()
 const themeStore = useThemeStore()
@@ -64,6 +64,11 @@ const handleColumns = (columns: any, status?: string) => {
         ...curColumn,
         formatter: ({ cellValue }: any) => formatTimezone(cellValue)
       }
+    } else if (item.formatter === 'number') {
+      curColumn = {
+        ...curColumn,
+        formatter: ({ cellValue }: any) => formatNumber(Number(cellValue), item?.digits)
+      }
     }
     return curColumn
   })

+ 5 - 1
src/views/Dashboard/src/components/ScoringSystem.vue

@@ -11,6 +11,10 @@ import hhhPng2 from '../image/hhh_2.png'
 import happyPng from '../image/score_happy.png'
 import happyPng2 from '../image/happy_2.png'
 import submitsucessful from '../image/submit_successful.png'
+import { useUserStore } from '@/stores/modules/user'
+
+const userStore = useUserStore()
+
 const dialogVisible = ref(false)
 const innerVisible = ref(false)
 const isShowAngry = ref(false)
@@ -235,7 +239,7 @@ const changeSmileRadio = (title: any, value: any) => {
 }
 // 提交details
 const submitDetails = (val: any) => {
-  const username = localStorage.getItem('account') ? localStorage.getItem('account') : ''
+  const username = userStore.userName
   if (checkboxGroup1.value.length) {
     $api
       .scoringgrade({

+ 14 - 8
src/views/Layout/src/components/Header/HeaderView.vue

@@ -31,7 +31,7 @@ const handleSearch = () => {
   }
   // 先判断是否登录
   // 未登录
-  if (!localStorage.getItem('username')) {
+  if (!userStore.userInfo?.uname) {
     $api.getPublicTrackingDetail({ reference_number: searchValue.value }).then((res) => {
       if (res.code === 200) {
         const { data } = res
@@ -177,7 +177,7 @@ const notificationDrawer = ref(false)
           <span style="margin-top: -1px" class="font_family icon-icon_search_b"></span>
         </template>
       </el-input>
-      <div class="notice-icon" v-if="userStore.username">
+      <div class="notice-icon" v-if="userStore.userInfo?.uname">
         <!-- <span
           @click="notificationDrawer = true"
           class="font_family icon-icon_notice_b"
@@ -275,9 +275,9 @@ const notificationDrawer = ref(false)
       >
         <div class="title">
           <div class="avatar">
-            <span>{{ userStore.username?.slice(0, 1) }}</span>
+            <span>{{ userStore.userName?.slice(0, 1) }}</span>
           </div>
-          <span class="name">{{ userStore.username }}</span>
+          <span class="name">{{ userStore.userName }}</span>
         </div>
         <div class="options">
           <div class="item" @click="handleChangePassword">
@@ -294,14 +294,17 @@ const notificationDrawer = ref(false)
           </div>
         </div>
         <template #reference>
-          <div class="header-avatar" v-if="userStore.username && userStore.isFirstLogin !== true">
-            <div>{{ userStore.username?.slice(0, 1) }}</div>
+          <div class="header-avatar" v-if="userStore.userName && userStore.isFirstLogin !== true">
+            <div>{{ userStore.userName.slice(0, 1) }}</div>
           </div>
         </template>
       </el-popover>
       <el-button
         :class="{ 'el-button--pain-theme': themeStore.theme === 'dark' }"
-        v-if="!userStore.username || (userStore.username && userStore.isFirstLogin === true)"
+        v-if="
+          !userStore.userInfo?.uname ||
+          (userStore.userInfo?.uname && userStore.isFirstLogin === true)
+        "
         class="el-button--main"
         style="padding: 8px 10px; margin-right: 20px; margin-left: 0"
         plain
@@ -311,7 +314,10 @@ const notificationDrawer = ref(false)
         Download KLN Portal
       </el-button>
       <el-button
-        v-if="!userStore.username || (userStore.username && userStore.isFirstLogin === true)"
+        v-if="
+          !userStore.userInfo?.uname ||
+          (userStore.userInfo?.uname && userStore.isFirstLogin === true)
+        "
         class="el-button--main"
         style="margin-left: -10px"
         @click="handleLogin"

+ 21 - 6
src/views/Layout/src/components/Header/components/TrainingCard.vue

@@ -104,14 +104,25 @@ const notificationList = []
 //   }
 // ]
 
-const curCard = ref(null)
-const curIndex = ref(-1)
+const getNotificationList = () => {
+  if (localStorage.getItem('showFeatureAfterLogin') !== 'true') return
+  // 获取数据
+
+  localStorage.removeItem('showFeatureAfterLogin')
+}
+
+const curCard = computed(() => {
+  return notificationList[curIndex.value] || null
+})
+const curIndex = ref(0)
+// 设置定时器进行自动轮播
+let intervalId = null
 
 const nextNotification = () => {
   let result = true
   // 更新当前索引和卡片
   curIndex.value = curIndex.value + 1
-  curCard.value = notificationList[curIndex.value]
+  // curCard.value = notificationList[curIndex.value]
   // 如果消息为password或者feature类型,暂停自动轮播
   if (
     curCard.value?.notificationType === 'password' ||
@@ -124,14 +135,18 @@ const nextNotification = () => {
   // 如果到达最后一个消息,设置为null以清除显示
   if (curIndex.value >= notificationList.length) {
     clearInterval(intervalId)
-    curCard.value = null
+    // curCard.value = null
     result = false
   }
   return result
 }
 
-// 设置定时器进行自动轮播
-let intervalId = setInterval(nextNotification, 2000)
+const initTrainingCard = () => {
+  if (curCard.value?.notificationType === 'event') {
+    intervalId = setInterval(nextNotification, 2000)
+  }
+}
+initTrainingCard()
 
 const closeMessage = () => {
   // 如果当前消息为event类型,则需先清除定时器

+ 3 - 3
src/views/Layout/src/components/Menu/MenuView.vue

@@ -11,7 +11,7 @@ const isCollapse = defineModel<boolean>()
 
 const menuList = ref()
 watch(
-  () => userStore.username,
+  () => userStore.userInfo?.uname,
   () => {
     getMenuList()
   }
@@ -84,7 +84,7 @@ const whiteList = ['/login', '/public-tracking', '/public-tracking/detail', '/re
 // 判断是否允许跳转
 const isAllowJump = (path: any) => {
   // 判断是否登录
-  if (!whiteList.includes(path) && !localStorage.getItem('username')) {
+  if (!whiteList.includes(path) && !userStore.userInfo?.uname) {
     ElMessage.warning({
       message: 'Please log in to use this feature.',
       grouping: true
@@ -124,7 +124,7 @@ const changeRouter = (path: any) => {
   emits('changeVisible', isVisible.value)
   isVisible.value = false
   let toPath = path
-  if (path === '/tracking' && !localStorage.getItem('username')) {
+  if (path === '/tracking' && !userStore.userInfo?.uname) {
     toPath = '/public-tracking'
   }
   // 如果允许跳转,执行跳转

+ 1 - 1
src/views/Login/src/components/ChangePasswordCard.vue

@@ -21,7 +21,7 @@ const loginForm = ref({
   newPassword: '',
   confirmPassword: ''
 })
-loginForm.value.username = localStorage.getItem('username') || ''
+loginForm.value.username = userStore.userInfo?.uname || ''
 if (!loginForm.value.username) {
   router.push({
     name: 'Login'

+ 4 - 3
src/views/Login/src/loginView.vue

@@ -210,8 +210,9 @@ const handleResult = (res: any) => {
         }
       })
     }
-    userStore.setUsername(res.data.uname || '')
+    userStore.setUserInfo(res.data?.user_info || {})
     router.push('/')
+    localStorage.setItem('showTrainingCardAfterLogin', 'true')
   } else if (res.code === 400) {
     const { data } = res
     if (data.msg === 'passwordExpires') {
@@ -220,12 +221,12 @@ const handleResult = (res: any) => {
         type: 'warning',
         confirmButtonClass: 'el-button--dark'
       })
-      userStore.setUsername(res.data.uname || '')
+      userStore.setUserInfo(res.data?.user_info || {})
       router.push({
         name: 'Reset Password'
       })
     } else if (data.msg === 'First login, please change your password') {
-      userStore.setUsername(res.data.uname, true)
+      userStore.setUserInfo(res.data?.user_info || {}, true)
       firstLoginTipsRef.value.openDialog()
     }
   }

+ 24 - 17
src/views/SystemMessage/src/SystemMessage.vue

@@ -137,6 +137,12 @@ const notificationList = [
           </div>
         </el-tab-pane>
         <el-tab-pane label="Unread" name="second">
+          <template #label>
+            <span style="margin-right: 4px">Unread</span>
+            <div class="count">
+              <span>33</span>
+            </div>
+          </template>
           <PersonalProfile />
         </el-tab-pane>
         <el-tab-pane label="Read" name="third">Role</el-tab-pane>
@@ -158,6 +164,23 @@ const notificationList = [
 .system-message {
   display: flex;
   height: calc(100% - 68px);
+  .count {
+    display: inline-flex;
+    justify-content: center;
+    height: 18px;
+    min-width: 18px;
+    padding-left: 4px;
+    padding-right: 5px;
+    background-color: var(--color-theme);
+    border-radius: 9px;
+    font-size: 12px;
+    line-height: 18px;
+    text-align: center;
+    span {
+      color: var(--color-white);
+      font-weight: 700;
+    }
+  }
 }
 .left-nav {
   width: 280px;
@@ -194,23 +217,7 @@ const notificationList = [
       border-radius: 12px;
       background-color: var(--color-theme);
     }
-    .count {
-      display: inline-flex;
-      justify-content: center;
-      height: 18px;
-      min-width: 18px;
-      padding-left: 5px;
-      padding-right: 5px;
-      background-color: var(--color-theme);
-      border-radius: 9px;
-      font-size: 12px;
-      line-height: 18px;
-      text-align: center;
-      span {
-        color: var(--color-white);
-        font-weight: 700;
-      }
-    }
+
     &.is-active {
       background-color: var(--color-system-message-nav-bg);
       & > span {

+ 26 - 15
src/views/SystemMessage/src/components/PersonalProfile.vue

@@ -2,12 +2,14 @@
 import dayjs from 'dayjs'
 import { isEuropean, getDateFormat } from '@/utils/tools'
 import ChangePasswordDialog from '@/views/Layout/src/components/Header/components/ChangePasswordDialog.vue'
+import { useUserStore } from '@/stores/modules/user'
 
+const userStore = useUserStore()
 const form = reactive({
-  firstName: 'z',
-  lastName: 'index',
-  username: 'Chud',
-  email: 'caroline.hu@kerrylogistics.com',
+  firstName: userStore.userInfo?.first_name,
+  lastName: userStore.userInfo?.last_name,
+  username: userStore.userInfo?.uname,
+  email: userStore.userInfo?.email,
   password: '**************'
 })
 
@@ -21,8 +23,20 @@ const handleChangePassword = () => {
   changePasswordDialogRef.value.openDialog()
 }
 
-const dateFormat = ref('MM/DD/YYYY')
-const selectVModel = ref('MM/DD/YYYY')
+const monthMap = {
+  'MMM/DD/YYYY': 'MM/DD/YYYY',
+  'DD/MMM/YYYY': 'DD/MM/YYYY',
+  'YYYY-MMM-DD': 'YYYY-MM-DD'
+}
+// 用户没有指定日期格式化时,通过时区自动判断
+const initDateFormat = () => {
+  return monthMap[userStore.userInfo?.date_format] || getDateFormat()
+}
+const initMonthFormat = () => {
+  return userStore.userInfo?.date_format || getDateFormat()
+}
+const dateFormat = ref(initDateFormat())
+const monthFormat = ref(initMonthFormat())
 const dateFormatExample = computed(() => {
   return {
     'MM/DD/YYYY': [
@@ -59,10 +73,10 @@ const dateFormatExample = computed(() => {
 })
 
 const handleDateFormat = (value: string) => {
-  selectVModel.value = dateFormatExample.value[value][0].value
+  monthFormat.value = dateFormatExample.value[value][0].value
 }
 
-const numbersFormat = ref()
+const numbersFormat = ref(userStore.userInfo?.numbers_format)
 
 // 判断用户是否指定数字格式化,没有指定则自动判断
 const isSpecifyNumbersFormat = () => {
@@ -70,21 +84,18 @@ const isSpecifyNumbersFormat = () => {
 }
 isSpecifyNumbersFormat()
 
-// 获取用户地区日期格式
-dateFormat.value = getDateFormat()
-
 const saveConfig = (model: string) => {
   let params = {}
   if (model === 'profile') {
     params = {
       save_model: 'profile',
-      user_name: form.username,
-      email: form.email
+      first_name: form.firstName,
+      last_name: form.lastName
     }
   } else {
     params = {
       save_model: 'no_profile',
-      date_fromat: selectVModel.value,
+      date_fromat: monthFormat.value,
       number_format: numbersFormat.value
     }
   }
@@ -183,7 +194,7 @@ const saveConfig = (model: string) => {
                       style="margin-left: 28px; width: 320px"
                       v-if="dateFormat === key"
                       size="large"
-                      v-model="selectVModel"
+                      v-model="monthFormat"
                     >
                       <el-option
                         v-for="item in list"

+ 6 - 1
src/views/Tracking/src/components/TrackingDetail/src/components/ContainersView.vue

@@ -2,7 +2,7 @@
 import { type VxeGridInstance, type VxeGridProps } from 'vxe-table'
 // import { autoWidth } from '@/utils/table'
 import { useRowClickStyle } from '@/hooks/rowClickStyle'
-import { formatTimezone } from '@/utils/tools'
+import { formatTimezone, formatNumber } from '@/utils/tools'
 
 const props = defineProps({
   data: Object
@@ -41,6 +41,11 @@ const handleColumns = (columns: any) => {
         ...curColumn,
         formatter: ({ cellValue }: any) => formatTimezone(cellValue)
       }
+    } else if (item.formatter === 'number') {
+      curColumn = {
+        ...curColumn,
+        formatter: ({ cellValue }: any) => formatNumber(Number(cellValue), item?.digits)
+      }
     }
     return curColumn
   })

+ 6 - 1
src/views/Tracking/src/components/TrackingTable/src/TrackingTable.vue

@@ -9,7 +9,7 @@ import { transportationMode } from '@/components/transportationMode'
 import { useLoadingState } from '@/stores/modules/loadingState'
 import { useThemeStore } from '@/stores/modules/theme'
 import { useVisitedRowState } from '@/stores/modules/visitedRow'
-import { formatTimezone } from '@/utils/tools'
+import { formatTimezone, formatNumber } from '@/utils/tools'
 
 const visitedRowState = useVisitedRowState()
 const themeStore = useThemeStore()
@@ -61,6 +61,11 @@ const handleColumns = (columns: any, status?: string) => {
         ...curColumn,
         formatter: ({ cellValue }: any) => formatTimezone(cellValue)
       }
+    } else if (item.formatter === 'number') {
+      curColumn = {
+        ...curColumn,
+        formatter: ({ cellValue }: any) => formatNumber(Number(cellValue), item?.digits)
+      }
     }
     return curColumn
   })