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

@@ -47,55 +47,57 @@ export default defineMock([
return { return {
code: "00000", code: "00000",
data: { data: [
list: [ {
{ id: "10001",
id: "10001", userId: 1,
userId: 1, username: "admin",
username: "admin", originalCommand: "跳转到用户管理",
originalCommand: "跳转到用户管理", aiProvider: "qwen",
aiProvider: "qwen", aiModel: "qwen-plus",
aiModel: "qwen-plus", parseStatus: 1,
parseStatus: 1, functionCalls: JSON.stringify(
functionCalls: JSON.stringify( [
[ {
{ name: "navigate",
name: "navigate", arguments: { path: "/system/user" },
arguments: { path: "/system/user" }, },
}, ],
], null,
null, 0
0 ),
), explanation: "Mock: 识别到跳转用户管理",
explanation: "Mock: 识别到跳转用户管理", confidence: 0.92,
confidence: 0.92, parseDurationMs: 128,
parseDurationMs: 128, functionName: "navigate",
functionName: "navigate", functionArguments: JSON.stringify({ path: "/system/user" }),
functionArguments: JSON.stringify({ path: "/system/user" }), executeStatus: 1,
executeStatus: 1, ipAddress: "127.0.0.1",
ipAddress: "127.0.0.1", createTime: "2025-12-17 15:00:00",
createTime: "2025-12-17 15:00:00", updateTime: "2025-12-17 15:00:00",
updateTime: "2025-12-17 15:00:00", },
}, {
{ id: "10002",
id: "10002", userId: 1,
userId: 1, username: "admin",
username: "admin", originalCommand: "获取姓名为张三的用户信息",
originalCommand: "获取姓名为张三的用户信息", aiProvider: "qwen",
aiProvider: "qwen", aiModel: "qwen-plus",
aiModel: "qwen-plus", parseStatus: 0,
parseStatus: 0, functionCalls: "[]",
functionCalls: "[]", explanation: "Mock: 解析失败示例",
explanation: "Mock: 解析失败示例", confidence: 0.2,
confidence: 0.2, parseErrorMessage: "Mock: 无法匹配函数",
parseErrorMessage: "Mock: 无法匹配函数", parseDurationMs: 256,
parseDurationMs: 256, executeStatus: 0,
executeStatus: 0, ipAddress: "127.0.0.1",
ipAddress: "127.0.0.1", createTime: "2025-12-17 15:01:00",
createTime: "2025-12-17 15:01:00", updateTime: "2025-12-17 15:01:00",
updateTime: "2025-12-17 15:01:00", },
}, ].slice((pageNum - 1) * pageSize, pageNum * pageSize),
].slice((pageNum - 1) * pageSize, pageNum * pageSize), page: {
pageNum,
pageSize,
total, total,
}, },
msg: "一切ok", msg: "一切ok",

View File

@@ -2,7 +2,7 @@ import { defineMock } from "./base";
export default defineMock([ export default defineMock([
{ {
url: "dept/options", url: "depts/options",
method: ["GET"], method: ["GET"],
body: { body: {
code: "00000", code: "00000",
@@ -27,7 +27,7 @@ export default defineMock([
}, },
{ {
url: "dept", url: "depts",
method: ["GET"], method: ["GET"],
body: { body: {
code: "00000", code: "00000",
@@ -73,7 +73,7 @@ export default defineMock([
// 新增部门 // 新增部门
{ {
url: "dept", url: "depts",
method: ["POST"], method: ["POST"],
body({ body }) { body({ body }) {
return { return {
@@ -86,7 +86,7 @@ export default defineMock([
// 获取部门表单数据 // 获取部门表单数据
{ {
url: "dept/:id/form", url: "depts/:id/form",
method: ["GET"], method: ["GET"],
body: ({ params }) => { body: ({ params }) => {
return { return {
@@ -99,7 +99,7 @@ export default defineMock([
// 修改部门 // 修改部门
{ {
url: "dept/:id", url: "depts/:id",
method: ["PUT"], method: ["PUT"],
body({ body }) { body({ body }) {
return { return {
@@ -112,7 +112,7 @@ export default defineMock([
// 删除部门 // 删除部门
{ {
url: "dept/:id", url: "depts/:id",
method: ["DELETE"], method: ["DELETE"],
body({ params }) { body({ params }) {
return { return {

View File

@@ -2,19 +2,21 @@ import { defineMock } from "./base";
export default defineMock([ export default defineMock([
{ {
url: "dicts/page", url: "dicts",
method: ["GET"], method: ["GET"],
body: { body: {
code: "00000", code: "00000",
data: { data: [
list: [ {
{ id: 1,
id: 1, name: "性别",
name: "性别", dictCode: "gender",
dictCode: "gender", status: 1,
status: 1, },
}, ],
], page: {
pageNum: 1,
pageSize: 10,
total: 1, total: 1,
}, },
msg: "一切ok", msg: "一切ok",
@@ -25,19 +27,16 @@ export default defineMock([
* 字典列表 * 字典列表
*/ */
{ {
url: "dicts", url: "dicts/options",
method: ["GET"], method: ["GET"],
body: { body: {
code: "00000", code: "00000",
data: { data: [
list: [ {
{ value: "gender",
value: "gender", label: "性别",
label: "性别", },
}, ],
],
total: 1,
},
msg: "一切ok", msg: "一切ok",
}, },
}, },
@@ -100,37 +99,42 @@ export default defineMock([
// 字典项分页列表 // 字典项分页列表
{ {
url: "dicts/:dictCode/items/page", url: "dicts/:dictCode/items",
method: ["GET"], method: ["GET"],
body: { body: {
code: "00000", code: "00000",
data: { data: [
list: [ {
{ id: 1,
id: 1, dictCode: "gender",
dictCode: "gender", label: "",
label: "", value: "1",
value: "1", sort: 1,
sort: 1, status: 1,
status: 1, tagType: "P",
}, },
{ {
id: 2, id: 2,
dictCode: "gender", dictCode: "gender",
label: "女", label: "女",
value: "2", value: "2",
sort: 2, sort: 2,
status: 1, status: 1,
}, tagType: "D",
{ },
id: 3, {
dictCode: "gender", id: 3,
label: "保密", dictCode: "gender",
value: "0", label: "保密",
sort: 3, value: "0",
status: 1, sort: 3,
}, status: 1,
], tagType: "I",
},
],
page: {
pageNum: 1,
pageSize: 10,
total: 3, total: 3,
}, },
msg: "一切ok", msg: "一切ok",
@@ -138,7 +142,7 @@ export default defineMock([
}, },
// 字典项列表 // 字典项列表
{ {
url: "dicts/:dictCode/items", url: "dicts/:dictCode/items/options",
method: ["GET"], method: ["GET"],
body: ({ params }) => { body: ({ params }) => {
const dictCode = params.dictCode; const dictCode = params.dictCode;
@@ -165,17 +169,17 @@ export default defineMock([
{ {
value: "L", value: "L",
label: "低", label: "低",
tag: "info", tagType: "I",
}, },
{ {
value: "M", value: "M",
label: "中", label: "中",
tag: "warning", tagType: "W",
}, },
{ {
value: "H", value: "H",
label: "高", label: "高",
tag: "danger", tagType: "D",
}, },
]; ];
} else if (dictCode == "notice_type") { } else if (dictCode == "notice_type") {
@@ -183,32 +187,32 @@ export default defineMock([
{ {
value: "1", value: "1",
label: "系统升级", label: "系统升级",
tag: "success", tagType: "S",
}, },
{ {
value: "2", value: "2",
label: "系统维护", label: "系统维护",
tag: "primary", tagType: "P",
}, },
{ {
value: "3", value: "3",
label: "安全警告", label: "安全警告",
tag: "danger", tagType: "D",
}, },
{ {
value: "4", value: "4",
label: "假期通知", label: "假期通知",
tag: "success", tagType: "S",
}, },
{ {
value: "5", value: "5",
label: "公司新闻", label: "公司新闻",
tag: "primary", tagType: "P",
}, },
{ {
value: "99", value: "99",
label: "其他", label: "其他",
tag: "info", tagType: "I",
}, },
]; ];
} }
@@ -228,7 +232,7 @@ export default defineMock([
return { return {
code: "00000", code: "00000",
data: null, data: null,
msg: "新增字典" + body.name + "成功", msg: "新增字典" + body.label + "成功",
}; };
}, },
}, },
@@ -254,7 +258,7 @@ export default defineMock([
return { return {
code: "00000", code: "00000",
data: null, data: null,
msg: "修改字典项" + body.name + "成功", msg: "修改字典项" + body.label + "成功",
}; };
}, },
}, },
@@ -291,7 +295,7 @@ const dictItemMap: Record<string, any> = {
label: "男", label: "男",
sort: 1, sort: 1,
status: 1, status: 1,
tagType: "primary", tagType: "P",
}, },
2: { 2: {
id: 2, id: 2,
@@ -299,7 +303,7 @@ const dictItemMap: Record<string, any> = {
label: "女", label: "女",
sort: 2, sort: 2,
status: 1, status: 1,
tagType: "danger", tagType: "D",
}, },
3: { 3: {
id: 3, id: 3,
@@ -307,6 +311,6 @@ const dictItemMap: Record<string, any> = {
label: "保密", label: "保密",
sort: 3, sort: 3,
status: 1, status: 1,
tagType: "info", tagType: "I",
}, },
}; };

View File

@@ -2,163 +2,165 @@ import { defineMock } from "./base";
export default defineMock([ export default defineMock([
{ {
url: "logs/page", url: "logs",
method: ["GET"], method: ["GET"],
body: { body: {
code: "00000", code: "00000",
data: { data: [
list: [ {
{ id: 36192,
id: 36192, module: "菜单",
module: "菜单", content: "菜单列表",
content: "菜单列表", requestUri: "/api/v1/menus",
requestUri: "/api/v1/menus", method: null,
method: null, ip: "183.156.148.241",
ip: "183.156.148.241", region: "浙江省 杭州市",
region: "浙江省 杭州市", browser: "Chrome 109.0.0.0",
browser: "Chrome 109.0.0.0", os: "OSX",
os: "OSX", executionTime: 5,
executionTime: 5, createBy: null,
createBy: null, createTime: "2024-07-07 20:38:47",
createTime: "2024-07-07 20:38:47", operator: "系统管理员",
operator: "系统管理员", },
}, {
{ id: 36190,
id: 36190, module: "字典",
module: "字典", content: "字典分页列表",
content: "字典分页列表", requestUri: "/api/v1/dicts",
requestUri: "/api/v1/dict/page", method: null,
method: null, ip: "183.156.148.241",
ip: "183.156.148.241", region: "浙江省 杭州市",
region: "浙江省 杭州市", browser: "Chrome 109.0.0.0",
browser: "Chrome 109.0.0.0", os: "OSX",
os: "OSX", executionTime: 9,
executionTime: 9, createBy: null,
createBy: null, createTime: "2024-07-07 20:38:45",
createTime: "2024-07-07 20:38:45", operator: "系统管理员",
operator: "系统管理员", },
}, {
{ id: 36193,
id: 36193, module: "部门",
module: "部门", content: "部门列表",
content: "部门列表", requestUri: "/api/v1/depts",
requestUri: "/api/v1/dept", method: null,
method: null, ip: "192.168.31.134",
ip: "192.168.31.134", region: "0 内网IP",
region: "0 内网IP", browser: "Chrome 125.0.0.0",
browser: "Chrome 125.0.0.0", os: "Windows 10 or Windows Server 2016",
os: "Windows 10 or Windows Server 2016", executionTime: 27,
executionTime: 27, createBy: null,
createBy: null, createTime: "2024-07-07 20:38:45",
createTime: "2024-07-07 20:38:45", operator: "系统管理员",
operator: "系统管理员", },
}, {
{ id: 36191,
id: 36191, module: "菜单",
module: "菜单", content: "菜单列表",
content: "菜单列表", requestUri: "/api/v1/menus",
requestUri: "/api/v1/menus", method: null,
method: null, ip: "192.168.31.134",
ip: "192.168.31.134", region: "0 内网IP",
region: "0 内网IP", browser: "Chrome 125.0.0.0",
browser: "Chrome 125.0.0.0", os: "Windows 10 or Windows Server 2016",
os: "Windows 10 or Windows Server 2016", executionTime: 39,
executionTime: 39, createBy: null,
createBy: null, createTime: "2024-07-07 20:38:44",
createTime: "2024-07-07 20:38:44", operator: "系统管理员",
operator: "系统管理员", },
}, {
{ id: 36189,
id: 36189, module: "角色",
module: "角色", content: "角色分页列表",
content: "角色分页列表", requestUri: "/api/v1/roles",
requestUri: "/api/v1/roles/page", method: null,
method: null, ip: "192.168.31.134",
ip: "192.168.31.134", region: "0 内网IP",
region: "0 内网IP", browser: "Chrome 125.0.0.0",
browser: "Chrome 125.0.0.0", os: "Windows 10 or Windows Server 2016",
os: "Windows 10 or Windows Server 2016", executionTime: 55,
executionTime: 55, createBy: null,
createBy: null, createTime: "2024-07-07 20:38:43",
createTime: "2024-07-07 20:38:43", operator: "系统管理员",
operator: "系统管理员", },
}, {
{ id: 36188,
id: 36188, module: "用户",
module: "用户", content: "用户分页列表",
content: "用户分页列表", requestUri: "/api/v1/users",
requestUri: "/api/v1/users/page", method: null,
method: null, ip: "192.168.31.134",
ip: "192.168.31.134", region: "0 内网IP",
region: "0 内网IP", browser: "Chrome 125.0.0.0",
browser: "Chrome 125.0.0.0", os: "Windows 10 or Windows Server 2016",
os: "Windows 10 or Windows Server 2016", executionTime: 92,
executionTime: 92, createBy: null,
createBy: null, createTime: "2024-07-07 20:38:42",
createTime: "2024-07-07 20:38:42", operator: "系统管理员",
operator: "系统管理员", },
}, {
{ id: 36187,
id: 36187, module: "登录",
module: "登录", content: "登录",
content: "登录", requestUri: "/api/v1/auth/login",
requestUri: "/api/v1/auth/login", method: null,
method: null, ip: "192.168.31.134",
ip: "192.168.31.134", region: "0 内网IP",
region: "0 内网IP", browser: "Chrome 125.0.0.0",
browser: "Chrome 125.0.0.0", os: "Windows 10 or Windows Server 2016",
os: "Windows 10 or Windows Server 2016", executionTime: 19340,
executionTime: 19340, createBy: null,
createBy: null, createTime: "2024-07-07 20:38:09",
createTime: "2024-07-07 20:38:09", operator: "系统管理员",
operator: "系统管理员", },
}, {
{ id: 36186,
id: 36186, module: "登录",
module: "登录", content: "登录",
content: "登录", requestUri: "/api/v1/auth/login",
requestUri: "/api/v1/auth/login", method: null,
method: null, ip: "192.168.31.134",
ip: "192.168.31.134", region: "0 内网IP",
region: "0 内网IP", browser: "Chrome 125.0.0.0",
browser: "Chrome 125.0.0.0", os: "Windows 10 or Windows Server 2016",
os: "Windows 10 or Windows Server 2016", executionTime: 19869,
executionTime: 19869, createBy: null,
createBy: null, createTime: "2024-07-07 20:37:59",
createTime: "2024-07-07 20:37:59", operator: "系统管理员",
operator: "系统管理员", },
}, {
{ id: 36185,
id: 36185, module: "登录",
module: "登录", content: "登录",
content: "登录", requestUri: "/api/v1/auth/login",
requestUri: "/api/v1/auth/login", method: null,
method: null, ip: "112.103.111.59",
ip: "112.103.111.59", region: "黑龙江省 哈尔滨市",
region: "黑龙江省 哈尔滨市", browser: "Chrome 97.0.4692.98",
browser: "Chrome 97.0.4692.98", os: "Android",
os: "Android", executionTime: 96,
executionTime: 96, createBy: null,
createBy: null, createTime: "2024-07-07 20:37:21",
createTime: "2024-07-07 20:37:21", operator: "系统管理员",
operator: "系统管理员", },
}, {
{ id: 36184,
id: 36184, module: "登录",
module: "登录", content: "登录",
content: "登录", requestUri: "/api/v1/auth/login",
requestUri: "/api/v1/auth/login", method: null,
method: null, ip: "114.86.204.190",
ip: "114.86.204.190", region: "上海 上海市",
region: "上海 上海市", browser: "Chrome 125.0.0.0",
browser: "Chrome 125.0.0.0", os: "Windows 10 or Windows Server 2016",
os: "Windows 10 or Windows Server 2016", executionTime: 89,
executionTime: 89, createBy: null,
createBy: null, createTime: "2024-07-07 20:29:37",
createTime: "2024-07-07 20:29:37", operator: "系统管理员",
operator: "系统管理员", },
}, ],
], page: {
pageNum: 1,
pageSize: 10,
total: 36188, total: 36188,
}, },
msg: "一切ok", msg: "一切ok",

View File

@@ -2,143 +2,145 @@ import { defineMock } from "./base";
export default defineMock([ export default defineMock([
{ {
url: "notices/page", url: "notices",
method: ["GET"], method: ["GET"],
body: { body: {
code: "00000", code: "00000",
data: { data: [
list: [ {
{ id: 1,
id: 1, title: "v2.12.0 新增系统日志,访问趋势统计功能。",
title: "v2.12.0 新增系统日志,访问趋势统计功能。", publishStatus: 1,
publishStatus: 1, type: 1,
type: 1, publisherName: "系统管理员",
publisherName: "系统管理员", level: "L",
level: "L", publishTime: "2024-09-30 17:21",
publishTime: "2024-09-30 17:21", isRead: null,
isRead: null, targetType: 1,
targetType: 1, createTime: "2024-09-28 11:21",
createTime: "2024-09-28 11:21", revokeTime: "2024-09-30 17:21",
revokeTime: "2024-09-30 17:21", },
}, {
{ id: 2,
id: 2, title: "v2.13.0 新增菜单搜索。",
title: "v2.13.0 新增菜单搜索。", publishStatus: 1,
publishStatus: 1, type: 1,
type: 1, publisherName: "系统管理员",
publisherName: "系统管理员", level: "L",
level: "L", publishTime: "2024-09-30 17:22",
publishTime: "2024-09-30 17:22", isRead: null,
isRead: null, targetType: 1,
targetType: 1, createTime: "2024-09-28 11:21",
createTime: "2024-09-28 11:21", revokeTime: "2024-09-30 17:21",
revokeTime: "2024-09-30 17:21", },
}, {
{ id: 3,
id: 3, title: "\r\nv2.14.0 新增个人中心。",
title: "\r\nv2.14.0 新增个人中心。", publishStatus: 1,
publishStatus: 1, type: 1,
type: 1, publisherName: "系统管理员",
publisherName: "系统管理员", level: "L",
level: "L", publishTime: "2024-09-30 17:23",
publishTime: "2024-09-30 17:23", isRead: null,
isRead: null, targetType: 1,
targetType: 1, createTime: "2024-09-28 11:21",
createTime: "2024-09-28 11:21", revokeTime: "2024-09-30 17:21",
revokeTime: "2024-09-30 17:21", },
}, {
{ id: 4,
id: 4, title: "v2.15.0 登录页面改造。",
title: "v2.15.0 登录页面改造。", publishStatus: 1,
publishStatus: 1, type: 1,
type: 1, publisherName: "系统管理员",
publisherName: "系统管理员", level: "L",
level: "L", publishTime: "2024-09-30 17:24",
publishTime: "2024-09-30 17:24", isRead: null,
isRead: null, targetType: 1,
targetType: 1, createTime: "2024-09-28 11:21",
createTime: "2024-09-28 11:21", revokeTime: "2024-09-30 17:21",
revokeTime: "2024-09-30 17:21", },
}, {
{ id: 5,
id: 5, title: "v2.16.0 通知公告、字典翻译组件。",
title: "v2.16.0 通知公告、字典翻译组件。", publishStatus: 1,
publishStatus: 1, type: 1,
type: 1, publisherName: "系统管理员",
publisherName: "系统管理员", level: "L",
level: "L", publishTime: "2024-09-30 17:25",
publishTime: "2024-09-30 17:25", isRead: null,
isRead: null, targetType: 1,
targetType: 1, createTime: "2024-09-28 11:21",
createTime: "2024-09-28 11:21", revokeTime: "2024-09-30 17:21",
revokeTime: "2024-09-30 17:21", },
}, {
{ id: 6,
id: 6, title: "系统将于本周六凌晨 2 点进行维护,预计维护时间为 2 小时。",
title: "系统将于本周六凌晨 2 点进行维护,预计维护时间为 2 小时。", publishStatus: 1,
publishStatus: 1, type: 2,
type: 2, publisherName: "系统管理员",
publisherName: "系统管理员", level: "L",
level: "L", publishTime: "2024-09-30 17:26",
publishTime: "2024-09-30 17:26", isRead: null,
isRead: null, targetType: 1,
targetType: 1, createTime: "2024-09-28 11:21",
createTime: "2024-09-28 11:21", revokeTime: "2024-09-30 17:21",
revokeTime: "2024-09-30 17:21", },
}, {
{ id: 7,
id: 7, title: "最近发现一些钓鱼邮件,请大家提高警惕,不要点击陌生链接。",
title: "最近发现一些钓鱼邮件,请大家提高警惕,不要点击陌生链接。", publishStatus: 1,
publishStatus: 1, type: 3,
type: 3, publisherName: "系统管理员",
publisherName: "系统管理员", level: "L",
level: "L", publishTime: "2024-09-30 17:27",
publishTime: "2024-09-30 17:27", isRead: null,
isRead: null, targetType: 1,
targetType: 1, createTime: "2024-09-28 11:21",
createTime: "2024-09-28 11:21", revokeTime: "2024-09-30 17:21",
revokeTime: "2024-09-30 17:21", },
}, {
{ id: 8,
id: 8, title: "国庆假期从 10 月 1 日至 10 月 7 日放假,共 7 天。",
title: "国庆假期从 10 月 1 日至 10 月 7 日放假,共 7 天。", publishStatus: 1,
publishStatus: 1, type: 4,
type: 4, publisherName: "系统管理员",
publisherName: "系统管理员", level: "L",
level: "L", publishTime: "2024-09-30 17:28",
publishTime: "2024-09-30 17:28", isRead: null,
isRead: null, targetType: 1,
targetType: 1, createTime: "2024-09-28 11:21",
createTime: "2024-09-28 11:21", revokeTime: "2024-09-30 17:21",
revokeTime: "2024-09-30 17:21", },
}, {
{ id: 9,
id: 9, title: "公司将在 10 月 15 日举办新产品发布会,敬请期待。",
title: "公司将在 10 月 15 日举办新产品发布会,敬请期待。", publishStatus: 1,
publishStatus: 1, type: 5,
type: 5, publisherName: "系统管理员",
publisherName: "系统管理员", level: "L",
level: "L", publishTime: "2024-09-30 17:29",
publishTime: "2024-09-30 17:29", isRead: null,
isRead: null, targetType: 1,
targetType: 1, createTime: "2024-09-28 11:21",
createTime: "2024-09-28 11:21", revokeTime: "2024-09-30 17:21",
revokeTime: "2024-09-30 17:21", },
}, {
{ id: 10,
id: 10, title: "v2.16.1 版本修复了 WebSocket 重复连接导致的后台线程阻塞问题,优化了通知公告。",
title: "v2.16.1 版本修复了 WebSocket 重复连接导致的后台线程阻塞问题,优化了通知公告。", publishStatus: 1,
publishStatus: 1, type: 1,
type: 1, publisherName: "系统管理员",
publisherName: "系统管理员", level: "L",
level: "L", publishTime: "2024-09-30 17:30",
publishTime: "2024-09-30 17:30", isRead: null,
isRead: null, targetType: 1,
targetType: 1, createTime: "2024-09-28 11:21",
createTime: "2024-09-28 11:21", revokeTime: "2024-09-30 17:21",
revokeTime: "2024-09-30 17:21", },
}, ],
], page: {
pageNum: 1,
pageSize: 10,
total: 10, total: 10,
}, },
msg: "一切ok", msg: "一切ok",
@@ -185,20 +187,20 @@ export default defineMock([
}, },
// 修改通知 // 修改通知
{ {
url: "roles/:id", url: "notices/:id",
method: ["PUT"], method: ["PUT"],
body({ body }) { body({ body }) {
return { return {
code: "00000", code: "00000",
data: null, data: null,
msg: "修改通知" + body.name + "成功", msg: "修改通知" + body.title + "成功",
}; };
}, },
}, },
// 删除通知 // 删除通知
{ {
url: "roles/:id", url: "notices/:id",
method: ["DELETE"], method: ["DELETE"],
body({ params }) { body({ params }) {
return { return {
@@ -215,54 +217,56 @@ export default defineMock([
method: ["GET"], method: ["GET"],
body: { body: {
code: "00000", code: "00000",
data: { data: [
list: [ {
{ id: 10,
id: 10, title: "v2.16.1 版本修复了 WebSocket 重复连接导致的后台线程阻塞问题,优化了通知公告。",
title: "v2.16.1 版本修复了 WebSocket 重复连接导致的后台线程阻塞问题,优化了通知公告。", type: 1,
type: 1, level: "L",
level: "L", publisherName: "系统管理员",
publisherName: "系统管理员", publishTime: "2024-09-30 17:30",
publishTime: "2024-09-30 17:30", isRead: 0,
isRead: 0, },
}, {
{ id: 9,
id: 9, title: "公司将在 10 月 15 日举办新产品发布会,敬请期待。",
title: "公司将在 10 月 15 日举办新产品发布会,敬请期待。", type: 5,
type: 5, level: "L",
level: "L", publisherName: "系统管理员",
publisherName: "系统管理员", publishTime: "2024-09-30 17:29",
publishTime: "2024-09-30 17:29", isRead: 0,
isRead: 0, },
}, {
{ id: 8,
id: 8, title: "国庆假期从 10 月 1 日至 10 月 7 日放假,共 7 天。",
title: "国庆假期从 10 月 1 日至 10 月 7 日放假,共 7 天。", type: 4,
type: 4, level: "L",
level: "L", publisherName: "系统管理员",
publisherName: "系统管理员", publishTime: "2024-09-30 17:28",
publishTime: "2024-09-30 17:28", isRead: 0,
isRead: 0, },
}, {
{ id: 7,
id: 7, title: "最近发现一些钓鱼邮件,请大家提高警惕,不要点击陌生链接。",
title: "最近发现一些钓鱼邮件,请大家提高警惕,不要点击陌生链接。", type: 3,
type: 3, level: "L",
level: "L", publisherName: "系统管理员",
publisherName: "系统管理员", publishTime: "2024-09-30 17:27",
publishTime: "2024-09-30 17:27", isRead: 0,
isRead: 0, },
}, {
{ id: 6,
id: 6, title: "系统将于本周六凌晨 2 点进行维护,预计维护时间为 2 小时。",
title: "系统将于本周六凌晨 2 点进行维护,预计维护时间为 2 小时。", type: 2,
type: 2, level: "L",
level: "L", publisherName: "系统管理员",
publisherName: "系统管理员", publishTime: "2024-09-30 17:26",
publishTime: "2024-09-30 17:26", isRead: 0,
isRead: 0, },
}, ],
], page: {
pageNum: 1,
pageSize: 10,
total: 10, total: 10,
}, },
msg: "一切ok", msg: "一切ok",

View File

@@ -57,103 +57,105 @@ export default defineMock([
}, },
{ {
url: "roles/page", url: "roles",
method: ["GET"], method: ["GET"],
body: { body: {
code: "00000", code: "00000",
data: { data: [
list: [ {
{ id: 2,
id: 2, name: "系统管理员",
name: "系统管理员", code: "ADMIN",
code: "ADMIN", status: 1,
status: 1, sort: 2,
sort: 2, createTime: "2021-03-25 12:39:54",
createTime: "2021-03-25 12:39:54", updateTime: null,
updateTime: null, },
}, {
{ id: 3,
id: 3, name: "访问游客",
name: "访问游客", code: "GUEST",
code: "GUEST", status: 1,
status: 1, sort: 3,
sort: 3, createTime: "2021-05-26 15:49:05",
createTime: "2021-05-26 15:49:05", updateTime: "2019-05-05 16:00:00",
updateTime: "2019-05-05 16:00:00", },
}, {
{ id: 4,
id: 4, name: "系统管理员1",
name: "系统管理员1", code: "ADMIN1",
code: "ADMIN1", status: 1,
status: 1, sort: 2,
sort: 2, createTime: "2021-03-25 12:39:54",
createTime: "2021-03-25 12:39:54", updateTime: null,
updateTime: null, },
}, {
{ id: 5,
id: 5, name: "系统管理员2",
name: "系统管理员2", code: "ADMIN2",
code: "ADMIN2", status: 1,
status: 1, sort: 2,
sort: 2, createTime: "2021-03-25 12:39:54",
createTime: "2021-03-25 12:39:54", updateTime: null,
updateTime: null, },
}, {
{ id: 6,
id: 6, name: "系统管理员3",
name: "系统管理员3", code: "ADMIN3",
code: "ADMIN3", status: 1,
status: 1, sort: 2,
sort: 2, createTime: "2021-03-25 12:39:54",
createTime: "2021-03-25 12:39:54", updateTime: null,
updateTime: null, },
}, {
{ id: 7,
id: 7, name: "系统管理员4",
name: "系统管理员4", code: "ADMIN4",
code: "ADMIN4", status: 1,
status: 1, sort: 2,
sort: 2, createTime: "2021-03-25 12:39:54",
createTime: "2021-03-25 12:39:54", updateTime: null,
updateTime: null, },
}, {
{ id: 8,
id: 8, name: "系统管理员5",
name: "系统管理员5", code: "ADMIN5",
code: "ADMIN5", status: 1,
status: 1, sort: 2,
sort: 2, createTime: "2021-03-25 12:39:54",
createTime: "2021-03-25 12:39:54", updateTime: null,
updateTime: null, },
}, {
{ id: 9,
id: 9, name: "系统管理员6",
name: "系统管理员6", code: "ADMIN6",
code: "ADMIN6", status: 1,
status: 1, sort: 2,
sort: 2, createTime: "2021-03-25 12:39:54",
createTime: "2021-03-25 12:39:54", updateTime: "2023-12-04 11:43:15",
updateTime: "2023-12-04 11:43:15", },
}, {
{ id: 10,
id: 10, name: "系统管理员7",
name: "系统管理员7", code: "ADMIN7",
code: "ADMIN7", status: 1,
status: 1, sort: 2,
sort: 2, createTime: "2021-03-25 12:39:54",
createTime: "2021-03-25 12:39:54", updateTime: null,
updateTime: null, },
}, {
{ id: 11,
id: 11, name: "系统管理员8",
name: "系统管理员8", code: "ADMIN8",
code: "ADMIN8", status: 1,
status: 1, sort: 2,
sort: 2, createTime: "2021-03-25 12:39:54",
createTime: "2021-03-25 12:39:54", updateTime: null,
updateTime: null, },
}, ],
], page: {
pageNum: 1,
pageSize: 10,
total: 10, total: 10,
}, },
msg: "一切ok", msg: "一切ok",
@@ -214,7 +216,7 @@ export default defineMock([
{ {
url: "roles/:id/menuIds", url: "roles/:id/menuIds",
method: ["GET"], method: ["GET"],
body: ({}) => { body: () => {
return { return {
code: "00000", code: "00000",
data: [ data: [

View File

@@ -66,37 +66,39 @@ export default defineMock([
}, },
{ {
url: "users/page", url: "users",
method: ["GET"], method: ["GET"],
body: { body: {
code: "00000", code: "00000",
data: { data: [
list: [ {
{ id: 2,
id: 2, username: "admin",
username: "admin", nickname: "系统管理员",
nickname: "系统管理员", mobile: "17621210366",
mobile: "17621210366", gender: 1,
gender: 1, avatar: "https://foruda.gitee.com/images/1723603502796844527/03cdca2a_716974.gif",
avatar: "https://foruda.gitee.com/images/1723603502796844527/03cdca2a_716974.gif", email: "",
email: "", status: 1,
status: 1, deptId: 1,
deptId: 1, roleIds: [2],
roleIds: [2], },
}, {
{ id: 3,
id: 3, username: "test",
username: "test", nickname: "测试小用户",
nickname: "测试小用户", mobile: "17621210366",
mobile: "17621210366", gender: 1,
gender: 1, avatar: "https://foruda.gitee.com/images/1723603502796844527/03cdca2a_716974.gif",
avatar: "https://foruda.gitee.com/images/1723603502796844527/03cdca2a_716974.gif", email: "youlaitech@163.com",
email: "youlaitech@163.com", status: 1,
status: 1, deptId: 3,
deptId: 3, roleIds: [3],
roleIds: [3], },
}, ],
], page: {
pageNum: 1,
pageSize: 10,
total: 2, total: 2,
}, },
msg: "一切ok", msg: "一切ok",
@@ -149,7 +151,7 @@ export default defineMock([
return { return {
code: "00000", code: "00000",
data: null, data: null,
msg: "删除用户" + params.id + "成功", msg: "删除用户" + params.userId + "成功",
}; };
}, },
}, },

View File

@@ -4,8 +4,8 @@ import type {
AiCommandResponse, AiCommandResponse,
AiExecuteRequest, AiExecuteRequest,
AiExecuteResponse, AiExecuteResponse,
AiCommandRecordPageQuery, AiAssistantRecordQueryParams,
AiCommandRecordVo, AiAssistantRecordItem,
} from "@/types/api"; } from "@/types/api";
const AI_BASE_URL = "/api/v1/ai/assistant"; const AI_BASE_URL = "/api/v1/ai/assistant";
@@ -48,8 +48,8 @@ const AiCommandApi = {
* @param queryParams 查询参数 * @param queryParams 查询参数
* @returns AI 命令记录分页列表 * @returns AI 命令记录分页列表
*/ */
getPage(queryParams: AiCommandRecordPageQuery) { getPage(queryParams: AiAssistantRecordQueryParams) {
return request<any, PageResult<AiCommandRecordVo[]>>({ return request<any, PageResult<AiAssistantRecordItem>>({
url: `${AI_BASE_URL}/records`, url: `${AI_BASE_URL}/records`,
method: "get", method: "get",
params: queryParams, params: queryParams,

View File

@@ -1,13 +1,13 @@
import request from "@/utils/request"; import request from "@/utils/request";
import type { GeneratorPreviewVo, TablePageQuery, TablePageVo, GenConfigForm } from "@/types/api"; import type { GeneratorPreviewItem, TableQueryParams, TableItem, GenConfigForm } from "@/types/api";
const GENERATOR_BASE_URL = "/api/v1/codegen"; const GENERATOR_BASE_URL = "/api/v1/codegen";
const GeneratorAPI = { const GeneratorAPI = {
/** 获取数据表分页列表 */ /** 获取数据表分页列表 */
getTablePage(params: TablePageQuery) { getTablePage(params: TableQueryParams) {
return request<any, PageResult<TablePageVo[]>>({ return request<any, PageResult<TableItem>>({
url: `${GENERATOR_BASE_URL}/table/page`, url: `${GENERATOR_BASE_URL}/table`,
method: "get", method: "get",
params, params,
}); });
@@ -32,7 +32,7 @@ const GeneratorAPI = {
/** 获取代码生成预览数据 */ /** 获取代码生成预览数据 */
getPreviewData(tableName: string, pageType?: "classic" | "curd") { getPreviewData(tableName: string, pageType?: "classic" | "curd") {
return request<any, GeneratorPreviewVo[]>({ return request<any, GeneratorPreviewItem[]>({
url: `${GENERATOR_BASE_URL}/${tableName}/preview`, url: `${GENERATOR_BASE_URL}/${tableName}/preview`,
method: "get", method: "get",
params: pageType ? { pageType } : undefined, params: pageType ? { pageType } : undefined,

View File

@@ -1,13 +1,13 @@
import request from "@/utils/request"; import request from "@/utils/request";
import type { ConfigPageQuery, ConfigForm, ConfigPageVo } from "@/types/api"; import type { ConfigQueryParams, ConfigForm, ConfigItem } from "@/types/api";
const CONFIG_BASE_URL = "/api/v1/configs"; const CONFIG_BASE_URL = "/api/v1/configs";
const ConfigAPI = { const ConfigAPI = {
/** 获取配置分页数据 */ /** 获取配置分页数据 */
getPage(queryParams?: ConfigPageQuery) { getPage(queryParams?: ConfigQueryParams) {
return request<any, PageResult<ConfigPageVo[]>>({ return request<any, PageResult<ConfigItem>>({
url: `${CONFIG_BASE_URL}/page`, url: `${CONFIG_BASE_URL}`,
method: "get", method: "get",
params: queryParams, params: queryParams,
}); });

View File

@@ -1,16 +1,20 @@
import request from "@/utils/request"; import request from "@/utils/request";
import type { DeptQuery, DeptVo, DeptForm } from "@/types/api"; import type { DeptQueryParams, DeptItem, DeptForm, OptionItem } from "@/types/api";
const DEPT_BASE_URL = "/api/v1/depts"; const DEPT_BASE_URL = "/api/v1/depts";
const DeptAPI = { const DeptAPI = {
/** 获取部门树形列表 */ /** 获取部门树形列表 */
getList(queryParams?: DeptQuery) { getList(queryParams?: DeptQueryParams) {
return request<any, DeptVo[]>({ url: `${DEPT_BASE_URL}`, method: "get", params: queryParams }); return request<any, DeptItem[]>({
url: `${DEPT_BASE_URL}`,
method: "get",
params: queryParams,
});
}, },
/** 获取部门下拉数据源 */ /** 获取部门下拉数据源 */
getOptions() { getOptions() {
return request<any, OptionType[]>({ url: `${DEPT_BASE_URL}/options`, method: "get" }); return request<any, OptionItem[]>({ url: `${DEPT_BASE_URL}/options`, method: "get" });
}, },
/** 获取部门表单数据 */ /** 获取部门表单数据 */
getFormData(id: string) { getFormData(id: string) {

View File

@@ -1,39 +1,86 @@
import request from "@/utils/request"; import request from "@/utils/request";
import type { import type {
DictPageQuery, DictTypeQueryParams,
DictPageVo, DictTypeItem,
DictForm, DictTypeForm,
DictItemPageQuery, DictItemQueryParams,
DictItemPageVo, DictItem,
DictItemForm, DictItemForm,
DictItemOption, DictItemOption,
OptionItem,
} from "@/types/api"; } from "@/types/api";
const DICT_BASE_URL = "/api/v1/dicts"; const DICT_BASE_URL = "/api/v1/dicts";
type DictTagTypeCode = "N" | "P" | "S" | "W" | "I" | "D";
const decodeDictTagType = (code?: unknown): DictItemForm["tagType"] => {
const val = String(code ?? "")
.trim()
.toUpperCase();
switch (val as DictTagTypeCode) {
case "P":
return "primary";
case "S":
return "success";
case "W":
return "warning";
case "I":
return "info";
case "D":
return "danger";
case "N":
default:
return "";
}
};
const encodeDictTagType = (tagType?: unknown): DictTagTypeCode => {
const val = String(tagType ?? "")
.trim()
.toLowerCase();
switch (val) {
case "primary":
return "P";
case "success":
return "S";
case "warning":
return "W";
case "info":
return "I";
case "danger":
case "error":
return "D";
case "default":
case "":
default:
return "N";
}
};
const DictAPI = { const DictAPI = {
/** 字典分页列表 */ /** 字典分页列表 */
getPage(queryParams: DictPageQuery) { getPage(queryParams: DictTypeQueryParams) {
return request<any, PageResult<DictPageVo[]>>({ return request<any, PageResult<DictTypeItem>>({
url: `${DICT_BASE_URL}/page`, url: `${DICT_BASE_URL}`,
method: "get", method: "get",
params: queryParams, params: queryParams,
}); });
}, },
/** 字典列表 */ /** 字典列表 */
getList() { getList() {
return request<any, OptionType[]>({ url: `${DICT_BASE_URL}`, method: "get" }); return request<any, OptionItem[]>({ url: `${DICT_BASE_URL}/options`, method: "get" });
}, },
/** 字典表单数据 */ /** 字典表单数据 */
getFormData(id: string) { getFormData(id: string) {
return request<any, DictForm>({ url: `${DICT_BASE_URL}/${id}/form`, method: "get" }); return request<any, DictTypeForm>({ url: `${DICT_BASE_URL}/${id}/form`, method: "get" });
}, },
/** 新增字典 */ /** 新增字典 */
create(data: DictForm) { create(data: DictTypeForm) {
return request({ url: `${DICT_BASE_URL}`, method: "post", data }); return request({ url: `${DICT_BASE_URL}`, method: "post", data });
}, },
/** 修改字典 */ /** 修改字典 */
update(id: string, data: DictForm) { update(id: string, data: DictTypeForm) {
return request({ url: `${DICT_BASE_URL}/${id}`, method: "put", data }); return request({ url: `${DICT_BASE_URL}/${id}`, method: "put", data });
}, },
/** 删除字典 */ /** 删除字典 */
@@ -42,34 +89,62 @@ const DictAPI = {
}, },
/** 获取字典项分页列表 */ /** 获取字典项分页列表 */
getDictItemPage(dictCode: string, queryParams: DictItemPageQuery) { getDictItemPage(dictCode: string, queryParams: DictItemQueryParams) {
return request<any, PageResult<DictItemPageVo[]>>({ return request<any, PageResult<DictItem>>({
url: `${DICT_BASE_URL}/${dictCode}/items/page`, url: `${DICT_BASE_URL}/${dictCode}/items`,
method: "get", method: "get",
params: queryParams, params: queryParams,
}); }).then((res) => ({
...res,
data: (res.data ?? []).map((item) => ({
...item,
tagType: decodeDictTagType((item as any).tagType),
})),
}));
}, },
/** 获取字典项列表 */ /** 获取字典项列表 */
getDictItems(dictCode: string) { getDictItems(dictCode: string) {
return request<any, DictItemOption[]>({ return request<any, DictItemOption[]>({
url: `${DICT_BASE_URL}/${dictCode}/items`, url: `${DICT_BASE_URL}/${dictCode}/items/options`,
method: "get", method: "get",
}); }).then((items) =>
(items ?? []).map((item) => ({
...item,
tagType: decodeDictTagType((item as any).tagType),
}))
);
}, },
/** 新增字典项 */ /** 新增字典项 */
createDictItem(dictCode: string, data: DictItemForm) { createDictItem(dictCode: string, data: DictItemForm) {
return request({ url: `${DICT_BASE_URL}/${dictCode}/items`, method: "post", data }); return request({
url: `${DICT_BASE_URL}/${dictCode}/items`,
method: "post",
data: {
...data,
tagType: encodeDictTagType((data as any).tagType),
},
});
}, },
/** 获取字典项表单数据 */ /** 获取字典项表单数据 */
getDictItemFormData(dictCode: string, id: string) { getDictItemFormData(dictCode: string, id: string) {
return request<any, DictItemForm>({ return request<any, DictItemForm>({
url: `${DICT_BASE_URL}/${dictCode}/items/${id}/form`, url: `${DICT_BASE_URL}/${dictCode}/items/${id}/form`,
method: "get", method: "get",
}); }).then((form) => ({
...form,
tagType: decodeDictTagType((form as any).tagType),
}));
}, },
/** 修改字典项 */ /** 修改字典项 */
updateDictItem(dictCode: string, id: string, data: DictItemForm) { updateDictItem(dictCode: string, id: string, data: DictItemForm) {
return request({ url: `${DICT_BASE_URL}/${dictCode}/items/${id}`, method: "put", data }); return request({
url: `${DICT_BASE_URL}/${dictCode}/items/${id}`,
method: "put",
data: {
...data,
tagType: encodeDictTagType((data as any).tagType),
},
});
}, },
/** 删除字典项 */ /** 删除字典项 */
deleteDictItems(dictCode: string, ids: string) { deleteDictItems(dictCode: string, ids: string) {

View File

@@ -1,13 +1,13 @@
import request from "@/utils/request"; import request from "@/utils/request";
import type { LogPageQuery, LogPageVo } from "@/types/api"; import type { LogQueryParams, LogItem } from "@/types/api";
const LOG_BASE_URL = "/api/v1/logs"; const LOG_BASE_URL = "/api/v1/logs";
const LogAPI = { const LogAPI = {
/** 获取日志分页列表 */ /** 获取日志分页列表 */
getPage(queryParams: LogPageQuery) { getPage(queryParams: LogQueryParams) {
return request<any, PageResult<LogPageVo[]>>({ return request<any, PageResult<LogItem>>({
url: `${LOG_BASE_URL}/page`, url: `${LOG_BASE_URL}`,
method: "get", method: "get",
params: queryParams, params: queryParams,
}); });

View File

@@ -1,20 +1,24 @@
import request from "@/utils/request"; import request from "@/utils/request";
import type { MenuQuery, MenuVo, MenuForm, RouteVo, OptionType } from "@/types/api"; import type { MenuQueryParams, MenuItem, MenuForm, RouteItem, OptionItem } from "@/types/api";
const MENU_BASE_URL = "/api/v1/menus"; const MENU_BASE_URL = "/api/v1/menus";
const MenuAPI = { const MenuAPI = {
/** 获取当前用户的路由列表 */ /** 获取当前用户的路由列表 */
getRoutes() { getRoutes() {
return request<any, RouteVo[]>({ url: `${MENU_BASE_URL}/routes`, method: "get" }); return request<any, RouteItem[]>({ url: `${MENU_BASE_URL}/routes`, method: "get" });
}, },
/** 获取菜单树形列表 */ /** 获取菜单树形列表 */
getList(queryParams: MenuQuery) { getList(queryParams: MenuQueryParams) {
return request<any, MenuVo[]>({ url: `${MENU_BASE_URL}`, method: "get", params: queryParams }); return request<any, MenuItem[]>({
url: `${MENU_BASE_URL}`,
method: "get",
params: queryParams,
});
}, },
/** 获取菜单下拉数据源 */ /** 获取菜单下拉数据源 */
getOptions(onlyParent?: boolean) { getOptions(onlyParent?: boolean) {
return request<any, OptionType[]>({ return request<any, OptionItem[]>({
url: `${MENU_BASE_URL}/options`, url: `${MENU_BASE_URL}/options`,
method: "get", method: "get",
params: { onlyParent }, params: { onlyParent },

View File

@@ -1,13 +1,13 @@
import request from "@/utils/request"; import request from "@/utils/request";
import type { NoticePageQuery, NoticeForm, NoticePageVo, NoticeDetailVo } from "@/types/api"; import type { NoticeQueryParams, NoticeForm, NoticeItem, NoticeDetail } from "@/types/api";
const NOTICE_BASE_URL = "/api/v1/notices"; const NOTICE_BASE_URL = "/api/v1/notices";
const NoticeAPI = { const NoticeAPI = {
/** 获取通知公告分页数据 */ /** 获取通知公告分页数据 */
getPage(queryParams?: NoticePageQuery) { getPage(queryParams?: NoticeQueryParams) {
return request<any, PageResult<NoticePageVo[]>>({ return request<any, PageResult<NoticeItem>>({
url: `${NOTICE_BASE_URL}/page`, url: `${NOTICE_BASE_URL}`,
method: "get", method: "get",
params: queryParams, params: queryParams,
}); });
@@ -38,15 +38,15 @@ const NoticeAPI = {
}, },
/** 查看通知 */ /** 查看通知 */
getDetail(id: string) { getDetail(id: string) {
return request<any, NoticeDetailVo>({ url: `${NOTICE_BASE_URL}/${id}/detail`, method: "get" }); return request<any, NoticeDetail>({ url: `${NOTICE_BASE_URL}/${id}/detail`, method: "get" });
}, },
/** 全部已读 */ /** 全部已读 */
readAll() { readAll() {
return request({ url: `${NOTICE_BASE_URL}/read-all`, method: "put" }); return request({ url: `${NOTICE_BASE_URL}/read-all`, method: "put" });
}, },
/** 获取我的通知分页列表 */ /** 获取我的通知分页列表 */
getMyNoticePage(queryParams?: NoticePageQuery) { getMyNoticePage(queryParams?: NoticeQueryParams) {
return request<any, PageResult<NoticePageVo[]>>({ return request<any, PageResult<NoticeItem>>({
url: `${NOTICE_BASE_URL}/my`, url: `${NOTICE_BASE_URL}/my`,
method: "get", method: "get",
params: queryParams, params: queryParams,

View File

@@ -1,20 +1,20 @@
import request from "@/utils/request"; import request from "@/utils/request";
import type { RolePageQuery, RolePageVo, RoleForm } from "@/types/api"; import type { RoleQueryParams, RoleItem, RoleForm, OptionItem } from "@/types/api";
const ROLE_BASE_URL = "/api/v1/roles"; const ROLE_BASE_URL = "/api/v1/roles";
const RoleAPI = { const RoleAPI = {
/** 获取角色分页数据 */ /** 获取角色分页数据 */
getPage(queryParams?: RolePageQuery) { getPage(queryParams?: RoleQueryParams) {
return request<any, PageResult<RolePageVo[]>>({ return request<any, PageResult<RoleItem>>({
url: `${ROLE_BASE_URL}/page`, url: `${ROLE_BASE_URL}`,
method: "get", method: "get",
params: queryParams, params: queryParams,
}); });
}, },
/** 获取角色下拉数据源 */ /** 获取角色下拉数据源 */
getOptions() { getOptions() {
return request<any, OptionType[]>({ url: `${ROLE_BASE_URL}/options`, method: "get" }); return request<any, OptionItem[]>({ url: `${ROLE_BASE_URL}/options`, method: "get" });
}, },
/** 获取角色的菜单ID集合 */ /** 获取角色的菜单ID集合 */
getRoleMenuIds(roleId: string) { getRoleMenuIds(roleId: string) {

View File

@@ -1,12 +1,12 @@
import request from "@/utils/request"; import request from "@/utils/request";
import type { VisitTrendQuery, VisitTrendVo, VisitStatsVo } from "@/types/api"; import type { VisitTrendQueryParams, VisitTrendDetail, VisitStatsDetail } from "@/types/api";
const STATISTICS_BASE_URL = "/api/v1/statistics"; const STATISTICS_BASE_URL = "/api/v1/statistics";
const StatisticsAPI = { const StatisticsAPI = {
/** 获取访问趋势统计 */ /** 获取访问趋势统计 */
getVisitTrend(queryParams: VisitTrendQuery) { getVisitTrend(queryParams: VisitTrendQueryParams) {
return request<any, VisitTrendVo>({ return request<any, VisitTrendDetail>({
url: `${STATISTICS_BASE_URL}/visits/trend`, url: `${STATISTICS_BASE_URL}/visits/trend`,
method: "get", method: "get",
params: queryParams, params: queryParams,
@@ -14,7 +14,7 @@ const StatisticsAPI = {
}, },
/** 获取访问概览统计 */ /** 获取访问概览统计 */
getVisitOverview() { getVisitOverview() {
return request<any, VisitStatsVo>({ return request<any, VisitStatsDetail>({
url: `${STATISTICS_BASE_URL}/visits/overview`, url: `${STATISTICS_BASE_URL}/visits/overview`,
method: "get", method: "get",
}); });

View File

@@ -1,11 +1,11 @@
import request from "@/utils/request"; import request from "@/utils/request";
import type { import type {
TenantCreateForm, TenantCreateForm,
TenantCreateResultVo,
TenantForm, TenantForm,
TenantInfo, TenantInfo,
TenantPageQuery, TenantCreateResult,
TenantPageVo, TenantQueryParams,
TenantItem,
} from "@/types/api"; } from "@/types/api";
const TENANT_BASE_URL = "/api/v1/tenants"; const TENANT_BASE_URL = "/api/v1/tenants";
@@ -20,7 +20,7 @@ const TenantAPI = {
*/ */
getTenantList() { getTenantList() {
return request<any, TenantInfo[]>({ return request<any, TenantInfo[]>({
url: `${TENANT_BASE_URL}`, url: `${TENANT_BASE_URL}/options`,
method: "get", method: "get",
}); });
}, },
@@ -48,9 +48,9 @@ const TenantAPI = {
}, },
/** 获取租户分页数据(平台租户管理) */ /** 获取租户分页数据(平台租户管理) */
getPage(queryParams?: TenantPageQuery) { getPage(queryParams?: TenantQueryParams) {
return request<any, PageResult<TenantPageVo[]>>({ return request<any, PageResult<TenantItem>>({
url: `${TENANT_BASE_URL}/page`, url: `${TENANT_BASE_URL}`,
method: "get", method: "get",
params: queryParams, params: queryParams,
}); });
@@ -66,7 +66,7 @@ const TenantAPI = {
/** 新增租户并初始化默认数据 */ /** 新增租户并初始化默认数据 */
create(data: TenantCreateForm) { create(data: TenantCreateForm) {
return request<any, TenantCreateResultVo>({ return request<any, TenantCreateResult>({
url: `${TENANT_BASE_URL}`, url: `${TENANT_BASE_URL}`,
method: "post", method: "post",
data, data,

View File

@@ -1,14 +1,15 @@
import request from "@/utils/request"; import request from "@/utils/request";
import type { import type {
UserInfo, UserInfo,
UserPageQuery,
UserPageVo,
UserForm, UserForm,
UserProfileVo, UserQueryParams,
UserItem,
UserProfileDetail,
UserProfileForm, UserProfileForm,
PasswordChangeForm, PasswordChangeForm,
MobileUpdateForm, MobileUpdateForm,
EmailUpdateForm, EmailUpdateForm,
OptionItem,
} from "@/types/api"; } from "@/types/api";
const USER_BASE_URL = "/api/v1/users"; const USER_BASE_URL = "/api/v1/users";
@@ -31,9 +32,9 @@ const UserAPI = {
* *
* @param queryParams 查询参数 * @param queryParams 查询参数
*/ */
getPage(queryParams: UserPageQuery) { getPage(queryParams: UserQueryParams) {
return request<any, PageResult<UserPageVo[]>>({ return request<any, PageResult<UserItem>>({
url: `${USER_BASE_URL}/page`, url: `${USER_BASE_URL}`,
method: "get", method: "get",
params: queryParams, params: queryParams,
}); });
@@ -119,7 +120,7 @@ const UserAPI = {
* *
* @param queryParams 查询参数 * @param queryParams 查询参数
*/ */
export(queryParams: UserPageQuery) { export(queryParams: UserQueryParams) {
return request({ return request({
url: `${USER_BASE_URL}/export`, url: `${USER_BASE_URL}/export`,
method: "get", method: "get",
@@ -150,7 +151,7 @@ const UserAPI = {
/** 获取个人中心用户信息 */ /** 获取个人中心用户信息 */
getProfile() { getProfile() {
return request<any, UserProfileVo>({ return request<any, UserProfileDetail>({
url: `${USER_BASE_URL}/profile`, url: `${USER_BASE_URL}/profile`,
method: "get", method: "get",
}); });
@@ -214,7 +215,7 @@ const UserAPI = {
* 获取用户下拉列表 * 获取用户下拉列表
*/ */
getOptions() { getOptions() {
return request<any, OptionType[]>({ return request<any, OptionItem[]>({
url: `${USER_BASE_URL}/options`, url: `${USER_BASE_URL}/options`,
method: "get", method: "get",
}); });

View File

@@ -870,13 +870,11 @@ function fetchPageData(formData: IObject = {}, isRestart = false) {
) )
.then((data) => { .then((data) => {
if (showPagination) { if (showPagination) {
if (props.contentConfig.parseData) { const pageResult = Array.isArray(data) ? { data, page: null } : data;
data = props.contentConfig.parseData(data); pagination.total = pageResult.page?.total ?? 0;
} pageData.value = pageResult.data ?? [];
pagination.total = data.total;
pageData.value = data.list;
} else { } else {
pageData.value = data; pageData.value = Array.isArray(data) ? data : (data.data ?? []);
} }
}) })
.finally(() => { .finally(() => {

View File

@@ -55,7 +55,7 @@ export interface ISearchConfig {
grid?: boolean | "left" | "right"; grid?: boolean | "left" | "right";
} }
export interface IContentConfig<T = any> { export interface IContentConfig<TQuery = any, TItem = any> {
// 权限前缀(如sys:user用于组成权限标识),不提供则不进行权限校验 // 权限前缀(如sys:user用于组成权限标识),不提供则不进行权限校验
permPrefix?: string; permPrefix?: string;
// table组件属性 // table组件属性
@@ -72,18 +72,13 @@ export interface IContentConfig<T = any> {
> >
>; >;
// 列表的网络请求函数(需返回promise) // 列表的网络请求函数(需返回promise)
indexAction: (queryParams: T) => Promise<any>; indexAction: (queryParams: TQuery) => Promise<PageResult<TItem> | TItem[]>;
// 默认的分页相关的请求参数 // 默认的分页相关的请求参数
request?: { request?: {
pageName: string; pageName: string;
limitName: string; limitName: string;
}; };
// 数据格式解析的回调函数 // 分页接口统一返回 PageResult { data, page }
parseData?: (res: any) => {
total: number;
list: IObject[];
[key: string]: any;
};
// 修改属性的网络请求函数(需返回promise) // 修改属性的网络请求函数(需返回promise)
modifyAction?: (data: { modifyAction?: (data: {
[key: string]: any; [key: string]: any;
@@ -93,9 +88,9 @@ export interface IContentConfig<T = any> {
// 删除的网络请求函数(需返回promise) // 删除的网络请求函数(需返回promise)
deleteAction?: (ids: string) => Promise<any>; deleteAction?: (ids: string) => Promise<any>;
// 后端导出的网络请求函数(需返回promise) // 后端导出的网络请求函数(需返回promise)
exportAction?: (queryParams: T) => Promise<any>; exportAction?: (queryParams: TQuery) => Promise<any>;
// 前端全量导出的网络请求函数(需返回promise) // 前端全量导出的网络请求函数(需返回promise)
exportsAction?: (queryParams: T) => Promise<IObject[]>; exportsAction?: (queryParams: TQuery) => Promise<TItem[]>;
// 导入模板 // 导入模板
importTemplate?: string | (() => Promise<any>); importTemplate?: string | (() => Promise<any>);
// 后端导入的网络请求函数(需返回promise) // 后端导入的网络请求函数(需返回promise)

View File

@@ -2,7 +2,7 @@
* 通知中心逻辑 * 通知中心逻辑
*/ */
import { ref, onMounted, onBeforeUnmount } from "vue"; import { ref, onMounted, onBeforeUnmount } from "vue";
import type { NoticePageVo, NoticeDetailVo, NoticePageQuery } from "@/types/api"; import type { NoticeItem, NoticeDetail, NoticeQueryParams } from "@/types/api";
import NoticeAPI from "@/api/system/notice"; import NoticeAPI from "@/api/system/notice";
import { useStomp } from "@/composables"; import { useStomp } from "@/composables";
import router from "@/router"; import router from "@/router";
@@ -13,8 +13,8 @@ export function useNotice() {
const { subscribe, unsubscribe, isConnected } = useStomp(); const { subscribe, unsubscribe, isConnected } = useStomp();
// 状态 // 状态
const list = ref<NoticePageVo[]>([]); const list = ref<NoticeItem[]>([]);
const detail = ref<NoticeDetailVo | null>(null); const detail = ref<NoticeDetail | null>(null);
const dialogVisible = ref(false); const dialogVisible = ref(false);
let subscribed = false; let subscribed = false;
@@ -23,15 +23,15 @@ export function useNotice() {
// 数据获取 // 数据获取
// ============================================ // ============================================
async function fetchList(params?: Partial<NoticePageQuery>) { async function fetchList(params?: Partial<NoticeQueryParams>) {
const query: NoticePageQuery = { const query: NoticeQueryParams = {
pageNum: 1, pageNum: 1,
pageSize: PAGE_SIZE, pageSize: PAGE_SIZE,
isRead: 0, isRead: 0,
...params, ...params,
} as NoticePageQuery; };
const page = await NoticeAPI.getMyNoticePage(query); const page = await NoticeAPI.getMyNoticePage(query);
list.value = page.list || []; list.value = page.data || [];
} }
async function read(id: string) { async function read(id: string) {
@@ -39,7 +39,7 @@ export function useNotice() {
dialogVisible.value = true; dialogVisible.value = true;
// 从列表中移除已读项 // 从列表中移除已读项
const idx = list.value.findIndex((item: NoticePageVo) => item.id === id); const idx = list.value.findIndex((item: NoticeItem) => item.id === id);
if (idx >= 0) list.value.splice(idx, 1); if (idx >= 0) list.value.splice(idx, 1);
} }
@@ -65,14 +65,14 @@ export function useNotice() {
if (!data.id) return; if (!data.id) return;
// 避免重复 // 避免重复
if (list.value.some((item: NoticePageVo) => item.id === data.id)) return; if (list.value.some((item: NoticeItem) => item.id === data.id)) return;
list.value.unshift({ list.value.unshift({
id: data.id, id: data.id,
title: data.title, title: data.title,
type: data.type, type: data.type,
publishTime: data.publishTime, publishTime: data.publishTime,
} as NoticePageVo); } as NoticeItem);
ElNotification({ ElNotification({
title: "您收到一条新的通知消息!", title: "您收到一条新的通知消息!",

View File

@@ -261,9 +261,9 @@ function fetchPageData(isRestart = false) {
} }
props.selectConfig props.selectConfig
.indexAction(queryParams) .indexAction(queryParams)
.then((data) => { .then((res) => {
total.value = data.total; total.value = res.page?.total ?? 0;
pageData.value = data.list; pageData.value = res.data ?? [];
}) })
.finally(() => { .finally(() => {
loading.value = false; loading.value = false;

View File

@@ -8,7 +8,7 @@
/** /**
* 表单类型枚举 * 表单类型枚举
*/ */
export const FormTypeEnum: Record<string, OptionType> = { export const FormTypeEnum: Record<string, OptionItem> = {
INPUT: { value: 1, label: "输入框" }, INPUT: { value: 1, label: "输入框" },
SELECT: { value: 2, label: "下拉框" }, SELECT: { value: 2, label: "下拉框" },
RADIO: { value: 3, label: "单选框" }, RADIO: { value: 3, label: "单选框" },
@@ -24,7 +24,7 @@ export const FormTypeEnum: Record<string, OptionType> = {
/** /**
* 查询类型枚举 * 查询类型枚举
*/ */
export const QueryTypeEnum: Record<string, OptionType> = { export const QueryTypeEnum: Record<string, OptionItem> = {
/** 等于 */ /** 等于 */
EQ: { value: 1, label: "=" }, EQ: { value: 1, label: "=" },

View File

@@ -332,6 +332,8 @@ const handleCloseDrawer = () => {
.settings-drawer { .settings-drawer {
:deep(.el-drawer__body) { :deep(.el-drawer__body) {
position: relative; position: relative;
display: flex;
flex-direction: column;
height: 100%; height: 100%;
padding: 0; padding: 0;
overflow: hidden; overflow: hidden;
@@ -340,7 +342,8 @@ const handleCloseDrawer = () => {
/* 设置内容区域 */ /* 设置内容区域 */
.settings-content { .settings-content {
max-height: calc(100vh - 120px); /* let drawer body control height with flex and make this area scrollable */
flex: 1 1 auto;
padding: 20px; padding: 20px;
overflow-y: auto; overflow-y: auto;
} }

View File

@@ -4,7 +4,7 @@ import { store } from "@/store";
import router from "@/router"; import router from "@/router";
import MenuAPI from "@/api/system/menu"; import MenuAPI from "@/api/system/menu";
import { RouteVo } from "@/types"; import { RouteItem } from "@/types";
const modules = import.meta.glob("../../views/**/**.vue"); const modules = import.meta.glob("../../views/**/**.vue");
const Layout = () => import("../../layouts/index.vue"); const Layout = () => import("../../layouts/index.vue");
@@ -69,7 +69,7 @@ export const usePermissionStore = defineStore("permission", () => {
* 转换后端路由数据为Vue Router配置 * 转换后端路由数据为Vue Router配置
* 处理组件路径映射和Layout层级嵌套 * 处理组件路径映射和Layout层级嵌套
*/ */
const transformRoutes = (routes: RouteVo[], isTopLevel: boolean = true): RouteRecordRaw[] => { const transformRoutes = (routes: RouteItem[], isTopLevel: boolean = true): RouteRecordRaw[] => {
return routes.map((route) => { return routes.map((route) => {
const { component, children, ...args } = route; const { component, children, ...args } = route;

View File

@@ -2,6 +2,8 @@
* AI 模块类型定义 * AI 模块类型定义
*/ */
import type { BaseQueryParams } from "./common";
/** AI命令请求参数 */ /** AI命令请求参数 */
export interface AiCommandRequest { export interface AiCommandRequest {
/** 用户输入的自然语言命令 */ /** 用户输入的自然语言命令 */
@@ -81,10 +83,12 @@ export interface AiExecuteResponse {
} }
/** AI命令记录分页查询参数 */ /** AI命令记录分页查询参数 */
export interface AiCommandRecordPageQuery extends PageQuery { export interface AiAssistantRecordQueryParams extends BaseQueryParams {
/** 搜索关键字 */ /** 搜索关键字 */
keywords?: string; keywords?: string;
/** 执行状态 */ /** 执行状态 */
status?: string;
/** 执行状态(0:待执行;1:成功;-1:失败) */
executeStatus?: number; executeStatus?: number;
/** 解析状态 */ /** 解析状态 */
parseStatus?: number; parseStatus?: number;
@@ -101,7 +105,7 @@ export interface AiCommandRecordPageQuery extends PageQuery {
} }
/** AI命令记录视图对象 */ /** AI命令记录视图对象 */
export interface AiCommandRecordVo { export interface AiAssistantRecordItem {
/** 记录ID */ /** 记录ID */
id: string; id: string;
/** 用户ID */ /** 用户ID */

View File

@@ -2,8 +2,10 @@
* CodeGen 代码生成类型定义 * CodeGen 代码生成类型定义
*/ */
import type { BaseQueryParams } from "./common";
/** 代码生成预览对象 */ /** 代码生成预览对象 */
export interface GeneratorPreviewVo { export interface GeneratorPreviewItem {
/** 文件生成路径 */ /** 文件生成路径 */
path: string; path: string;
/** 文件名称 */ /** 文件名称 */
@@ -13,13 +15,13 @@ export interface GeneratorPreviewVo {
} }
/** 数据表分页查询参数 */ /** 数据表分页查询参数 */
export interface TablePageQuery extends PageQuery { export interface TableQueryParams extends BaseQueryParams {
/** 搜索关键字(表名) */ /** 搜索关键字(表名) */
keywords?: string; keywords?: string;
} }
/** 数据表分页对象 */ /** 数据表分页对象 */
export interface TablePageVo { export interface TableItem {
/** 表名称 */ /** 表名称 */
tableName: string; tableName: string;
/** 表描述 */ /** 表描述 */

View File

@@ -10,32 +10,49 @@ export interface ApiResponse<T = any> {
data: T; data: T;
/** 响应消息 */ /** 响应消息 */
msg: string; msg: string;
/** 分页信息(非列表接口通常不存在该字段) */
page?: PageMeta | null;
} }
/** 分页查询参数 */ /** 基础查询参数 */
export interface PageQuery { export interface BaseQueryParams {
/** 页码 */ /** 页码 */
pageNum: number; pageNum: number;
/** 每页记录数 */ /** 每页记录数 */
pageSize: number; pageSize: number;
/** 排序字段 */
sortBy?: string;
/** 排序方式(正序:ASC反序:DESC */
order?: string;
} }
/** 分页响应结构 */ /** 分页元信息 */
export interface PageResult<T> { export interface PageMeta {
/** 数据列表 */ pageNum: number;
list: T; pageSize: number;
/** 总记录数 */
total: number; total: number;
} }
/** 列表响应结构(统一) */
export interface PageResult<T> {
/** 数据列表 */
data: T[];
/** 分页信息,不分页时为 null */
page: PageMeta | null;
}
/** 下拉选项 */ /** 下拉选项 */
export interface OptionType { export interface OptionItem {
/** 选项值 */ /** 选项值 */
value: string | number; value: string | number;
/** 选项标签 */ /** 选项标签 */
label: string; label: string;
/** 子选项 */ /** 子选项 */
children?: OptionType[]; children?: OptionItem[];
} }
/** Excel 导入结果 */ /** Excel 导入结果 */

View File

@@ -2,8 +2,10 @@
* Config 配置类型定义 * Config 配置类型定义
*/ */
import type { BaseQueryParams } from "./common";
/** 配置分页查询参数 */ /** 配置分页查询参数 */
export interface ConfigPageQuery extends PageQuery { export interface ConfigQueryParams extends BaseQueryParams {
/** 搜索关键字 */ /** 搜索关键字 */
keywords?: string; keywords?: string;
} }
@@ -23,7 +25,7 @@ export interface ConfigForm {
} }
/** 配置分页对象 */ /** 配置分页对象 */
export interface ConfigPageVo { export interface ConfigItem {
/** 配置ID */ /** 配置ID */
id?: string; id?: string;
/** 配置名称 */ /** 配置名称 */

View File

@@ -3,7 +3,7 @@
*/ */
/** 部门查询参数 */ /** 部门查询参数 */
export interface DeptQuery { export interface DeptQueryParams {
/** 搜索关键字 */ /** 搜索关键字 */
keywords?: string; keywords?: string;
/** 状态 */ /** 状态 */
@@ -11,9 +11,9 @@ export interface DeptQuery {
} }
/** 部门视图对象 */ /** 部门视图对象 */
export interface DeptVo { export interface DeptItem {
/** 子部门 */ /** 子部门 */
children?: DeptVo[]; children?: DeptItem[];
/** 创建时间 */ /** 创建时间 */
createTime?: Date; createTime?: Date;
/** 部门ID */ /** 部门ID */

View File

@@ -2,9 +2,11 @@
* Dict 字典类型定义 * Dict 字典类型定义
*/ */
import type { BaseQueryParams } from "./common";
/** 字典分页查询参数 */ /** 字典分页查询参数 */
export interface DictPageQuery extends PageQuery { export interface DictTypeQueryParams extends BaseQueryParams {
/** 搜索关键字 */ /** 搜索关键字 */
keywords?: string; keywords?: string;
/** 状态(1:启用;0:禁用) */ /** 状态(1:启用;0:禁用) */
@@ -12,7 +14,7 @@ export interface DictPageQuery extends PageQuery {
} }
/** 字典分页对象 */ /** 字典分页对象 */
export interface DictPageVo { export interface DictTypeItem {
/** 字典ID */ /** 字典ID */
id: string; id: string;
/** 字典名称 */ /** 字典名称 */
@@ -24,7 +26,7 @@ export interface DictPageVo {
} }
/** 字典表单对象 */ /** 字典表单对象 */
export interface DictForm { export interface DictTypeForm {
/** 字典ID */ /** 字典ID */
id?: string; id?: string;
/** 字典名称 */ /** 字典名称 */
@@ -38,7 +40,7 @@ export interface DictForm {
} }
/** 字典项分页查询参数 */ /** 字典项分页查询参数 */
export interface DictItemPageQuery extends PageQuery { export interface DictItemQueryParams extends BaseQueryParams {
/** 搜索关键字 */ /** 搜索关键字 */
keywords?: string; keywords?: string;
/** 字典编码 */ /** 字典编码 */
@@ -46,7 +48,7 @@ export interface DictItemPageQuery extends PageQuery {
} }
/** 字典项分页对象 */ /** 字典项分页对象 */
export interface DictItemPageVo { export interface DictItem {
/** 字典项ID */ /** 字典项ID */
id: string; id: string;
/** 字典编码 */ /** 字典编码 */

View File

@@ -2,8 +2,10 @@
* Log 日志类型定义 * Log 日志类型定义
*/ */
import type { BaseQueryParams } from "./common";
/** 日志分页查询参数 */ /** 日志分页查询参数 */
export interface LogPageQuery extends PageQuery { export interface LogQueryParams extends BaseQueryParams {
/** 搜索关键字 */ /** 搜索关键字 */
keywords?: string; keywords?: string;
/** 操作时间 */ /** 操作时间 */
@@ -11,7 +13,7 @@ export interface LogPageQuery extends PageQuery {
} }
/** 日志分页对象 */ /** 日志分页对象 */
export interface LogPageVo { export interface LogItem {
/** 日志ID */ /** 日志ID */
id: string; id: string;
/** 日志模块 */ /** 日志模块 */

View File

@@ -3,15 +3,15 @@
*/ */
/** 菜单查询参数 */ /** 菜单查询参数 */
export interface MenuQuery { export interface MenuQueryParams {
/** 搜索关键字 */ /** 搜索关键字 */
keywords?: string; keywords?: string;
} }
/** 菜单视图对象 */ /** 菜单视图对象 */
export interface MenuVo { export interface MenuItem {
/** 子菜单 */ /** 子菜单 */
children?: MenuVo[]; children?: MenuItem[];
/** 组件路径 */ /** 组件路径 */
component?: string; component?: string;
/** ICON */ /** ICON */
@@ -79,9 +79,9 @@ export interface MenuOption {
} }
/** 路由对象 */ /** 路由对象 */
export interface RouteVo { export interface RouteItem {
/** 子路由列表 */ /** 子路由列表 */
children: RouteVo[]; children: RouteItem[];
/** 组件路径 */ /** 组件路径 */
component?: string; component?: string;
/** 路由名称 */ /** 路由名称 */

View File

@@ -2,8 +2,10 @@
* Notice 通知类型定义 * Notice 通知类型定义
*/ */
import type { BaseQueryParams } from "./common";
/** 通知分页查询参数 */ /** 通知分页查询参数 */
export interface NoticePageQuery extends PageQuery { export interface NoticeQueryParams extends BaseQueryParams {
/** 通知标题 */ /** 通知标题 */
title?: string; title?: string;
/** 发布状态(0:草稿;1:已发布;2:已撤回) */ /** 发布状态(0:草稿;1:已发布;2:已撤回) */
@@ -33,7 +35,7 @@ export interface NoticeForm {
} }
/** 通知分页对象 */ /** 通知分页对象 */
export interface NoticePageVo { export interface NoticeItem {
/** 通知ID */ /** 通知ID */
id: string; id: string;
/** 通知标题 */ /** 通知标题 */
@@ -55,7 +57,7 @@ export interface NoticePageVo {
} }
/** 通知详情对象 */ /** 通知详情对象 */
export interface NoticeDetailVo { export interface NoticeDetail {
/** 通知ID */ /** 通知ID */
id?: string; id?: string;
/** 通知标题 */ /** 通知标题 */

View File

@@ -2,14 +2,16 @@
* Role 角色类型定义 * Role 角色类型定义
*/ */
import type { BaseQueryParams } from "./common";
/** 角色分页查询参数 */ /** 角色分页查询参数 */
export interface RolePageQuery extends PageQuery { export interface RoleQueryParams extends BaseQueryParams {
/** 搜索关键字 */ /** 搜索关键字 */
keywords?: string; keywords?: string;
} }
/** 角色分页对象 */ /** 角色分页对象 */
export interface RolePageVo { export interface RoleItem {
/** 角色ID */ /** 角色ID */
id?: string; id?: string;
/** 角色编码 */ /** 角色编码 */

View File

@@ -3,7 +3,7 @@
*/ */
/** 访问趋势查询参数 */ /** 访问趋势查询参数 */
export interface VisitTrendQuery { export interface VisitTrendQueryParams {
/** 开始日期 */ /** 开始日期 */
startDate: string; startDate: string;
/** 结束日期 */ /** 结束日期 */
@@ -11,7 +11,7 @@ export interface VisitTrendQuery {
} }
/** 访问趋势视图对象 */ /** 访问趋势视图对象 */
export interface VisitTrendVo { export interface VisitTrendDetail {
/** 日期列表 */ /** 日期列表 */
dates: string[]; dates: string[];
/** 浏览量(PV)列表 */ /** 浏览量(PV)列表 */
@@ -23,7 +23,7 @@ export interface VisitTrendVo {
} }
/** 访问量统计视图对象 */ /** 访问量统计视图对象 */
export interface VisitStatsVo { export interface VisitStatsDetail {
/** 今日独立访客数(UV) */ /** 今日独立访客数(UV) */
todayUvCount: number; todayUvCount: number;
/** 累计独立访客数(UV) */ /** 累计独立访客数(UV) */

View File

@@ -2,7 +2,7 @@
* Tenant 租户类型定义 * Tenant 租户类型定义
*/ */
import type { PageQuery } from "./common"; import type { BaseQueryParams } from "./common";
/** 租户信息 */ /** 租户信息 */
export interface TenantInfo { export interface TenantInfo {
@@ -15,7 +15,7 @@ export interface TenantInfo {
} }
/** 租户分页查询参数 */ /** 租户分页查询参数 */
export interface TenantPageQuery extends PageQuery { export interface TenantQueryParams extends BaseQueryParams {
/** 关键字(租户名称/租户编码/域名) */ /** 关键字(租户名称/租户编码/域名) */
keywords?: string; keywords?: string;
/** 租户状态(1-正常 0-禁用) */ /** 租户状态(1-正常 0-禁用) */
@@ -23,7 +23,7 @@ export interface TenantPageQuery extends PageQuery {
} }
/** 租户分页对象 */ /** 租户分页对象 */
export interface TenantPageVo { export interface TenantItem {
id?: string; id?: string;
name?: string; name?: string;
code?: string; code?: string;
@@ -69,7 +69,7 @@ export interface TenantCreateForm {
} }
/** 新增租户结果 */ /** 新增租户结果 */
export interface TenantCreateResultVo { export interface TenantCreateResult {
tenantId?: string; tenantId?: string;
tenantCode?: string; tenantCode?: string;
tenantName?: string; tenantName?: string;

View File

@@ -2,6 +2,8 @@
* User 用户类型定义 * User 用户类型定义
*/ */
import type { BaseQueryParams } from "./common";
/** 登录用户信息 */ /** 登录用户信息 */
export interface UserInfo { export interface UserInfo {
/** 用户ID */ /** 用户ID */
@@ -19,7 +21,7 @@ export interface UserInfo {
} }
/** 用户分页查询参数 */ /** 用户分页查询参数 */
export interface UserPageQuery extends PageQuery { export interface UserQueryParams extends BaseQueryParams {
/** 搜索关键字 */ /** 搜索关键字 */
keywords?: string; keywords?: string;
/** 用户状态 */ /** 用户状态 */
@@ -31,7 +33,7 @@ export interface UserPageQuery extends PageQuery {
} }
/** 用户分页对象 */ /** 用户分页对象 */
export interface UserPageVo { export interface UserItem {
/** 用户ID */ /** 用户ID */
id: string; id: string;
/** 用户头像地址 */ /** 用户头像地址 */
@@ -81,7 +83,7 @@ export interface UserForm {
} }
/** 个人中心用户信息 */ /** 个人中心用户信息 */
export interface UserProfileVo { export interface UserProfileDetail {
/** 用户ID */ /** 用户ID */
id?: string; id?: string;
/** 用户名 */ /** 用户名 */

View File

@@ -6,7 +6,7 @@
// Generated by unplugin-vue-components // Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399 // Read more: https://github.com/vuejs/core/pull/3399
export {}; export {}
/* prettier-ignore */ /* prettier-ignore */
declare module 'vue' { declare module 'vue' {

View File

@@ -5,9 +5,9 @@
*/ */
declare global { declare global {
type ApiResponse<T = any> = import("@/types/api").ApiResponse<T>; type ApiResponse<T = any> = import("@/types/api").ApiResponse<T>;
type PageQuery = import("@/types/api").PageQuery; type BaseQueryParams = import("@/types/api").BaseQueryParams;
type PageResult<T> = import("@/types/api").PageResult<T>; type PageResult<T> = import("@/types/api").PageResult<T>;
type OptionType = import("@/types/api").OptionType; type OptionItem = import("@/types/api").OptionItem;
type ExcelResult = import("@/types/api").ExcelResult; type ExcelResult = import("@/types/api").ExcelResult;
type TagView = import("@/types/ui").TagView; type TagView = import("@/types/ui").TagView;
type AppSettings = import("@/types/ui").AppSettings; type AppSettings = import("@/types/ui").AppSettings;

View File

@@ -15,6 +15,21 @@ const http = axios.create({
paramsSerializer: (params) => qs.stringify(params), paramsSerializer: (params) => qs.stringify(params),
}); });
type PageMeta = { pageNum: number; pageSize: number; total: number };
type PagedApiResponse<T = any> = ApiResponse<T> & { page: PageMeta | null };
function isPagedApiResponse<T>(payload: ApiResponse<T>): payload is PagedApiResponse<T> {
// Treat as paged response only when `page` is a non-null object (contains pagination meta).
// Some APIs return `page: null` for non-paged endpoints; checking for the presence
// of the `page` property alone causes unintended branching (e.g. captcha endpoint).
return (
payload != null &&
typeof payload === "object" &&
payload.page != null &&
typeof (payload as any).page === "object"
);
}
// ============================================ // ============================================
// 请求拦截器 // 请求拦截器
// ============================================ // ============================================
@@ -49,6 +64,11 @@ http.interceptors.response.use(
const { code, data, msg } = response.data; const { code, data, msg } = response.data;
if (code === ApiCodeEnum.SUCCESS) { if (code === ApiCodeEnum.SUCCESS) {
// 分页接口需要同时返回 data 与 page 元信息
if (isPagedApiResponse(response.data)) {
const { page } = response.data;
return { data, page: page ?? null };
}
return data; return data;
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,6 +1,27 @@
import type { IContentConfig } from "@/components/CURD/types"; 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", // 不写不进行按钮权限校验 // permPrefix: "sys:demo", // 不写不进行按钮权限校验
table: { table: {
showOverflowTooltip: true, showOverflowTooltip: true,
@@ -10,38 +31,49 @@ const contentConfig: IContentConfig = {
indexAction(params) { indexAction(params) {
// 模拟发起网络请求获取列表数据 // 模拟发起网络请求获取列表数据
console.log("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({ return Promise.resolve({
total: 2, data: list.slice(start, end),
list: [ page: {
{ pageNum,
id: 1, pageSize,
username: "root", total: list.length,
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,
},
],
}); });
}, },
modifyAction(data) { modifyAction(data) {

View File

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

View File

@@ -227,7 +227,8 @@ onBeforeUnmount(() => {
animation: featureFade 0.8s ease-out; animation: featureFade 0.8s ease-out;
@media (prefers-color-scheme: dark) { @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> <script lang="ts" setup>
import UserAPI from "@/api/system/user"; import UserAPI from "@/api/system/user";
import type { import type {
UserProfileVo, UserProfileDetail,
PasswordChangeForm, PasswordChangeForm,
MobileUpdateForm, MobileUpdateForm,
EmailUpdateForm, EmailUpdateForm,
@@ -241,7 +241,7 @@ import { Camera } from "@element-plus/icons-vue";
const userStore = useUserStoreHook(); const userStore = useUserStoreHook();
const userProfile = ref<UserProfileVo>({}); const userProfile = ref<UserProfileDetail>({});
const enum DialogType { const enum DialogType {
ACCOUNT = "account", ACCOUNT = "account",

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -345,7 +345,7 @@ import { useAppStore } from "@/store/modules/app";
import { DeviceEnum } from "@/enums/settings"; import { DeviceEnum } from "@/enums/settings";
import MenuAPI from "@/api/system/menu"; 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"; import { MenuTypeEnum } from "@/enums/business";
defineOptions({ defineOptions({
@@ -366,11 +366,11 @@ const dialog = reactive({
const drawerSize = computed(() => (appStore.device === DeviceEnum.DESKTOP ? "600px" : "90%")); 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>({ const initialMenuFormData = ref<MenuForm>({
id: undefined, id: undefined,
@@ -437,7 +437,7 @@ function handleResetQuery() {
} }
// 行点击事件 // 行点击事件
function handleRowClick(row: MenuVo) { function handleRowClick(row: MenuItem) {
selectedMenuId.value = row.id; selectedMenuId.value = row.id;
} }

View File

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

View File

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

View File

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

View File

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

View File

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