Merge pull request #19 from Bull-BCLS/dev

refactor: 适配系统配置
This commit is contained in:
Charles7c 2023-09-23 19:27:04 +08:00 committed by GitHub
commit 6013211a09
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 114 additions and 39 deletions

View File

@ -3,6 +3,7 @@ import qs from 'query-string';
import { ListParam as DeptParam } from '@/api/system/dept';
import { ListParam as MenuParam } from '@/api/system/menu';
import { ListParam as RoleParam } from '@/api/system/role';
import { ListParam as OptionParam } from '@/api/system/config';
import { TreeNodeData } from '@arco-design/web-vue';
import { LabelValueState } from '@/store/modules/dict/types';
@ -39,6 +40,15 @@ export function listDict(code: string) {
return axios.get<LabelValueState[]>(`${BASE_URL}/dict/${code}`);
}
export function listOption(params: OptionParam) {
return axios.get<LabelValueState[]>(`${BASE_URL}/option`, {
params,
paramsSerializer: (obj) => {
return qs.stringify(obj);
},
});
}
export function upload(data: FormData) {
return axios.post(`${BASE_URL}/file`, data);
}

View File

@ -1,28 +1,14 @@
<template>
<a-layout-footer class="footer">
{{ `Copyright © 2022-${new Date().getFullYear()}` }}&nbsp;
<a
href="https://blog.charles7c.top/about/me"
target="_blank"
rel="noopener"
>
Charles7c
</a>
<span>&nbsp;&nbsp;</span>
<a
href="https://github.com/Charles7c/continew-admin"
target="_blank"
rel="noopener"
>{{ $t('title') }}</a
>&nbsp; v1.2.0-SNAPSHOT
<span>&nbsp;&nbsp;</span>
<a href="https://beian.miit.gov.cn" target="_blank" rel="noopener">
津ICP备2022005864号-2
</a>
<div v-html="appStore.getCopyright"></div>
</a-layout-footer>
</template>
<script lang="ts" setup></script>
<script lang="ts" setup>
import { useAppStore } from '@/store';
const appStore = useAppStore();
</script>
<style lang="less" scoped>
.footer {
@ -33,13 +19,4 @@
color: var(--color-text-2);
text-align: center;
}
a {
text-decoration: none;
color: var(--color-text-2);
}
a:hover {
color: rgb(var(--gray-6));
}
</style>

View File

@ -2,12 +2,12 @@
<div class="navbar">
<div class="left-side">
<a-space>
<img alt="logo" src="/logo.svg" />
<img alt="logo" :src="getFile(appStore.getLogo)" height="33"/>
<a-typography-title
:style="{ margin: 0, fontSize: '18px' }"
:heading="5"
>
{{ $t('title') }}
{{ appStore.getTitle }}
</a-typography-title>
<icon-menu-fold
v-if="!topMenu && appStore.device === 'mobile'"
@ -198,6 +198,7 @@
import useUser from '@/hooks/user';
import Menu from '@/components/menu/index.vue';
import getAvatar from '@/utils/avatar';
import getFile from '@/utils/file';
import MessageBox from '../message-box/index.vue';
const appStore = useAppStore();

View File

@ -1,13 +1,15 @@
import type { Router, LocationQueryRaw } from 'vue-router';
import NProgress from 'nprogress'; // progress bar
import { useLoginStore } from '@/store';
import { useLoginStore, useAppStore } from '@/store';
import { isLogin } from '@/utils/auth';
export default function setupUserLoginInfoGuard(router: Router) {
router.beforeEach(async (to, from, next) => {
NProgress.start();
const loginStore = useLoginStore();
const appStore = useAppStore();
appStore.init();
if (isLogin()) {
if (loginStore.roles[0]) {
next();

View File

@ -9,7 +9,9 @@ import type { MessageReturn } from '@arco-design/web-vue/es/message/interface';
import type { RouteRecordNormalized } from 'vue-router';
import defaultSettings from '@/config/settings.json';
import { listRoute } from '@/api/auth/login';
import { AppState } from './types';
import { listOption } from '@/api/common';
import getFile from '@/utils/file';
import { AppState, Config } from './types';
const recursionMenu = (
appMenu: RouteRecordNormalized[],
@ -45,6 +47,18 @@ const useAppStore = defineStore('app', {
);
return menuList;
},
getLogo(state: AppState): string | undefined {
return state.config?.site_logo;
},
getFavicon(state: AppState): string | undefined {
return state.config?.site_favicon;
},
getTitle(state: AppState): string | undefined {
return state.config?.site_title;
},
getCopyright(state: AppState): string | undefined {
return state.config?.site_copyright;
},
},
actions: {
@ -97,6 +111,51 @@ const useAppStore = defineStore('app', {
clearServerMenu() {
this.serverMenu = [];
},
/**
*
*/
init() {
listOption({
code: ['site_title', 'site_copyright', 'site_favicon', 'site_logo'],
}).then((res) => {
const resMap = new Map();
res.data.forEach((item) => {
resMap.set(item.label, item.value);
});
this.config = {
site_title: resMap.get('site_title'),
site_copyright: resMap.get('site_copyright'),
site_logo: resMap.get('site_logo'),
site_favicon: resMap.get('site_logo'),
};
document.title = resMap.get('site_title');
document
.querySelector('link[rel="shortcut icon"]')
?.setAttribute(
'href',
getFile(resMap.get('site_favicon')) ||
'https://cnadmin.charles7c.top/favicon.ico'
);
});
},
/**
*
*
* @param config
*/
save(config: Config) {
this.$state.config = config;
document.title = config.site_title || '';
document
.querySelector('link[rel="shortcut icon"]')
?.setAttribute(
'href',
getFile(config.site_favicon) ||
'https://cnadmin.charles7c.top/favicon.ico'
);
},
},
});

View File

@ -1,5 +1,11 @@
import type { RouteRecordNormalized } from 'vue-router';
export interface Config {
site_title?: string;
site_copyright?: string;
site_logo?: string;
site_favicon?: string;
}
export interface AppState {
theme: string;
colorWeak: boolean;
@ -18,4 +24,5 @@ export interface AppState {
menuFromServer: boolean;
serverMenu: RouteRecordNormalized[];
[key: string]: unknown;
config?: Config;
}

View File

@ -1,6 +1,6 @@
<template>
<div class="login-form-wrapper">
<div class="login-form-title">{{ $t('login.form.title') }}</div>
<div class="login-form-title">登录 {{ appStore.getTitle }}</div>
<div class="login-form-sub-title">{{ $t('login.form.subTitle') }}</div>
<a-form
ref="formRef"
@ -71,7 +71,7 @@
import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';
import { useStorage } from '@vueuse/core';
import { useLoginStore } from '@/store';
import { useLoginStore, useAppStore } from '@/store';
import { encryptByRsa } from '@/utils/encrypt';
// import debug from '@/utils/env';
@ -79,6 +79,7 @@
const captchaImgBase64 = ref('');
const loginStore = useLoginStore();
const appStore = useAppStore();
const loading = ref(false);
const { t } = useI18n();
const router = useRouter();

View File

@ -1,8 +1,8 @@
<template>
<div class="container">
<div class="logo">
<img src="/logo.svg" alt="logo" />
<div class="logo-text">{{ $t('title') }}</div>
<img :src="getFile(appStore.getLogo)" alt="logo" height="33" />
<div class="logo-text">{{ appStore.getTitle }}</div>
</div>
<LoginBanner />
<div class="content">
@ -18,8 +18,12 @@
<script lang="ts" setup>
import Footer from '@/components/footer/index.vue';
import { useAppStore } from '@/store';
import getFile from '@/utils/file';
import LoginBanner from './components/banner.vue';
import LoginForm from './components/login-form.vue';
const appStore = useAppStore();
</script>
<style lang="less" scoped>

View File

@ -170,6 +170,7 @@
} from '@/api/system/config';
import { upload } from '@/api/common';
import getFile from '@/utils/file';
import { useAppStore } from '@/store';
const { proxy } = getCurrentInstance() as any;
const dataList = ref<DataRecord[]>([]);
@ -180,6 +181,7 @@
const siteCopyright = ref<DataRecord>();
const siteLogo = ref<DataRecord>();
const siteFavicon = ref<DataRecord>();
const appStore = useAppStore();
const data = reactive({
queryParams: {
@ -251,7 +253,7 @@
}
);
save(optionList).then((res) => {
// siteConfigStore().save(data.form);
appStore.save(form.value);
handleCancel();
proxy.$message.success(res.msg);
});
@ -360,6 +362,7 @@
await resetValue(queryParams.value);
proxy.$message.success('恢复成功');
await getConfig();
appStore.save(form.value);
};
/**

View File

@ -37,6 +37,7 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.StrUtil;
@ -54,6 +55,7 @@ import top.charles7c.cnadmin.common.util.validate.ValidationUtils;
import top.charles7c.cnadmin.monitor.annotation.Log;
import top.charles7c.cnadmin.system.model.query.DeptQuery;
import top.charles7c.cnadmin.system.model.query.MenuQuery;
import top.charles7c.cnadmin.system.model.query.OptionQuery;
import top.charles7c.cnadmin.system.model.query.RoleQuery;
import top.charles7c.cnadmin.system.model.vo.RoleVO;
import top.charles7c.cnadmin.system.service.*;
@ -78,6 +80,7 @@ public class CommonController {
private final DictItemService dictItemService;
private final ProjectProperties projectProperties;
private final LocalStorageProperties localStorageProperties;
private final OptionService optionService;
@Operation(summary = "上传文件", description = "上传文件")
@PostMapping("/file")
@ -123,6 +126,14 @@ public class CommonController {
return enumClass.map(this::listEnumDict).orElseGet(() -> R.ok(dictItemService.listByDictCode(code)));
}
@SaIgnore
@Operation(summary = "查询参数", description = "查询参数")
@GetMapping("/option")
public R<List<LabelValueVO>> listOption(@Validated OptionQuery query) {
return R.ok(optionService.list(query).stream().map(option -> new LabelValueVO(option.getCode(),
StrUtil.nullToDefault(option.getValue(), option.getDefaultValue()))).collect(Collectors.toList()));
}
/**
* 根据枚举类名查询
*
@ -140,7 +151,7 @@ public class CommonController {
/**
* 查询枚举字典
*
*
* @param enumClass
* 枚举类型
* @return 枚举字典