refactor: 更新API接口与数据结构,统一分页返回格式

This commit is contained in:
Ray.Hao
2026-01-09 00:07:25 +08:00
parent 4a8efc770e
commit a5885d0710
64 changed files with 1085 additions and 910 deletions

View File

@@ -259,12 +259,12 @@
<script setup lang="ts">
defineOptions({
name: "AiCommandRecord",
name: "AiAssistantRecord",
inheritAttrs: false,
});
import AiCommandApi from "@/api/ai";
import type { AiCommandRecordVo, AiCommandRecordPageQuery } from "@/types/api";
import type { AiAssistantRecordItem, AiAssistantRecordQueryParams } from "@/types/api";
import { onMounted, reactive, ref } from "vue";
const queryFormRef = ref();
@@ -272,7 +272,7 @@ const queryFormRef = ref();
const loading = ref(false);
const total = ref(0);
const queryParams = reactive<AiCommandRecordPageQuery>({
const queryParams = reactive<AiAssistantRecordQueryParams>({
pageNum: 1,
pageSize: 10,
keywords: "",
@@ -283,10 +283,10 @@ const queryParams = reactive<AiCommandRecordPageQuery>({
createTime: ["", ""],
});
const pageData = ref<AiCommandRecordVo[]>([]);
const pageData = ref<AiAssistantRecordItem[]>([]);
const detailDialogVisible = ref(false);
const currentRow = ref<AiCommandRecordVo>();
const currentRow = ref<AiAssistantRecordItem>();
function getExecuteStatusText(status: number): string {
switch (status) {
@@ -317,9 +317,9 @@ function getExecuteStatusTagType(status: number): "info" | "success" | "danger"
function fetchData() {
loading.value = true;
AiCommandApi.getPage(queryParams)
.then((data) => {
pageData.value = data.list || [];
total.value = data.total || 0;
.then((res) => {
pageData.value = res.data || [];
total.value = res.page?.total ?? 0;
})
.finally(() => {
loading.value = false;
@@ -337,7 +337,7 @@ function handleResetQuery() {
fetchData();
}
function handleViewDetail(row: AiCommandRecordVo) {
function handleViewDetail(row: AiAssistantRecordItem) {
currentRow.value = row;
detailDialogVisible.value = true;
}

View File

@@ -525,7 +525,7 @@ import type { EditorConfiguration } from "codemirror";
import { FormTypeEnum, QueryTypeEnum } from "@/enums/codegen";
import GeneratorAPI from "@/api/codegen";
import type { FieldConfig, GenConfigForm, TablePageQuery, TablePageVo } from "@/api/types";
import type { FieldConfig, GenConfigForm, TableQueryParams, TableItem } from "@/api/types";
import { ElLoading } from "element-plus";
import DictAPI from "@/api/system/dict";
@@ -574,7 +574,7 @@ const filteredTreeData = computed<TreeNode[]>(() => {
});
const queryFormRef = ref();
const queryParams = reactive<TablePageQuery>({
const queryParams = reactive<TableQueryParams>({
pageNum: 1,
pageSize: 10,
});
@@ -582,13 +582,13 @@ const queryParams = reactive<TablePageQuery>({
const loading = ref(false);
const loadingText = ref("loading...");
const pageData = ref<TablePageVo[]>([]);
const pageData = ref<TableItem[]>([]);
const total = ref(0);
const formTypeOptions: Record<string, OptionType> = FormTypeEnum;
const queryTypeOptions: Record<string, OptionType> = QueryTypeEnum;
const dictOptions = ref<OptionType[]>();
const menuOptions = ref<OptionType[]>([]);
const formTypeOptions: Record<string, OptionItem> = FormTypeEnum;
const queryTypeOptions: Record<string, OptionItem> = QueryTypeEnum;
const dictOptions = ref<OptionItem[]>();
const menuOptions = ref<OptionItem[]>([]);
const genConfigFormData = ref<GenConfigForm>({
fieldConfigs: [],
pageType: "classic",
@@ -818,9 +818,9 @@ function handleNextClick() {
function handleQuery() {
loading.value = true;
GeneratorAPI.getTablePage(queryParams)
.then((data) => {
pageData.value = data.list;
total.value = data.total;
.then((res) => {
pageData.value = res.data;
total.value = res.page?.total ?? 0;
})
.finally(() => {
loading.value = false;

View File

@@ -359,7 +359,7 @@ defineOptions({
import { dayjs } from "element-plus";
import { ref } from "vue";
import StatisticsAPI from "@/api/system/statistics";
import type { VisitStatsVo, VisitTrendVo } from "@/types/api";
import type { VisitStatsDetail, VisitTrendDetail } from "@/types/api";
import { useUserStore } from "@/store/modules/user";
import { formatGrowthRate } from "@/utils";
import { useTransition, useDateFormat } from "@vueuse/core";
@@ -447,7 +447,7 @@ const greetings = computed(() => {
// 访客统计数据加载状态
const visitStatsLoading = ref(true);
// 访客统计数据
const visitStatsData = ref<VisitStatsVo>({
const visitStatsData = ref<VisitStatsDetail>({
todayUvCount: 0,
uvGrowthRate: 0,
totalUvCount: 0,
@@ -543,7 +543,7 @@ const fetchVisitTrendData = () => {
*
* @param data - 访问趋势数据
*/
const updateVisitTrendChartOptions = (data: VisitTrendVo) => {
const updateVisitTrendChartOptions = (data: VisitTrendDetail) => {
visitTrendChartOptions.value = {
tooltip: {
trigger: "axis",

View File

@@ -71,7 +71,7 @@
import UserAPI from "@/api/system/user";
import DeptAPI from "@/api/system/dept";
import RoleAPI from "@/api/system/role";
import type { UserForm, UserPageQuery } from "@/types/api";
import type { UserForm, UserQueryParams, UserItem } from "@/types/api";
import type { IObject, IModalConfig, IContentConfig, ISearchConfig } from "@/components/CURD/types";
import { DeviceEnum } from "@/enums/settings";
import { useAppStore } from "@/store";
@@ -83,16 +83,16 @@ defineOptions({
});
// ========================= 选项数据管理 =========================
interface OptionType {
interface OptionItem {
label: string;
value: any;
[key: string]: any;
}
// 共享选项数据
const deptArr = ref<OptionType[]>([]);
const roleArr = ref<OptionType[]>([]);
const stateArr = ref<OptionType[]>([
const deptArr = ref<OptionItem[]>([]);
const roleArr = ref<OptionItem[]>([]);
const stateArr = ref<OptionItem[]>([
{ label: "启用", value: 1 },
{ label: "禁用", value: 0 },
]);
@@ -165,7 +165,7 @@ const searchConfig: ISearchConfig = reactive({
});
// ========================= 内容配置 =========================
const contentConfig: IContentConfig<UserPageQuery> = reactive({
const contentConfig: IContentConfig<UserQueryParams, UserItem> = reactive({
permPrefix: "sys:user",
table: {
border: true,
@@ -177,12 +177,6 @@ const contentConfig: IContentConfig<UserPageQuery> = reactive({
pageSize: 20,
pageSizes: [10, 20, 30, 50],
},
parseData(res: any) {
return {
total: res.total,
list: res.list,
};
},
indexAction(params: any) {
return UserAPI.getPage(params);
},
@@ -198,8 +192,8 @@ const contentConfig: IContentConfig<UserPageQuery> = reactive({
},
async exportsAction(params: any) {
const res = await UserAPI.getPage(params);
console.log("exportsAction", res.list);
return res.list;
console.log("exportsAction", res.data);
return res.data;
},
pk: "id",
toolbar: [

View File

@@ -1,9 +1,9 @@
import UserAPI from "@/api/system/user";
import RoleAPI from "@/api/system/role";
import type { UserPageQuery } from "@/types/api";
import type { UserQueryParams, UserItem } from "@/types/api";
import type { IContentConfig } from "@/components/CURD/types";
const contentConfig: IContentConfig<UserPageQuery> = {
const contentConfig: IContentConfig<UserQueryParams, UserItem> = {
permPrefix: "sys:user", // 不写不进行按钮权限校验
table: {
border: true,
@@ -15,12 +15,6 @@ const contentConfig: IContentConfig<UserPageQuery> = {
pageSize: 20,
pageSizes: [10, 20, 30, 50],
},
parseData(res) {
return {
total: res.total,
list: res.list,
};
},
indexAction(params) {
return UserAPI.getPage(params);
},
@@ -38,8 +32,8 @@ const contentConfig: IContentConfig<UserPageQuery> = {
async exportsAction(params) {
// 模拟获取到的是全量数据
const res = await UserAPI.getPage(params);
console.log("exportsAction", res.list);
return res.list;
console.log("exportsAction", res.data);
return res.data;
},
pk: "id",
toolbar: [

View File

@@ -2,16 +2,16 @@
import DeptAPI from "@/api/system/dept";
import RoleAPI from "@/api/system/role";
interface OptionType {
interface OptionItem {
label: string;
value: any;
[key: string]: any; // 允许其他属性
}
// 明确指定类型为 OptionType[]
export const deptArr = ref<OptionType[]>([]);
export const roleArr = ref<OptionType[]>([]);
export const stateArr = ref<OptionType[]>([
// 明确指定类型为 OptionItem[]
export const deptArr = ref<OptionItem[]>([]);
export const roleArr = ref<OptionItem[]>([]);
export const stateArr = ref<OptionItem[]>([
{ label: "启用", value: 1 },
{ label: "禁用", value: 0 },
]);

View File

@@ -1,6 +1,27 @@
import type { IContentConfig } from "@/components/CURD/types";
const contentConfig: IContentConfig = {
interface DemoQueryParams {
pageNum?: number;
pageSize?: number;
[key: string]: any;
}
interface DemoItem {
id: number;
username: string;
avatar: string;
percent: number;
price: number;
url: string;
icon: string;
gender: number;
status: number;
status2: number;
sort: number;
createTime: number;
}
const contentConfig: IContentConfig<DemoQueryParams, DemoItem> = {
// permPrefix: "sys:demo", // 不写不进行按钮权限校验
table: {
showOverflowTooltip: true,
@@ -10,38 +31,49 @@ const contentConfig: IContentConfig = {
indexAction(params) {
// 模拟发起网络请求获取列表数据
console.log("indexAction:", params);
const list = [
{
id: 1,
username: "root",
avatar: "https://foruda.gitee.com/images/1723603502796844527/03cdca2a_716974.gif",
percent: 99,
price: 10,
url: "https://www.baidu.com",
icon: "el-icon-setting",
gender: 1,
status: 1,
status2: 1,
sort: 99,
createTime: 1715647982437,
},
{
id: 2,
username: "jerry",
avatar: "https://foruda.gitee.com/images/1723603502796844527/03cdca2a_716974.gif",
percent: 88,
price: 999,
url: "https://www.google.com",
icon: "el-icon-user",
gender: 0,
status: 0,
status2: 0,
sort: 0,
createTime: 1715648977426,
},
];
const pageNum = Number(params?.pageNum ?? 1) || 1;
const pageSize = Number(params?.pageSize ?? list.length) || list.length;
const start = (pageNum - 1) * pageSize;
const end = start + pageSize;
return Promise.resolve({
total: 2,
list: [
{
id: 1,
username: "root",
avatar: "https://foruda.gitee.com/images/1723603502796844527/03cdca2a_716974.gif",
percent: 99,
price: 10,
url: "https://www.baidu.com",
icon: "el-icon-setting",
gender: 1,
status: 1,
status2: 1,
sort: 99,
createTime: 1715647982437,
},
{
id: 2,
username: "jerry",
avatar: "https://foruda.gitee.com/images/1723603502796844527/03cdca2a_716974.gif",
percent: 88,
price: 999,
url: "https://www.google.com",
icon: "el-icon-user",
gender: 0,
status: 0,
status2: 0,
sort: 0,
createTime: 1715648977426,
},
],
data: list.slice(start, end),
page: {
pageNum,
pageSize,
total: list.length,
},
});
},
modifyAction(data) {

View File

@@ -56,10 +56,13 @@
border-rd-4px
w-full
h-full
object-contain
block
object-cover
shadow="[0_0_0_1px_var(--el-border-color)_inset]"
:src="captchaBase64"
alt="captchaCode"
title="点击刷新验证码"
@error="getCaptcha"
/>
<el-text v-else type="info" size="small">点击获取验证码</el-text>
</div>

View File

@@ -227,7 +227,8 @@ onBeforeUnmount(() => {
animation: featureFade 0.8s ease-out;
@media (prefers-color-scheme: dark) {
color: rgba(236, 242, 255, 0.92);
/* use theme variable so dark mode colors follow theme variables */
color: var(--el-text-color-primary);
}
}

View File

@@ -226,7 +226,7 @@
<script lang="ts" setup>
import UserAPI from "@/api/system/user";
import type {
UserProfileVo,
UserProfileDetail,
PasswordChangeForm,
MobileUpdateForm,
EmailUpdateForm,
@@ -241,7 +241,7 @@ import { Camera } from "@element-plus/icons-vue";
const userStore = useUserStoreHook();
const userProfile = ref<UserProfileVo>({});
const userProfile = ref<UserProfileDetail>({});
const enum DialogType {
ACCOUNT = "account",

View File

@@ -116,27 +116,27 @@ defineOptions({
import { onMounted, reactive, ref } from "vue";
import { ElMessage } from "element-plus";
import NoticeAPI from "@/api/system/notice";
import type { NoticePageVo, NoticePageQuery } from "@/types/api";
import type { NoticeDetail, NoticeItem, NoticeQueryParams } from "@/types/api";
const queryFormRef = ref();
const pageData = ref<NoticePageVo[]>([]);
const pageData = ref<NoticeItem[]>([]);
const loading = ref(false);
const total = ref(0);
const queryParams = reactive<NoticePageQuery>({
const queryParams = reactive<NoticeQueryParams>({
pageNum: 1,
pageSize: 10,
});
const noticeDialogVisible = ref(false);
const noticeDetail = ref<any>(null);
const noticeDetail = ref<NoticeDetail | null>(null);
async function handleQuery() {
loading.value = true;
try {
const data = await NoticeAPI.getMyNoticePage(queryParams);
pageData.value = data.list;
total.value = data.total;
const res = await NoticeAPI.getMyNoticePage(queryParams);
pageData.value = res.data;
total.value = res.page?.total ?? 0;
} catch (error) {
ElMessage.error("获取通知列表失败");
console.error("获取我的通知失败", error);

View File

@@ -142,7 +142,7 @@ defineOptions({
});
import ConfigAPI from "@/api/system/config";
import type { ConfigPageVo, ConfigForm, ConfigPageQuery } from "@/types/api";
import type { ConfigItem, ConfigForm, ConfigQueryParams } from "@/types/api";
import { ElMessage, ElMessageBox } from "element-plus";
import { useDebounceFn } from "@vueuse/core";
@@ -153,14 +153,14 @@ const loading = ref(false);
const selectIds = ref<number[]>([]);
const total = ref(0);
const queryParams = reactive<ConfigPageQuery>({
const queryParams = reactive<ConfigQueryParams>({
pageNum: 1,
pageSize: 10,
keywords: "",
});
// 系统配置表格数据
const pageData = ref<ConfigPageVo[]>([]);
const pageData = ref<ConfigItem[]>([]);
const dialog = reactive({
title: "",
@@ -185,9 +185,9 @@ const rules = reactive({
function fetchData() {
loading.value = true;
ConfigAPI.getPage(queryParams)
.then((data) => {
pageData.value = data.list;
total.value = data.total;
.then((res) => {
pageData.value = res.data;
total.value = res.page?.total ?? 0;
})
.finally(() => {
loading.value = false;

View File

@@ -164,22 +164,22 @@ defineOptions({
});
import DeptAPI from "@/api/system/dept";
import type { DeptVo, DeptForm, DeptQuery } from "@/types/api";
import type { DeptItem, DeptForm, DeptQueryParams } from "@/types/api";
const queryFormRef = ref();
const deptFormRef = ref();
const loading = ref(false);
const selectIds = ref<number[]>([]);
const queryParams = reactive<DeptQuery>({});
const queryParams = reactive<DeptQueryParams>({});
const dialog = reactive({
title: "",
visible: false,
});
const deptList = ref<DeptVo[]>();
const deptOptions = ref<OptionType[]>();
const deptList = ref<DeptItem[]>();
const deptOptions = ref<OptionItem[]>();
const formData = reactive<DeptForm>({
status: 1,
parentId: "0",

View File

@@ -156,7 +156,7 @@
<script setup lang="ts">
import type { TagProps } from "element-plus";
import DictAPI from "@/api/system/dict";
import type { DictItemPageQuery, DictItemPageVo, DictItemForm } from "@/types/api";
import type { DictItemQueryParams, DictItem, DictItemForm } from "@/types/api";
const route = useRoute();
@@ -169,12 +169,12 @@ const loading = ref(false);
const ids = ref<number[]>([]);
const total = ref(0);
const queryParams = reactive<DictItemPageQuery>({
const queryParams = reactive<DictItemQueryParams>({
pageNum: 1,
pageSize: 10,
});
const tableData = ref<DictItemPageVo[]>();
const tableData = ref<DictItem[]>();
const dialog = reactive({
title: "",
@@ -199,9 +199,9 @@ const computedRules = computed(() => {
function fetchData() {
loading.value = true;
DictAPI.getDictItemPage(dictCode.value, queryParams)
.then((data) => {
tableData.value = data.list;
total.value = data.total;
.then((res) => {
tableData.value = res.data;
total.value = res.page?.total ?? 0;
})
.finally(() => {
loading.value = false;
@@ -227,7 +227,7 @@ function handleSelectionChange(selection: any) {
}
// 打开弹窗
function handleOpenDialog(row?: DictItemPageVo) {
function handleOpenDialog(row?: DictItem) {
dialog.visible = true;
dialog.title = row ? "编辑字典值" : "新增字典值";

View File

@@ -1,4 +1,4 @@
<!-- 字典 -->
<!-- 字典 -->
<template>
<div class="app-container">
<!-- 搜索区域 -->
@@ -139,7 +139,7 @@ defineOptions({
import { ref, reactive } from "vue";
import DictAPI from "@/api/system/dict";
import type { DictPageQuery, DictPageVo, DictForm } from "@/types/api";
import type { DictTypeQueryParams, DictTypeItem, DictTypeForm } from "@/types/api";
import router from "@/router";
@@ -150,19 +150,19 @@ const loading = ref(false);
const ids = ref<number[]>([]);
const total = ref(0);
const queryParams = reactive<DictPageQuery>({
const queryParams = reactive<DictTypeQueryParams>({
pageNum: 1,
pageSize: 10,
});
const tableData = ref<DictPageVo[]>();
const tableData = ref<DictTypeItem[]>();
const dialog = reactive({
title: "",
visible: false,
});
const formData = reactive<DictForm>({});
const formData = reactive<DictTypeForm>({});
const computedRules = computed(() => {
const rules: Partial<Record<string, any>> = {
@@ -176,9 +176,9 @@ const computedRules = computed(() => {
function fetchData() {
loading.value = true;
DictAPI.getPage(queryParams)
.then((data) => {
tableData.value = data.list;
total.value = data.total;
.then((res) => {
tableData.value = res.data;
total.value = res.page?.total ?? 0;
})
.finally(() => {
loading.value = false;
@@ -287,7 +287,7 @@ function handleDelete(id?: number) {
}
// 打开字典值"
function handleOpenDictData(row: DictPageVo) {
function handleOpenDictData(row: DictTypeItem) {
router.push({
path: "/system/dict-item",
query: { dictCode: row.dictCode, title: `${row.name}】字典数据` },

View File

@@ -69,14 +69,14 @@ defineOptions({
});
import LogAPI from "@/api/system/log";
import type { LogPageVo, LogPageQuery } from "@/types/api";
import type { LogItem, LogQueryParams } from "@/types/api";
const queryFormRef = ref();
const loading = ref(false);
const total = ref(0);
const queryParams = reactive<LogPageQuery>({
const queryParams = reactive<LogQueryParams>({
pageNum: 1,
pageSize: 10,
keywords: "",
@@ -84,15 +84,15 @@ const queryParams = reactive<LogPageQuery>({
});
// 日志表格数据
const pageData = ref<LogPageVo[]>();
const pageData = ref<LogItem[]>();
/** 获取数据 */
function fetchData() {
loading.value = true;
LogAPI.getPage(queryParams)
.then((data) => {
pageData.value = data.list;
total.value = data.total;
.then((res) => {
pageData.value = res.data;
total.value = res.page?.total ?? 0;
})
.finally(() => {
loading.value = false;

View File

@@ -345,7 +345,7 @@ import { useAppStore } from "@/store/modules/app";
import { DeviceEnum } from "@/enums/settings";
import MenuAPI from "@/api/system/menu";
import type { MenuQuery, MenuForm, MenuVo } from "@/types/api";
import type { MenuQueryParams, MenuForm, MenuItem } from "@/types/api";
import { MenuTypeEnum } from "@/enums/business";
defineOptions({
@@ -366,11 +366,11 @@ const dialog = reactive({
const drawerSize = computed(() => (appStore.device === DeviceEnum.DESKTOP ? "600px" : "90%"));
// 查询参数
const queryParams = reactive<MenuQuery>({});
const queryParams = reactive<MenuQueryParams>({});
// 菜单表格数据
const menuTableData = ref<MenuVo[]>([]);
const menuTableData = ref<MenuItem[]>([]);
// 顶级菜单下拉选项
const menuOptions = ref<OptionType[]>([]);
const menuOptions = ref<OptionItem[]>([]);
// 初始菜单表单数据
const initialMenuFormData = ref<MenuForm>({
id: undefined,
@@ -437,7 +437,7 @@ function handleResetQuery() {
}
// 行点击事件
function handleRowClick(row: MenuVo) {
function handleRowClick(row: MenuItem) {
selectedMenuId.value = row.id;
}

View File

@@ -262,7 +262,7 @@ defineOptions({
import { ref, reactive } from "vue";
import NoticeAPI from "@/api/system/notice";
import type { NoticePageVo, NoticeForm, NoticePageQuery, NoticeDetailVo } from "@/types/api";
import type { NoticeItem, NoticeForm, NoticeQueryParams, NoticeDetail } from "@/types/api";
import UserAPI from "@/api/system/user";
const queryFormRef = ref();
@@ -272,14 +272,14 @@ const loading = ref(false);
const selectIds = ref<number[]>([]);
const total = ref(0);
const queryParams = reactive<NoticePageQuery>({
const queryParams = reactive<NoticeQueryParams>({
pageNum: 1,
pageSize: 10,
});
const userOptions = ref<OptionType[]>([]);
const userOptions = ref<OptionItem[]>([]);
// 通知公告表格数据
const pageData = ref<NoticePageVo[]>([]);
const pageData = ref<NoticeItem[]>([]);
// 弹窗
const dialog = reactive({
@@ -316,7 +316,7 @@ const rules = reactive({
const detailDialog = reactive({
visible: false,
});
const currentNotice = ref<NoticeDetailVo>({});
const currentNotice = ref<NoticeDetail>({});
// 查询通知公告
function handleQuery() {
@@ -328,9 +328,9 @@ function handleQuery() {
function fetchData() {
loading.value = true;
NoticeAPI.getPage(queryParams)
.then((data) => {
pageData.value = data.list;
total.value = data.total;
.then((res) => {
pageData.value = res.data;
total.value = res.page?.total ?? 0;
})
.finally(() => {
loading.value = false;

View File

@@ -63,7 +63,7 @@
size="small"
link
icon="position"
@click="handleOpenAssignPermDialog(scope.row)"
@click="openRolePermissionAssignment(scope.row)"
>
分配权限
</el-button>
@@ -216,7 +216,7 @@ import { useAppStore } from "@/store/modules/app";
import { DeviceEnum } from "@/enums/settings";
import RoleAPI from "@/api/system/role";
import type { RolePageVo, RoleForm, RolePageQuery } from "@/types/api";
import type { RoleItem, RoleForm, RoleQueryParams } from "@/types/api";
import MenuAPI from "@/api/system/menu";
defineOptions({
@@ -234,15 +234,15 @@ const loading = ref(false);
const ids = ref<number[]>([]);
const total = ref(0);
const queryParams = reactive<RolePageQuery>({
const queryParams = reactive<RoleQueryParams>({
pageNum: 1,
pageSize: 10,
});
// 角色表格数据
const roleList = ref<RolePageVo[]>();
const roleList = ref<RoleItem[]>();
// 菜单权限下拉
const menuPermOptions = ref<OptionType[]>([]);
const menuPermOptions = ref<OptionItem[]>([]);
// 弹窗
const dialog = reactive({
@@ -282,9 +282,9 @@ const parentChildLinked = ref(true);
function fetchData() {
loading.value = true;
RoleAPI.getPage(queryParams)
.then((data) => {
roleList.value = data.list;
total.value = data.total;
.then((res) => {
roleList.value = res.data;
total.value = res.page?.total ?? 0;
})
.finally(() => {
loading.value = false;
@@ -390,7 +390,7 @@ function handleDelete(roleId?: number) {
}
// 打开分配菜单权限弹窗
async function handleOpenAssignPermDialog(row: RolePageVo) {
async function openRolePermissionAssignment(row: RoleItem) {
const roleId = row.id;
if (roleId) {
assignPermDialogVisible.value = true;

View File

@@ -204,7 +204,7 @@ import { useDebounceFn } from "@vueuse/core";
import { hasPerm } from "@/utils/auth";
import TenantAPI from "@/api/system/tenant";
import type { TenantCreateForm, TenantForm, TenantPageQuery, TenantPageVo } from "@/types/api";
import type { TenantCreateForm, TenantForm, TenantQueryParams, TenantItem } from "@/types/api";
const queryFormRef = ref();
const dataFormRef = ref();
@@ -213,13 +213,13 @@ const loading = ref(false);
const ids = ref<number[]>([]);
const total = ref(0);
const queryParams = reactive<TenantPageQuery>({
const queryParams = reactive<TenantQueryParams>({
pageNum: 1,
pageSize: 10,
keywords: "",
});
const pageData = ref<TenantPageVo[]>([]);
const pageData = ref<TenantItem[]>([]);
const dialog = reactive({
title: "",
@@ -250,9 +250,9 @@ const hasPermChangeStatus = computed(() => hasPerm("sys:tenant:change-status"));
function fetchData() {
loading.value = true;
TenantAPI.getPage(queryParams)
.then((data) => {
pageData.value = data.list;
total.value = data.total;
.then((res) => {
pageData.value = res.data;
total.value = res.page?.total ?? 0;
})
.finally(() => {
loading.value = false;

View File

@@ -28,7 +28,7 @@ const props = defineProps({
},
});
const deptList = ref<OptionType[]>(); // 部门列表
const deptList = ref<OptionItem[]>(); // 部门列表
const deptTreeRef = ref(); // 部门树
const deptName = ref(); // 部门名称

View File

@@ -116,7 +116,7 @@
</el-tag>
</template>
</el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" width="150" />
<el-table-column label="创建时间" align="center" prop="createTime" width="180" />
<el-table-column label="操作" fixed="right" width="220">
<template #default="scope">
<el-button
@@ -253,7 +253,7 @@ import { useDebounceFn } from "@vueuse/core";
import { ElMessage, ElMessageBox, type FormInstance } from "element-plus";
// ==================== 3. 类型定义 ====================
import type { UserForm, UserPageQuery, UserPageVo } from "@/types/api";
import type { UserForm, UserQueryParams, UserItem } from "@/types/api";
// ==================== 3.5 工具函数 ====================
import { downloadFile, VALIDATORS } from "@/utils";
@@ -292,13 +292,13 @@ const queryFormRef = ref<FormInstance>();
const userFormRef = ref<FormInstance>();
// 列表查询参数
const queryParams = reactive<UserPageQuery>({
const queryParams = reactive<UserQueryParams>({
pageNum: 1,
pageSize: 10,
});
// 列表数据
const userList = ref<UserPageVo[]>([]);
const userList = ref<UserItem[]>([]);
const total = ref(0);
const loading = ref(false);
@@ -318,8 +318,8 @@ const initialFormData: UserForm = {
const formData = reactive<UserForm>({ ...initialFormData });
// 下拉选项数据
const deptOptions = ref<OptionType[]>();
const roleOptions = ref<OptionType[]>();
const deptOptions = ref<OptionItem[]>();
const roleOptions = ref<OptionItem[]>();
// 导入弹窗
const importDialogVisible = ref(false);
@@ -350,9 +350,9 @@ const rules = reactive({
async function fetchUserList(): Promise<void> {
loading.value = true;
try {
const data = await UserAPI.getPage(queryParams);
userList.value = data.list;
total.value = data.total;
const res = await UserAPI.getPage(queryParams);
userList.value = res.data;
total.value = res.page?.total ?? 0;
} catch (error) {
ElMessage.error("获取用户列表失败");
console.error("获取用户列表失败:", error);
@@ -362,7 +362,7 @@ async function fetchUserList(): Promise<void> {
}
// ==================== 表格选择 ====================
const { selectedIds, hasSelection, handleSelectionChange } = useTableSelection<UserPageVo>();
const { selectedIds, hasSelection, handleSelectionChange } = useTableSelection<UserItem>();
// ==================== 查询操作 ====================
@@ -389,7 +389,7 @@ function handleResetQuery(): void {
* 重置用户密码
* @param row 用户数据
*/
function handleResetPassword(row: UserPageVo): void {
function handleResetPassword(row: UserItem): void {
ElMessageBox.prompt(`请输入用户【${row.username}】的新密码`, "重置密码", {
confirmButtonText: "确定",
cancelButtonText: "取消",