1 Commits

4 changed files with 53 additions and 37 deletions

View File

@@ -8,8 +8,7 @@
import { onMounted } from "vue"; import { onMounted } from "vue";
import { useRoute } from "vue-router"; import { useRoute } from "vue-router";
import storage from "@/plugins/storage"; import storage from "@/plugins/storage";
import { getBaseSite, getThemeSetting } from "@/api/common.js"; import { loadSiteSettings } from "@/composables/useSiteSettings";
import { fetchAndApplyTheme } from "@/utils/theme";
import { useAppStore } from "@/stores/app"; import { useAppStore } from "@/stores/app";
defineOptions({ name: "App" }); defineOptions({ name: "App" });
@@ -49,27 +48,15 @@ function init() {
}); });
} }
getSite(); getSite();
getTheme();
} }
function getSite() { function getSite() {
getBaseSite().then((res) => { loadSiteSettings().then((data) => {
if (res.success && res.result.settingValue) { if (data) {
try { applySiteInfo(data);
const data = JSON.parse(res.result.settingValue);
applySiteInfo(data);
} catch {
// 站点配置解析失败时使用缓存
}
} }
}).catch((err) => { }).catch((err) => {
console.warn('获取站点配置失败', err); console.warn("获取站点配置失败", err);
});
}
function getTheme() {
fetchAndApplyTheme(getThemeSetting).catch((err) => {
console.warn('获取主题配置失败', err);
}); });
} }

View File

@@ -37,6 +37,8 @@
<script setup> <script setup>
import { computed } from 'vue'; import { computed } from 'vue';
import Cookies from 'js-cookie'; import Cookies from 'js-cookie';
import storage from '@/plugins/storage';
import { logout } from '@/api/account';
const props = defineProps({ const props = defineProps({
options: { options: {
@@ -69,12 +71,22 @@ const username = computed(() => {
return ''; return '';
}); });
function handleLogout() { function clearLocalAuth() {
storage.removeItem('userInfo');
storage.removeItem('accessToken');
storage.removeItem('refreshToken');
storage.removeItem('cartNum');
Cookies.remove('userInfo'); Cookies.remove('userInfo');
Cookies.remove('accessToken'); Cookies.remove('accessToken');
window.location.reload(); window.location.reload();
} }
function handleLogout() {
logout().finally(() => {
clearLocalAuth();
});
}
const customStyle = computed(() => { const customStyle = computed(() => {
const s = props.componentStyle || {}; const s = props.componentStyle || {};
const opt = props.options || {}; const opt = props.options || {};

View File

@@ -2,11 +2,14 @@ import { computed, onMounted, ref } from "vue";
import { getBaseSite } from "@/api/common.js"; import { getBaseSite } from "@/api/common.js";
import config from "@/config"; import config from "@/config";
// 同页的页头、页脚共享请求;每次重新进入页面时刷新,避免旧缓存覆盖后台设置。 // 全局共享站点配置;应用生命周期内仅拉取一次,同页与切页均复用请求与结果。
const settings = ref(null); const settings = ref(null);
let pendingRequest; let pendingRequest = null;
export function loadSiteSettings() { export function loadSiteSettings() {
if (settings.value) {
return Promise.resolve(settings.value);
}
if (!pendingRequest) { if (!pendingRequest) {
pendingRequest = getBaseSite() pendingRequest = getBaseSite()
.then((res) => { .then((res) => {
@@ -16,7 +19,9 @@ export function loadSiteSettings() {
return settings.value; return settings.value;
}) })
.catch(() => settings.value) .catch(() => settings.value)
.finally(() => { pendingRequest = null; }); .finally(() => {
pendingRequest = null;
});
} }
return pendingRequest; return pendingRequest;
} }

View File

@@ -69,27 +69,39 @@ export function normalizeTheme(data = {}) {
}; };
} }
let pendingThemeRequest = null;
export async function fetchAndApplyTheme(requestFn) { export async function fetchAndApplyTheme(requestFn) {
const cachedTheme = loadCachedTheme(); const cachedTheme = loadCachedTheme();
if (cachedTheme) { if (cachedTheme) {
applyThemeToDocument(normalizeTheme(cachedTheme)); applyThemeToDocument(normalizeTheme(cachedTheme));
} }
try { if (pendingThemeRequest) {
const res = await requestFn(); return pendingThemeRequest;
if (res?.success && res?.result?.settingValue) {
const data = JSON.parse(res.result.settingValue);
const normalized = normalizeTheme(data);
applyThemeToDocument(normalized);
cacheTheme(normalized);
return normalized;
}
} catch (error) {
console.warn(
"[theme] 主题色加载失败,请确认 buyer-api 已启动且站点主题配置可用",
error
);
} }
return cachedTheme ? normalizeTheme(cachedTheme) : normalizeTheme(); pendingThemeRequest = (async () => {
try {
const res = await requestFn();
if (res?.success && res?.result?.settingValue) {
const data = JSON.parse(res.result.settingValue);
const normalized = normalizeTheme(data);
applyThemeToDocument(normalized);
cacheTheme(normalized);
return normalized;
}
} catch (error) {
console.warn(
"[theme] 主题色加载失败,请确认 buyer-api 已启动且站点主题配置可用",
error
);
} finally {
pendingThemeRequest = null;
}
return cachedTheme ? normalizeTheme(cachedTheme) : normalizeTheme();
})();
return pendingThemeRequest;
} }