App.vue 2.23 KB
<template>
  <el-config-provider :locale="locale">
    <div id="app">
      <router-view />
      <!-- 全局 AI 客服悬浮入口(在隐藏路由上不显示,例如登录页) -->
      <AICustomerService v-if="showAICustomerService" />
    </div>
  </el-config-provider>
</template>

<script setup lang="ts">
import { onMounted, computed } from "vue";
import { useAppStore } from "@/stores/app";
import zhCn from "element-plus/es/locale/lang/zh-cn";
import en from "element-plus/es/locale/lang/en";
import AICustomerService from "@/layout/AICustomerService.vue";

const route = useRoute();

const appStore = useAppStore();

const locale = computed(() => {
  return appStore.language === "zh-CN" ? zhCn : en;
});

const showAICustomerService = computed(() => !route.meta.hidden);

onMounted(() => {
  // 初始化语言
  const savedLang = localStorage.getItem("language") || "zh-CN";
  document.documentElement.setAttribute("lang", savedLang);

  // 初始化主题,默认使用亮色主题
  const savedTheme = localStorage.getItem("theme") || "light";
  
  // 只有当 store 中的主题与保存的主题不一致时才更新
  if (appStore.theme !== savedTheme) {
    applyTheme(savedTheme);
    appStore.setTheme(savedTheme);
  } else {
    // 确保 class 已正确应用(针对 index.html 脚本可能未覆盖到的 body 元素)
    applyTheme(savedTheme);
  }

  // 如果本地没有保存主题,则保存默认主题
  if (!localStorage.getItem("theme")) {
    localStorage.setItem("theme", "light");
    appStore.setTheme("light");
  }
});

const applyTheme = (theme: string) => {
  document.documentElement.classList.remove("theme-dark", "theme-light");
  document.documentElement.classList.add(`theme-${theme}`);
  document.body.classList.remove("theme-dark", "theme-light");
  document.body.classList.add(`theme-${theme}`);
};

// 暴露全局主题切换方法
(window as any).setTheme = (theme: string) => {
  applyTheme(theme);
  appStore.setTheme(theme);
};
</script>

<style>
#app {
  font-family: "Inter", "PingFang SC", "Microsoft YaHei", Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  margin: 0;
  padding: 0;
}
</style>