perf: 优化系统设置加载时机

pull/213/head
xiaojunnuo 2024-10-12 14:59:12 +08:00
parent 38be8d84b2
commit 73962536d5
16 changed files with 171 additions and 185 deletions

View File

@ -6,7 +6,7 @@ import { CacheManager } from '@midwayjs/cache';
import { BaseSettings, SysPrivateSettings, SysPublicSettings } from './models.js';
import * as _ from 'lodash-es';
import { BaseService } from '../../../basic/index.js';
import { checkComm } from '@certd/pipeline';
import { isComm } from '@certd/pipeline';
/**
*
@ -40,8 +40,8 @@ export class SysSettingsService extends BaseService<SysSettingsEntity> {
if (!key) {
return null;
}
if (key === 'sys.site') {
checkComm();
if (key === 'sys.site' && isComm()) {
return null;
}
return await this.repository.findOne({
where: {

View File

@ -48,7 +48,6 @@ export default {
const pageStore = usePageStore();
pageStore.init();
const settingStore = useSettingStore();
settingStore.init();
return {
routerEnabled,

View File

@ -1,6 +1,28 @@
import { request } from "../service";
import { SiteEnv, SiteInfo } from "/@/store/modules/settings";
export type SiteEnv = {
agent?: {
enabled?: boolean;
contactText?: string;
contactLink?: string;
};
};
export type SiteInfo = {
title: string;
slogan: string;
logo: string;
loginLogo: string;
icpNo: string;
licenseTo?: string;
licenseToUrl?: string;
};
export type PlusInfo = {
vipType?: string;
expireTime?: number;
isPlus: boolean;
isComm?: boolean;
};
export type SysPublicSetting = {
registerEnabled: boolean;
managerOtherUserPipeline: boolean;
@ -11,29 +33,17 @@ export type SysInstallInfo = {
siteId: string;
};
export async function getSysPublicSettings(): Promise<SysPublicSetting> {
return await request({
url: "/basic/settings/public",
method: "get"
});
}
export type AllSettings = {
sysPublic: SysPublicSetting;
installInfo: SysInstallInfo;
plusInfo: PlusInfo;
siteInfo: SiteInfo;
siteEnv: SiteEnv;
};
export async function getInstallInfo(): Promise<SysInstallInfo> {
export async function loadAllSettings(): Promise<AllSettings> {
return await request({
url: "/basic/settings/install",
method: "get"
});
}
export async function getSiteInfo(): Promise<SiteInfo> {
return await request({
url: "/basic/settings/siteInfo",
method: "get"
});
}
export async function getSiteEnv(): Promise<SiteEnv> {
return await request({
url: "/basic/settings/siteEnv",
url: "/basic/settings/all",
method: "get"
});
}
@ -45,10 +55,3 @@ export async function bindUrl(data: any): Promise<any> {
data
});
}
export async function getPlusInfo() {
return await request({
url: "/basic/settings/plusInfo",
method: "get"
});
}

View File

@ -3,6 +3,9 @@
<div class="fs-user-info">您好{{ userStore.getUserInfo?.nickName }}</div>
<template #overlay>
<a-menu>
<a-menu-item>
<div @click="goUserProfile"></div>
</a-menu-item>
<a-menu-item>
<div @click="doLogout"></div>
</a-menu-item>
@ -10,17 +13,25 @@
</template>
</a-dropdown>
</template>
<script lang="ts">
import { defineComponent } from "vue";
<script lang="ts" setup>
import { useUserStore } from "/src/store/modules/user";
import { Modal } from "ant-design-vue";
import { useI18n } from "vue-i18n";
export default defineComponent({
name: "FsUserInfo",
setup() {
import { useRouter } from "vue-router";
defineOptions({
name: "FsUserInfo"
});
const userStore = useUserStore();
console.log("user", userStore);
const { t } = useI18n();
const router = useRouter();
function goUserProfile() {
console.log("goUserProfile");
router.push("/certd/mine/user-profile");
}
function doLogout() {
Modal.confirm({
iconType: "warning",
@ -31,10 +42,4 @@ export default defineComponent({
}
});
}
return {
userStore,
doLogout
};
}
});
</script>

View File

@ -7,6 +7,8 @@ import { site } from "../utils/util.site";
import { routes } from "./resolve";
import { useResourceStore } from "../store/modules/resource";
import { useUserStore } from "../store/modules/user";
import { useSettingStore } from "/@/store/modules/settings";
const router = createRouter({
history: createWebHashHistory(),
routes
@ -18,6 +20,8 @@ const router = createRouter({
router.beforeEach(async (to, from, next) => {
// 进度条
NProgress.start();
const settingStore = useSettingStore();
await settingStore.initOnce();
// 修复三级以上路由页面无法缓存的问题
if (to.matched && to.matched.length > 2) {
to.matched.splice(1, to.matched.length - 2);

View File

@ -27,8 +27,7 @@ export const frameworkResource = [
}
},
//...crudResources,
...certdResources,
...sysResources
...certdResources
]
}
];

View File

@ -1,3 +1,5 @@
import { sysResources } from "/@/router/source/modules/sys";
export const certdResources = [
{
title: "证书自动化",
@ -73,9 +75,11 @@ export const certdResources = [
component: "/certd/mine/user-profile.vue",
meta: {
icon: "ion:person-outline",
auth: true
}
auth: true,
isMenu: false
}
},
...sysResources
]
}
];

View File

@ -13,40 +13,6 @@ export const sysResources = [
permission: "sys"
},
children: [
{
title: "权限管理",
name: "AuthorityManager",
path: "/sys/authority",
redirect: "/sys/authority/permission",
meta: {
icon: "ion:ribbon-outline",
//需要校验权限
permission: "sys:auth"
},
children: [
{
title: "权限资源管理",
name: "PermissionManager",
path: "/sys/authority/permission",
component: "/sys/authority/permission/index.vue",
meta: {
icon: "ion:list-outline",
//需要校验权限
permission: "sys:auth:per:view"
}
},
{
title: "角色管理",
name: "RoleManager",
path: "/sys/authority/role",
component: "/sys/authority/role/index.vue",
meta: {
icon: "ion:people-outline",
permission: "sys:auth:role:view"
}
}
]
},
{
title: "用户管理",
name: "UserManager",
@ -102,6 +68,37 @@ export const sysResources = [
permission: "sys:settings:view"
}
},
{
title: "账号绑定",
name: "AccountBind",
path: "/sys/account",
component: "/sys/account/index.vue",
meta: {
icon: "ion:golf-outline",
permission: "sys:settings:view"
}
},
{
title: "权限管理",
name: "PermissionManager",
path: "/sys/authority/permission",
component: "/sys/authority/permission/index.vue",
meta: {
icon: "ion:list-outline",
//需要校验权限
permission: "sys:auth:per:view"
}
},
{
title: "角色管理",
name: "RoleManager",
path: "/sys/authority/role",
component: "/sys/authority/role/index.vue",
meta: {
icon: "ion:people-outline",
permission: "sys:auth:role:view"
}
}
// {
// title: "商业版设置",
@ -130,16 +127,6 @@ export const sysResources = [
// }
// ]
// }
{
title: "账号绑定",
name: "AccountBind",
path: "/sys/account",
component: "/sys/account/index.vue",
meta: {
icon: "ion:golf-outline",
permission: "sys:settings:view"
}
}
]
}
];

View File

@ -5,7 +5,7 @@ import _ from "lodash-es";
import { LocalStorage } from "/src/utils/util.storage";
import * as basicApi from "/@/api/modules/api.basic";
import { SysInstallInfo, SysPublicSetting } from "/@/api/modules/api.basic";
import { PlusInfo, SiteEnv, SiteInfo, SysInstallInfo, SysPublicSetting } from "/@/api/modules/api.basic";
import { useUserStore } from "/@/store/modules/user";
import { mitter } from "/@/utils/util.mitt";
import { env } from "/@/utils/util.env";
@ -36,31 +36,7 @@ export interface SettingState {
siteInfo: SiteInfo;
plusInfo?: PlusInfo;
siteEnv?: SiteEnv;
}
export type SiteEnv = {
agent?: {
enabled?: boolean;
contactText?: string;
contactLink?: string;
};
};
export type SiteInfo = {
title: string;
slogan: string;
logo: string;
loginLogo: string;
warningOff: boolean;
icpNo: string;
licenseTo?: string;
licenseToUrl?: string;
};
interface PlusInfo {
vipType?: string;
expireTime?: number;
isPlus: boolean;
isComm?: boolean;
inited?: boolean;
}
const defaultThemeConfig = {
@ -73,7 +49,6 @@ const defaultSiteInfo = {
slogan: env.SLOGAN || "让你的证书永不过期",
logo: env.LOGO || "/static/images/logo/logo.svg",
loginLogo: env.LOGIN_LOGO || "/static/images/logo/rect-block.svg",
warningOff: false,
icpNo: env.ICP_NO,
licenseTo: "",
licenseToUrl: ""
@ -88,7 +63,8 @@ export const useSettingStore = defineStore({
},
plusInfo: {
isPlus: false,
vipType: "free"
vipType: "free",
isComm: false
},
sysPublic: {
registerEnabled: false,
@ -109,7 +85,8 @@ export const useSettingStore = defineStore({
contactText: "",
contactLink: ""
}
}
},
inited: false
}),
getters: {
getThemeConfig(): any {
@ -127,6 +104,12 @@ export const useSettingStore = defineStore({
isComm(): boolean {
return this.plusInfo?.isComm && this.plusInfo?.expireTime > new Date().getTime();
},
isAgent(): boolean {
return this.siteEnv?.agent?.enabled === true;
},
isCommOrAgent() {
return this.isComm || this.isAgent;
},
vipLabel(): string {
const vipLabelMap: any = {
free: "免费版",
@ -146,33 +129,18 @@ export const useSettingStore = defineStore({
}
},
async loadSysSettings() {
await this.loadSysPublicSettings();
await this.loadSiteEnv();
await this.loadInstallInfo();
await this.loadPlusInfo();
await this.loadSiteInfo();
const allSettings = await basicApi.loadAllSettings();
_.merge(this.sysPublic, allSettings.sysPublic || {});
_.merge(this.installInfo, allSettings.installInfo || {});
_.merge(this.siteEnv, allSettings.siteEnv || {});
_.merge(this.plusInfo, allSettings.plusInfo || {});
//@ts-ignore
this.initSiteInfo(allSettings.siteInfo || {});
await this.checkUrlBound();
},
async loadSysPublicSettings() {
const settings = await basicApi.getSysPublicSettings();
_.merge(this.sysPublic, settings);
},
async loadInstallInfo() {
const installInfo = await basicApi.getInstallInfo();
_.merge(this.installInfo, installInfo);
},
async loadSiteEnv() {
const siteEnv = await basicApi.getSiteEnv();
_.merge(this.siteEnv, siteEnv);
},
async loadPlusInfo() {
this.plusInfo = await basicApi.getPlusInfo();
},
async loadSiteInfo() {
const isComm = this.isComm;
let siteInfo: SiteInfo = {};
if (isComm) {
siteInfo = await basicApi.getSiteInfo();
initSiteInfo(siteInfo: SiteInfo) {
//@ts-ignore
if (this.isComm) {
if (siteInfo.logo) {
siteInfo.logo = `/api/basic/file/download?key=${siteInfo.logo}`;
}
@ -205,8 +173,9 @@ export const useSettingStore = defineStore({
const doBindUrl = async (url: string) => {
await basicApi.bindUrl({ url });
await this.loadInstallInfo();
await this.loadSysSettings();
};
const baseUrl = getBaseUrl();
if (!bindUrl) {
//绑定url
@ -269,6 +238,13 @@ export const useSettingStore = defineStore({
async init() {
await this.setThemeConfig(this.getThemeConfig);
await this.loadSysSettings();
},
async initOnce() {
if (this.inited) {
return;
}
await this.init();
this.inited = true;
}
}
});

View File

@ -1,7 +1,7 @@
import * as envs from "./util.env";
import * as sites from "./util.site";
import * as storages from "./util.storage";
import * as commons from "./util.common";
import commons from "./util.common";
import * as mitt from "./util.mitt";
export const util = {
...envs,

View File

@ -29,5 +29,9 @@ export default {
array.push(item);
}
return array;
},
async sleep(ms: number) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
};

View File

@ -5,7 +5,7 @@
</template>
<div class="p-10">
<a-descriptions title="" bordered>
<a-descriptions-item label="用户名">{{ userInfo.userInfoname }}</a-descriptions-item>
<a-descriptions-item label="用户名">{{ userInfo.username }}</a-descriptions-item>
<a-descriptions-item label="昵称">{{ userInfo.nickName }}</a-descriptions-item>
<a-descriptions-item label="邮箱">{{ userInfo.email }}</a-descriptions-item>
<a-descriptions-item label="手机号">{{ userInfo.phoneCode }}{{ userInfo.mobile }}</a-descriptions-item>

View File

@ -6,7 +6,7 @@
</div>
</div>
<p class="d2-page-cover__sub-title">{{ siteInfo.slogan }}</p>
<div v-if="siteInfo.warningOff !== true && settingStore.siteEnv?.agent?.enabled === false" class="warning">
<div v-if="!settingStore.isCommOrAgent" class="warning">
<a-alert type="warning" show-icon>
<template #description>
<div class="flex">
@ -17,10 +17,10 @@
</template>
</a-alert>
</div>
<div class="content">
<div v-if="!settingStore.isCommOrAgent" class="content">
<img src="/static/images/preview.png" class="preview_img" />
</div>
<div v-if="!settingStore.isComm" class="footer_box">
<div v-if="!settingStore.isCommOrAgent" class="footer_box">
<div>如果觉得好用请不要吝啬你的star哟</div>
<a href="https://gitee.com/certd/certd" target="_blank"><img src="https://gitee.com/certd/certd/badge/star.svg?theme=dark" alt="star" /></a>
<a href="https://github.com/certd/certd" target="_blank"><img alt="GitHub stars" src="https://img.shields.io/github/stars/certd/certd?logo=github" /></a>
@ -29,7 +29,8 @@
</template>
<script lang="ts" setup>
import { computed, ref, Ref } from "vue";
import { SiteInfo, useSettingStore } from "/@/store/modules/settings";
import { useSettingStore } from "/@/store/modules/settings";
import { SiteInfo } from "/@/api/modules/api.basic";
const version = ref(import.meta.env.VITE_APP_VERSION);
const settingStore = useSettingStore();

View File

@ -54,11 +54,13 @@ defineOptions({
interface FormState {
registerEnabled: boolean;
managerOtherUserPipeline: boolean;
icpNo: string;
}
const formState = reactive<Partial<FormState>>({
registerEnabled: false,
managerOtherUserPipeline: false
managerOtherUserPipeline: false,
icpNo: ""
});
async function loadSysPublicSettings() {

View File

@ -37,9 +37,6 @@
:build-url="buildUrl"
/>
</a-form-item>
<a-form-item label="关闭首页告警" name="warningOff">
<a-switch v-model:checked="formState.warningOff" />
</a-form-item>
<a-form-item label="你的主体名称" name="licenseTo">
<a-input v-model:value="formState.licenseTo" />
<div class="helper">将会显示在底部</div>
@ -77,7 +74,6 @@ interface FormState {
slogan: string;
logo: string;
loginLogo: string;
warningOff: boolean;
licenseTo: string;
licenseToUrl: string;
}

View File

@ -1,4 +1,4 @@
import { ALL, Body, Config, Controller, Get, Inject, Provide } from '@midwayjs/core';
import { Config, Controller, Get, Inject, Provide } from '@midwayjs/core';
import { BaseController, Constants, SysInstallInfo, SysPublicSettings, SysSettingsService, SysSiteEnv, SysSiteInfo } from '@certd/lib-server';
import { AppKey, getPlusInfo } from '@certd/pipeline';
@ -15,39 +15,45 @@ export class BasicSettingsController extends BaseController {
@Config('agent')
agentConfig: SysSiteEnv['agent'];
@Get('/public', { summary: Constants.per.guest })
public async getSysPublic() {
const settings = await this.sysSettingsService.getSetting(SysPublicSettings);
return this.ok(settings);
return await this.sysSettingsService.getSetting(SysPublicSettings);
}
@Get('/install', { summary: Constants.per.guest })
public async getInstallInfo() {
const settings: SysInstallInfo = await this.sysSettingsService.getSetting(SysInstallInfo);
settings.accountServerBaseUrl = this.accountServerBaseUrl;
settings.appKey = AppKey;
return this.ok(settings);
return settings;
}
@Get('/siteInfo', { summary: Constants.per.guest })
public async getSiteInfo() {
const settings: SysSiteInfo = await this.sysSettingsService.getSetting(SysSiteInfo);
return this.ok(settings);
return await this.sysSettingsService.getSetting(SysSiteInfo);
}
@Get('/siteEnv', { summary: Constants.per.guest })
public async getSiteEnv() {
const env: SysSiteEnv = {
agent: this.agentConfig,
};
return this.ok(env);
return env;
}
@Get('/plusInfo', { summary: Constants.per.guest })
async plusInfo(@Body(ALL) body: any) {
const info = getPlusInfo();
async plusInfo() {
return getPlusInfo();
}
@Get('/all', { summary: Constants.per.guest })
async getAllSettings() {
const sysPublic = await this.getSysPublic();
const installInfo = await this.getInstallInfo();
const siteInfo = await this.getSiteInfo();
const siteEnv = await this.getSiteEnv();
const plusInfo = await this.plusInfo();
return this.ok({
...info,
sysPublic,
installInfo,
siteInfo,
siteEnv,
plusInfo,
});
}
}