diff --git a/src/api/admin/order.js b/src/api/admin/order.js index d58fa36..7a4340f 100644 --- a/src/api/admin/order.js +++ b/src/api/admin/order.js @@ -33,3 +33,11 @@ export const updateOrder = (data) => { } }) } +/**重试订单流程 */ +export const retryOrderHook = (data) => { + return http2.post('/api/v1/admin/order/retry_hook', data,{ + headers:{ + 'Content-Type':'multipart/form-data' + } + }) +} diff --git a/src/api/admin/webRouts.js b/src/api/admin/webRouts.js new file mode 100644 index 0000000..210b136 --- /dev/null +++ b/src/api/admin/webRouts.js @@ -0,0 +1,64 @@ +import { http2 } from "@/utils/request.js" + +// ========== 后台菜单管理 ========== + +/** 获取后台菜单列表 */ +export const getWebRoutsList = (params) => { + return http2.get('/api/v1/admin/server/web_routs/list', { params }) +} + +/** 新增后台菜单 */ +export const addWebRouts = (data) => { + return http2.post('/api/v1/admin/server/web_routs/add', data, { + headers: { 'Content-Type': 'multipart/form-data' } + }) +} + +/** 修改后台菜单 */ +export const updateWebRouts = (data) => { + return http2.post('/api/v1/admin/server/web_routs/update', data, { + headers: { 'Content-Type': 'multipart/form-data' } + }) +} + +/** 删除后台菜单 */ +export const deleteWebRouts = (data) => { + return http2.delete('/api/v1/admin/server/web_routs/delete', { + data, + headers: { 'Content-Type': 'multipart/form-data' } + }) +} + +// ========== 后台菜单权限管理 ========== + +/** 获取后台菜单权限列表 */ +export const getWebRoutsPermissionList = (params) => { + return http2.get('/api/v1/admin/server/web_routs/permission/list', { params }) +} + +/** 新增后台菜单权限 */ +export const addWebRoutsPermission = (data) => { + return http2.post('/api/v1/admin/server/web_routs/permission/add', data, { + headers: { 'Content-Type': 'multipart/form-data' } + }) +} + +/** 修改后台菜单权限 */ +export const updateWebRoutsPermission = (data) => { + return http2.post('/api/v1/admin/server/web_routs/permission/update', data, { + headers: { 'Content-Type': 'multipart/form-data' } + }) +} + +/** 删除后台菜单权限 */ +export const deleteWebRoutsPermission = (data) => { + return http2.delete('/api/v1/admin/server/web_routs/permission/delete', { + data, + headers: { 'Content-Type': 'multipart/form-data' } + }) +} + +/** 获取当前用户的后台菜单权限树 */ +export const getMyWebRoutsPermission = () => { + return http2.get('/api/v1/admin/server/web_routs/my') +} diff --git a/src/components/admin/IconSelector.vue b/src/components/admin/IconSelector.vue new file mode 100644 index 0000000..b6b4ee8 --- /dev/null +++ b/src/components/admin/IconSelector.vue @@ -0,0 +1,131 @@ + + + + + diff --git a/src/components/admin/MenuPathSelector.vue b/src/components/admin/MenuPathSelector.vue new file mode 100644 index 0000000..582cfdb --- /dev/null +++ b/src/components/admin/MenuPathSelector.vue @@ -0,0 +1,148 @@ + + + + + diff --git a/src/config/menus.js b/src/config/menus.js index aa2ec32..de9e6cd 100644 --- a/src/config/menus.js +++ b/src/config/menus.js @@ -185,6 +185,14 @@ export const menus = [ { path: '/system/setting-manage', title: '配置管理' + }, + { + path: '/system/menu', + title: '菜单管理', + children: [ + { path: '/system/menu-manage', title: '菜单列表' }, + { path: '/system/menu-permission', title: '菜单权限' } + ] } ] } diff --git a/src/router/index.js b/src/router/index.js index 4dba18a..9e36974 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -407,6 +407,18 @@ const routes = [ name: 'SettingManage', component: () => import('../views/system/SettingManage.vue'), meta: { title: '配置管理' } + }, + { + path: 'menu-manage', + name: 'MenuManage', + component: () => import('../views/system/MenuManage.vue'), + meta: { title: '菜单管理' } + }, + { + path: 'menu-permission', + name: 'MenuPermission', + component: () => import('../views/system/MenuPermission.vue'), + meta: { title: '菜单权限' } } ] }, diff --git a/src/views/order/OrderList.vue b/src/views/order/OrderList.vue index 7443a3b..be0593e 100644 --- a/src/views/order/OrderList.vue +++ b/src/views/order/OrderList.vue @@ -22,6 +22,12 @@ + + + + + + 搜索 @@ -89,11 +95,22 @@ {{ row.payNum }} - + + + + @@ -111,11 +128,12 @@ {{ formatDate(row.CreatedAt) }} - + @@ -162,6 +180,10 @@ {{ formatDate(orderDetail.CreatedAt) }} {{ formatDate(orderDetail.UpdatedAt) }} {{ orderDetail.args || '-' }} + + 异常 + {{ orderDetail.error }} + {{ orderDetail.note || '无' }} @@ -389,7 +411,7 @@ import { ref, reactive, onMounted } from 'vue' import { ElMessage, ElMessageBox } from 'element-plus' import { Plus, Delete, Search, Download, Refresh, User, ShoppingCart, Ticket, Money, Close } from '@element-plus/icons-vue' -import { getOrderList, getOrderDetail, createOrder, updateOrder, deleteOrder } from '@/api/admin/order' +import { getOrderList, getOrderDetail, createOrder, updateOrder, deleteOrder, retryOrderHook } from '@/api/admin/order' import UserListSelector from '@/components/admin/UserListSelector.vue' import ProductSelector from '@/components/admin/ProductSelector.vue' import DiscountCodeSelector from '@/components/admin/DiscountCodeSelector.vue' @@ -403,7 +425,8 @@ const queryParams = reactive({ key: '', state: '', user_id: '', - user_key: '' + user_key: '', + error: null }) // 订单表单 @@ -544,6 +567,7 @@ const resetQuery = () => { queryParams.state = '' queryParams.user_id = '' queryParams.user_key = '' + queryParams.error = null queryParams.page = 1 fetchOrderList() } @@ -644,6 +668,32 @@ const handleEdit = (row) => { } } +// 重试订单流程 +const handleRetryOrder = (row) => { + ElMessageBox.confirm( + `确认对订单「${row.name}」(ID: ${row.id}) 重试流程吗?`, + '重试订单流程', + { + confirmButtonText: '确认重试', + cancelButtonText: '取消', + type: 'warning' + } + ).then(async () => { + try { + const res = await retryOrderHook({ order_id: row.id }) + if (res.data.code === 200) { + ElMessage.success('重试流程已触发') + fetchOrderList() + } else { + ElMessage.error(res.data.message || '重试失败') + } + } catch (error) { + console.error('重试订单流程失败:', error) + ElMessage.error(error.response?.data?.message || '重试订单流程失败') + } + }).catch(() => {}) +} + // 删除订单 const handleDelete = (row) => { ElMessageBox.confirm(`确认删除订单 ${row.name} 吗?`, '警告', { @@ -966,4 +1016,21 @@ onMounted(() => { .unit-input-row { display: flex; align-items: center; gap: 6px; width: 100%; } .unit-text { font-size: 13px; color: #606266; flex-shrink: 0; white-space: nowrap; } + +.error-text { + color: #f56c6c; + font-size: 12px; + display: -webkit-box; + -webkit-line-clamp: 2; + line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; + text-overflow: ellipsis; + word-break: break-all; + cursor: pointer; +} + +.text-muted { + color: #c0c4cc; +} diff --git a/src/views/system/MenuManage.vue b/src/views/system/MenuManage.vue new file mode 100644 index 0000000..78fadb3 --- /dev/null +++ b/src/views/system/MenuManage.vue @@ -0,0 +1,400 @@ + + + + + diff --git a/src/views/system/MenuPermission.vue b/src/views/system/MenuPermission.vue new file mode 100644 index 0000000..160c57b --- /dev/null +++ b/src/views/system/MenuPermission.vue @@ -0,0 +1,610 @@ + + + + + diff --git a/默认模块.openapi.json b/默认模块.openapi.json index 63c6a91..07b6b3d 100644 --- a/默认模块.openapi.json +++ b/默认模块.openapi.json @@ -7,20 +7,54 @@ }, "tags": [ { - "name": "VNC指令管理" + "name": "后台菜单权限管理" + }, + { + "name": "后台菜单管理" } ], "paths": { - "/api/v1/admin/server/vnc_command/group/list": { + "/api/v1/admin/server/web_routs/permission/list": { "get": { - "summary": "获取指令分组列表(含指令项)", + "summary": "获取后台菜单权限列表", "deprecated": false, "description": "", - "operationId": "VncCommandGroupList", "tags": [ - "VNC指令管理" + "后台菜单权限管理" ], "parameters": [ + { + "name": "owner_type", + "in": "query", + "description": "所属类型", + "required": false, + "schema": { + "type": "string", + "enum": [ + "user", + "group" + ], + "default": "group" + } + }, + { + "name": "user_id", + "in": "query", + "description": "用户ID(owner_type为user时必填)", + "required": false, + "schema": { + "type": "integer" + } + }, + { + "name": "admin_group_id", + "in": "query", + "description": "管理员组ID(owner_type为group时必填)", + "required": false, + "schema": { + "type": "integer" + } + }, { "name": "Authorization", "in": "header", @@ -34,12 +68,14 @@ ], "responses": { "200": { - "description": "查询成功", + "description": "成功", "content": { "application/json": { "schema": { - "type": "object", - "properties": {} + "type": "array", + "items": { + "$ref": "#/components/schemas/AdminWebRoutsPermission" + } } } }, @@ -49,14 +85,13 @@ "security": [] } }, - "/api/v1/admin/server/vnc_command/group/create": { + "/api/v1/admin/server/web_routs/permission/add": { "post": { - "summary": "创建指令分组", + "summary": "新增后台菜单权限", "deprecated": false, "description": "", - "operationId": "VncCommandGroupCreate", "tags": [ - "VNC指令管理" + "后台菜单权限管理" ], "parameters": [ { @@ -76,53 +111,69 @@ "schema": { "type": "object", "properties": { - "name": { - "type": "string", - "description": "分组名称", - "example": "" - }, - "sort": { + "web_routs_id": { "type": "integer", - "description": "排序", + "description": "菜单ID", "example": 0 }, - "default_icon": { - "description": "分组文本图标(如 📚),当无文件图标时使用", - "example": "", - "type": "string" + "enable": { + "type": "boolean", + "default": true, + "description": "是否启用", + "example": "true" }, - "icon_file_id": { - "description": "分组图标文件ID", - "example": "", - "type": "string" + "owner_type": { + "type": "string", + "enum": [ + "user", + "group" + ], + "description": "所属类型", + "example": "" + }, + "admin_group_id": { + "type": "integer", + "description": "管理员组ID(owner_type为group时使用)", + "example": 0 + }, + "user_id": { + "type": "integer", + "description": "用户ID(owner_type为user时使用)", + "example": 0 } }, "required": [ - "name" + "web_routs_id", + "owner_type" ] - }, - "examples": {} + } } }, "required": true }, "responses": { "200": { - "description": "创建成功", + "description": "成功", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AdminWebRoutsPermission" + } + } + }, "headers": {} } }, "security": [] } }, - "/api/v1/admin/server/vnc_command/group/update": { + "/api/v1/admin/server/web_routs/permission/update": { "post": { - "summary": "修改指令分组", + "summary": "修改后台菜单权限", "deprecated": false, "description": "", - "operationId": "VncCommandGroupUpdate", "tags": [ - "VNC指令管理" + "后台菜单权限管理" ], "parameters": [ { @@ -144,143 +195,42 @@ "properties": { "id": { "type": "integer", - "description": "分组ID", + "description": "权限记录ID", "example": 0 }, - "name": { - "type": "string", + "web_routs_id": { + "type": "integer", + "description": "菜单ID", + "example": 0 + }, + "enable": { + "type": "boolean", + "description": "是否启用", "example": "" }, - "sort": { + "admin_group_id": { "type": "integer", + "description": "管理员组ID", "example": 0 }, - "default_icon": { - "description": "分组文本图标(如 📚),当无文件图标时使用", - "example": "", - "type": "string" - }, - "icon_file_id": { + "user_id": { "type": "integer", - "description": "分组图标文件ID", + "description": "用户ID", "example": 0 + }, + "owner_type": { + "type": "string", + "enum": [ + "user", + "group" + ], + "description": "所属类型", + "example": "" } }, "required": [ "id" ] - }, - "examples": {} - } - }, - "required": true - }, - "responses": { - "200": { - "description": "修改成功", - "headers": {} - } - }, - "security": [] - } - }, - "/api/v1/admin/server/vnc_command/group/delete": { - "delete": { - "summary": "删除指令分组(级联删除指令项)", - "deprecated": false, - "description": "", - "operationId": "VncCommandGroupDelete", - "tags": [ - "VNC指令管理" - ], - "parameters": [ - { - "name": "id", - "in": "query", - "description": "", - "required": true, - "schema": { - "type": "integer" - } - }, - { - "name": "Authorization", - "in": "header", - "description": "", - "example": "Bearer {{token}}", - "schema": { - "type": "string", - "default": "Bearer {{token}}" - } - } - ], - "responses": { - "200": { - "description": "删除成功", - "headers": {} - } - }, - "security": [] - } - }, - "/api/v1/admin/server/vnc_command/item/create": { - "post": { - "summary": "创建指令项", - "deprecated": false, - "description": "", - "operationId": "VncCommandItemCreate", - "tags": [ - "VNC指令管理" - ], - "parameters": [ - { - "name": "Authorization", - "in": "header", - "description": "", - "example": "Bearer {{token}}", - "schema": { - "type": "string", - "default": "Bearer {{token}}" - } - } - ], - "requestBody": { - "content": { - "multipart/form-data": { - "schema": { - "type": "object", - "properties": { - "group_id": { - "type": "integer", - "description": "所属分组ID", - "example": 0 - }, - "label": { - "type": "string", - "description": "指令名称", - "example": "" - }, - "cmd": { - "type": "string", - "description": "指令内容(支持 %var% 变量占位符)", - "example": "" - }, - "vars": { - "type": "string", - "description": "变量列表 JSON,格式 [{\"k\":\"path\",\"p\":\"目录路径\"}]", - "example": "" - }, - "sort": { - "type": "integer", - "description": "排序", - "example": 0 - } - }, - "required": [ - "group_id", - "label", - "cmd" - ] } } }, @@ -288,21 +238,27 @@ }, "responses": { "200": { - "description": "创建成功", + "description": "成功", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AdminWebRoutsPermission" + } + } + }, "headers": {} } }, "security": [] } }, - "/api/v1/admin/server/vnc_command/item/update": { - "post": { - "summary": "修改指令项", + "/api/v1/admin/server/web_routs/permission/delete": { + "delete": { + "summary": "删除后台菜单权限", "deprecated": false, "description": "", - "operationId": "VncCommandItemUpdate", "tags": [ - "VNC指令管理" + "后台菜单权限管理" ], "parameters": [ { @@ -324,23 +280,7 @@ "properties": { "id": { "type": "integer", - "description": "指令项ID", - "example": 0 - }, - "label": { - "type": "string", - "example": "" - }, - "cmd": { - "type": "string", - "example": "" - }, - "vars": { - "type": "string", - "example": "" - }, - "sort": { - "type": "integer", + "description": "权限记录ID", "example": 0 } }, @@ -354,28 +294,114 @@ }, "responses": { "200": { - "description": "修改成功", + "description": "成功", "headers": {} } }, "security": [] } }, - "/api/v1/admin/server/vnc_command/item/delete": { - "delete": { - "summary": "删除指令项", + "/api/v1/admin/server/web_routs/my": { + "get": { + "summary": "获取当前用户的后台菜单权限树", "deprecated": false, - "description": "", - "operationId": "VncCommandItemDelete", + "description": "自动读取当前用户的 user_id 与 AdminGroupId,合并用户级与管理员组级菜单权限,返回完整的菜单树形结构。每个菜单节点包含 enable 状态,用户级权限优先于管理员组级权限。", "tags": [ - "VNC指令管理" + "后台菜单权限管理" ], "parameters": [ { - "name": "id", - "in": "query", + "name": "Authorization", + "in": "header", "description": "", - "required": true, + "example": "Bearer {{token}}", + "schema": { + "type": "string", + "default": "Bearer {{token}}" + } + } + ], + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WebRoutsWithPermission" + } + }, + "example": { + "id": 1, + "path": "/dashboard", + "title": "仪表盘", + "icon": "dashboard", + "parentId": null, + "enable": true, + "children": [ + { + "id": 2, + "path": "/dashboard/overview", + "title": "概览", + "icon": "overview", + "parentId": 1, + "enable": true, + "children": [] + } + ] + } + } + }, + "headers": {} + } + }, + "security": [] + } + }, + "/api/v1/admin/server/web_routs/list": { + "get": { + "summary": "获取后台菜单列表", + "deprecated": false, + "description": "", + "tags": [ + "后台菜单管理" + ], + "parameters": [ + { + "name": "page", + "in": "query", + "description": "页码", + "required": false, + "schema": { + "type": "integer", + "default": 1 + } + }, + { + "name": "count", + "in": "query", + "description": "每页数量", + "required": false, + "schema": { + "type": "integer", + "default": 10 + } + }, + { + "name": "key", + "in": "query", + "description": "搜索关键字(匹配标题或路径)", + "required": false, + "schema": { + "type": "string" + } + }, + { + "name": "parent_id", + "in": "query", + "description": "父级菜单ID,不传则获取顶级菜单", + "required": false, "schema": { "type": "integer" } @@ -393,7 +419,223 @@ ], "responses": { "200": { - "description": "删除成功", + "description": "成功", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "list": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AdminWebRouts" + } + }, + "all_count": { + "type": "integer" + } + } + } + } + }, + "headers": {} + } + }, + "security": [] + } + }, + "/api/v1/admin/server/web_routs/add": { + "post": { + "summary": "新增后台菜单", + "deprecated": false, + "description": "", + "tags": [ + "后台菜单管理" + ], + "parameters": [ + { + "name": "Authorization", + "in": "header", + "description": "", + "example": "Bearer {{token}}", + "schema": { + "type": "string", + "default": "Bearer {{token}}" + } + } + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "path": { + "type": "string", + "description": "菜单路径", + "example": "" + }, + "title": { + "type": "string", + "description": "菜单名称", + "example": "" + }, + "icon": { + "type": "string", + "description": "菜单图标", + "example": "" + }, + "parent_id": { + "type": "integer", + "description": "父级菜单ID", + "example": 0 + } + }, + "required": [ + "path", + "title", + "icon" + ] + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AdminWebRouts" + } + } + }, + "headers": {} + } + }, + "security": [] + } + }, + "/api/v1/admin/server/web_routs/update": { + "post": { + "summary": "修改后台菜单", + "deprecated": false, + "description": "", + "tags": [ + "后台菜单管理" + ], + "parameters": [ + { + "name": "Authorization", + "in": "header", + "description": "", + "example": "Bearer {{token}}", + "schema": { + "type": "string", + "default": "Bearer {{token}}" + } + } + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "description": "菜单ID", + "example": 0 + }, + "path": { + "type": "string", + "description": "菜单路径", + "example": "" + }, + "title": { + "type": "string", + "description": "菜单名称", + "example": "" + }, + "icon": { + "type": "string", + "description": "菜单图标", + "example": "" + }, + "parent_id": { + "type": "integer", + "description": "父级菜单ID", + "example": 0 + } + }, + "required": [ + "id" + ] + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "成功", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AdminWebRouts" + } + } + }, + "headers": {} + } + }, + "security": [] + } + }, + "/api/v1/admin/server/web_routs/delete": { + "delete": { + "summary": "删除后台菜单", + "deprecated": false, + "description": "", + "tags": [ + "后台菜单管理" + ], + "parameters": [ + { + "name": "Authorization", + "in": "header", + "description": "", + "example": "Bearer {{token}}", + "schema": { + "type": "string", + "default": "Bearer {{token}}" + } + } + ], + "requestBody": { + "content": { + "multipart/form-data": { + "schema": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "description": "菜单ID", + "example": 0 + } + }, + "required": [ + "id" + ] + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "成功", "headers": {} } }, @@ -402,7 +644,122 @@ } }, "components": { - "schemas": {}, + "schemas": { + "AdminWebRouts": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "path": { + "type": "string", + "description": "菜单路径" + }, + "title": { + "type": "string", + "description": "菜单名称" + }, + "icon": { + "type": "string", + "description": "菜单图标" + }, + "parentId": { + "type": "integer", + "description": "父级菜单ID", + "nullable": true + }, + "children": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AdminWebRouts" + }, + "description": "子菜单列表" + }, + "CreatedAt": { + "type": "string", + "format": "date-time" + }, + "UpdatedAt": { + "type": "string", + "format": "date-time" + } + } + }, + "WebRoutsWithPermission": { + "type": "object", + "properties": { + "id": { + "type": "integer", + "description": "菜单ID" + }, + "path": { + "type": "string", + "description": "菜单路径" + }, + "title": { + "type": "string", + "description": "菜单名称" + }, + "icon": { + "type": "string", + "description": "菜单图标" + }, + "parentId": { + "type": "integer", + "description": "父级菜单ID", + "nullable": true + }, + "enable": { + "type": "boolean", + "description": "是否启用(合并用户级与管理员组级权限后的结果,用户级优先)" + }, + "children": { + "type": "array", + "items": { + "$ref": "#/components/schemas/WebRoutsWithPermission" + }, + "description": "子菜单列表" + } + } + }, + "AdminWebRoutsPermission": { + "type": "object", + "properties": { + "id": { + "type": "integer" + }, + "webRoutsId": { + "type": "integer", + "description": "菜单ID" + }, + "webRouts": { + "$ref": "#/components/schemas/AdminWebRouts" + }, + "enable": { + "type": "boolean", + "description": "是否启用" + }, + "adminGroupId": { + "type": "integer", + "description": "管理员组ID", + "nullable": true + }, + "userId": { + "type": "integer", + "description": "用户ID", + "nullable": true + }, + "CreatedAt": { + "type": "string", + "format": "date-time" + }, + "UpdatedAt": { + "type": "string", + "format": "date-time" + } + } + } + }, "responses": {}, "securitySchemes": {} },