Browse Source

修改暗黑模式样式

zhouyuhao 11 months ago
parent
commit
9c706285f1

+ 35 - 7
src/components/ContainerStatus/src/ContainerStatus.vue

@@ -1,6 +1,31 @@
 <script setup lang="ts">
-import emptyImage from './image/no-data.png'
+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 props = defineProps({
   data: Object
@@ -58,7 +83,12 @@ watch(
       </el-collapse-item>
     </el-collapse>
     <div v-else class="empty-content" style="">
-      <el-image :src="emptyImage" alt="empty"></el-image>
+      <img
+        :src="emptyImg"
+        :class="{ 'is-dark': themeStore.theme === 'dark' }"
+        fit="contain"
+        alt="empty"
+      />
       <div class="empty-text" style="">No data</div>
     </div>
     <div class="footer">
@@ -84,11 +114,9 @@ watch(
     flex-direction: column;
     align-items: center;
     height: 394px;
-    .el-image {
-      width: 200px;
-      height: 200px;
-      margin-top: 20px;
-      object-fit: cover;
+    img.is-dark {
+      display: block;
+      margin-top: 100px;
     }
     .empty-text {
       margin-top: 8px;

+ 0 - 0
src/components/ContainerStatus/src/image/no-data.png → src/components/ContainerStatus/src/image/no_data.png


BIN
src/components/ContainerStatus/src/image/no_data_dark.png


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

@@ -1,9 +1,34 @@
-<script setup lang="ts"></script>
+<script setup lang="ts">
+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
+    }
+  )
+})
+</script>
 
 <template>
   <div class="v-empty">
     <div class="empty-img">
-      <img src="./images/default_image.png" alt="" />
+      <img :src="emptyImg" alt="" />
     </div>
     <p class="title">
       <slot name="title">No Results Found</slot>

BIN
src/components/VEmpty/src/images/default_dark_image.png


+ 3 - 3
src/stores/modules/theme.ts

@@ -8,14 +8,14 @@ export const useThemeStore = defineStore('theme', {
     theme: localStorage.getItem('theme') || 'light'
   }),
   actions: {
-    toggleTheme() {
+    toggleTheme(theme: string) {
       const html = document.documentElement
-      if (html.classList.contains('dark')) {
+      if (html.classList.contains('dark') && theme === 'light') {
         unloadDarkTheme()
         html.classList.remove('dark')
         localStorage.setItem('theme', 'light')
         this.theme = 'light'
-      } else {
+      } else if (!html.classList.contains('dark') && theme === 'dark') {
         loadDarkTheme()
         html.classList.add('dark')
         localStorage.setItem('theme', 'dark')

+ 1 - 1
src/styles/elementui.scss

@@ -286,7 +286,7 @@ div.el-message-box {
   .el-message-box__header {
     height: 56px;
     padding: 16px;
-    background-color: var(--color-table-header-bg);
+    background-color: var(--color-message-box-header-bg);
     & > span {
       font-weight: 700;
       font-size: var(--font-size-4);

+ 28 - 2
src/styles/theme.scss

@@ -179,6 +179,7 @@
   // 滚动条
   --color-scrollbar-thumb: #d9dddf;
 
+  --color-message-box-header-bg: #f6f8fa;
   --color-table-header-bg: #f8f9fd;
   --color-table-click-row-bg: #ffe3cc;
 
@@ -205,6 +206,13 @@
   --color-public-tracking-bg-mask: rgba(255, 255, 255, 0.85);
   --color-public-tracking-search-input-btn: #000;
   --color-public-tracking-search-input-border: #2b2f36;
+
+  --color-v-box-content-drag-bg: #fff;
+
+  --color-toggle-btn-module-bg: #f0f1f3;
+  --color-toggle-btn-module-active-bg: #fff;
+
+  --color-user-config-title-bottom-border: #eeeeed;
 }
 
 :root.dark {
@@ -241,6 +249,11 @@
   --color-public-tracking-bg-mask: rgba(43, 47, 54, 0.75);
   --color-public-tracking-search-input-btn: #ed6d00;
   --color-public-tracking-search-input-border: #656f7d;
+
+  --color-toggle-btn-module-bg: #434b53;
+  --color-toggle-btn-module-active-bg: #656f7d;
+
+  --color-user-config-title-bottom-border: #3f434a;
   // 滚动条
   --color-scrollbar-thumb: #656f7d;
 
@@ -250,12 +263,20 @@
   --color-tracking-routes-item-bg: #403631;
   --color-tracking-routes-item-leg-bg: #524843;
 
+  --color-v-box-content-drag-bg: #2b2f36;
+
   // 邮件
   --w-e-toolbar-bg-color: var(--color-email-bg);
   --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;
+  button.w-e-menu-tooltip-v5::before {
+    color: var(--color-neutral-1);
+  }
+  div.w-e-bar-item button:hover {
+    color: var(--color-neutral-1);
+  }
   --color-email-border: #656f7d;
   --color-email-bg: #3c414a;
   --color-detail-email-record-bg: #343a43;
@@ -264,8 +285,9 @@
   --color-header-bg: #343a43;
 
   // ElementUI
+  --color-message-box-header-bg: #3e454f;
   // 整体背景颜色
-  --el-bg-color: #2b2f36;
+  --el-bg-color: #30353c;
   // 按钮边框颜色
   --color-accent-13: #656f7d;
   --el-border: #656f7d;
@@ -280,7 +302,11 @@
     --el-card-bg-color: #30353c;
   }
   --color-el-popper-bg: #1a1c20;
-  --el-bg-color: var(--color-neutral-1);
+  // --el-bg-color: var(--color-neutral-1);
+  --el-bg-color-overlay: #30353c;
+  div.el-popper.is-dark {
+    --el-bg-color: var(--color-neutral-1);
+  }
 
   // vxe-table
   --vxe-ui-layout-background-color: #2b2f36;

+ 2 - 2
src/views/Booking/src/components/BookingDetail/src/BookingDetail.vue

@@ -317,6 +317,7 @@ const { isOverflow: isDestinationOverflow } = useOverflow(destinationRef, allDat
           .line_container hr {
             width: 100%;
             border-radius: 0 2px 6px 0;
+            border-color: var(--color-neutral-1);
           }
           .line_container .right-icon {
             position: absolute;
@@ -339,9 +340,8 @@ const { isOverflow: isDestinationOverflow } = useOverflow(destinationRef, allDat
 }
 .fallback-class {
   opacity: 1 !important;
-  // background-color: #fff1e5 !important;
   cursor: move !important;
-  background-color: #fff;
+  background-color: var(--color-v-box-content-drag-bg);
   box-shadow: 4px 4px 32px 0px rgba(0, 0, 0, 0.2);
   border-radius: 12px;
 }

+ 10 - 6
src/views/Booking/src/components/BookingDetail/src/components/EmailView.vue

@@ -238,7 +238,7 @@ const sendEmail = () => {
   padding: 16px;
   border-radius: 12px;
   border-bottom: 1px solid var(--color-border);
-  background: var(--color-header-bg);
+  background: var(--color-email-bg);
 
   .show-records {
     max-height: 370px;
@@ -248,7 +248,7 @@ const sendEmail = () => {
 
 :deep(.w-e-text-container) {
   min-height: 170px;
-
+  border-radius: 0 0 6px 6px;
   p {
     margin: 0px;
   }
@@ -278,7 +278,11 @@ const sendEmail = () => {
 .text-editor {
   margin-top: 16px;
   border-radius: 6px;
-  border: 1px solid var(--color-border);
+  border: 1px solid var(--color-email-border);
+  // overflow: hidden;
+  :deep(div.w-e-toolbar) {
+    border-radius: 6px 6px 0 0;
+  }
 }
 
 .record-item {
@@ -300,7 +304,7 @@ const sendEmail = () => {
       div {
         height: 14px;
         line-height: 14px;
-        color: #fff;
+        color: var(--color-avatar);
         font-weight: 700;
       }
     }
@@ -324,14 +328,14 @@ const sendEmail = () => {
 
   & > .content {
     padding: 16px 6px;
-    background-color: #eceef1;
+    background-color: var(--color-detail-email-record-bg);
     border-radius: 6px;
   }
 }
 
 :deep(.text-editor) {
   & > div:first-of-type {
-    border-bottom: 1px solid var(--color-border) !important;
+    border-bottom: 1px solid var(--color-email-border) !important;
   }
 }
 </style>

+ 146 - 5
src/views/Layout/src/components/Header/HeaderView.vue

@@ -15,9 +15,10 @@ const route = useRoute()
 const router = useRouter()
 const headerSearch = useHeaderSearch()
 
+const themePopoverRef = ref()
 // 切换系统主题颜色
-const toggleThemeMode = () => {
-  themeStore.toggleTheme()
+const toggleThemeMode = (theme: string) => {
+  themeStore.toggleTheme(theme)
 }
 
 const searchValue = ref('')
@@ -149,7 +150,6 @@ const handleLogin = () => {
   <div class="layout-toolbar">
     <VBreadcrumb></VBreadcrumb>
     <div class="right-info">
-      <el-button @click="toggleThemeMode">切换主题</el-button>
       <el-input
         v-model="searchValue"
         size="large"
@@ -163,12 +163,67 @@ const handleLogin = () => {
       <!-- <span class="font_family icon-icon_notice_b" style="font-size: 18px"></span>
       <span class="font_family icon-icon_language_b" style="font-size: 16px"></span> -->
 
+      <el-popover
+        placement="bottom-end"
+        :width="400"
+        trigger="click"
+        ref="themePopoverRef"
+        popper-class="toggle-theme-popover"
+      >
+        <div>
+          <div class="header">
+            <span class="title">Themes</span>
+            <el-button @click="themePopoverRef.hide()" class="close-icon el-button--text">
+              <span class="font_family icon-icon_reject_b"></span>
+            </el-button>
+          </div>
+          <div class="tips">
+            Customize your workspace by changing the appearance and theme color
+          </div>
+          <div class="picture-module">
+            <div class="item" :class="{ active: themeStore.theme === 'light' }">
+              <img src="./images/kandroid.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/kandroid.png" alt="" />
+              <div v-if="themeStore.theme === 'dark'" class="selected-icon">
+                <span class="font_family icon-icon_confirm_b"></span>
+              </div>
+            </div>
+          </div>
+          <div class="btn-module">
+            <div
+              class="btn-item"
+              @click="toggleThemeMode('light')"
+              :class="{ active: themeStore.theme === 'light' }"
+            >
+              <span class="font_family icon-icon_light_b"></span>
+              Light
+            </div>
+            <div
+              class="btn-item"
+              @click="toggleThemeMode('dark')"
+              :class="{ active: themeStore.theme === 'dark' }"
+            >
+              <span class="font_family icon-icon_dark_b"></span>Dark
+            </div>
+          </div>
+        </div>
+        <template #reference>
+          <el-button>
+            <span class="font_family icon-icon_themes_b" style="font-size: 16px"></span
+          ></el-button>
+        </template>
+      </el-popover>
+
       <el-popover
         placement="bottom-end"
         :width="256"
         trigger="click"
         popper-class="user-config-popover"
-        content="this is content, this is content, this is content"
       >
         <div class="title">
           <div class="avatar">
@@ -270,6 +325,92 @@ const handleLogin = () => {
 }
 </style>
 <style lang="scss">
+div.el-popover.el-popper.toggle-theme-popover {
+  width: 400px;
+  height: 278px;
+  padding: 16px;
+  .header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    margin-bottom: 8px;
+    .title {
+      font-size: 18px;
+      font-weight: 700;
+    }
+    .close-icon {
+      width: 24px;
+      cursor: pointer;
+    }
+  }
+  .tips {
+    color: var(--color-neutral-2);
+  }
+  .picture-module {
+    display: flex;
+    justify-content: center;
+    gap: 6px;
+    margin-top: 16px;
+    .item {
+      position: relative;
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      width: 174px;
+      height: 108px;
+      padding: 8px;
+      img {
+        width: 154px;
+        height: 90px;
+        border-radius: 6px;
+      }
+      &.active {
+        border: 2px solid var(--color-theme);
+        border-radius: 6px;
+      }
+      .selected-icon {
+        position: absolute;
+        bottom: 8px;
+        left: 50%;
+        transform: translateX(-50%);
+        height: 16px;
+        span {
+          height: 16px;
+          width: 16px;
+          background-color: var(--color-theme);
+          color: #fff;
+          border-radius: 50%;
+        }
+      }
+    }
+  }
+  .btn-module {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    width: 368px;
+    height: 40px;
+    margin-top: 10px;
+    padding: 0 8px;
+    background-color: var(--color-toggle-btn-module-bg);
+    border-radius: 6px;
+    .btn-item {
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      gap: 4px;
+      width: 180px;
+      height: 32px;
+      border-radius: 6px;
+      color: var(--color-neutral-2);
+      cursor: pointer;
+      &.active {
+        background-color: var(--color-toggle-btn-module-active-bg);
+        color: var(--color-neutral-1);
+      }
+    }
+  }
+}
 div.el-popover.el-popper.user-config-popover {
   padding: 8px;
   width: 240px;
@@ -279,7 +420,7 @@ div.el-popover.el-popper.user-config-popover {
     align-items: center;
     gap: 8px;
     height: 70px;
-    border-bottom: 1px solid #eeeeed;
+    border-bottom: 1px solid var(--color-user-config-title-bottom-border);
     & > .avatar {
       width: 48px;
       height: 48px;

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

@@ -1,5 +1,5 @@
 <script setup lang="ts">
-const dialogVisible = ref(false)
+const dialogVisible = ref(true)
 
 const openDialog = () => {
   dialogVisible.value = true

+ 1 - 0
src/views/Tracking/src/components/PublicTracking/src/components/PublicTrackingDetail.vue

@@ -265,6 +265,7 @@ const { isOverflow: isDestinationOverflow } = useOverflow(destinationRef, allDat
           .line_container hr {
             width: 100%;
             border-radius: 0 2px 6px 0;
+            border-color: var(--color-neutral-1);
           }
           .line_container .right-icon {
             position: absolute;

+ 21 - 16
src/views/Tracking/src/components/TrackingDetail/src/TrackingDetail.vue

@@ -14,9 +14,12 @@ import { transportationMode } from '@/components/TransportationMode'
 import { useRoute } from 'vue-router'
 import { useOverflow } from '@/hooks/useOverflow'
 import { formatTimezone } from '@/utils/tools'
+import { useThemeStore } from '@/stores/modules/theme'
 
 const route = useRoute()
 
+const themeStore = useThemeStore()
+
 // 可拖拽模块的列表
 const boxList = ref([
   { id: 1, name: 'Basic Information' },
@@ -113,7 +116,7 @@ const { isOverflow: isDestinationOverflow } = useOverflow(destinationRef, allDat
 
 <template>
   <div class="tracking-detail" v-vloading="loading">
-    <div class="header">
+    <div class="header" :class="{ 'is-dark': themeStore.theme === 'dark' }">
       <div class="detail-status">
         <span
           class="font_family"
@@ -301,21 +304,23 @@ const { isOverflow: isDestinationOverflow } = useOverflow(destinationRef, allDat
   padding-bottom: 16px;
   & > .header {
     background: linear-gradient(
-      270deg,
-      rgba(43, 47, 54, 0.05) 1.88%,
-      rgba(255, 182, 121, 0.05) 15.6%,
-      rgba(118, 145, 255, 0.05) 49.92%,
-      rgba(96, 242, 255, 0.05) 81.78%,
-      rgba(43, 47, 54, 0.05) 97.95%
+      251deg,
+      rgba(255, 255, 255, 0.3),
+      rgba(255, 244, 235, 0.5) 22.66%,
+      rgba(240, 243, 255, 0.5) 44.57%,
+      rgba(224, 247, 249, 0.6) 80.46%,
+      rgba(255, 255, 255, 0.3)
     );
-    // background: linear-gradient(
-    //   251deg,
-    //   rgba(255, 255, 255, 0.3),
-    //   rgba(255, 244, 235, 0.5) 22.66%,
-    //   rgba(240, 243, 255, 0.5) 44.57%,
-    //   rgba(224, 247, 249, 0.6) 80.46%,
-    //   rgba(255, 255, 255, 0.3)
-    // );
+    &.is-dark {
+      background: linear-gradient(
+        270deg,
+        rgba(43, 47, 54, 0.1) 1.88%,
+        rgba(255, 182, 121, 0.1) 15.6%,
+        rgba(118, 145, 255, 0.1) 49.92%,
+        rgba(96, 242, 255, 0.1) 81.78%,
+        rgba(43, 47, 54, 0.1) 97.95%
+      );
+    }
 
     .detail-status {
       position: relative;
@@ -437,7 +442,7 @@ const { isOverflow: isDestinationOverflow } = useOverflow(destinationRef, allDat
 .fallback-class {
   opacity: 1 !important;
   cursor: move !important;
-  background-color: #fff;
+  background-color: var(--color-v-box-content-drag-bg);
   box-shadow: 4px 4px 32px 0px rgba(0, 0, 0, 0.2);
   border-radius: 12px;
 }

+ 5 - 1
src/views/Tracking/src/components/TrackingDetail/src/components/EmailDrawer.vue

@@ -251,6 +251,7 @@ const sendEmail = () => {
 
 :deep(.w-e-text-container) {
   min-height: 170px;
+  border-radius: 0 0 6px 6px;
   p {
     margin: 0px;
   }
@@ -283,7 +284,10 @@ const sendEmail = () => {
   margin-top: 16px;
   border-radius: 6px;
   border: 1px solid var(--color-email-border);
-  overflow: hidden;
+  // overflow: hidden;
+  :deep(div.w-e-toolbar) {
+    border-radius: 6px 6px 0 0;
+  }
 }
 
 .record-item {