refactor: ♻️ 字典调整按需加载,api、store和枚举文件命名优化
This commit is contained in:
@@ -15,18 +15,18 @@
|
||||
<script setup lang="ts">
|
||||
import { useAppStore, useSettingsStore } from "@/store";
|
||||
import defaultSettings from "@/settings";
|
||||
import { ThemeEnum } from "@/enums/ThemeEnum";
|
||||
import { SizeEnum } from "@/enums/SizeEnum";
|
||||
import { ThemeMode } from "@/enums/settings/theme.enum";
|
||||
import { ComponentSize } from "@/enums/settings/layout.enum";
|
||||
|
||||
const appStore = useAppStore();
|
||||
const settingsStore = useSettingsStore();
|
||||
|
||||
const locale = computed(() => appStore.locale);
|
||||
const size = computed(() => appStore.size as SizeEnum);
|
||||
const size = computed(() => appStore.size as ComponentSize);
|
||||
const watermarkEnabled = computed(() => settingsStore.watermarkEnabled);
|
||||
|
||||
// 明亮/暗黑主题水印字体颜色适配
|
||||
const fontColor = computed(() => {
|
||||
return settingsStore.theme === ThemeEnum.DARK ? "rgba(255, 255, 255, .15)" : "rgba(0, 0, 0, .15)";
|
||||
return settingsStore.theme === ThemeMode.DARK ? "rgba(255, 255, 255, .15)" : "rgba(0, 0, 0, .15)";
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -3,7 +3,7 @@ import request from "@/utils/request";
|
||||
const CONFIG_BASE_URL = "/api/v1/config";
|
||||
|
||||
const ConfigAPI = {
|
||||
/** 获取系统配置分页数据 */
|
||||
/** 系统配置分页 */
|
||||
getPage(queryParams?: ConfigPageQuery) {
|
||||
return request<any, PageResult<ConfigPageVO[]>>({
|
||||
url: `${CONFIG_BASE_URL}/page`,
|
||||
@@ -11,12 +11,8 @@ const ConfigAPI = {
|
||||
params: queryParams,
|
||||
});
|
||||
},
|
||||
/**
|
||||
* 获取系统配置表单数据
|
||||
*
|
||||
* @param id ConfigID
|
||||
* @returns Config表单数据
|
||||
*/
|
||||
|
||||
/** 系统配置表单数据 */
|
||||
getFormData(id: number) {
|
||||
return request<any, ConfigForm>({
|
||||
url: `${CONFIG_BASE_URL}/${id}/form`,
|
||||
@@ -24,8 +20,8 @@ const ConfigAPI = {
|
||||
});
|
||||
},
|
||||
|
||||
/** 添加系统配置*/
|
||||
add(data: ConfigForm) {
|
||||
/** 新增系统配置 */
|
||||
create(data: ConfigForm) {
|
||||
return request({
|
||||
url: `${CONFIG_BASE_URL}`,
|
||||
method: "post",
|
||||
@@ -33,12 +29,7 @@ const ConfigAPI = {
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 更新系统配置
|
||||
*
|
||||
* @param id ConfigID
|
||||
* @param data Config表单数据
|
||||
*/
|
||||
/** 更新系统配置 */
|
||||
update(id: number, data: ConfigForm) {
|
||||
return request({
|
||||
url: `${CONFIG_BASE_URL}/${id}`,
|
||||
@@ -44,7 +44,7 @@ const DeptAPI = {
|
||||
* @param data 部门表单数据
|
||||
* @returns 请求结果
|
||||
*/
|
||||
add(data: DeptForm) {
|
||||
create(data: DeptForm) {
|
||||
return request({
|
||||
url: `${DEPT_BASE_URL}`,
|
||||
method: "post",
|
||||
@@ -1,162 +0,0 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
const DICT_DATA_BASE_URL = "/api/v1/dict-data";
|
||||
|
||||
const DictDataAPI = {
|
||||
/**
|
||||
* 获取字典分页列表
|
||||
*
|
||||
* @param queryParams 查询参数
|
||||
* @returns 字典分页结果
|
||||
*/
|
||||
getPage(queryParams: DictDataPageQuery) {
|
||||
return request<any, PageResult<DictDataPageVO[]>>({
|
||||
url: `${DICT_DATA_BASE_URL}/page`,
|
||||
method: "get",
|
||||
params: queryParams,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取字典数据表单
|
||||
*
|
||||
* @param id 字典ID
|
||||
* @returns 字典数据表单
|
||||
*/
|
||||
getFormData(id: number) {
|
||||
return request<any, ResponseData<DictDataForm>>({
|
||||
url: `${DICT_DATA_BASE_URL}/${id}/form`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 新增字典数据
|
||||
*
|
||||
* @param data 字典数据
|
||||
*/
|
||||
add(data: DictDataForm) {
|
||||
return request({
|
||||
url: `${DICT_DATA_BASE_URL}`,
|
||||
method: "post",
|
||||
data: data,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 修改字典数据
|
||||
*
|
||||
* @param id 字典ID
|
||||
* @param data 字典数据
|
||||
*/
|
||||
update(id: number, data: DictDataForm) {
|
||||
return request({
|
||||
url: `${DICT_DATA_BASE_URL}/${id}`,
|
||||
method: "put",
|
||||
data: data,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除字典
|
||||
*
|
||||
* @param ids 字典ID,多个以英文逗号(,)分隔
|
||||
*/
|
||||
deleteByIds(ids: string) {
|
||||
return request({
|
||||
url: `${DICT_DATA_BASE_URL}/${ids}`,
|
||||
method: "delete",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取字典的数据项
|
||||
*
|
||||
* @param dictCode 字典编码
|
||||
* @returns 字典数据项
|
||||
*/
|
||||
getOptions(dictCode: string) {
|
||||
return request<any, OptionType[]>({
|
||||
url: `${DICT_DATA_BASE_URL}/${dictCode}/options`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export default DictDataAPI;
|
||||
|
||||
/**
|
||||
* 字典查询参数
|
||||
*/
|
||||
export interface DictDataPageQuery extends PageQuery {
|
||||
/** 关键字(字典数据值/标签) */
|
||||
keywords?: string;
|
||||
|
||||
/** 字典编码 */
|
||||
dictCode?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字典分页对象
|
||||
*/
|
||||
export interface DictDataPageVO {
|
||||
/**
|
||||
* 字典ID
|
||||
*/
|
||||
id: number;
|
||||
/**
|
||||
* 字典编码
|
||||
*/
|
||||
dictCode: string;
|
||||
/**
|
||||
* 字典数据值
|
||||
*/
|
||||
value: string;
|
||||
/**
|
||||
* 字典数据标签
|
||||
*/
|
||||
label: string;
|
||||
/**
|
||||
* 状态(1:启用,0:禁用)
|
||||
*/
|
||||
status: number;
|
||||
/**
|
||||
* 字典排序
|
||||
*/
|
||||
sort?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字典
|
||||
*/
|
||||
export interface DictDataForm {
|
||||
/**
|
||||
* 字典ID
|
||||
*/
|
||||
id?: number;
|
||||
/**
|
||||
* 字典编码
|
||||
*/
|
||||
dictCode?: string;
|
||||
/**
|
||||
* 字典数据值
|
||||
*/
|
||||
value?: string;
|
||||
/**
|
||||
* 字典数据标签
|
||||
*/
|
||||
label?: string;
|
||||
/**
|
||||
* 状态(1:启用,0:禁用)
|
||||
*/
|
||||
status?: number;
|
||||
/**
|
||||
* 字典排序
|
||||
*/
|
||||
sort?: number;
|
||||
|
||||
/**
|
||||
* 标签类型
|
||||
*/
|
||||
tagType?: "success" | "warning" | "info" | "primary" | "danger" | undefined;
|
||||
}
|
||||
302
src/api/system/dict.api.ts
Normal file
302
src/api/system/dict.api.ts
Normal file
@@ -0,0 +1,302 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
const DICT_BASE_URL = "/api/v1/dicts";
|
||||
|
||||
const DictAPI = {
|
||||
//---------------------------------------------------
|
||||
// 字典相关接口
|
||||
//---------------------------------------------------
|
||||
|
||||
/**
|
||||
* 字典分页列表
|
||||
*
|
||||
* @param queryParams 查询参数
|
||||
* @returns 字典分页结果
|
||||
*/
|
||||
getPage(queryParams: DictPageQuery) {
|
||||
return request<any, PageResult<DictPageVO[]>>({
|
||||
url: `${DICT_BASE_URL}/page`,
|
||||
method: "get",
|
||||
params: queryParams,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 字典表单数据
|
||||
*
|
||||
* @param id 字典ID
|
||||
* @returns 字典表单数据
|
||||
*/
|
||||
getFormData(id: number) {
|
||||
return request<any, ResponseData<DictForm>>({
|
||||
url: `${DICT_BASE_URL}/${id}/form`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 新增字典
|
||||
*
|
||||
* @param data 字典表单数据
|
||||
*/
|
||||
create(data: DictForm) {
|
||||
return request({
|
||||
url: `${DICT_BASE_URL}`,
|
||||
method: "post",
|
||||
data: data,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 修改字典
|
||||
*
|
||||
* @param id 字典ID
|
||||
* @param data 字典表单数据
|
||||
*/
|
||||
update(id: number, data: DictForm) {
|
||||
return request({
|
||||
url: `${DICT_BASE_URL}/${id}`,
|
||||
method: "put",
|
||||
data: data,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除字典
|
||||
*
|
||||
* @param ids 字典ID,多个以英文逗号(,)分隔
|
||||
*/
|
||||
deleteByIds(ids: string) {
|
||||
return request({
|
||||
url: `${DICT_BASE_URL}/${ids}`,
|
||||
method: "delete",
|
||||
});
|
||||
},
|
||||
|
||||
//---------------------------------------------------
|
||||
// 字典项相关接口
|
||||
//---------------------------------------------------
|
||||
/**
|
||||
* 获取字典分页列表
|
||||
*
|
||||
* @param queryParams 查询参数
|
||||
* @returns 字典分页结果
|
||||
*/
|
||||
getDictItemPage(dictCode: string, queryParams: DictItemPageQuery) {
|
||||
return request<any, PageResult<DictItemPageVO[]>>({
|
||||
url: `${DICT_BASE_URL}/${dictCode}/items/page`,
|
||||
method: "get",
|
||||
params: queryParams,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取字典项列表
|
||||
*/
|
||||
getDictItems(dictCode: string) {
|
||||
return request<any, DictItemOption[]>({
|
||||
url: `${DICT_BASE_URL}/${dictCode}/items`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 新增字典项
|
||||
*/
|
||||
createDictItem(dictCode: string, data: DictItemForm) {
|
||||
return request({
|
||||
url: `${DICT_BASE_URL}/${dictCode}/items`,
|
||||
method: "post",
|
||||
data: data,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取字典项表单数据
|
||||
*
|
||||
* @param id 字典项ID
|
||||
* @returns 字典项表单数据
|
||||
*/
|
||||
getDictItemFormData(dictCode: string, id: number) {
|
||||
return request<any, ResponseData<DictItemForm>>({
|
||||
url: `${DICT_BASE_URL}/${dictCode}/items/${id}/form`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 修改字典项
|
||||
*/
|
||||
updateDictItem(dictCode: string, id: number, data: DictItemForm) {
|
||||
return request({
|
||||
url: `${DICT_BASE_URL}/${dictCode}/items/${id}`,
|
||||
method: "put",
|
||||
data: data,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除字典项
|
||||
*/
|
||||
deleteDictItems(dictCode: string, ids: string) {
|
||||
return request({
|
||||
url: `${DICT_BASE_URL}/${dictCode}/items/${ids}`,
|
||||
method: "delete",
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export default DictAPI;
|
||||
|
||||
/**
|
||||
* 字典查询参数
|
||||
*/
|
||||
export interface DictPageQuery extends PageQuery {
|
||||
/**
|
||||
* 关键字(字典名称/编码)
|
||||
*/
|
||||
keywords?: string;
|
||||
|
||||
/**
|
||||
* 字典状态(1:启用,0:禁用)
|
||||
*/
|
||||
status?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字典分页对象
|
||||
*/
|
||||
export interface DictPageVO {
|
||||
/**
|
||||
* 字典ID
|
||||
*/
|
||||
id: number;
|
||||
/**
|
||||
* 字典名称
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* 字典编码
|
||||
*/
|
||||
dictCode: string;
|
||||
/**
|
||||
* 字典状态(1:启用,0:禁用)
|
||||
*/
|
||||
status: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字典
|
||||
*/
|
||||
export interface DictForm {
|
||||
/**
|
||||
* 字典ID
|
||||
*/
|
||||
id?: number;
|
||||
/**
|
||||
* 字典名称
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* 字典编码
|
||||
*/
|
||||
dictCode?: string;
|
||||
/**
|
||||
* 字典状态(1-启用,0-禁用)
|
||||
*/
|
||||
status?: number;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
remark?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字典查询参数
|
||||
*/
|
||||
export interface DictItemPageQuery extends PageQuery {
|
||||
/** 关键字(字典数据值/标签) */
|
||||
keywords?: string;
|
||||
|
||||
/** 字典编码 */
|
||||
dictCode?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字典分页对象
|
||||
*/
|
||||
export interface DictItemPageVO {
|
||||
/**
|
||||
* 字典ID
|
||||
*/
|
||||
id: number;
|
||||
/**
|
||||
* 字典编码
|
||||
*/
|
||||
dictCode: string;
|
||||
/**
|
||||
* 字典数据值
|
||||
*/
|
||||
value: string;
|
||||
/**
|
||||
* 字典数据标签
|
||||
*/
|
||||
label: string;
|
||||
/**
|
||||
* 状态(1:启用,0:禁用)
|
||||
*/
|
||||
status: number;
|
||||
/**
|
||||
* 字典排序
|
||||
*/
|
||||
sort?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字典
|
||||
*/
|
||||
export interface DictItemForm {
|
||||
/**
|
||||
* 字典ID
|
||||
*/
|
||||
id?: number;
|
||||
/**
|
||||
* 字典编码
|
||||
*/
|
||||
dictCode?: string;
|
||||
/**
|
||||
* 字典数据值
|
||||
*/
|
||||
value?: string;
|
||||
/**
|
||||
* 字典数据标签
|
||||
*/
|
||||
label?: string;
|
||||
/**
|
||||
* 状态(1:启用,0:禁用)
|
||||
*/
|
||||
status?: number;
|
||||
/**
|
||||
* 字典排序
|
||||
*/
|
||||
sort?: number;
|
||||
|
||||
/**
|
||||
* 标签类型
|
||||
*/
|
||||
tagType?: "success" | "warning" | "info" | "primary" | "danger" | undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字典项下拉选项
|
||||
*/
|
||||
export interface DictItemOption {
|
||||
/** 字典数据值 */
|
||||
value: string;
|
||||
|
||||
/** 字典数据标签 */
|
||||
label: string;
|
||||
|
||||
/** 标签类型 */
|
||||
tagType: string;
|
||||
}
|
||||
@@ -1,180 +0,0 @@
|
||||
import request from "@/utils/request";
|
||||
|
||||
const DICT_BASE_URL = "/api/v1/dict";
|
||||
|
||||
const DictAPI = {
|
||||
/**
|
||||
* 获取字典分页列表
|
||||
*
|
||||
* @param queryParams 查询参数
|
||||
* @returns 字典分页结果
|
||||
*/
|
||||
getPage(queryParams: DictPageQuery) {
|
||||
return request<any, PageResult<DictPageVO[]>>({
|
||||
url: `${DICT_BASE_URL}/page`,
|
||||
method: "get",
|
||||
params: queryParams,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取字典表单数据
|
||||
*
|
||||
* @param id 字典ID
|
||||
* @returns 字典表单数据
|
||||
*/
|
||||
getFormData(id: number) {
|
||||
return request<any, ResponseData<DictForm>>({
|
||||
url: `${DICT_BASE_URL}/${id}/form`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 新增字典
|
||||
*
|
||||
* @param data 字典表单数据
|
||||
*/
|
||||
add(data: DictForm) {
|
||||
return request({
|
||||
url: `${DICT_BASE_URL}`,
|
||||
method: "post",
|
||||
data: data,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 修改字典
|
||||
*
|
||||
* @param id 字典ID
|
||||
* @param data 字典表单数据
|
||||
*/
|
||||
update(id: number, data: DictForm) {
|
||||
return request({
|
||||
url: `${DICT_BASE_URL}/${id}`,
|
||||
method: "put",
|
||||
data: data,
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除字典
|
||||
*
|
||||
* @param ids 字典ID,多个以英文逗号(,)分隔
|
||||
*/
|
||||
deleteByIds(ids: string) {
|
||||
return request({
|
||||
url: `${DICT_BASE_URL}/${ids}`,
|
||||
method: "delete",
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取字典列表
|
||||
*
|
||||
* @returns 字典列表
|
||||
*/
|
||||
getList() {
|
||||
return request<any, DictVO[]>({
|
||||
url: `${DICT_BASE_URL}/list`,
|
||||
method: "get",
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export default DictAPI;
|
||||
|
||||
/**
|
||||
* 字典查询参数
|
||||
*/
|
||||
export interface DictPageQuery extends PageQuery {
|
||||
/**
|
||||
* 关键字(字典名称/编码)
|
||||
*/
|
||||
keywords?: string;
|
||||
|
||||
/**
|
||||
* 字典状态(1:启用,0:禁用)
|
||||
*/
|
||||
status?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字典分页对象
|
||||
*/
|
||||
export interface DictPageVO {
|
||||
/**
|
||||
* 字典ID
|
||||
*/
|
||||
id: number;
|
||||
/**
|
||||
* 字典名称
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* 字典编码
|
||||
*/
|
||||
dictCode: string;
|
||||
/**
|
||||
* 字典状态(1:启用,0:禁用)
|
||||
*/
|
||||
status: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字典
|
||||
*/
|
||||
export interface DictForm {
|
||||
/**
|
||||
* 字典ID
|
||||
*/
|
||||
id?: number;
|
||||
/**
|
||||
* 字典名称
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* 字典编码
|
||||
*/
|
||||
dictCode?: string;
|
||||
/**
|
||||
* 字典状态(1-启用,0-禁用)
|
||||
*/
|
||||
status?: number;
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
remark?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字典数据项分页VO
|
||||
*
|
||||
* @description 字典数据分页对象
|
||||
*/
|
||||
export interface DictVO {
|
||||
/** 字典名称 */
|
||||
name: string;
|
||||
|
||||
/** 字典编码 */
|
||||
dictCode: string;
|
||||
|
||||
/** 字典数据集合 */
|
||||
dictDataList: DictData[];
|
||||
}
|
||||
|
||||
/**
|
||||
* 字典数据
|
||||
*
|
||||
* @description 字典数据
|
||||
*/
|
||||
export interface DictData {
|
||||
/** 字典数据值 */
|
||||
value: string;
|
||||
|
||||
/** 字典数据标签 */
|
||||
label: string;
|
||||
|
||||
/** 标签类型 */
|
||||
tagType: string;
|
||||
}
|
||||
@@ -62,7 +62,7 @@ const MenuAPI = {
|
||||
* @param data 菜单表单数据
|
||||
* @returns 请求结果
|
||||
*/
|
||||
add(data: MenuForm) {
|
||||
create(data: MenuForm) {
|
||||
return request({
|
||||
url: `${MENU_BASE_URL}`,
|
||||
method: "post",
|
||||
@@ -101,7 +101,7 @@ const MenuAPI = {
|
||||
|
||||
export default MenuAPI;
|
||||
|
||||
import type { MenuTypeEnum } from "@/enums/MenuTypeEnum";
|
||||
import type { MenuTypeEnum } from "@/enums/system/menu.enum";
|
||||
|
||||
/** 菜单查询参数 */
|
||||
export interface MenuQuery {
|
||||
@@ -31,7 +31,7 @@ const NoticeAPI = {
|
||||
* @param data Notice表单数据
|
||||
* @returns
|
||||
*/
|
||||
add(data: NoticeForm) {
|
||||
create(data: NoticeForm) {
|
||||
return request({
|
||||
url: `${NOTICE_BASE_URL}`,
|
||||
method: "post",
|
||||
@@ -60,7 +60,7 @@ const RoleAPI = {
|
||||
},
|
||||
|
||||
/** 添加角色 */
|
||||
add(data: RoleForm) {
|
||||
create(data: RoleForm) {
|
||||
return request({
|
||||
url: `${ROLE_BASE_URL}`,
|
||||
method: "post",
|
||||
@@ -46,7 +46,7 @@ const UserAPI = {
|
||||
*
|
||||
* @param data 用户表单数据
|
||||
*/
|
||||
add(data: UserForm) {
|
||||
create(data: UserForm) {
|
||||
return request({
|
||||
url: `${USER_BASE_URL}`,
|
||||
method: "post",
|
||||
@@ -6,47 +6,55 @@
|
||||
<span>{{ label }}</span>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useDictStore } from "@/store";
|
||||
const dictStore = useDictStore();
|
||||
|
||||
const props = defineProps({
|
||||
code: String,
|
||||
modelValue: [String, Number],
|
||||
code: String, // 字典编码
|
||||
modelValue: [String, Number], // 字典项的值
|
||||
size: {
|
||||
type: String,
|
||||
default: "default",
|
||||
default: "default", // 标签大小
|
||||
},
|
||||
});
|
||||
|
||||
const label = ref("");
|
||||
const tagType = ref<"success" | "warning" | "info" | "primary" | "danger" | undefined>();
|
||||
|
||||
const tagSize = ref(props.size as "default" | "large" | "small");
|
||||
const tagType = ref<"success" | "warning" | "info" | "primary" | "danger" | undefined>(); // 标签类型
|
||||
const tagSize = ref<"default" | "large" | "small">(props.size as "default" | "large" | "small"); // 标签大小
|
||||
|
||||
const dictStore = useDictStore();
|
||||
/**
|
||||
* 根据字典项的值获取对应的 label 和 tagType
|
||||
* @param dictCode 字典编码
|
||||
* @param value 字典项的值
|
||||
* @returns 包含 label 和 tagType 的对象
|
||||
*/
|
||||
const getLabelAndTagByValue = async (dictCode: string, value: any) => {
|
||||
// 先从本地缓存中获取字典数据
|
||||
const dictData = dictStore.getDictionary(dictCode);
|
||||
|
||||
// 按需加载字典数据
|
||||
await dictStore.loadDictItems(dictCode);
|
||||
// 从缓存中获取字典数据
|
||||
const dictItems = dictStore.getDictItems(dictCode);
|
||||
// 查找对应的字典项
|
||||
const dictEntry = dictData.find((item: any) => item.value == value);
|
||||
const dictItem = dictItems.find((item) => item.value == value);
|
||||
return {
|
||||
label: dictEntry ? dictEntry.label : "",
|
||||
tag: dictEntry ? dictEntry.tagType : undefined,
|
||||
label: dictItem?.label || "",
|
||||
tagType: dictItem?.tagType,
|
||||
};
|
||||
};
|
||||
|
||||
// 监听 props 的变化,获取并更新 label 和 tag
|
||||
const fetchLabelAndTag = async () => {
|
||||
const result = await getLabelAndTagByValue(props.code as string, props.modelValue);
|
||||
label.value = result.label;
|
||||
tagType.value = result.tag as "success" | "warning" | "info" | "primary" | "danger" | undefined;
|
||||
/**
|
||||
* 更新 label 和 tagType
|
||||
*/
|
||||
const updateLabelAndTag = async () => {
|
||||
console.log("updateLabelAndTag", props.code, props.modelValue);
|
||||
if (!props.code || props.modelValue === undefined) return;
|
||||
const { label: newLabel, tagType: newTagType } = await getLabelAndTagByValue(
|
||||
props.code,
|
||||
props.modelValue
|
||||
);
|
||||
label.value = newLabel;
|
||||
tagType.value = newTagType as typeof tagType.value;
|
||||
};
|
||||
|
||||
// 首次挂载时获取字典数据
|
||||
onMounted(fetchLabelAndTag);
|
||||
watch([() => props.code, () => props.modelValue], updateLabelAndTag);
|
||||
|
||||
// 当 modelValue 发生变化时重新获取
|
||||
watch(() => props.modelValue, fetchLabelAndTag);
|
||||
onMounted(updateLabelAndTag);
|
||||
</script>
|
||||
|
||||
@@ -100,41 +100,34 @@ const selectedValue = ref<any>(
|
||||
: undefined
|
||||
);
|
||||
|
||||
// 监听 modelValue 变化
|
||||
// 监听 modelValue 和 options 的变化
|
||||
watch(
|
||||
() => props.modelValue,
|
||||
(newValue) => {
|
||||
if (props.type === "checkbox") {
|
||||
selectedValue.value = Array.isArray(newValue) ? newValue : [];
|
||||
[() => props.modelValue, () => options.value],
|
||||
([newValue, newOptions]) => {
|
||||
if (newOptions.length > 0 && newValue !== undefined) {
|
||||
if (props.type === "checkbox") {
|
||||
selectedValue.value = Array.isArray(newValue) ? newValue : [];
|
||||
} else {
|
||||
const matchedOption = newOptions.find(
|
||||
(option) => String(option.value) === String(newValue)
|
||||
);
|
||||
selectedValue.value = matchedOption?.value;
|
||||
}
|
||||
} else {
|
||||
selectedValue.value = newValue?.toString() || "";
|
||||
selectedValue.value = undefined;
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
// 监听 options 变化并重新匹配 selectedValue
|
||||
watch(
|
||||
() => options.value,
|
||||
(newOptions) => {
|
||||
// options 加载后,确保 selectedValue 可以正确匹配到 options
|
||||
if (newOptions.length > 0 && selectedValue.value !== undefined) {
|
||||
const matchedOption = newOptions.find((option) => option.value === selectedValue.value);
|
||||
if (!matchedOption && props.type !== "checkbox") {
|
||||
// 如果找不到匹配项,清空选中
|
||||
selectedValue.value = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// 监听 selectedValue 的变化并触发 update:modelValue
|
||||
function handleChange(val: any) {
|
||||
emit("update:modelValue", val);
|
||||
}
|
||||
|
||||
// 获取字典数据
|
||||
onMounted(() => {
|
||||
options.value = dictStore.getDictionary(props.code);
|
||||
onMounted(async () => {
|
||||
await dictStore.loadDictItems(props.code);
|
||||
options.value = dictStore.getDictItems(props.code);
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useSettingsStore } from "@/store";
|
||||
import { ThemeEnum, SidebarColorEnum } from "@/enums/ThemeEnum";
|
||||
import { LayoutEnum } from "@/enums/LayoutEnum";
|
||||
import { ThemeMode, SidebarColor } from "@/enums/settings/theme.enum";
|
||||
import { LayoutMode } from "@/enums/settings/layout.enum";
|
||||
|
||||
defineProps({
|
||||
isActive: { type: Boolean, required: true },
|
||||
@@ -20,14 +20,14 @@ const layout = computed(() => settingsStore.layout);
|
||||
|
||||
const hamburgerClass = computed(() => {
|
||||
// 如果暗黑主题
|
||||
if (settingsStore.theme === ThemeEnum.DARK) {
|
||||
if (settingsStore.theme === ThemeMode.DARK) {
|
||||
return "hamburger--white";
|
||||
}
|
||||
|
||||
// 如果是混合布局 && 侧边栏配色方案是经典蓝
|
||||
if (
|
||||
layout.value === LayoutEnum.MIX &&
|
||||
settingsStore.sidebarColorScheme === SidebarColorEnum.CLASSIC_BLUE
|
||||
layout.value === LayoutMode.MIX &&
|
||||
settingsStore.sidebarColorScheme === SidebarColor.CLASSIC_BLUE
|
||||
) {
|
||||
return "hamburger--white";
|
||||
}
|
||||
|
||||
@@ -17,8 +17,8 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useAppStore } from "@/store/modules/app";
|
||||
import { LanguageEnum } from "@/enums/LanguageEnum";
|
||||
import { useAppStore } from "@/store/modules/app.store";
|
||||
import { LanguageEnum } from "@/enums/settings/locale.enum";
|
||||
|
||||
defineProps({
|
||||
size: {
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import NoticeAPI, { NoticePageVO, NoticeDetailVO } from "@/api/system/notice";
|
||||
import NoticeAPI, { NoticePageVO, NoticeDetailVO } from "@/api/system/notice.api";
|
||||
import router from "@/router";
|
||||
|
||||
const noticeList = ref<NoticePageVO[]>([]);
|
||||
|
||||
@@ -22,15 +22,15 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { SizeEnum } from "@/enums/SizeEnum";
|
||||
import { useAppStore } from "@/store/modules/app";
|
||||
import { ComponentSize } from "@/enums/settings/layout.enum";
|
||||
import { useAppStore } from "@/store/modules/app.store";
|
||||
|
||||
const { t } = useI18n();
|
||||
const sizeOptions = computed(() => {
|
||||
return [
|
||||
{ label: t("sizeSelect.default"), value: SizeEnum.DEFAULT },
|
||||
{ label: t("sizeSelect.large"), value: SizeEnum.LARGE },
|
||||
{ label: t("sizeSelect.small"), value: SizeEnum.SMALL },
|
||||
{ label: t("sizeSelect.default"), value: ComponentSize.DEFAULT },
|
||||
{ label: t("sizeSelect.large"), value: ComponentSize.LARGE },
|
||||
{ label: t("sizeSelect.small"), value: ComponentSize.SMALL },
|
||||
];
|
||||
});
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ import {
|
||||
UploadRequestOptions,
|
||||
} from "element-plus";
|
||||
|
||||
import FileAPI, { FileInfo } from "@/api/file";
|
||||
import FileAPI, { FileInfo } from "@/api/file.api";
|
||||
|
||||
const props = defineProps({
|
||||
/**
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { UploadRawFile, UploadRequestOptions, UploadUserFile } from "element-plus";
|
||||
import FileAPI, { FileInfo } from "@/api/file";
|
||||
import FileAPI, { FileInfo } from "@/api/file.api";
|
||||
|
||||
const props = defineProps({
|
||||
/**
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { UploadRawFile, UploadRequestOptions } from "element-plus";
|
||||
import FileAPI, { FileInfo } from "@/api/file";
|
||||
import FileAPI, { FileInfo } from "@/api/file.api";
|
||||
|
||||
const props = defineProps({
|
||||
/**
|
||||
|
||||
@@ -34,7 +34,7 @@ import { Toolbar, Editor } from "@wangeditor-next/editor-for-vue";
|
||||
import { IToolbarConfig, IEditorConfig } from "@wangeditor-next/editor";
|
||||
|
||||
// 文件上传 API
|
||||
import FileAPI from "@/api/file";
|
||||
import FileAPI from "@/api/file.api";
|
||||
|
||||
// 上传图片回调函数类型
|
||||
type InsertFnType = (_url: string, _alt: string, _href: string) => void;
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
/**
|
||||
* 菜单布局枚举
|
||||
*/
|
||||
export const enum LayoutEnum {
|
||||
/**
|
||||
* 左侧菜单布局
|
||||
*/
|
||||
LEFT = "left",
|
||||
/**
|
||||
* 顶部菜单布局
|
||||
*/
|
||||
TOP = "top",
|
||||
|
||||
/**
|
||||
* 混合菜单布局
|
||||
*/
|
||||
MIX = "mix",
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
/**
|
||||
* 侧边栏状态枚举
|
||||
*/
|
||||
export const enum SidebarStatusEnum {
|
||||
/**
|
||||
* 展开
|
||||
*/
|
||||
OPENED = "opened",
|
||||
|
||||
/**
|
||||
* 关闭
|
||||
*/
|
||||
CLOSED = "closed",
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
/**
|
||||
* 布局大小枚举
|
||||
*/
|
||||
export const enum SizeEnum {
|
||||
/**
|
||||
* 默认
|
||||
*/
|
||||
DEFAULT = "default",
|
||||
|
||||
/**
|
||||
* 大型
|
||||
*/
|
||||
LARGE = "large",
|
||||
|
||||
/**
|
||||
* 小型
|
||||
*/
|
||||
SMALL = "small",
|
||||
}
|
||||
11
src/enums/index.ts
Normal file
11
src/enums/index.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
export * from "./api/result.enum";
|
||||
|
||||
export * from "./codegen/form.enum";
|
||||
export * from "./codegen/query.enum";
|
||||
|
||||
export * from "./settings/layout.enum";
|
||||
export * from "./settings/theme.enum";
|
||||
export * from "./settings/locale.enum";
|
||||
export * from "./settings/device.enum";
|
||||
|
||||
export * from "./system/menu.enum";
|
||||
53
src/enums/settings/layout.enum.ts
Normal file
53
src/enums/settings/layout.enum.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* 菜单布局枚举
|
||||
*/
|
||||
export const enum LayoutMode {
|
||||
/**
|
||||
* 左侧菜单布局
|
||||
*/
|
||||
LEFT = "left",
|
||||
/**
|
||||
* 顶部菜单布局
|
||||
*/
|
||||
TOP = "top",
|
||||
|
||||
/**
|
||||
* 混合菜单布局
|
||||
*/
|
||||
MIX = "mix",
|
||||
}
|
||||
|
||||
/**
|
||||
* 侧边栏状态枚举
|
||||
*/
|
||||
export const enum SidebarStatus {
|
||||
/**
|
||||
* 展开
|
||||
*/
|
||||
OPENED = "opened",
|
||||
|
||||
/**
|
||||
* 关闭
|
||||
*/
|
||||
CLOSED = "closed",
|
||||
}
|
||||
|
||||
/**
|
||||
* 组件尺寸枚举
|
||||
*/
|
||||
export const enum ComponentSize {
|
||||
/**
|
||||
* 默认
|
||||
*/
|
||||
DEFAULT = "default",
|
||||
|
||||
/**
|
||||
* 大型
|
||||
*/
|
||||
LARGE = "large",
|
||||
|
||||
/**
|
||||
* 小型
|
||||
*/
|
||||
SMALL = "small",
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* 主题枚举
|
||||
*/
|
||||
export const enum ThemeEnum {
|
||||
export const enum ThemeMode {
|
||||
/**
|
||||
* 明亮主题
|
||||
*/
|
||||
@@ -20,7 +20,7 @@ export const enum ThemeEnum {
|
||||
/**
|
||||
* 侧边栏配色方案枚举
|
||||
*/
|
||||
export const enum SidebarColorEnum {
|
||||
export const enum SidebarColor {
|
||||
/**
|
||||
* 经典蓝
|
||||
*/
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { App } from "vue";
|
||||
import { createI18n } from "vue-i18n";
|
||||
import { useAppStoreHook } from "@/store/modules/app";
|
||||
import { useAppStoreHook } from "@/store/modules/app.store";
|
||||
// 本地语言包
|
||||
import enLocale from "./package/en";
|
||||
import zhCnLocale from "./package/zh-cn";
|
||||
|
||||
@@ -30,7 +30,7 @@ export default {
|
||||
// 导航栏国际化
|
||||
navbar: {
|
||||
dashboard: "首页",
|
||||
logout: "注销登出",
|
||||
logout: "注销登录",
|
||||
document: "项目文档",
|
||||
gitee: "项目地址",
|
||||
profile: "个人中心",
|
||||
|
||||
@@ -44,10 +44,10 @@
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import defaultSettings from "@/settings";
|
||||
import { DeviceEnum } from "@/enums/DeviceEnum";
|
||||
import { DeviceEnum } from "@/enums/settings/device.enum";
|
||||
import { useAppStore, useSettingsStore, useUserStore, useTagsViewStore } from "@/store";
|
||||
|
||||
import { SidebarColorEnum, ThemeEnum } from "@/enums/ThemeEnum";
|
||||
import { SidebarColor, ThemeMode } from "@/enums/settings/theme.enum";
|
||||
|
||||
const appStore = useAppStore();
|
||||
const settingStore = useSettingsStore();
|
||||
@@ -68,12 +68,12 @@ function handleProfileClick() {
|
||||
// 根据主题和侧边栏配色方案选择 navbar 右侧的样式类
|
||||
const navbarRightClass = computed(() => {
|
||||
// 如果暗黑主题
|
||||
if (settingStore.theme === ThemeEnum.DARK) {
|
||||
if (settingStore.theme === ThemeMode.DARK) {
|
||||
return "navbar__right--white";
|
||||
}
|
||||
|
||||
// 如果侧边栏是经典蓝
|
||||
if (settingStore.sidebarColorScheme === SidebarColorEnum.CLASSIC_BLUE) {
|
||||
if (settingStore.sidebarColorScheme === SidebarColor.CLASSIC_BLUE) {
|
||||
return "navbar__right--white";
|
||||
}
|
||||
});
|
||||
|
||||
@@ -21,26 +21,26 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { LayoutEnum } from "@/enums/LayoutEnum";
|
||||
import { LayoutMode } from "@/enums/settings/layout.enum";
|
||||
|
||||
interface LayoutOption {
|
||||
value: LayoutEnum;
|
||||
value: LayoutMode;
|
||||
label: string;
|
||||
className: string;
|
||||
}
|
||||
|
||||
const layoutOptions: LayoutOption[] = [
|
||||
{ value: LayoutEnum.LEFT, label: "左侧模式", className: "left" },
|
||||
{ value: LayoutEnum.TOP, label: "顶部模式", className: "top" },
|
||||
{ value: LayoutEnum.MIX, label: "混合模式", className: "mix" },
|
||||
{ value: LayoutMode.LEFT, label: "左侧模式", className: "left" },
|
||||
{ value: LayoutMode.TOP, label: "顶部模式", className: "top" },
|
||||
{ value: LayoutMode.MIX, label: "混合模式", className: "mix" },
|
||||
];
|
||||
|
||||
const modelValue = defineModel<LayoutEnum>("modelValue", {
|
||||
const modelValue = defineModel<LayoutMode>("modelValue", {
|
||||
required: true,
|
||||
default: () => LayoutEnum.LEFT,
|
||||
default: () => LayoutMode.LEFT,
|
||||
});
|
||||
|
||||
function handleLayoutChange(layout: LayoutEnum) {
|
||||
function handleLayoutChange(layout: LayoutMode) {
|
||||
modelValue.value = layout;
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -48,10 +48,10 @@
|
||||
<div v-if="!isDark" class="config-item flex-x-between">
|
||||
<span class="text-xs">{{ $t("settings.sidebarColorScheme") }}</span>
|
||||
<el-radio-group v-model="sidebarColor" @change="changeSidebarColor">
|
||||
<el-radio :value="SidebarColorEnum.CLASSIC_BLUE">
|
||||
<el-radio :value="SidebarColor.CLASSIC_BLUE">
|
||||
{{ $t("settings.classicBlue") }}
|
||||
</el-radio>
|
||||
<el-radio :value="SidebarColorEnum.MINIMAL_WHITE">
|
||||
<el-radio :value="SidebarColor.MINIMAL_WHITE">
|
||||
{{ $t("settings.minimalWhite") }}
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
@@ -67,9 +67,9 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { LayoutEnum } from "@/enums/LayoutEnum";
|
||||
import { ThemeEnum } from "@/enums/ThemeEnum";
|
||||
import { SidebarColorEnum } from "@/enums/ThemeEnum";
|
||||
import { LayoutMode } from "@/enums/settings/layout.enum";
|
||||
import { ThemeMode } from "@/enums/settings/theme.enum";
|
||||
import { SidebarColor } from "@/enums/settings/theme.enum";
|
||||
import { useSettingsStore, usePermissionStore, useAppStore } from "@/store";
|
||||
// 颜色预设
|
||||
const colorPresets = [
|
||||
@@ -89,7 +89,7 @@ const appStore = useAppStore();
|
||||
const settingsStore = useSettingsStore();
|
||||
const permissionStore = usePermissionStore();
|
||||
|
||||
const isDark = ref<boolean>(settingsStore.theme === ThemeEnum.DARK);
|
||||
const isDark = ref<boolean>(settingsStore.theme === ThemeMode.DARK);
|
||||
const sidebarColor = ref(settingsStore.sidebarColorScheme);
|
||||
|
||||
const selectedThemeColor = computed({
|
||||
@@ -108,7 +108,7 @@ const drawerVisible = computed({
|
||||
* @param isDark 是否启用暗黑模式
|
||||
*/
|
||||
const handleThemeChange = (isDark: string | number | boolean) => {
|
||||
settingsStore.changeTheme(isDark ? ThemeEnum.DARK : ThemeEnum.LIGHT);
|
||||
settingsStore.changeTheme(isDark ? ThemeMode.DARK : ThemeMode.LIGHT);
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -125,9 +125,9 @@ const changeSidebarColor = (val: any) => {
|
||||
*
|
||||
* @param layout - 布局模式
|
||||
*/
|
||||
const handleLayoutChange = (layout: LayoutEnum) => {
|
||||
const handleLayoutChange = (layout: LayoutMode) => {
|
||||
settingsStore.changeLayout(layout);
|
||||
if (layout === LayoutEnum.MIX && route.name) {
|
||||
if (layout === LayoutMode.MIX && route.name) {
|
||||
const topLevelRoute = findTopLevelRoute(permissionStore.routes, route.name as string);
|
||||
if (appStore.activeTopMenuPath !== topLevelRoute.path) {
|
||||
appStore.activeTopMenu(topLevelRoute.path);
|
||||
|
||||
@@ -5,17 +5,17 @@
|
||||
:default-active="currentRoute.path"
|
||||
:collapse="!appStore.sidebar.opened"
|
||||
:background-color="
|
||||
theme === 'dark' || sidebarColorScheme === SidebarColorEnum.CLASSIC_BLUE
|
||||
theme === 'dark' || sidebarColorScheme === SidebarColor.CLASSIC_BLUE
|
||||
? variables['menu-background']
|
||||
: undefined
|
||||
"
|
||||
:text-color="
|
||||
theme === 'dark' || sidebarColorScheme === SidebarColorEnum.CLASSIC_BLUE
|
||||
theme === 'dark' || sidebarColorScheme === SidebarColor.CLASSIC_BLUE
|
||||
? variables['menu-text']
|
||||
: undefined
|
||||
"
|
||||
:active-text-color="
|
||||
theme === 'dark' || sidebarColorScheme === SidebarColorEnum.CLASSIC_BLUE
|
||||
theme === 'dark' || sidebarColorScheme === SidebarColor.CLASSIC_BLUE
|
||||
? variables['menu-active-text']
|
||||
: undefined
|
||||
"
|
||||
@@ -41,8 +41,8 @@ import path from "path-browserify";
|
||||
import type { MenuInstance } from "element-plus";
|
||||
import type { RouteRecordRaw } from "vue-router";
|
||||
|
||||
import { LayoutEnum } from "@/enums/LayoutEnum";
|
||||
import { SidebarColorEnum } from "@/enums/ThemeEnum";
|
||||
import { LayoutMode } from "@/enums/settings/layout.enum";
|
||||
import { SidebarColor } from "@/enums/settings/theme.enum";
|
||||
import { useSettingsStore, useAppStore } from "@/store";
|
||||
import { isExternal } from "@/utils/index";
|
||||
|
||||
@@ -70,7 +70,7 @@ const expandedMenuIndexes = ref<string[]>([]);
|
||||
|
||||
// 根据布局模式设置菜单的显示方式:顶部布局使用水平模式,其他使用垂直模式
|
||||
const menuMode = computed(() => {
|
||||
return settingsStore.layout === LayoutEnum.TOP ? "horizontal" : "vertical";
|
||||
return settingsStore.layout === LayoutMode.TOP ? "horizontal" : "vertical";
|
||||
});
|
||||
|
||||
// 获取主题
|
||||
|
||||
@@ -5,17 +5,17 @@
|
||||
mode="horizontal"
|
||||
:default-active="activePath"
|
||||
:background-color="
|
||||
theme === 'dark' || sidebarColorScheme === SidebarColorEnum.CLASSIC_BLUE
|
||||
theme === 'dark' || sidebarColorScheme === SidebarColor.CLASSIC_BLUE
|
||||
? variables['menu-background']
|
||||
: undefined
|
||||
"
|
||||
:text-color="
|
||||
theme === 'dark' || sidebarColorScheme === SidebarColorEnum.CLASSIC_BLUE
|
||||
theme === 'dark' || sidebarColorScheme === SidebarColor.CLASSIC_BLUE
|
||||
? variables['menu-text']
|
||||
: undefined
|
||||
"
|
||||
:active-text-color="
|
||||
theme === 'dark' || sidebarColorScheme === SidebarColorEnum.CLASSIC_BLUE
|
||||
theme === 'dark' || sidebarColorScheme === SidebarColor.CLASSIC_BLUE
|
||||
? variables['menu-active-text']
|
||||
: undefined
|
||||
"
|
||||
@@ -44,7 +44,7 @@ import { LocationQueryRaw, RouteRecordRaw } from "vue-router";
|
||||
import { usePermissionStore, useAppStore, useSettingsStore } from "@/store";
|
||||
import { translateRouteTitle } from "@/utils/i18n";
|
||||
import variables from "@/styles/variables.module.scss";
|
||||
import { SidebarColorEnum } from "@/enums/ThemeEnum";
|
||||
import { SidebarColor } from "@/enums/settings/theme.enum";
|
||||
|
||||
const router = useRouter();
|
||||
const appStore = useAppStore();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div :class="{ 'has-logo': sidebarLogo }">
|
||||
<!-- 混合布局 -->
|
||||
<div v-if="layout == LayoutEnum.MIX" class="flex w-full">
|
||||
<div v-if="layout == LayoutMode.MIX" class="flex w-full">
|
||||
<SidebarLogo v-if="sidebarLogo" :collapse="isSidebarCollapsed" />
|
||||
<SidebarMixTopMenu class="flex-1" />
|
||||
<NavbarRight />
|
||||
@@ -15,13 +15,13 @@
|
||||
</el-scrollbar>
|
||||
|
||||
<!-- 顶部导航 -->
|
||||
<NavbarRight v-if="layout == LayoutEnum.TOP" />
|
||||
<NavbarRight v-if="layout == LayoutMode.TOP" />
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { LayoutEnum } from "@/enums/LayoutEnum";
|
||||
import { LayoutMode } from "@/enums/settings/layout.enum";
|
||||
import { useSettingsStore, usePermissionStore, useAppStore } from "@/store";
|
||||
|
||||
import NavbarRight from "../NavBar/components/NavbarRight.vue";
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<Sidebar class="layout__sidebar" />
|
||||
|
||||
<!-- 混合布局 -->
|
||||
<div v-if="layout === LayoutEnum.MIX" class="layout__container">
|
||||
<div v-if="layout === LayoutMode.MIX" class="layout__container">
|
||||
<!-- 左侧菜单栏 -->
|
||||
<div class="layout__sidebar--left">
|
||||
<el-scrollbar>
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
<!-- 左侧或顶部布局的主内容区 -->
|
||||
<div v-else :class="{ hasTagsView: isShowTagsView }" class="layout__main">
|
||||
<NavBar v-if="layout === LayoutEnum.LEFT" />
|
||||
<NavBar v-if="layout === LayoutMode.LEFT" />
|
||||
<TagsView v-if="isShowTagsView" />
|
||||
<AppMain />
|
||||
<Settings v-if="defaultSettings.showSettings" />
|
||||
@@ -52,8 +52,8 @@ import { useAppStore, useSettingsStore, usePermissionStore } from "@/store";
|
||||
import defaultSettings from "@/settings";
|
||||
|
||||
// 枚举
|
||||
import { DeviceEnum } from "@/enums/DeviceEnum";
|
||||
import { LayoutEnum } from "@/enums/LayoutEnum";
|
||||
import { DeviceEnum } from "@/enums/settings/device.enum";
|
||||
import { LayoutMode } from "@/enums/settings/layout.enum";
|
||||
|
||||
// 组件
|
||||
import NavBar from "./components/NavBar/index.vue";
|
||||
|
||||
@@ -40,7 +40,7 @@ export function setupPermission() {
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
// 路由加载失败,重置 token 并重定向到登录页
|
||||
await useUserStore().clearUserData();
|
||||
await useUserStore().clearSessionAndCache();
|
||||
redirectToLogin(to, next);
|
||||
NProgress.done();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import { SizeEnum } from "./enums/SizeEnum";
|
||||
import { LayoutEnum } from "./enums/LayoutEnum";
|
||||
import { ThemeEnum, SidebarColorEnum } from "./enums/ThemeEnum";
|
||||
import { LanguageEnum } from "./enums/LanguageEnum";
|
||||
import { LayoutMode, ComponentSize, SidebarColor, ThemeMode, LanguageEnum } from "./enums";
|
||||
|
||||
const { pkg } = __APP_INFO__;
|
||||
|
||||
@@ -20,11 +17,11 @@ const defaultSettings: AppSettings = {
|
||||
// 是否显示侧边栏Logo
|
||||
sidebarLogo: true,
|
||||
// 布局方式,默认为左侧布局
|
||||
layout: LayoutEnum.LEFT,
|
||||
layout: LayoutMode.LEFT,
|
||||
// 主题,根据操作系统的色彩方案自动选择
|
||||
theme: mediaQueryList.matches ? ThemeEnum.DARK : ThemeEnum.LIGHT,
|
||||
theme: mediaQueryList.matches ? ThemeMode.DARK : ThemeMode.LIGHT,
|
||||
// 组件大小 default | medium | small | large
|
||||
size: SizeEnum.DEFAULT,
|
||||
size: ComponentSize.DEFAULT,
|
||||
// 语言
|
||||
language: LanguageEnum.ZH_CN,
|
||||
// 主题颜色
|
||||
@@ -34,7 +31,7 @@ const defaultSettings: AppSettings = {
|
||||
// 水印内容
|
||||
watermarkContent: pkg.name,
|
||||
// 侧边栏配色方案
|
||||
sidebarColorScheme: SidebarColorEnum.CLASSIC_BLUE,
|
||||
sidebarColorScheme: SidebarColor.CLASSIC_BLUE,
|
||||
};
|
||||
|
||||
export default defaultSettings;
|
||||
|
||||
@@ -8,10 +8,10 @@ export function setupStore(app: App<Element>) {
|
||||
app.use(store);
|
||||
}
|
||||
|
||||
export * from "./modules/app";
|
||||
export * from "./modules/permission";
|
||||
export * from "./modules/settings";
|
||||
export * from "./modules/tags-view";
|
||||
export * from "./modules/user";
|
||||
export * from "./modules/dict";
|
||||
export * from "./modules/app.store";
|
||||
export * from "./modules/permission.store";
|
||||
export * from "./modules/settings.store";
|
||||
export * from "./modules/tags-view.store";
|
||||
export * from "./modules/user.store";
|
||||
export * from "./modules/dict.store";
|
||||
export { store };
|
||||
|
||||
@@ -4,8 +4,8 @@ import defaultSettings from "@/settings";
|
||||
import zhCn from "element-plus/es/locale/lang/zh-cn";
|
||||
import en from "element-plus/es/locale/lang/en";
|
||||
import { store } from "@/store";
|
||||
import { DeviceEnum } from "@/enums/DeviceEnum";
|
||||
import { SidebarStatusEnum } from "@/enums/SidebarStatusEnum";
|
||||
import { DeviceEnum } from "@/enums/settings/device.enum";
|
||||
import { SidebarStatus } from "@/enums/settings/layout.enum";
|
||||
|
||||
export const useAppStore = defineStore("app", () => {
|
||||
// 设备类型
|
||||
@@ -15,9 +15,9 @@ export const useAppStore = defineStore("app", () => {
|
||||
// 语言
|
||||
const language = useStorage("language", defaultSettings.language);
|
||||
// 侧边栏状态
|
||||
const sidebarStatus = useStorage("sidebarStatus", SidebarStatusEnum.CLOSED);
|
||||
const sidebarStatus = useStorage("sidebarStatus", SidebarStatus.CLOSED);
|
||||
const sidebar = reactive({
|
||||
opened: sidebarStatus.value === SidebarStatusEnum.OPENED,
|
||||
opened: sidebarStatus.value === SidebarStatus.OPENED,
|
||||
withoutAnimation: false,
|
||||
});
|
||||
|
||||
@@ -38,19 +38,19 @@ export const useAppStore = defineStore("app", () => {
|
||||
// 切换侧边栏
|
||||
function toggleSidebar() {
|
||||
sidebar.opened = !sidebar.opened;
|
||||
sidebarStatus.value = sidebar.opened ? SidebarStatusEnum.OPENED : SidebarStatusEnum.CLOSED;
|
||||
sidebarStatus.value = sidebar.opened ? SidebarStatus.OPENED : SidebarStatus.CLOSED;
|
||||
}
|
||||
|
||||
// 关闭侧边栏
|
||||
function closeSideBar() {
|
||||
sidebar.opened = false;
|
||||
sidebarStatus.value = SidebarStatusEnum.CLOSED;
|
||||
sidebarStatus.value = SidebarStatus.CLOSED;
|
||||
}
|
||||
|
||||
// 打开侧边栏
|
||||
function openSideBar() {
|
||||
sidebar.opened = true;
|
||||
sidebarStatus.value = SidebarStatusEnum.OPENED;
|
||||
sidebarStatus.value = SidebarStatus.OPENED;
|
||||
}
|
||||
|
||||
// 切换设备
|
||||
55
src/store/modules/dict.store.ts
Normal file
55
src/store/modules/dict.store.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import { store } from "@/store";
|
||||
import DictAPI, { type DictItemOption } from "@/api/system/dict.api";
|
||||
|
||||
export const useDictStore = defineStore("dict", () => {
|
||||
// 字典数据缓存
|
||||
const dictCache = useStorage<Record<string, DictItemOption[]>>("dict_cache", {});
|
||||
// 请求队列(防止重复请求)
|
||||
const requestQueue: Record<string, Promise<void>> = {};
|
||||
/**
|
||||
* 缓存字典数据
|
||||
* @param dictCode 字典编码
|
||||
* @param data 字典项列表
|
||||
*/
|
||||
const cacheDictItems = (dictCode: string, data: DictItemOption[]) => {
|
||||
dictCache.value[dictCode] = data;
|
||||
};
|
||||
/**
|
||||
* 加载字典数据(如果缓存中没有则请求)
|
||||
* @param dictCode 字典编码
|
||||
*/
|
||||
const loadDictItems = async (dictCode: string) => {
|
||||
if (dictCache.value[dictCode]) return;
|
||||
// 防止重复请求
|
||||
if (!requestQueue[dictCode]) {
|
||||
requestQueue[dictCode] = DictAPI.getDictItems(dictCode).then((data) => {
|
||||
cacheDictItems(dictCode, data);
|
||||
Reflect.deleteProperty(requestQueue, dictCode);
|
||||
});
|
||||
}
|
||||
await requestQueue[dictCode];
|
||||
};
|
||||
/**
|
||||
* 获取字典项列表
|
||||
* @param dictCode 字典编码
|
||||
* @returns 字典项列表
|
||||
*/
|
||||
const getDictItems = (dictCode: string): DictItemOption[] => {
|
||||
return dictCache.value[dictCode] || [];
|
||||
};
|
||||
/**
|
||||
* 清空字典缓存
|
||||
*/
|
||||
const clearDictCache = () => {
|
||||
dictCache.value = {};
|
||||
};
|
||||
return {
|
||||
loadDictItems,
|
||||
getDictItems,
|
||||
clearDictCache,
|
||||
};
|
||||
});
|
||||
|
||||
export function useDictStoreHook() {
|
||||
return useDictStore(store);
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
import { store } from "@/store";
|
||||
import DictionaryAPI, { type DictVO, type DictData } from "@/api/system/dict";
|
||||
|
||||
export const useDictStore = defineStore("dict", () => {
|
||||
const dictionary = useStorage<Record<string, DictData[]>>("dictionary", {});
|
||||
|
||||
const setDictionary = (dict: DictVO) => {
|
||||
dictionary.value[dict.dictCode] = dict.dictDataList;
|
||||
};
|
||||
|
||||
const loadDictionaries = async () => {
|
||||
const dictList = await DictionaryAPI.getList();
|
||||
dictList.forEach(setDictionary);
|
||||
};
|
||||
|
||||
const getDictionary = (dictCode: string): DictData[] => {
|
||||
return dictionary.value[dictCode] || [];
|
||||
};
|
||||
|
||||
const clearDictionaryCache = () => {
|
||||
dictionary.value = {};
|
||||
};
|
||||
|
||||
const updateDictionaryCache = async () => {
|
||||
clearDictionaryCache(); // 先清除旧缓存
|
||||
await loadDictionaries(); // 重新加载最新字典数据
|
||||
};
|
||||
|
||||
return {
|
||||
dictionary,
|
||||
setDictionary,
|
||||
loadDictionaries,
|
||||
getDictionary,
|
||||
clearDictionaryCache,
|
||||
updateDictionaryCache,
|
||||
};
|
||||
});
|
||||
|
||||
export function useDictStoreHook() {
|
||||
return useDictStore(store);
|
||||
}
|
||||
@@ -3,7 +3,7 @@ import { constantRoutes } from "@/router";
|
||||
import { store } from "@/store";
|
||||
import router from "@/router";
|
||||
|
||||
import MenuAPI, { type RouteVO } from "@/api/system/menu";
|
||||
import MenuAPI, { type RouteVO } from "@/api/system/menu.api";
|
||||
const modules = import.meta.glob("../../views/**/**.vue");
|
||||
const Layout = () => import("@/layout/index.vue");
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import defaultSettings from "@/settings";
|
||||
import { SidebarColorEnum, ThemeEnum } from "@/enums/ThemeEnum";
|
||||
import { LayoutEnum } from "@/enums/LayoutEnum";
|
||||
import { SidebarColor, ThemeMode } from "@/enums/settings/theme.enum";
|
||||
import { LayoutMode } from "@/enums/settings/layout.enum";
|
||||
import { generateThemeColors, applyTheme, toggleDarkMode, toggleSidebarColor } from "@/utils/theme";
|
||||
|
||||
type SettingsValue = boolean | string;
|
||||
@@ -18,7 +18,7 @@ export const useSettingsStore = defineStore("setting", () => {
|
||||
defaultSettings.sidebarColorScheme
|
||||
);
|
||||
// 布局
|
||||
const layout = useStorage<LayoutEnum>("layout", defaultSettings.layout as LayoutEnum);
|
||||
const layout = useStorage<LayoutMode>("layout", defaultSettings.layout as LayoutMode);
|
||||
// 水印
|
||||
const watermarkEnabled = useStorage<boolean>(
|
||||
"watermarkEnabled",
|
||||
@@ -33,7 +33,7 @@ export const useSettingsStore = defineStore("setting", () => {
|
||||
watch(
|
||||
[theme, themeColor],
|
||||
([newTheme, newThemeColor]) => {
|
||||
toggleDarkMode(newTheme === ThemeEnum.DARK);
|
||||
toggleDarkMode(newTheme === ThemeMode.DARK);
|
||||
const colors = generateThemeColors(newThemeColor);
|
||||
applyTheme(colors);
|
||||
},
|
||||
@@ -44,7 +44,7 @@ export const useSettingsStore = defineStore("setting", () => {
|
||||
watch(
|
||||
[sidebarColorScheme],
|
||||
([newSidebarColorScheme]) => {
|
||||
toggleSidebarColor(newSidebarColorScheme === SidebarColorEnum.CLASSIC_BLUE);
|
||||
toggleSidebarColor(newSidebarColorScheme === SidebarColor.CLASSIC_BLUE);
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
@@ -75,7 +75,7 @@ export const useSettingsStore = defineStore("setting", () => {
|
||||
themeColor.value = color;
|
||||
}
|
||||
|
||||
function changeLayout(val: LayoutEnum) {
|
||||
function changeLayout(val: LayoutMode) {
|
||||
layout.value = val;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { store } from "@/store";
|
||||
import { usePermissionStoreHook } from "@/store/modules/permission";
|
||||
import { useDictStoreHook } from "@/store/modules/dict";
|
||||
import { usePermissionStoreHook } from "@/store/modules/permission.store";
|
||||
import { useDictStoreHook } from "@/store/modules/dict.store";
|
||||
|
||||
import AuthAPI, { type LoginFormData } from "@/api/auth";
|
||||
import UserAPI, { type UserInfo } from "@/api/system/user";
|
||||
import AuthAPI, { type LoginFormData } from "@/api/auth.api";
|
||||
import UserAPI, { type UserInfo } from "@/api/system/user.api";
|
||||
|
||||
import { setAccessToken, setRefreshToken, getRefreshToken, clearToken } from "@/utils/auth";
|
||||
|
||||
@@ -60,7 +60,7 @@ export const useUserStore = defineStore("user", () => {
|
||||
return new Promise<void>((resolve, reject) => {
|
||||
AuthAPI.logout()
|
||||
.then(() => {
|
||||
clearUserData();
|
||||
clearSessionAndCache();
|
||||
resolve();
|
||||
})
|
||||
.catch((error) => {
|
||||
@@ -90,15 +90,13 @@ export const useUserStore = defineStore("user", () => {
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理用户数据
|
||||
*
|
||||
* @returns
|
||||
* 清除用户会话和缓存
|
||||
*/
|
||||
function clearUserData() {
|
||||
function clearSessionAndCache() {
|
||||
return new Promise<void>((resolve) => {
|
||||
clearToken();
|
||||
usePermissionStoreHook().resetRouter();
|
||||
useDictStoreHook().clearDictionaryCache();
|
||||
useDictStoreHook().clearDictCache();
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
@@ -108,7 +106,7 @@ export const useUserStore = defineStore("user", () => {
|
||||
getUserInfo,
|
||||
login,
|
||||
logout,
|
||||
clearUserData,
|
||||
clearSessionAndCache,
|
||||
refreshToken,
|
||||
};
|
||||
});
|
||||
@@ -1,7 +1,7 @@
|
||||
import axios, { type InternalAxiosRequestConfig, type AxiosResponse } from "axios";
|
||||
import qs from "qs";
|
||||
import { useUserStoreHook } from "@/store/modules/user";
|
||||
import { ResultEnum } from "@/enums/ResultEnum";
|
||||
import { useUserStoreHook } from "@/store/modules/user.store";
|
||||
import { ResultEnum } from "@/enums/api/result.enum";
|
||||
import { getAccessToken } from "@/utils/auth";
|
||||
import router from "@/router";
|
||||
|
||||
@@ -12,12 +12,11 @@ const service = axios.create({
|
||||
headers: { "Content-Type": "application/json;charset=utf-8" },
|
||||
paramsSerializer: (params) => qs.stringify(params),
|
||||
});
|
||||
|
||||
// 请求拦截器
|
||||
service.interceptors.request.use(
|
||||
(config: InternalAxiosRequestConfig) => {
|
||||
const accessToken = getAccessToken();
|
||||
// 如果 Authorization 设置为 no-auth,则不携带 Token,用于登录、刷新 Token 等接口
|
||||
// 如果 Authorization 设置为 no-auth,则不携带 Token
|
||||
if (config.headers.Authorization !== "no-auth" && accessToken) {
|
||||
config.headers.Authorization = `Bearer ${accessToken}`;
|
||||
} else {
|
||||
@@ -27,7 +26,6 @@ service.interceptors.request.use(
|
||||
},
|
||||
(error) => Promise.reject(error)
|
||||
);
|
||||
|
||||
// 响应拦截器
|
||||
service.interceptors.response.use(
|
||||
(response: AxiosResponse) => {
|
||||
@@ -35,18 +33,15 @@ service.interceptors.response.use(
|
||||
if (response.config.responseType === "blob") {
|
||||
return response;
|
||||
}
|
||||
|
||||
const { code, data, msg } = response.data;
|
||||
if (code === ResultEnum.SUCCESS) {
|
||||
return data;
|
||||
}
|
||||
|
||||
ElMessage.error(msg || "系统出错");
|
||||
return Promise.reject(new Error(msg || "Error"));
|
||||
},
|
||||
async (error) => {
|
||||
console.error("request error", error); // for debug
|
||||
// 非 2xx 状态码处理 401、403、500 等
|
||||
const { config, response } = error;
|
||||
if (response) {
|
||||
const { code, msg } = response.data;
|
||||
@@ -54,6 +49,8 @@ service.interceptors.response.use(
|
||||
// Token 过期,刷新 Token
|
||||
return handleTokenRefresh(config);
|
||||
} else if (code === ResultEnum.REFRESH_TOKEN_INVALID) {
|
||||
// 刷新 Token 过期,跳转登录页
|
||||
await handleSessionExpired();
|
||||
return Promise.reject(new Error(msg || "Error"));
|
||||
} else {
|
||||
ElMessage.error(msg || "系统出错");
|
||||
@@ -62,29 +59,22 @@ service.interceptors.response.use(
|
||||
return Promise.reject(error.message);
|
||||
}
|
||||
);
|
||||
|
||||
export default service;
|
||||
|
||||
// 是否正在刷新标识,避免重复刷新
|
||||
let isRefreshing = false;
|
||||
// 因 Token 过期导致的请求等待队列
|
||||
const waitingQueue: Array<() => void> = [];
|
||||
|
||||
// 刷新 Token 处理
|
||||
async function handleTokenRefresh(config: InternalAxiosRequestConfig) {
|
||||
return new Promise((resolve) => {
|
||||
// 封装需要重试的请求
|
||||
const retryRequest = () => {
|
||||
config.headers.Authorization = getAccessToken();
|
||||
config.headers.Authorization = `Bearer ${getAccessToken()}`;
|
||||
resolve(service(config));
|
||||
};
|
||||
|
||||
waitingQueue.push(retryRequest);
|
||||
|
||||
if (!isRefreshing) {
|
||||
isRefreshing = true;
|
||||
|
||||
// 刷新 Token
|
||||
useUserStoreHook()
|
||||
.refreshToken()
|
||||
.then(() => {
|
||||
@@ -92,19 +82,10 @@ async function handleTokenRefresh(config: InternalAxiosRequestConfig) {
|
||||
waitingQueue.forEach((callback) => callback());
|
||||
waitingQueue.length = 0;
|
||||
})
|
||||
.catch((error: any) => {
|
||||
console.log("handleTokenRefresh error", error);
|
||||
.catch(async (error) => {
|
||||
console.error("handleTokenRefresh error", error);
|
||||
// 刷新 Token 失败,跳转登录页
|
||||
ElNotification({
|
||||
title: "提示",
|
||||
message: "您的会话已过期,请重新登录",
|
||||
type: "info",
|
||||
});
|
||||
useUserStoreHook()
|
||||
.clearUserData()
|
||||
.then(() => {
|
||||
router.push("/login");
|
||||
});
|
||||
await handleSessionExpired();
|
||||
})
|
||||
.finally(() => {
|
||||
isRefreshing = false;
|
||||
@@ -112,3 +93,13 @@ async function handleTokenRefresh(config: InternalAxiosRequestConfig) {
|
||||
}
|
||||
});
|
||||
}
|
||||
// 处理会话过期
|
||||
async function handleSessionExpired() {
|
||||
ElNotification({
|
||||
title: "提示",
|
||||
message: "您的会话已过期,请重新登录",
|
||||
type: "info",
|
||||
});
|
||||
await useUserStoreHook().clearSessionAndCache();
|
||||
router.push("/login");
|
||||
}
|
||||
|
||||
@@ -417,18 +417,18 @@ import Codemirror from "codemirror-editor-vue3";
|
||||
import type { CmComponentRef } from "codemirror-editor-vue3";
|
||||
import type { EditorConfiguration } from "codemirror";
|
||||
|
||||
import { FormTypeEnum } from "@/enums/FormTypeEnum";
|
||||
import { QueryTypeEnum } from "@/enums/QueryTypeEnum";
|
||||
import { FormTypeEnum } from "@/enums/codegen/form.enum";
|
||||
import { QueryTypeEnum } from "@/enums/codegen/query.enum";
|
||||
|
||||
import GeneratorAPI, {
|
||||
TablePageVO,
|
||||
GenConfigForm,
|
||||
TablePageQuery,
|
||||
FieldConfig,
|
||||
} from "@/api/codegen";
|
||||
} from "@/api/codegen.api";
|
||||
|
||||
import DictAPI from "@/api/system/dict";
|
||||
import MenuAPI from "@/api/system/menu";
|
||||
import DictAPI from "@/api/system/dict.api";
|
||||
import MenuAPI from "@/api/system/menu.api";
|
||||
|
||||
interface TreeNode {
|
||||
label: string;
|
||||
|
||||
@@ -285,8 +285,8 @@ defineOptions({
|
||||
});
|
||||
|
||||
import { dayjs } from "element-plus";
|
||||
import LogAPI, { VisitStatsVO, VisitTrendVO } from "@/api/system/log";
|
||||
import { useUserStore } from "@/store/modules/user";
|
||||
import LogAPI, { VisitStatsVO, VisitTrendVO } from "@/api/system/log.api";
|
||||
import { useUserStore } from "@/store/modules/user.store";
|
||||
import { formatGrowthRate } from "@/utils";
|
||||
|
||||
interface VersionItem {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import UserAPI, { type UserForm } from "@/api/system/user";
|
||||
import UserAPI, { type UserForm } from "@/api/system/user.api";
|
||||
import type { IModalConfig } from "@/components/CURD/types";
|
||||
|
||||
const modalConfig: IModalConfig<UserForm> = {
|
||||
@@ -11,7 +11,7 @@ const modalConfig: IModalConfig<UserForm> = {
|
||||
form: {
|
||||
labelWidth: 100,
|
||||
},
|
||||
formAction: UserAPI.add,
|
||||
formAction: UserAPI.create,
|
||||
beforeSubmit(data) {
|
||||
console.log("提交之前处理", data);
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import UserAPI from "@/api/system/user";
|
||||
import RoleAPI from "@/api/system/role";
|
||||
import type { UserPageQuery } from "@/api/system/user";
|
||||
import UserAPI from "@/api/system/user.api";
|
||||
import RoleAPI from "@/api/system/role.api";
|
||||
import type { UserPageQuery } from "@/api/system/user.api";
|
||||
import type { IContentConfig } from "@/components/CURD/types";
|
||||
|
||||
const contentConfig: IContentConfig<UserPageQuery> = {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import UserAPI, { type UserForm } from "@/api/system/user";
|
||||
import UserAPI, { type UserForm } from "@/api/system/user.api";
|
||||
import type { IModalConfig } from "@/components/CURD/types";
|
||||
import { DeviceEnum } from "@/enums/DeviceEnum";
|
||||
import { DeviceEnum } from "@/enums/settings/device.enum";
|
||||
import { useAppStore } from "@/store";
|
||||
|
||||
const modalConfig: IModalConfig<UserForm> = {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import DeptAPI from "@/api/system/dept";
|
||||
import DeptAPI from "@/api/system/dept.api";
|
||||
import type { ISearchConfig } from "@/components/CURD/types";
|
||||
|
||||
const searchConfig: ISearchConfig = {
|
||||
|
||||
@@ -90,9 +90,9 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import UserAPI from "@/api/system/user";
|
||||
import DeptAPI from "@/api/system/dept";
|
||||
import RoleAPI from "@/api/system/role";
|
||||
import UserAPI from "@/api/system/user.api";
|
||||
import DeptAPI from "@/api/system/dept.api";
|
||||
import RoleAPI from "@/api/system/role.api";
|
||||
import type { IObject, IOperatData } from "@/components/CURD/types";
|
||||
import usePage from "@/components/CURD/usePage";
|
||||
import addModalConfig from "./config/add";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import FileAPI from "@/api/file";
|
||||
import FileAPI from "@/api/file.api";
|
||||
|
||||
const imgUrl = ref("");
|
||||
const canvas = ref();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import UserAPI from "@/api/system/user";
|
||||
import UserAPI from "@/api/system/user.api";
|
||||
import type { ISelectConfig } from "@/components/TableSelect/index.vue";
|
||||
|
||||
const selectConfig: ISelectConfig = {
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useStomp } from "@/hooks/useStomp";
|
||||
import { useUserStoreHook } from "@/store/modules/user";
|
||||
import { useUserStoreHook } from "@/store/modules/user.store";
|
||||
|
||||
const userStore = useUserStoreHook();
|
||||
// 用于手动调整 WebSocket 地址
|
||||
|
||||
@@ -146,28 +146,27 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { LocationQuery, useRoute } from "vue-router";
|
||||
import { LocationQuery, RouteLocationRaw, useRoute } from "vue-router";
|
||||
import { useI18n } from "vue-i18n";
|
||||
|
||||
import AuthAPI, { type LoginFormData } from "@/api/auth";
|
||||
import AuthAPI, { type LoginFormData } from "@/api/auth.api";
|
||||
import router from "@/router";
|
||||
|
||||
import type { FormInstance } from "element-plus";
|
||||
|
||||
import defaultSettings from "@/settings";
|
||||
import { ThemeEnum } from "@/enums/ThemeEnum";
|
||||
import { ThemeMode } from "@/enums/settings/theme.enum";
|
||||
|
||||
import { useSettingsStore, useUserStore, useDictStore } from "@/store";
|
||||
import { useSettingsStore, useUserStore } from "@/store";
|
||||
|
||||
const userStore = useUserStore();
|
||||
const settingsStore = useSettingsStore();
|
||||
const dictStore = useDictStore();
|
||||
|
||||
const route = useRoute();
|
||||
const { t } = useI18n();
|
||||
const loginFormRef = ref<FormInstance>();
|
||||
|
||||
const isDark = ref(settingsStore.theme === ThemeEnum.DARK); // 是否暗黑模式
|
||||
const isDark = ref(settingsStore.theme === ThemeMode.DARK); // 是否暗黑模式
|
||||
const loading = ref(false); // 按钮 loading 状态
|
||||
const isCapslock = ref(false); // 是否大写锁定
|
||||
const captchaBase64 = ref(); // 验证码图片Base64字符串
|
||||
@@ -218,57 +217,60 @@ function getCaptcha() {
|
||||
});
|
||||
}
|
||||
|
||||
// 登录
|
||||
// 登录提交处理
|
||||
async function handleLoginSubmit() {
|
||||
loginFormRef.value?.validate((valid: boolean) => {
|
||||
if (valid) {
|
||||
loading.value = true;
|
||||
userStore
|
||||
.login(loginFormData.value)
|
||||
.then(async () => {
|
||||
await userStore.getUserInfo();
|
||||
// 需要在路由跳转前加载字典数据,否则会出现字典数据未加载完成导致页面渲染异常
|
||||
await dictStore.loadDictionaries();
|
||||
// 跳转到登录前的页面
|
||||
const { path, queryParams } = parseRedirect();
|
||||
router.push({ path: path, query: queryParams });
|
||||
})
|
||||
.catch(() => {
|
||||
getCaptcha();
|
||||
})
|
||||
.finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
}
|
||||
});
|
||||
// 1. 表单验证
|
||||
const valid = await loginFormRef.value?.validate();
|
||||
if (!valid) return;
|
||||
|
||||
loading.value = true;
|
||||
try {
|
||||
// 2. 执行登录
|
||||
await userStore.login(loginFormData.value);
|
||||
|
||||
// 3. 获取用户信息
|
||||
await userStore.getUserInfo();
|
||||
|
||||
// 4. 解析并跳转目标地址
|
||||
const redirect = resolveRedirectTarget(route.query);
|
||||
await router.push(redirect);
|
||||
} catch (error) {
|
||||
// 5. 统一错误处理
|
||||
getCaptcha(); // 刷新验证码
|
||||
console.error("登录失败:", error);
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析 redirect 字符串 为 path 和 queryParams
|
||||
*
|
||||
* @returns { path: string, queryParams: Record<string, string> } 解析后的 path 和 queryParams
|
||||
* 解析重定向目标
|
||||
* @param query 路由查询参数
|
||||
* @returns 标准化后的路由地址对象
|
||||
*/
|
||||
function parseRedirect(): {
|
||||
path: string;
|
||||
queryParams: Record<string, string>;
|
||||
} {
|
||||
const query: LocationQuery = route.query;
|
||||
const redirect = (query.redirect as string) ?? "/";
|
||||
function resolveRedirectTarget(query: LocationQuery): RouteLocationRaw {
|
||||
// 默认跳转路径
|
||||
const defaultPath = "/";
|
||||
|
||||
const url = new URL(redirect, window.location.origin);
|
||||
const path = url.pathname;
|
||||
const queryParams: Record<string, string> = {};
|
||||
// 获取原始重定向路径
|
||||
const rawRedirect = (query.redirect as string) || defaultPath;
|
||||
|
||||
url.searchParams.forEach((value, key) => {
|
||||
queryParams[key] = value;
|
||||
});
|
||||
|
||||
return { path, queryParams };
|
||||
try {
|
||||
// 6. 使用Vue Router解析路径
|
||||
const resolved = router.resolve(rawRedirect);
|
||||
return {
|
||||
path: resolved.path,
|
||||
query: resolved.query,
|
||||
};
|
||||
} catch {
|
||||
// 7. 异常处理:返回安全路径
|
||||
return { path: defaultPath };
|
||||
}
|
||||
}
|
||||
|
||||
// 主题切换
|
||||
const toggleTheme = () => {
|
||||
const newTheme = settingsStore.theme === ThemeEnum.DARK ? ThemeEnum.LIGHT : ThemeEnum.DARK;
|
||||
const newTheme = settingsStore.theme === ThemeMode.DARK ? ThemeMode.LIGHT : ThemeMode.DARK;
|
||||
settingsStore.changeTheme(newTheme);
|
||||
};
|
||||
|
||||
|
||||
@@ -260,9 +260,9 @@ import UserAPI, {
|
||||
MobileUpdateForm,
|
||||
EmailUpdateForm,
|
||||
UserProfileForm,
|
||||
} from "@/api/system/user";
|
||||
} from "@/api/system/user.api";
|
||||
|
||||
import FileAPI from "@/api/file";
|
||||
import FileAPI from "@/api/file.api";
|
||||
|
||||
import { Camera } from "@element-plus/icons-vue";
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ defineOptions({
|
||||
inheritAttrs: false,
|
||||
});
|
||||
|
||||
import ConfigAPI, { ConfigPageVO, ConfigForm, ConfigPageQuery } from "@/api/system/config";
|
||||
import ConfigAPI, { ConfigPageVO, ConfigForm, ConfigPageQuery } from "@/api/system/config.api";
|
||||
|
||||
const queryFormRef = ref();
|
||||
const dataFormRef = ref();
|
||||
@@ -233,7 +233,7 @@ function handleSubmit() {
|
||||
})
|
||||
.finally(() => (loading.value = false));
|
||||
} else {
|
||||
ConfigAPI.add(formData)
|
||||
ConfigAPI.create(formData)
|
||||
.then(() => {
|
||||
ElMessage.success("新增成功");
|
||||
handleCloseDialog();
|
||||
|
||||
@@ -158,7 +158,7 @@ defineOptions({
|
||||
inheritAttrs: false,
|
||||
});
|
||||
|
||||
import DeptAPI, { DeptVO, DeptForm, DeptQuery } from "@/api/system/dept";
|
||||
import DeptAPI, { DeptVO, DeptForm, DeptQuery } from "@/api/system/dept.api";
|
||||
|
||||
const queryFormRef = ref();
|
||||
const deptFormRef = ref();
|
||||
@@ -251,7 +251,7 @@ function handleSubmit() {
|
||||
})
|
||||
.finally(() => (loading.value = false));
|
||||
} else {
|
||||
DeptAPI.add(formData)
|
||||
DeptAPI.create(formData)
|
||||
.then(() => {
|
||||
ElMessage.success("新增成功");
|
||||
handleCloseDialog();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<!-- 字典数据 -->
|
||||
<!-- 字典项 -->
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="search-bar mt-5">
|
||||
@@ -34,8 +34,8 @@
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="字典标签" prop="label" />
|
||||
<el-table-column label="字典值" prop="value" />
|
||||
<el-table-column label="字典项标签" prop="label" />
|
||||
<el-table-column label="字典项值" prop="value" />
|
||||
<el-table-column label="排序" prop="sort" />
|
||||
<el-table-column label="状态">
|
||||
<template #default="scope">
|
||||
@@ -78,7 +78,7 @@
|
||||
/>
|
||||
</el-card>
|
||||
|
||||
<!--字典弹窗-->
|
||||
<!--字典项弹窗-->
|
||||
<el-dialog
|
||||
v-model="dialog.visible"
|
||||
:title="dialog.title"
|
||||
@@ -87,10 +87,10 @@
|
||||
>
|
||||
<el-form ref="dataFormRef" :model="formData" :rules="computedRules" label-width="100px">
|
||||
<el-card shadow="never">
|
||||
<el-form-item label="字典标签" prop="label">
|
||||
<el-form-item label="字典项标签" prop="label">
|
||||
<el-input v-model="formData.label" placeholder="请输入字典标签" />
|
||||
</el-form-item>
|
||||
<el-form-item label="字典值" prop="value">
|
||||
<el-form-item label="字典项值" prop="value">
|
||||
<el-input v-model="formData.value" placeholder="请输入字典值" />
|
||||
</el-form-item>
|
||||
<el-form-item label="状态">
|
||||
@@ -130,15 +130,11 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
defineOptions({
|
||||
name: "DictData",
|
||||
name: "DictItem",
|
||||
inherititems: false,
|
||||
});
|
||||
|
||||
import DictDataAPI, {
|
||||
DictDataPageQuery,
|
||||
DictDataPageVO,
|
||||
DictDataForm,
|
||||
} from "@/api/system/dict-data";
|
||||
import DictAPI, { DictItemPageQuery, DictItemPageVO, DictItemForm } from "@/api/system/dict.api";
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
@@ -151,20 +147,19 @@ const loading = ref(false);
|
||||
const ids = ref<number[]>([]);
|
||||
const total = ref(0);
|
||||
|
||||
const queryParams = reactive<DictDataPageQuery>({
|
||||
const queryParams = reactive<DictItemPageQuery>({
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
dictCode: dictCode.value,
|
||||
});
|
||||
|
||||
const tableData = ref<DictDataPageVO[]>();
|
||||
const tableData = ref<DictItemPageVO[]>();
|
||||
|
||||
const dialog = reactive({
|
||||
title: "",
|
||||
visible: false,
|
||||
});
|
||||
|
||||
const formData = reactive<DictDataForm>({});
|
||||
const formData = reactive<DictItemForm>({});
|
||||
|
||||
const computedRules = computed(() => {
|
||||
const rules: Partial<Record<string, any>> = {
|
||||
@@ -177,7 +172,7 @@ const computedRules = computed(() => {
|
||||
// 查询
|
||||
function handleQuery() {
|
||||
loading.value = true;
|
||||
DictDataAPI.getPage(queryParams)
|
||||
DictAPI.getDictItemPage(dictCode.value, queryParams)
|
||||
.then((data) => {
|
||||
tableData.value = data.list;
|
||||
total.value = data.total;
|
||||
@@ -200,12 +195,12 @@ function handleSelectionChange(selection: any) {
|
||||
}
|
||||
|
||||
// 打开弹窗
|
||||
function handleOpenDialog(row?: DictDataPageVO) {
|
||||
function handleOpenDialog(row?: DictItemPageVO) {
|
||||
dialog.visible = true;
|
||||
dialog.title = row ? "编辑字典数据" : "新增字典数据";
|
||||
dialog.title = row ? "编辑字典项" : "新增字典项";
|
||||
|
||||
if (row?.id) {
|
||||
DictDataAPI.getFormData(row.id).then((data) => {
|
||||
DictAPI.getDictItemFormData(dictCode.value, row.id).then((data) => {
|
||||
Object.assign(formData, data);
|
||||
});
|
||||
}
|
||||
@@ -219,7 +214,7 @@ function handleSubmitClick() {
|
||||
const id = formData.id;
|
||||
formData.dictCode = dictCode.value;
|
||||
if (id) {
|
||||
DictDataAPI.update(id, formData)
|
||||
DictAPI.updateDictItem(dictCode.value, id, formData)
|
||||
.then(() => {
|
||||
ElMessage.success("修改成功");
|
||||
handleCloseDialog();
|
||||
@@ -227,7 +222,7 @@ function handleSubmitClick() {
|
||||
})
|
||||
.finally(() => (loading.value = false));
|
||||
} else {
|
||||
DictDataAPI.add(formData)
|
||||
DictAPI.createDictItem(dictCode.value, formData)
|
||||
.then(() => {
|
||||
ElMessage.success("新增成功");
|
||||
handleCloseDialog();
|
||||
@@ -256,8 +251,8 @@ function handleCloseDialog() {
|
||||
* @param id 字典ID
|
||||
*/
|
||||
function handleDelete(id?: number) {
|
||||
const attrGroupIds = [id || ids.value].join(",");
|
||||
if (!attrGroupIds) {
|
||||
const itemIds = [id || ids.value].join(",");
|
||||
if (!itemIds) {
|
||||
ElMessage.warning("请勾选删除项");
|
||||
return;
|
||||
}
|
||||
@@ -267,7 +262,7 @@ function handleDelete(id?: number) {
|
||||
type: "warning",
|
||||
}).then(
|
||||
() => {
|
||||
DictDataAPI.deleteByIds(attrGroupIds).then(() => {
|
||||
DictAPI.deleteDictItems(dictCode.value, itemIds).then(() => {
|
||||
ElMessage.success("删除成功");
|
||||
handleResetQuery();
|
||||
});
|
||||
@@ -129,7 +129,7 @@ defineOptions({
|
||||
inherititems: false,
|
||||
});
|
||||
|
||||
import DictAPI, { DictPageQuery, DictPageVO, DictForm } from "@/api/system/dict";
|
||||
import DictAPI, { DictPageQuery, DictPageVO, DictForm } from "@/api/system/dict.api";
|
||||
|
||||
import router from "@/router";
|
||||
|
||||
@@ -221,7 +221,7 @@ function handleSubmitClick() {
|
||||
})
|
||||
.finally(() => (loading.value = false));
|
||||
} else {
|
||||
DictAPI.add(formData)
|
||||
DictAPI.create(formData)
|
||||
.then(() => {
|
||||
ElMessage.success("新增成功");
|
||||
handleCloseDialog();
|
||||
@@ -270,17 +270,12 @@ function handleDelete(id?: number) {
|
||||
);
|
||||
}
|
||||
|
||||
// 打开字典数据
|
||||
// 打开字典项
|
||||
function handleOpenDictData(row: DictPageVO) {
|
||||
router.push({
|
||||
path: "/system/dict-data",
|
||||
path: "/system/dict-item",
|
||||
query: { dictCode: row.dictCode, title: "【" + row.name + "】字典数据" },
|
||||
});
|
||||
|
||||
/* router.push({
|
||||
name: "DictData",
|
||||
params: { dictCode: row.dictCode, title: "【" + row.name + "】字典数据" },
|
||||
}); */
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
@@ -60,7 +60,7 @@ defineOptions({
|
||||
inheritAttrs: false,
|
||||
});
|
||||
|
||||
import LogAPI, { LogPageVO, LogPageQuery } from "@/api/system/log";
|
||||
import LogAPI, { LogPageVO, LogPageQuery } from "@/api/system/log.api";
|
||||
|
||||
const queryFormRef = ref();
|
||||
|
||||
|
||||
@@ -335,8 +335,8 @@ defineOptions({
|
||||
inheritAttrs: false,
|
||||
});
|
||||
|
||||
import MenuAPI, { MenuQuery, MenuForm, MenuVO } from "@/api/system/menu";
|
||||
import { MenuTypeEnum } from "@/enums/MenuTypeEnum";
|
||||
import MenuAPI, { MenuQuery, MenuForm, MenuVO } from "@/api/system/menu.api";
|
||||
import { MenuTypeEnum } from "@/enums/system/menu.enum";
|
||||
|
||||
const queryFormRef = ref();
|
||||
const menuFormRef = ref();
|
||||
@@ -465,7 +465,7 @@ function handleSubmit() {
|
||||
handleQuery();
|
||||
});
|
||||
} else {
|
||||
MenuAPI.add(formData.value).then(() => {
|
||||
MenuAPI.create(formData.value).then(() => {
|
||||
ElMessage.success("新增成功");
|
||||
handleCloseDialog();
|
||||
handleQuery();
|
||||
|
||||
@@ -107,7 +107,7 @@ defineOptions({
|
||||
inheritAttrs: false,
|
||||
});
|
||||
|
||||
import NoticeAPI, { NoticePageVO, NoticePageQuery, NoticeDetailVO } from "@/api/system/notice";
|
||||
import NoticeAPI, { NoticePageVO, NoticePageQuery, NoticeDetailVO } from "@/api/system/notice.api";
|
||||
|
||||
const queryFormRef = ref();
|
||||
const pageData = ref<NoticePageVO[]>([]);
|
||||
|
||||
@@ -259,8 +259,8 @@ import NoticeAPI, {
|
||||
NoticeForm,
|
||||
NoticePageQuery,
|
||||
NoticeDetailVO,
|
||||
} from "@/api/system/notice";
|
||||
import UserAPI from "@/api/system/user";
|
||||
} from "@/api/system/notice.api";
|
||||
import UserAPI from "@/api/system/user.api";
|
||||
|
||||
const queryFormRef = ref();
|
||||
const dataFormRef = ref();
|
||||
@@ -389,7 +389,7 @@ function handleSubmit() {
|
||||
})
|
||||
.finally(() => (loading.value = false));
|
||||
} else {
|
||||
NoticeAPI.add(formData)
|
||||
NoticeAPI.create(formData)
|
||||
.then(() => {
|
||||
ElMessage.success("新增成功");
|
||||
handleCloseDialog();
|
||||
|
||||
@@ -208,8 +208,8 @@ defineOptions({
|
||||
inheritAttrs: false,
|
||||
});
|
||||
|
||||
import RoleAPI, { RolePageVO, RoleForm, RolePageQuery } from "@/api/system/role";
|
||||
import MenuAPI from "@/api/system/menu";
|
||||
import RoleAPI, { RolePageVO, RoleForm, RolePageQuery } from "@/api/system/role.api";
|
||||
import MenuAPI from "@/api/system/menu.api";
|
||||
|
||||
const queryFormRef = ref();
|
||||
const roleFormRef = ref();
|
||||
@@ -313,7 +313,7 @@ function handleSubmit() {
|
||||
})
|
||||
.finally(() => (loading.value = false));
|
||||
} else {
|
||||
RoleAPI.add(formData)
|
||||
RoleAPI.create(formData)
|
||||
.then(() => {
|
||||
ElMessage.success("新增成功");
|
||||
handleCloseDialog();
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import DeptAPI from "@/api/system/dept";
|
||||
import DeptAPI from "@/api/system/dept.api";
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: [Number],
|
||||
|
||||
@@ -90,8 +90,8 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ElMessage, type UploadUserFile } from "element-plus";
|
||||
import UserAPI from "@/api/system/user";
|
||||
import { ResultEnum } from "@/enums/ResultEnum";
|
||||
import UserAPI from "@/api/system/user.api";
|
||||
import { ResultEnum } from "@/enums/api/result.enum";
|
||||
|
||||
const emit = defineEmits(["import-success"]);
|
||||
const visible = defineModel("modelValue", {
|
||||
|
||||
@@ -237,10 +237,10 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import UserAPI, { UserForm, UserPageQuery, UserPageVO } from "@/api/system/user";
|
||||
import UserAPI, { UserForm, UserPageQuery, UserPageVO } from "@/api/system/user.api";
|
||||
|
||||
import DeptAPI from "@/api/system/dept";
|
||||
import RoleAPI from "@/api/system/role";
|
||||
import DeptAPI from "@/api/system/dept.api";
|
||||
import RoleAPI from "@/api/system/role.api";
|
||||
|
||||
import DeptTree from "./components/DeptTree.vue";
|
||||
import UserImport from "./components/UserImport.vue";
|
||||
@@ -301,7 +301,7 @@ const roleOptions = ref<OptionType[]>();
|
||||
const importDialogVisible = ref(false);
|
||||
|
||||
// 查询
|
||||
function handleQuery() {
|
||||
async function handleQuery() {
|
||||
loading.value = true;
|
||||
UserAPI.getPage(queryParams)
|
||||
.then((data) => {
|
||||
@@ -395,7 +395,7 @@ const handleSubmit = useDebounceFn(() => {
|
||||
})
|
||||
.finally(() => (loading.value = false));
|
||||
} else {
|
||||
UserAPI.add(formData)
|
||||
UserAPI.create(formData)
|
||||
.then(() => {
|
||||
ElMessage.success("新增用户成功");
|
||||
handleCloseDialog();
|
||||
|
||||
Reference in New Issue
Block a user