Răsfoiți Sursa

Merge branch 'feat_theme_zyh' of United_Software/k_online_ui into feat_theme

Jack Zhou 11 luni în urmă
părinte
comite
bc60e55c90
27 a modificat fișierele cu 201 adăugiri și 204 ștergeri
  1. 1 2
      src/auto-imports.d.ts
  2. 8 26
      src/components/ContainerStatus/src/ContainerStatus.vue
  3. 0 1
      src/components/CustomizeColumns/src/CustomizeColumns.vue
  4. 15 3
      src/components/VBreadcrumb/src/VBreadcrumb.vue
  5. 2 17
      src/components/VEmpty/src/VEmpty.vue
  6. 1 1
      src/components/VLoading/src/VLoading.vue
  7. 39 27
      src/main.ts
  8. 12 6
      src/stores/modules/theme.ts
  9. 13 3
      src/styles/elementui.scss
  10. 23 6
      src/styles/theme.scss
  11. 7 0
      src/styles/vxeTable.scss
  12. 1 1
      src/utils/axios.ts
  13. 2 1
      src/views/Booking/src/BookingView.vue
  14. 2 4
      src/views/Booking/src/components/BookingTable/src/components/DownloadDialog.vue
  15. 2 2
      src/views/Dashboard/src/DashboardView.vue
  16. 5 5
      src/views/Dashboard/src/components/TopMap.vue
  17. 19 3
      src/views/Layout/src/components/Header/HeaderView.vue
  18. 5 1
      src/views/Layout/src/components/Header/components/ChangePasswordDialog.vue
  19. 6 20
      src/views/Login/src/components/ChangePasswordCard.vue
  20. 1 20
      src/views/Login/src/loginView.vue
  21. 2 4
      src/views/OperationLog/src/components/BookingTable/src/components/DownloadDialog.vue
  22. 2 0
      src/views/Tracking/src/TrackingView.vue
  23. 1 21
      src/views/Tracking/src/components/PublicTracking/src/PublicTrackingSearch.vue
  24. 4 9
      src/views/Tracking/src/components/TrackingDetail/src/TrackingDetail.vue
  25. 19 13
      src/views/Tracking/src/components/TrackingDetail/src/components/MapView.vue
  26. 7 4
      src/views/Tracking/src/components/TrackingDetail/src/components/TransportStep.vue
  27. 2 4
      src/views/Tracking/src/components/TrackingTable/src/components/DownloadDialog.vue

+ 1 - 2
src/auto-imports.d.ts

@@ -3,7 +3,6 @@
 // @ts-nocheck
 // noinspection JSUnusedGlobalSymbols
 // Generated by unplugin-auto-import
-// biome-ignore lint: disable
 export {}
 declare global {
   const $api: typeof import('@/api/index')['default']
@@ -69,6 +68,6 @@ declare global {
 // for type re-export
 declare global {
   // @ts-ignore
-  export type { Component, ComponentPublicInstance, ComputedRef, DirectiveBinding, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, MaybeRef, MaybeRefOrGetter, VNode, WritableComputedRef } from 'vue'
+  export type { Component, ComponentPublicInstance, ComputedRef, ExtractDefaultPropTypes, ExtractPropTypes, ExtractPublicPropTypes, InjectionKey, PropType, Ref, VNode, WritableComputedRef } from 'vue'
   import('vue')
 }

+ 8 - 26
src/components/ContainerStatus/src/ContainerStatus.vue

@@ -1,32 +1,14 @@
 <script setup lang="ts">
-import emptyImage from './image/no_data.png'
 import { formatTimezone } from '@/utils/tools'
 import { useThemeStore } from '@/stores/modules/theme'
 import lightPng from './image/no_data.png'
 import darkPng from './image/no_data_dark.png'
 
-const emptyImg = ref(lightPng)
-
 const themeStore = useThemeStore()
-// 判断当前系统主题模式
-onMounted(() => {
-  watch(
-    () => themeStore.theme,
-    (newVal) => {
-      console.log(newVal, 'value')
-      if (newVal === 'dark') {
-        emptyImg.value = darkPng
-      } else {
-        emptyImg.value = lightPng
-      }
-    },
-    {
-      immediate: true,
-      deep: true
-    }
-  )
-})
 
+const emptyImg = computed(() => {
+  return themeStore.theme === 'dark' ? darkPng : lightPng
+})
 const props = defineProps({
   data: Object
 })
@@ -103,9 +85,8 @@ watch(
   position: relative;
   width: 100%;
   height: 100%;
-  overflow: auto;
   .container {
-    height: 394px;
+    height: 358px;
     padding-bottom: 8px;
     overflow: auto;
   }
@@ -113,8 +94,8 @@ watch(
     display: flex;
     flex-direction: column;
     align-items: center;
-    height: 394px;
-    padding-top: 125px;
+    height: 358px;
+    padding-top: 140px;
 
     .empty-text {
       margin-top: 8px;
@@ -152,6 +133,7 @@ watch(
     line-height: 50px;
     & > .title {
       font-size: 16px;
+      color: var(--color-neutral-2);
       span {
         margin-left: 4px;
         font-weight: 700;
@@ -175,7 +157,7 @@ watch(
       display: flex;
       height: 52px;
       margin-top: -22px;
-      background-color: var(--color-table-header-bg);
+      background-color: var(--color-container-status-node-bg);
       border: 1px solid var(--color-border);
       border-radius: 6px;
       color: var(--color-neutral-1);

+ 0 - 1
src/components/CustomizeColumns/src/CustomizeColumns.vue

@@ -380,7 +380,6 @@ defineExpose({
               <VueDraggable
                 v-model="groupItem.children"
                 class="column-list"
-                :sort="false"
                 ghost-class="ghost-column"
                 :forceFallback="true"
                 fallbackClass="fallback-class"

+ 15 - 3
src/components/VBreadcrumb/src/VBreadcrumb.vue

@@ -1,9 +1,11 @@
 <script setup lang="ts">
 import { useRouter } from 'vue-router'
 import { useBreadCrumb } from '@/stores/modules/breadCrumb'
+import { useThemeStore } from '@/stores/modules/theme'
 
 const router = useRouter()
 const breadCrumb = useBreadCrumb()
+const themeStore = useThemeStore()
 
 const handleGoBack = () => {
   const routeData = breadCrumb.getUpperRoute()
@@ -22,7 +24,11 @@ const jumpLink = (label: string, query: any) => {
 </script>
 
 <template>
-  <div class="v-breadcrumd" v-if="breadCrumb.routeList.length > 1">
+  <div
+    class="v-breadcrumd"
+    :class="{ 'is-dark': themeStore.theme === 'dark' }"
+    v-if="breadCrumb.routeList.length > 1"
+  >
     <span class="font_family icon-icon_back_b" @click="handleGoBack"></span>
     <template v-for="(routeItem, index) in breadCrumb.routeList" :key="routeItem.label">
       <template v-if="index + 1 !== breadCrumb.routeList.length">
@@ -31,7 +37,7 @@ const jumpLink = (label: string, query: any) => {
         }}</span>
         <span class="interval">|</span>
       </template>
-      <span v-else style="font-weight: 700">{{ routeItem.label }}</span>
+      <span v-else>{{ routeItem.label }}</span>
     </template>
   </div>
   <div v-else></div>
@@ -41,6 +47,7 @@ const jumpLink = (label: string, query: any) => {
 .v-breadcrumd {
   display: flex;
   align-items: center;
+  font-weight: 700;
   gap: 4px;
   .icon-icon_back_b {
     font-size: 18px;
@@ -55,9 +62,14 @@ const jumpLink = (label: string, query: any) => {
     color: var(--color-neutral-3);
     cursor: pointer;
     &:hover {
-      font-weight: 500;
       color: var(--color-theme);
     }
   }
+  &.is-dark {
+    .interval,
+    .previous-route {
+      color: var(--color-neutral-2);
+    }
+  }
 }
 </style>

+ 2 - 17
src/components/VEmpty/src/VEmpty.vue

@@ -3,25 +3,10 @@ import lightPng from './images/default_image.png'
 import darkPng from './images/default_dark_image.png'
 import { useThemeStore } from '@/stores/modules/theme'
 
-const emptyImg = ref(lightPng)
-
 const themeStore = useThemeStore()
 // 判断当前系统主题模式
-onMounted(() => {
-  watch(
-    () => themeStore.theme,
-    (newVal) => {
-      if (newVal === 'dark') {
-        emptyImg.value = darkPng
-      } else {
-        emptyImg.value = lightPng
-      }
-    },
-    {
-      immediate: true,
-      deep: true
-    }
-  )
+const emptyImg = computed(() => {
+  return themeStore.theme === 'dark' ? darkPng : lightPng
 })
 </script>
 

+ 1 - 1
src/components/VLoading/src/VLoading.vue

@@ -62,7 +62,7 @@ const props = withDefaults(defineProps<internalProps>(), {
 }
 
 .loading-text {
-  color: var(--color-neutral-3);
+  color: #b5b9bf;
 }
 
 @keyframes loading-rotate {

+ 39 - 27
src/main.ts

@@ -19,9 +19,31 @@ import { createPinia } from 'pinia'
 
 import App from './App.vue'
 import router from './router'
+import { useThemeStore } from '@/stores/modules/theme'
 
 const app = createApp(App)
 
+for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
+  app.component(key, component)
+}
+// 让VxeTable支持导出Excel
+VXETable.use(VXETablePluginExportXLSX, {
+  ExcelJS
+})
+VXETable.setI18n('en-US', enUS)
+VXETable.setLanguage('en-US')
+
+app.use(createPinia())
+app.use(VXETable)
+app.use(VxeUI)
+app.use(router)
+app.use(Antd)
+
+// 注册全局指令
+app.directive('vloading', VLoading)
+
+const themeStore = useThemeStore()
+
 // 动态加载暗黑主题
 async function loadDarkTheme() {
   await import('element-plus/theme-chalk/dark/css-vars.css') // 动态导入暗黑主题
@@ -33,15 +55,24 @@ function unloadDarkTheme() {
     darkThemeStylesheet.remove()
   }
 }
-// 根据用户偏好或系统设置决定是否加载暗黑主题 (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) ||
-if (localStorage.getItem('theme') === 'dark') {
-  loadDarkTheme()
-  document.documentElement.classList.add('dark')
+// 用户没有手动切换主题时,根据系统设置自动切换
+if (!themeStore.isManualChange) {
+  // 根据用户偏好或系统设置决定是否添加暗黑模式类名
+  if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
+    themeStore.toggleTheme('dark')
+    loadDarkTheme()
+  } else {
+    unloadDarkTheme()
+    themeStore.toggleTheme('light')
+  }
+} else {
+  // 用户手动切换主题时,根据用户设置切换
+  if (themeStore.theme === 'dark') {
+    loadDarkTheme()
+    themeStore.toggleTheme('dark')
+  }
 }
-// 根据用户偏好或系统设置决定是否添加暗黑模式类名
-// if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
-//   document.documentElement.classList.add('dark')
-// }
+
 // 提供一个全局方法来切换主题
 app.config.globalProperties.$toggleDarkMode = () => {
   const html = document.documentElement
@@ -56,23 +87,4 @@ app.config.globalProperties.$toggleDarkMode = () => {
   }
 }
 
-for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
-  app.component(key, component)
-}
-// 让VxeTable支持导出Excel
-VXETable.use(VXETablePluginExportXLSX, {
-  ExcelJS
-})
-VXETable.setI18n('en-US', enUS)
-VXETable.setLanguage('en-US')
-
-app.use(createPinia())
-app.use(VXETable)
-app.use(VxeUI)
-app.use(router)
-app.use(Antd)
-
-// 注册全局指令
-app.directive('vloading', VLoading)
-
 app.mount('#app')

+ 12 - 6
src/stores/modules/theme.ts

@@ -2,24 +2,30 @@ import { defineStore } from 'pinia'
 
 interface ThemeState {
   theme: string
+  isManualChange: boolean
 }
 export const useThemeStore = defineStore('theme', {
   state: (): ThemeState => ({
-    theme: localStorage.getItem('theme') || 'light'
+    theme: localStorage.getItem('theme') || 'light',
+    isManualChange: JSON.parse(localStorage.getItem('isManualChange')) || false
   }),
   actions: {
-    toggleTheme(theme: string) {
+    toggleTheme(theme: string, isManualChange = false) {
+      localStorage.setItem('theme', theme)
+      this.theme = theme
+
       const html = document.documentElement
       if (html.classList.contains('dark') && theme === 'light') {
         unloadDarkTheme()
         html.classList.remove('dark')
-        localStorage.setItem('theme', 'light')
-        this.theme = 'light'
       } else if (!html.classList.contains('dark') && theme === 'dark') {
         loadDarkTheme()
         html.classList.add('dark')
-        localStorage.setItem('theme', 'dark')
-        this.theme = 'dark'
+      }
+      // 主动修改主题后,不再跟随系统设置
+      if (isManualChange) {
+        localStorage.setItem('isManualChange', JSON.stringify(isManualChange))
+        this.isManualChange = isManualChange
       }
     }
   }

+ 13 - 3
src/styles/elementui.scss

@@ -349,7 +349,7 @@ div.el-drawer {
   }
   .el-drawer__body {
     padding: 16px;
-    background-color: var(--color-table-header-bg);
+    background-color: var(--color-drawer-body-bg);
   }
   .el-drawer__close-btn:focus i,
   .el-drawer__close-btn:hover i {
@@ -362,7 +362,7 @@ div .el-input__inner {
   font-size: var(--font-size-3);
 }
 .el-input__inner::placeholder {
-  color: #6c6f75;
+  color: var(--color-neutral-3);
   font-size: var(--font-size-3);
 }
 div .el-select__placeholder.is-transparent {
@@ -372,7 +372,7 @@ div .el-select__placeholder.is-transparent {
   }
 }
 div.el-input__wrapper {
-  box-shadow: 0 0 0 1px var(--color-border) inset;
+  box-shadow: 0 0 0 1px var(--el-border) inset;
   padding: 0 8px;
 }
 div.el-input div.el-input__wrapper.is-focus {
@@ -436,6 +436,13 @@ div .el-checkbox.el-checkbox--large span.el-checkbox__inner::after {
   width: 5px; /* 打勾图标宽度 */
   height: 10px; /* 打勾图标高度 */
 }
+/* 修改暗黑模式下选中时打勾图标的大小 */
+html.dark .el-checkbox.el-checkbox--large span.el-checkbox__inner::after {
+  left: 5px; /* 调整左边距 */
+  top: 1px; /* 调整上边距 */
+  width: 5px; /* 打勾图标宽度 */
+  height: 10px; /* 打勾图标高度 */
+}
 div .el-popper__arrow,
 div .el-popper__arrow:before {
   // height: 0;
@@ -755,6 +762,9 @@ div .el-select-dropdown {
 div label.smile_radio .el-radio__inner {
   background-color: var(--management-bg-color);
 }
+span.el-radio__inner {
+  border: 1px solid var(--el-radio-input-border);
+}
 div .el-radio__inner:hover {
   border-color: var(--color-theme);
 }

+ 23 - 6
src/styles/theme.scss

@@ -66,7 +66,7 @@
   --color-tag-created-bg: #e5f0fb;
   --color-tag-booked-bg: #f3e6fa;
   --color-tag-all-bg: #ffe5cf;
-  --color-tag-all-bg-color:#feecf3;
+  --color-tag-all-bg-color: #feecf3;
   --color-tag-cargo-received-bg: #eaecff;
   --color-tag-departure-bg: #d9edfa;
   --color-tag-arrived-bg: #e7faf8;
@@ -85,6 +85,7 @@
 
   --color-dialog-header-bg: #f6f8fa;
   --color-dialog-body-bg: #ffffff;
+  --color-drawer-body-bg: #fff;
 
   // 按钮
   // default
@@ -146,9 +147,10 @@
   --dashboard-text-color: #646a73;
 
   --el-input-focus: #fff;
-
+  .el-radio {
+    --el-radio-input-border: #dcdfe6;
+  }
   // 发送邮件部分
-
   --color-avatar: #fff;
   --color-email-bg: #f6f8fa;
   --color-detail-email-record-bg: #eceef1;
@@ -200,6 +202,7 @@
   --color-customize-column-item-drag-bg: var(--color-customize-column-right-section-bg);
   --color-customize-column-tabs-header-border: #ebeef5;
 
+  --color-shipment-status-header-bg: #f6f8fa;
   --color-shipment-status-label-bg: #ccd1db;
   --color-shipment-status-shadow: rgba(0, 0, 0, 0.1);
 
@@ -216,6 +219,9 @@
   --color-toggle-btn-module-active-bg: #fff;
 
   --color-user-config-title-bottom-border: #eeeeed;
+
+  --color-container-status-node-bg: #f8f9fd;
+
   // 输入框禁用的颜色
   --input-disabled-bg-color: #f5f7fa;
   --input-disabled-text-color: #a8abb2;
@@ -230,6 +236,10 @@
 
   --color-recent-name: rgba(43, 47, 54, 0.05);
   --color-disabled-bg: #eaebed;
+
+  .el-input {
+    --el-border: #eaebed;
+  }
 }
 
 :root.dark {
@@ -256,6 +266,7 @@
   --color-customize-column-item-drag-bg: #7d4c26;
   --color-customize-column-tabs-header-border: #3f434a;
 
+  --color-shipment-status-header-bg: #3f434a;
   --color-shipment-status-shadow: rgba(0, 0, 0, 0.5);
   --color-shipment-status-label-bg: #656f7d;
   --color-shipment-status-detail-path-font-color: #b5b7ba;
@@ -272,6 +283,7 @@
   --color-toggle-btn-module-active-bg: #656f7d;
 
   --color-user-config-title-bottom-border: #3f434a;
+  --color-container-status-node-bg: #3e454f;
 
   --color-btn-blue-bg: rgba(255, 255, 255, 0);
 
@@ -300,7 +312,8 @@
   --w-e-textarea-bg-color: var(--color-email-bg);
   --w-e-toolbar-border-color: #656f7d;
   --w-e-toolbar-color: var(--color-neutral-1);
-  --w-e-toolbar-active-bg-color: #553d2b;
+  --w-e-toolbar-active-bg-color: rgba(255, 117, 0, 0.2);
+  --w-e-toolbar-active-color: #1a1c20;
   button.w-e-menu-tooltip-v5::before {
     color: var(--color-neutral-1);
   }
@@ -320,14 +333,17 @@
   --el-bg-color: #30353c;
   // 按钮边框颜色
   --color-accent-13: #656f7d;
+  // 输入框边框颜色
   --el-border: #656f7d;
   .el-input {
-    --el-input-border: #656f7d;
+    --el-border: #656f7d;
   }
+  --el-radio-input-border: #656f7d;
   --color-table-header-bg: #34383f;
   --el-input-focus: #2b2f36;
   --color-dialog-header-bg: #3e454f;
   --color-dialog-body-bg: #30353c;
+  --color-drawer-body-bg: #2b2f36;
   div.el-card {
     --el-card-bg-color: #30353c;
   }
@@ -344,6 +360,7 @@
   --vxe-ui-table-border-color: #3f434a;
   --vxe-ui-table-column-icon-border-color: #6a6d73;
   --color-table-header-bg: #30353c;
-
+  --vxe-ui-table-header-background-color: #30353c;
   --color-table-click-row-bg: #8b582f;
+  --vxe-ui-input-border-color: #656f7d;
 }

+ 7 - 0
src/styles/vxeTable.scss

@@ -103,3 +103,10 @@ div.w-e-bar svg {
 .w-e-bar.w-e-hover-bar.w-e-bar-show {
   display: none;
 }
+
+button.w-e-menu-tooltip-v5:before {
+  border-radius: 3px;
+}
+button.w-e-menu-tooltip-v5:after {
+  border: 0;
+}

+ 1 - 1
src/utils/axios.ts

@@ -60,7 +60,7 @@ class HttpAxios {
         sessionStorage.clear()
         router.push('/login')
         const userStore = useUserStore()
-        userStore.logout(false)
+        userStore.logout()
         ElMessage.warning({
           message: 'Please log in to use this feature.',
           grouping: true

+ 2 - 1
src/views/Booking/src/BookingView.vue

@@ -397,9 +397,10 @@ const SearchInput = () => {
     <div class="heaer_top">
       <div class="search">
         <el-input
-          placeholder="Enter Booking/HBL/PO/Container/Carrier Booking No. "
+          placeholder="Enter Booking/HBL/PO/Carrier Booking No. "
           v-model="BookingSearch"
           class="log_input"
+          @keyup.enter="SearchInput"
         >
           <template #prefix>
             <span class="iconfont_icon">

+ 2 - 4
src/views/Booking/src/components/BookingTable/src/components/DownloadDialog.vue

@@ -116,11 +116,9 @@ defineExpose({
     display: flex;
     flex-direction: column;
     align-items: flex-start;
-    gap: 8px;
 
     .el-radio {
-      height: auto;
-      margin-top: 8px;
+      height: 40px;
       align-items: center;
     }
 
@@ -149,7 +147,7 @@ defineExpose({
       max-height: 350px;
       padding: 8px;
       margin-top: 8px;
-      background-color: var(--color-header-bg);
+      background-color: var(--color-dialog-header-bg);
       border-radius: 6px;
       overflow: auto;
 

+ 2 - 2
src/views/Dashboard/src/DashboardView.vue

@@ -90,7 +90,7 @@ const GetDashboardData = () => {
         GetTop10ODEcharts(Top10DefaultData.value)
         GetCo2EmissionEcharts(Co2OriginDefaultData.value)
         GetCo2DestinationEcharts(Co2DestinationDefaultData.value)
-        // GetRevenueEcharts(RevenueDefaultData.value)
+        GetRevenueEcharts(RevenueDefaultData.value)
       })
     })
 }
@@ -1409,4 +1409,4 @@ const ClickParams = (val: any) => {
   height: 48px;
   margin-bottom: 0;
 }
-</style>
+</style>

+ 5 - 5
src/views/Dashboard/src/components/TopMap.vue

@@ -193,7 +193,7 @@ defineExpose({
     border-radius: 4px;
     box-shadow: none;
     a {
-      background-color: #3c414a;
+      background-color: #2b2f36;
       border-bottom: none;
       span {
         color: var(--color-neutral-1);
@@ -202,17 +202,17 @@ defineExpose({
         span {
           display: inline-block;
           width: 24px;
-          border-bottom: 2px solid #575c64;
+          border-bottom: 1px solid #3f434a;
         }
       }
     }
   }
   .reset-zoom-control {
     border: none;
-    background-color: #3c414a;
+    background-color: #2b2f36;
   }
   a.leaflet-bar-part {
-    background-color: #3c414a;
+    background-color: #2b2f36;
     border-radius: 4px;
     box-shadow: none;
     overflow: hidden;
@@ -226,7 +226,7 @@ defineExpose({
 }
 /* 示例:将所有地图图片的颜色反转 */
 .dark-mode img:not(.leaflet-marker-icon) {
-  filter: invert(1) hue-rotate(170deg);
+  filter: invert(1) hue-rotate(230deg) saturate(60%) brightness(60%) opacity(80%);
 }
 // 防止暗黑模式下地图超出容器
 #map {

+ 19 - 3
src/views/Layout/src/components/Header/HeaderView.vue

@@ -18,7 +18,7 @@ const headerSearch = useHeaderSearch()
 const themePopoverRef = ref()
 // 切换系统主题颜色
 const toggleThemeMode = (theme: string) => {
-  themeStore.toggleTheme(theme)
+  themeStore.toggleTheme(theme, true)
 }
 
 const searchValue = ref('')
@@ -182,13 +182,13 @@ const handleLogin = () => {
           </div>
           <div class="picture-module">
             <div class="item" :class="{ active: themeStore.theme === 'light' }">
-              <img src="./images/light.png" alt="" />
+              <img @click="toggleThemeMode('light')" src="./images/light.png" alt="" />
               <div v-if="themeStore.theme === 'light'" class="selected-icon">
                 <span class="font_family icon-icon_confirm_b"></span>
               </div>
             </div>
             <div class="item" :class="{ active: themeStore.theme === 'dark' }">
-              <img src="./images/dark.png" alt="" />
+              <img @click="toggleThemeMode('dark')" src="./images/dark.png" alt="" />
               <div v-if="themeStore.theme === 'dark'" class="selected-icon">
                 <span class="font_family icon-icon_confirm_b"></span>
               </div>
@@ -216,6 +216,18 @@ const handleLogin = () => {
           <el-button style="height: 40px; width: 40px" class="el-button--text">
             <span class="font_family icon-icon_themes_b" style="font-size: 16px"></span
           ></el-button>
+          <el-tooltip
+            popper-class="theme-popper-class"
+            effect="dark"
+            content="Themes"
+            placement="top"
+            :offset="4"
+            trigger="hover"
+          >
+            <el-button style="height: 40px; width: 40px" class="el-button--text">
+              <span class="font_family icon-icon_themes_b" style="font-size: 16px"></span
+            ></el-button>
+          </el-tooltip>
         </template>
       </el-popover>
 
@@ -363,6 +375,7 @@ div.el-popover.el-popper.toggle-theme-popover {
       img {
         width: 154px;
         height: 90px;
+        cursor: pointer;
       }
       &.active {
         border: 2px solid var(--color-theme);
@@ -454,4 +467,7 @@ div.el-popover.el-popper.user-config-popover {
     }
   }
 }
+div.el-popper.theme-popper-class {
+  padding: 3px 4px;
+}
 </style>

+ 5 - 1
src/views/Layout/src/components/Header/components/ChangePasswordDialog.vue

@@ -154,7 +154,11 @@ defineExpose({
         <div class="error" v-if="loginError.newPassword">{{ newPwdErrTips }}</div>
         <div class="limit-tips">
           <div class="tip-item">
-            <span class="font_family icon-icon_confirm_b" :class="{ active: hasUppercase }"></span>
+            <span
+              style="padding-top: 2px"
+              class="font_family icon-icon_confirm_b"
+              :class="{ active: hasUppercase }"
+            ></span>
             <span>Password must contain uppercase letters</span>
           </div>
           <div class="tip-item">

+ 6 - 20
src/views/Login/src/components/ChangePasswordCard.vue

@@ -7,24 +7,6 @@ const userStore = useUserStore()
 const router = useRouter()
 
 const themeStore = useThemeStore()
-const changePasswordRef = ref()
-// 判断当前系统主题模式
-onMounted(() => {
-  watch(
-    () => themeStore.theme,
-    (newVal) => {
-      if (newVal === 'dark') {
-        changePasswordRef.value.classList.add('dark-bg')
-      } else {
-        changePasswordRef.value.classList.remove('dark-bg')
-      }
-    },
-    {
-      immediate: true,
-      deep: true
-    }
-  )
-})
 
 const route = useRoute()
 
@@ -147,7 +129,7 @@ onUnmounted(() => {
 </script>
 
 <template>
-  <div class="login" ref="changePasswordRef">
+  <div class="login" :class="{ 'dark-bg': themeStore.theme === 'dark' }">
     <el-card class="login-card">
       <div class="title" :class="{ 'is-dark': themeStore.theme === 'dark' }">
         <span class="welcome">Change Password</span>
@@ -216,7 +198,11 @@ onUnmounted(() => {
             <span>Password must contain numbers</span>
           </div>
           <div class="tip-item">
-            <span class="font_family icon-icon_confirm_b" :class="{ active: isValidLength }"></span>
+            <span
+              style="padding-top: 2px"
+              class="font_family icon-icon_confirm_b"
+              :class="{ active: isValidLength }"
+            ></span>
             <span>Password length between12 - 20 </span>
           </div>
         </div>

+ 1 - 20
src/views/Login/src/loginView.vue

@@ -12,25 +12,6 @@ const router = useRouter()
 const route = useRoute()
 const themeStore = useThemeStore()
 
-const loginRef = ref()
-// 判断当前系统主题模式
-onMounted(() => {
-  watch(
-    () => themeStore.theme,
-    (newVal) => {
-      if (newVal === 'dark') {
-        loginRef.value.classList.add('dark-bg')
-      } else {
-        loginRef.value.classList.remove('dark-bg')
-      }
-    },
-    {
-      immediate: true,
-      deep: true
-    }
-  )
-})
-
 // 手动获取url中的参数,直接获取route.query的参数时如果有+号会被转义成空格
 const getQueryParams = (url: string) => {
   const params = url.split('?')[1]
@@ -343,7 +324,7 @@ const firstLoginTipsRef = ref()
 </script>
 
 <template>
-  <div class="login" ref="loginRef">
+  <div class="login" :class="{ 'dark-bg': themeStore.theme === 'dark' }">
     <ScoringSystem class="scoring-system"></ScoringSystem>
     <el-card class="login-card" v-if="status === 'login'">
       <div class="card-title" :class="{ 'is-dark': themeStore.theme === 'dark' }">

+ 2 - 4
src/views/OperationLog/src/components/BookingTable/src/components/DownloadDialog.vue

@@ -111,11 +111,9 @@ defineExpose({
     display: flex;
     flex-direction: column;
     align-items: flex-start;
-    gap: 8px;
 
     .el-radio {
-      height: auto;
-      margin-top: 8px;
+      height: 40px;
       align-items: center;
     }
 
@@ -144,7 +142,7 @@ defineExpose({
       max-height: 350px;
       padding: 8px;
       margin-top: 8px;
-      background-color: var(--color-header-bg);
+      background-color: var(--color-dialog-header-bg);
       border-radius: 6px;
       overflow: hidden;
 

+ 2 - 0
src/views/Tracking/src/TrackingView.vue

@@ -646,6 +646,7 @@ const SearchInput = () => {
           placeholder="Enter Booking/HBL/PO/Container/Carrier Booking No. "
           v-model="TrackingSearch"
           class="log_input"
+          @keyup.enter="SearchInput"
         >
           <template #prefix>
             <span class="iconfont_icon">
@@ -733,6 +734,7 @@ const SearchInput = () => {
   display: flex;
   height: 68px;
   border: 1px solid var(--color-border);
+  border-top: none;
   border-width: 1px 0 1px 0;
   font-size: var(--font-size-6);
   font-weight: 700;

+ 1 - 21
src/views/Tracking/src/components/PublicTracking/src/PublicTrackingSearch.vue

@@ -1,30 +1,11 @@
 <script setup lang="ts">
 import { useRouter } from 'vue-router'
 import { useHeaderSearch } from '@/stores/modules/headerSearch'
-import SlideVerify from './components/SlideVerify.vue'
 import CryptoJS from 'crypto-js'
 import dayjs from 'dayjs'
 import { useThemeStore } from '@/stores/modules/theme'
 
 const themeStore = useThemeStore()
-const publicTrackingRef = ref()
-// 判断当前系统主题模式
-onMounted(() => {
-  watch(
-    () => themeStore.theme,
-    (newVal) => {
-      if (newVal === 'dark') {
-        publicTrackingRef.value.classList.add('dark-bg')
-      } else {
-        publicTrackingRef.value.classList.remove('dark-bg')
-      }
-    },
-    {
-      immediate: true,
-      deep: true
-    }
-  )
-})
 
 const router = useRouter()
 
@@ -112,7 +93,7 @@ const encryptPassword = (password) => {
 </script>
 
 <template>
-  <div class="public-tracking-search" ref="publicTrackingRef" v-vloading="loading">
+  <div class="public-tracking-search" v-vloading="loading" :class="{ 'dark-bg': themeStore.theme }">
     <div class="search-info">
       <div class="title">Tracking</div>
       <el-input
@@ -151,7 +132,6 @@ const encryptPassword = (password) => {
         </VEmpty>
       </div>
     </div>
-    <!-- <SlideVerify ref="slideVerifyRef" @verify-success="confirmVerify"></SlideVerify> -->
     <VSliderVerification
       v-if="isShowSliderVerification"
       @close="confirmVerification"

+ 4 - 9
src/views/Tracking/src/components/TrackingDetail/src/TrackingDetail.vue

@@ -204,7 +204,7 @@ const { isOverflow: isDestinationOverflow } = useOverflow(destinationRef, allDat
       </div>
     </div>
     <div class="transport-map">
-      <MapView :serial_no="allData?.serial_no" :uncode="allData?.uncode"></MapView>
+      <MapView style="flex: 1" :serial_no="allData?.serial_no" :uncode="allData?.uncode"></MapView>
       <TransportStep class="transport-step" :data="allData"></TransportStep>
     </div>
     <div class="info-content">
@@ -425,15 +425,10 @@ const { isOverflow: isDestinationOverflow } = useOverflow(destinationRef, allDat
     }
   }
   .transport-map {
-    position: relative;
+    display: flex;
+    gap: 8px;
     margin-bottom: 8px;
-    .transport-step {
-      position: absolute;
-      top: 8px;
-      right: 16px;
-      z-index: 1000;
-      overflow: hidden;
-    }
+    padding: 0 24px;
   }
 }
 

+ 19 - 13
src/views/Tracking/src/components/TrackingDetail/src/components/MapView.vue

@@ -2,7 +2,7 @@
   <div
     id="tracking-map"
     ref="mapContainer"
-    style="width: 100%; height: 520px"
+    style="width: 100%; height: 448px"
     class="tracking-map"
     :class="{ 'dark-mode': themeStore.theme === 'dark' }"
   ></div>
@@ -277,7 +277,6 @@ let visibleMarkers = new Set()
 
 // 添加标记后更新中心和缩放级别
 const addMarkersToMap = () => {
-  // debugger
   if (!map) return // 确保地图已经初始化
 
   markerPositions.value.forEach((position) => {
@@ -307,7 +306,7 @@ const addMarkersToMap = () => {
   if (viewData.value.length > 0) {
     // 根据标记的位置设置中心点以及缩放级别
     const bounds = L.latLngBounds(viewData.value)
-    map!.fitBounds(bounds, { paddingTopLeft: [20, 70], paddingBottomRight: [400, 0] })
+    map!.fitBounds(bounds, { paddingTopLeft: [20, 70], paddingBottomRight: [0, 0] })
     setTimeout(() => {
       if (isFirstRender) {
         initialCenter = map!.getCenter()
@@ -315,7 +314,7 @@ const addMarkersToMap = () => {
         isFirstRender = false
       }
       addResetZoomButton(initialCenter!, initialZoomLevel!)
-    }, 0)
+    }, 1000)
   }
 }
 
@@ -349,7 +348,6 @@ const addShipMarker = (x: number) => {
     // 获取线段的最后一个点和倒数第二个点
     const lastPoint = solidLine[solidLine.length - 1]
     const secondLastPoint = solidLine[solidLine.length - 2]
-    console.log(lastPoint, secondLastPoint, 'lastPoint, secondLastPoint')
     // 计算线段末端的角度(以弧度为单位)
     const angle =
       (Math.atan2(
@@ -485,8 +483,8 @@ const getMarker = () => {
               Transfer: { color: '#ed0000', icon: transferIcon }
             }
             markerPositions.value.push({
-              lat: item.lat,
-              lng: (Number(item.lng) + 360) % 360,
+              lat: Number(item.lat),
+              lng: Number(item.lng),
               city: item.infor,
               label: item.label,
               icon: iconColorList[item.label].icon,
@@ -495,7 +493,7 @@ const getMarker = () => {
           })
         viewData.value = (data?.rangePoint.length > 0 ? data?.rangePoint : data?.point)?.map(
           (item) => {
-            return [Number(item.lat), (Number(item.lon || item.lng) + 360) % 360]
+            return [Number(item.lat), Number(item.lon || item.lng)]
           }
         )
         // 请求成功后添加标记,并动态添加重置按钮
@@ -539,6 +537,7 @@ onUnmounted(() => {
 <style lang="scss">
 @import 'leaflet/dist/leaflet.css';
 .tracking-map {
+  border-radius: 12px;
   .leaflet-popup-content-wrapper {
     border-radius: 6px;
   }
@@ -584,6 +583,12 @@ onUnmounted(() => {
     height: 26px;
     font-size: 18px;
   }
+  a.leaflet-control-zoom-in,
+  a.leaflet-control-zoom-out {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+  }
 }
 .dark-mode {
   div.leaflet-control-zoom.leaflet-bar.leaflet-control {
@@ -591,7 +596,7 @@ onUnmounted(() => {
     border-radius: 4px;
     box-shadow: none;
     a {
-      background-color: #3c414a;
+      background-color: #2b2f36;
       border-bottom: none;
       span {
         color: var(--color-neutral-1);
@@ -600,17 +605,18 @@ onUnmounted(() => {
         span {
           display: inline-block;
           width: 24px;
-          border-bottom: 2px solid #575c64;
+          height: 28px;
+          border-bottom: 1px solid #3f434a;
         }
       }
     }
   }
   .reset-zoom-control {
     border: none;
-    background-color: #3c414a;
+    background-color: #2b2f36;
   }
   a.leaflet-bar-part {
-    background-color: #3c414a;
+    background-color: #2b2f36;
     border-radius: 4px;
     box-shadow: none;
     overflow: hidden;
@@ -625,7 +631,7 @@ onUnmounted(() => {
 
 /* 示例:将所有地图图片的颜色反转 */
 .dark-mode img:not(.leaflet-marker-icon) {
-  filter: invert(1) hue-rotate(170deg);
+  filter: invert(1) hue-rotate(230deg) saturate(60%) brightness(60%) opacity(80%);
 }
 // 防止暗黑模式下地图超出容器
 .tracking-map {

+ 7 - 4
src/views/Tracking/src/components/TrackingDetail/src/components/TransportStep.vue

@@ -42,16 +42,16 @@ const handleTabClick = (name: string) => {
 <style lang="scss" scoped>
 .transport-step {
   width: 400px;
-  height: 484px;
   background-color: var(--color-header-bg);
-  border-radius: 12px;
+  height: 448px;
+  border-radius: 3px;
   border: 1px solid var(--color-border);
-  box-shadow: -2px 2px 12px 0px var(--color-shipment-status-shadow);
+  // box-shadow: -2px 2px 12px 0px var(--color-shipment-status-shadow);
   .header {
     display: flex;
     height: 48px;
     border-radius: 6px 6px 0 0;
-    background-color: var(--color-header-bg);
+    background-color: var(--color-shipment-status-header-bg);
     .tab {
       flex: 1;
       text-align: center;
@@ -70,5 +70,8 @@ const handleTabClick = (name: string) => {
     height: calc(100% - 48px);
     background-color: var(--color-mode);
   }
+  :deep(.el-collapse-item__wrap) {
+    border-bottom: none;
+  }
 }
 </style>

+ 2 - 4
src/views/Tracking/src/components/TrackingTable/src/components/DownloadDialog.vue

@@ -116,11 +116,9 @@ defineExpose({
     display: flex;
     flex-direction: column;
     align-items: flex-start;
-    gap: 8px;
 
     .el-radio {
-      height: auto;
-      margin-top: 8px;
+      height: 40px;
       align-items: center;
     }
 
@@ -149,7 +147,7 @@ defineExpose({
       max-height: 350px;
       padding: 8px;
       margin-top: 8px;
-      background-color: var(--color-header-bg);
+      background-color: var(--color-dialog-header-bg);
       border-radius: 6px;
       overflow: auto;