perf: 同步近期修改

This commit is contained in:
2025-02-22 00:22:38 +08:00
parent f01a672b2d
commit 177bda9d99
24 changed files with 170 additions and 62 deletions

1
.gitignore vendored
View File

@@ -20,3 +20,4 @@ tests/**/coverage/
*.njsproj *.njsproj
*.sln *.sln
tsconfig.tsbuildinfo tsconfig.tsbuildinfo
.hintrc

View File

@@ -26,6 +26,11 @@ buttons:Add: Add
buttons:Update: Update buttons:Update: Update
buttons:Delete: Delete buttons:Delete: Delete
buttons:Export: Export buttons:Export: Export
buttons:Import: Import
buttons:DownLoded: DownLoded
buttons:DownLodedTemplate: DownLoded Template
buttons:Hide: Hide
buttons:ConfirmUpload: Confirm Upload
buttons:Save: Save buttons:Save: Save
buttons:Permission: Permission buttons:Permission: Permission
buttons:ExpandOrCollapse: Expand Or Collapse buttons:ExpandOrCollapse: Expand Or Collapse
@@ -34,6 +39,8 @@ buttons:Linked: Linked
buttons:More: More buttons:More: More
buttons:Deselect: Deselect buttons:Deselect: Deselect
buttons:DeleteInBatches: Delete In Batches buttons:DeleteInBatches: Delete In Batches
buttons:ExportInBatches: Export In Batches
buttons:ExportAll: Export All
buttons:UploadAvatar: Upload Avatar buttons:UploadAvatar: Upload Avatar
buttons:ResetPassword: Reset Password buttons:ResetPassword: Reset Password
buttons:RoleAllocation: Role Allocation buttons:RoleAllocation: Role Allocation
@@ -97,7 +104,7 @@ menus:LoginLog: Login Log
menus:OperationLog: Operation Log menus:OperationLog: Operation Log
menus:CacheMonitor: Cache Monitor menus:CacheMonitor: Cache Monitor
menus:CacheList: Cache List menus:CacheList: Cache List
menus:ServerMonitor: Server Monitor menus:PropertyMonitor: Property Monitor
menus:Abnormal: Abnormal Page menus:Abnormal: Abnormal Page
menus:FourZeroFour: "404" menus:FourZeroFour: "404"
menus:FourZeroOne: "403" menus:FourZeroOne: "403"

View File

@@ -26,6 +26,11 @@ buttons:Add: 添加
buttons:Update: 修改 buttons:Update: 修改
buttons:Delete: 删除 buttons:Delete: 删除
buttons:Export: 导出 buttons:Export: 导出
buttons:Import: 导入
buttons:DownLoded: 下载
buttons:DownLodedTemplate: 下载模版
buttons:Hide: 隐藏
buttons:ConfirmUpload: 确认上传
buttons:Save: 保存 buttons:Save: 保存
buttons:Permission: 权限 buttons:Permission: 权限
buttons:ExpandOrCollapse: 展开或折叠 buttons:ExpandOrCollapse: 展开或折叠
@@ -34,6 +39,8 @@ buttons:Linked: 联动
buttons:More: 更多 buttons:More: 更多
buttons:Deselect: 取消选择 buttons:Deselect: 取消选择
buttons:DeleteInBatches: 批量删除 buttons:DeleteInBatches: 批量删除
buttons:ExportInBatches: 批量导出
buttons:ExportAll: 全部导出
buttons:UploadAvatar: 上传头像 buttons:UploadAvatar: 上传头像
buttons:ResetPassword: 重置密码 buttons:ResetPassword: 重置密码
buttons:RoleAllocation: 角色分配 buttons:RoleAllocation: 角色分配
@@ -97,7 +104,7 @@ menus:LoginLog: 登录日志
menus:OperationLog: 操作日志 menus:OperationLog: 操作日志
menus:CacheMonitor: 缓存监控 menus:CacheMonitor: 缓存监控
menus:CacheList: 缓存列表 menus:CacheList: 缓存列表
menus:ServerMonitor: 服务监控 menus:PropertyMonitor: 性能监控
menus:Abnormal: 异常页面 menus:Abnormal: 异常页面
menus:FourZeroFour: "404" menus:FourZeroFour: "404"
menus:FourZeroOne: "403" menus:FourZeroOne: "403"
@@ -162,4 +169,3 @@ logout:message: 是否退出当前系统?
logout:success: 退出成功 logout:success: 退出成功
logout:fail: 退出失败 logout:fail: 退出失败
logout:cancel: 退出取消 logout:cancel: 退出取消

View File

@@ -1,9 +1,9 @@
{ {
"Version": "5.9.0", "Version": "1.0.0",
"Period": "2024-present", "Period": "2024-present",
"FixedHeader": true, "FixedHeader": true,
"HiddenSideBar": false, "HiddenSideBar": false,
"MultiTagsCache": false, "MultiTagsCache": true,
"KeepAlive": true, "KeepAlive": true,
"Locale": "zh", "Locale": "zh",
"Layout": "vertical", "Layout": "vertical",
@@ -18,7 +18,7 @@
"SidebarStatus": true, "SidebarStatus": true,
"EpThemeColor": "#409EFF", "EpThemeColor": "#409EFF",
"ShowLogo": true, "ShowLogo": true,
"ShowModel": "smart", "ShowModel": "chrome",
"MenuArrowIconNoTransition": false, "MenuArrowIconNoTransition": false,
"CachingAsyncRoutes": false, "CachingAsyncRoutes": false,
"TooltipEffect": "light", "TooltipEffect": "light",

17
src/api/file.ts Normal file
View File

@@ -0,0 +1,17 @@
import { http } from "@/utils/http";
import type { FileInfo } from "types/file";
/**上传文件 */
export const postUploadFileAPI = (data: { file: Blob }) => {
return http.request<FileInfo>("post", "/api/file/upload", {
data,
headers: {
"Content-Type": "multipart/form-data"
}
});
};
/**删除文件 */
export const deleteFileAPI = (id: string) => {
return http.request<null>("delete", `/api/file/delete/${id}`);
};

View File

@@ -59,18 +59,14 @@ type GetLoacleListParams = {
code?: string; code?: string;
}; };
type GetLocaleListResult = {
/**语言列表 */
result: LanguageInfo[];
/**总条数 */
total: number;
/**页码 */
page: number;
};
export const getLocaleListAPI = (params: GetLoacleListParams) => { export const getLocaleListAPI = (params: GetLoacleListParams) => {
return http.request<GetLocaleListResult>("get", "/api/i18n/locale/list", { return http.request<QueryListResult<LanguageInfo>>(
"get",
"/api/i18n/locale/list",
{
params params
}); }
);
}; };
/** /**
@@ -111,17 +107,6 @@ type GetI18nListParams = {
/**翻译内容 */ /**翻译内容 */
translation?: string; translation?: string;
}; };
/**
* 获取翻译列表
*/
type GetI18nListResult = {
/**翻译列表 */
result: TranslationInfo[];
/**总条数 */
total: number;
/**页码 */
page: number;
};
/** /**
* 获取翻译列表 * 获取翻译列表
@@ -129,9 +114,13 @@ type GetI18nListResult = {
* @returns * @returns
*/ */
export const getI18nListAPI = (params: GetI18nListParams) => { export const getI18nListAPI = (params: GetI18nListParams) => {
return http.request<GetI18nListResult>("get", "/api/i18n/list", { return http.request<QueryListResult<TranslationInfo>>(
"get",
"/api/i18n/list",
{
params params
}); }
);
}; };
/** /**

View File

@@ -0,0 +1,39 @@
.point {
width: var(--point-width);
height: var(--point-height);
background: var(--point-background);
position: relative;
border-radius: var(--point-border-radius);
}
.point-flicker:after {
background: var(--point-background);
}
.point-flicker:before,
.point-flicker:after {
content: "";
width: 100%;
height: 100%;
top: 0;
left: 0;
position: absolute;
border-radius: var(--point-border-radius);
animation: flicker 1.2s ease-out infinite;
}
@keyframes flicker {
0% {
transform: scale(0.5);
opacity: 1;
}
30% {
opacity: 1;
}
100% {
transform: scale(var(--point-scale));
opacity: 0;
}
}

View File

@@ -0,0 +1,44 @@
import "./index.css";
import { type Component, h, defineComponent } from "vue";
export interface attrsType {
width?: string;
height?: string;
borderRadius?: number | string;
background?: string;
scale?: number | string;
}
/**
* 圆点、方形闪烁动画组件
* @param width 可选 string 宽
* @param height 可选 string 高
* @param borderRadius 可选 number | string 传0为方形、传50%或者不传为圆形
* @param background 可选 string 闪烁颜色
* @param scale 可选 number | string 闪烁范围默认2值越大闪烁范围越大
* @returns Component
*/
export function useRenderFlicker(attrs?: attrsType): Component {
return defineComponent({
name: "ReFlicker",
render() {
return h(
"div",
{
class: "point point-flicker",
style: {
"--point-width": attrs?.width ?? "12px",
"--point-height": attrs?.height ?? "12px",
"--point-background":
attrs?.background ?? "var(--el-color-primary)",
"--point-border-radius": attrs?.borderRadius ?? "50%",
"--point-scale": attrs?.scale ?? "2"
}
},
{
default: () => []
}
);
}
});
}

View File

@@ -1,7 +1,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { useNav } from "@/layout/hooks/useNav"; import { useNav } from "@/layout/hooks/useNav";
import LaySearch from "../lay-search/index.vue"; import LaySearch from "../lay-search/index.vue";
import LayNotice from "../lay-notice/index.vue"; // import LayNotice from "../lay-notice/index.vue";
import LayNavMix from "../lay-sidebar/NavMix.vue"; import LayNavMix from "../lay-sidebar/NavMix.vue";
import { useTranslationLang } from "@/layout/hooks/useTranslationLang"; import { useTranslationLang } from "@/layout/hooks/useTranslationLang";
import LaySidebarFullScreen from "../lay-sidebar/components/SidebarFullScreen.vue"; import LaySidebarFullScreen from "../lay-sidebar/components/SidebarFullScreen.vue";
@@ -86,7 +86,7 @@ const { t, locale, translationCh, translationEn } = useTranslationLang();
<!-- 全屏 --> <!-- 全屏 -->
<LaySidebarFullScreen id="full-screen" /> <LaySidebarFullScreen id="full-screen" />
<!-- 消息通知 --> <!-- 消息通知 -->
<LayNotice id="header-notice" /> <!-- <LayNotice id="header-notice" /> -->
<!-- 退出登录 --> <!-- 退出登录 -->
<el-dropdown trigger="click"> <el-dropdown trigger="click">
<span class="el-dropdown-link navbar-bg-hover select-none"> <span class="el-dropdown-link navbar-bg-hover select-none">

View File

@@ -2,7 +2,7 @@
import { emitter } from "@/utils/mitt"; import { emitter } from "@/utils/mitt";
import { useNav } from "@/layout/hooks/useNav"; import { useNav } from "@/layout/hooks/useNav";
import LaySearch from "../lay-search/index.vue"; import LaySearch from "../lay-search/index.vue";
import LayNotice from "../lay-notice/index.vue"; // import LayNotice from "../lay-notice/index.vue";
import { responsiveStorageNameSpace } from "@/config"; import { responsiveStorageNameSpace } from "@/config";
import { ref, nextTick, computed, onMounted } from "vue"; import { ref, nextTick, computed, onMounted } from "vue";
import { storageLocal, isAllEmpty } from "@pureadmin/utils"; import { storageLocal, isAllEmpty } from "@pureadmin/utils";
@@ -114,7 +114,7 @@ onMounted(() => {
<!-- 全屏 --> <!-- 全屏 -->
<LaySidebarFullScreen id="full-screen" /> <LaySidebarFullScreen id="full-screen" />
<!-- 消息通知 --> <!-- 消息通知 -->
<LayNotice id="header-notice" /> <!-- <LayNotice id="header-notice" /> -->
<!-- 退出登录 --> <!-- 退出登录 -->
<el-dropdown trigger="click"> <el-dropdown trigger="click">
<span class="el-dropdown-link navbar-bg-hover"> <span class="el-dropdown-link navbar-bg-hover">

View File

@@ -3,7 +3,7 @@ import { isAllEmpty } from "@pureadmin/utils";
import { useNav } from "@/layout/hooks/useNav"; import { useNav } from "@/layout/hooks/useNav";
import { transformI18n } from "@/plugins/i18n"; import { transformI18n } from "@/plugins/i18n";
import LaySearch from "../lay-search/index.vue"; import LaySearch from "../lay-search/index.vue";
import LayNotice from "../lay-notice/index.vue"; // import LayNotice from "../lay-notice/index.vue";
import { ref, toRaw, watch, onMounted, nextTick } from "vue"; import { ref, toRaw, watch, onMounted, nextTick } from "vue";
import { useRenderIcon } from "@/components/ReIcon/src/hooks"; import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import { getParentPaths, findRouteByPath } from "@/router/utils"; import { getParentPaths, findRouteByPath } from "@/router/utils";
@@ -135,7 +135,7 @@ watch(
<!-- 全屏 --> <!-- 全屏 -->
<LaySidebarFullScreen id="full-screen" /> <LaySidebarFullScreen id="full-screen" />
<!-- 消息通知 --> <!-- 消息通知 -->
<LayNotice id="header-notice" /> <!-- <LayNotice id="header-notice" /> -->
<!-- 退出登录 --> <!-- 退出登录 -->
<el-dropdown trigger="click"> <el-dropdown trigger="click">
<span class="el-dropdown-link navbar-bg-hover select-none"> <span class="el-dropdown-link navbar-bg-hover select-none">

View File

@@ -44,7 +44,7 @@ export function useNav() {
const userAvatar = computed(() => { const userAvatar = computed(() => {
return isAllEmpty(useUserStoreHook()?.avatar) return isAllEmpty(useUserStoreHook()?.avatar)
? Avatar ? Avatar
: useUserStoreHook()?.avatar; : `/api/${useUserStoreHook()?.avatar}`;
}); });
/** 昵称(如果昵称为空则显示用户名) */ /** 昵称(如果昵称为空则显示用户名) */

View File

@@ -31,9 +31,8 @@ const username = computed(() => {
}); });
/** 用户头像 */ /** 用户头像 */
const userAvatar = computed(() => { const userAvatar = computed(() => {
console.log(useUserStoreHook()?.avatar);
if (useUserStoreHook()?.avatar) { if (useUserStoreHook()?.avatar) {
return useUserStoreHook()?.avatar; return `/api/${useUserStoreHook()?.avatar}`;
} else { } else {
} }
return Avatar; return Avatar;

View File

@@ -124,7 +124,7 @@ const start = async (
if (isValid) { if (isValid) {
const res = await postGetCodeAPI({ const res = await postGetCodeAPI({
username: ruleForm.username, username: ruleForm.username,
title: "注册", title: "Register",
mail: ruleForm.email mail: ruleForm.email
}); });
if (res.code === 200) { if (res.code === 200) {

View File

@@ -81,7 +81,7 @@ const start = async (
if (isValid) { if (isValid) {
const res = await postGetCodeAPI({ const res = await postGetCodeAPI({
username: ruleForm.username, username: ruleForm.username,
title: "重置", title: "Reset",
mail: ruleForm.email mail: ruleForm.email
}); });
if (res.code === 200) { if (res.code === 200) {

View File

@@ -10,7 +10,9 @@ import { useNav } from "@/layout/hooks/useNav";
import { useEventListener } from "@vueuse/core"; import { useEventListener } from "@vueuse/core";
import type { FormInstance } from "element-plus"; import type { FormInstance } from "element-plus";
import { $t, transformI18n } from "@/plugins/i18n"; import { $t, transformI18n } from "@/plugins/i18n";
import { operates } from "./utils/enums"; import { getConfig } from "@/config";
// import { operates } from "./utils/enums";
import { useLayout } from "@/layout/hooks/useLayout"; import { useLayout } from "@/layout/hooks/useLayout";
import LoginPhone from "./components/LoginPhone.vue"; import LoginPhone from "./components/LoginPhone.vue";
import LoginRegist from "./components/LoginRegist.vue"; import LoginRegist from "./components/LoginRegist.vue";
@@ -34,6 +36,7 @@ import Info from "@iconify-icons/ri/information-line";
import { GetCaptchaAPI } from "@/api/login"; import { GetCaptchaAPI } from "@/api/login";
import { getUserInfoAPI } from "@/api/login"; import { getUserInfoAPI } from "@/api/login";
import { setUserInfo } from "@/utils/auth"; import { setUserInfo } from "@/utils/auth";
const Period = getConfig("Period");
defineOptions({ defineOptions({
name: "Login" name: "Login"
@@ -80,7 +83,7 @@ const onLogin = async (formEl: FormInstance | undefined) => {
code: ruleForm.verifyCode code: ruleForm.verifyCode
}) })
.then(async res => { .then(async res => {
if (res.code === 200) { if (res.success) {
useUserStoreHook().SET_ACCESSTOKEN(res.data.accessToken); useUserStoreHook().SET_ACCESSTOKEN(res.data.accessToken);
// 获取后端路由 // 获取后端路由
return initRouter().then(async () => { return initRouter().then(async () => {
@@ -95,6 +98,7 @@ const onLogin = async (formEl: FormInstance | undefined) => {
message(t("login:LoginSuccess"), { type: "success" }); message(t("login:LoginSuccess"), { type: "success" });
}) })
.finally(() => (disabled.value = false)); .finally(() => (disabled.value = false));
window.location.reload();
}); });
} else { } else {
message(t("login:LoginFail"), { type: "error" }); message(t("login:LoginFail"), { type: "error" });
@@ -347,12 +351,8 @@ onMounted(async () => {
<div <div
class="w-full flex-c absolute bottom-3 text-sm text-[rgba(0,0,0,0.6)] dark:text-[rgba(220,220,242,0.8)]" class="w-full flex-c absolute bottom-3 text-sm text-[rgba(0,0,0,0.6)] dark:text-[rgba(220,220,242,0.8)]"
> >
Copyright © 2020-present Copyright © {{ Period }}
<a <a class="hover:text-primary" href="#" target="_blank">
class="hover:text-primary"
href="https://github.com/pure-admin"
target="_blank"
>
&nbsp;{{ title }} &nbsp;{{ title }}
</a> </a>
</div> </div>

View File

@@ -33,7 +33,8 @@ export const useLogin = (tableRef: Ref) => {
total: 0, total: 0,
pageSize: 10, pageSize: 10,
currentPage: 1, currentPage: 1,
background: true background: true,
pageSizes: [10, 20, 30, 40, 50]
}); });
const columns: TableColumnList = [ const columns: TableColumnList = [
{ {

View File

@@ -24,7 +24,8 @@ export function useOperation(tableRef: Ref) {
total: 0, total: 0,
pageSize: 10, pageSize: 10,
currentPage: 1, currentPage: 1,
background: true background: true,
pageSizes: [10, 20, 30, 40, 50]
}); });
const getOperationType = (type: number) => { const getOperationType = (type: number) => {

View File

@@ -46,7 +46,8 @@ export const useConfig = (tableRef: Ref) => {
total: 0, total: 0,
pageSize: 10, pageSize: 10,
currentPage: 1, currentPage: 1,
background: true background: true,
pageSizes: [10, 20, 30, 40, 50]
}); });
/** /**

View File

@@ -128,7 +128,7 @@ onBeforeRouteUpdate((to, from, next) => {
type="primary" type="primary"
:size="size" :size="size"
:icon="useRenderIcon(AddFill)" :icon="useRenderIcon(AddFill)"
@click="openDialog('新增', { parentId: row.id } as any)" @click="openDialog('新增', { parent_id: row.id } as any)"
> >
{{ t("buttons:Add") }} {{ t("buttons:Add") }}
</el-button> </el-button>

View File

@@ -141,7 +141,7 @@ export const useDepartment = () => {
title: `${title}部门`, title: `${title}部门`,
props: { props: {
formInline: { formInline: {
higherDeptOptions: formatHigherOptions(cloneDeep(dataList.value)), higherOptions: formatHigherOptions(cloneDeep(dataList.value)),
id: row?.id ?? "", id: row?.id ?? "",
parent_id: row?.parent_id ?? "", parent_id: row?.parent_id ?? "",
name: row?.name ?? "", name: row?.name ?? "",

View File

@@ -45,7 +45,8 @@ export const useI18n = (tableRef: Ref) => {
total: 0, total: 0,
pageSize: 10, pageSize: 10,
currentPage: 1, currentPage: 1,
background: true background: true,
pageSizes: [10, 20, 30, 40, 50]
}); });
/** /**
* 表格列设置 * 表格列设置

View File

@@ -68,7 +68,8 @@ export const useRole = (treeRef: Ref) => {
total: 0, total: 0,
pageSize: 10, pageSize: 10,
currentPage: 1, currentPage: 1,
background: true background: true,
pageSizes: [10, 20, 30, 40, 50]
}); });
const curRow = ref(); const curRow = ref();
/** /**

View File

@@ -81,7 +81,8 @@ export const useUser = (tableRef: Ref, treeRef: Ref) => {
total: 0, total: 0,
pageSize: 10, pageSize: 10,
currentPage: 1, currentPage: 1,
background: true background: true,
pageSizes: [10, 20, 30, 40, 50]
}); });
/** /**
* 表格列配置 * 表格列配置
@@ -104,8 +105,8 @@ export const useUser = (tableRef: Ref, treeRef: Ref) => {
<el-image <el-image
fit="cover" fit="cover"
preview-teleported={true} preview-teleported={true}
src={row.avatar || Avatar} src={`/api/${row.avatar}` || Avatar}
preview-src-list={Array.of(row.avatar || Avatar)} preview-src-list={Array.of(`/api/${row.avatar}` || Avatar)}
class="w-[24px] h-[24px] rounded-full align-middle" class="w-[24px] h-[24px] rounded-full align-middle"
/> />
) )