feat: 文档整理+前端修复

- 工单分页查询适配(PageResponse/服务端分页)
- 前后端枚举统一(TriggerType/TaskStatus/PlanStatus)
- Permission类型增加菜单路由属性
- SpaceNode类型增加code字段
- WorkOrder状态机补全(SUSPENDED/RETURNED)
- Dashboard适配分页查询
This commit is contained in:
chiguyong 2026-05-18 10:46:45 +08:00
parent 72f7c891f3
commit 50760cde6e
11 changed files with 193 additions and 58 deletions

View File

@ -3,7 +3,7 @@ import type { ApiResponse } from '@/types'
// ==================== 维保计划类型 ==================== // ==================== 维保计划类型 ====================
export type PlanType = 'PREVENTIVE' | 'CORRECTIVE' export type PlanType = 'PREVENTIVE' | 'CORRECTIVE'
export type PlanStatus = 'ACTIVE' | 'INACTIVE' export type PlanStatus = 'ACTIVE' | 'INACTIVE' | 'SUSPENDED'
export interface MaintenancePlan { export interface MaintenancePlan {
id?: string id?: string
@ -71,5 +71,6 @@ export const PLAN_TYPE_OPTIONS = [
export const PLAN_STATUS_OPTIONS = [ export const PLAN_STATUS_OPTIONS = [
{ value: 'ACTIVE', label: '启用' }, { value: 'ACTIVE', label: '启用' },
{ value: 'INACTIVE', label: '停用' } { value: 'INACTIVE', label: '停用' },
{ value: 'SUSPENDED', label: '暂停' }
] ]

View File

@ -8,7 +8,7 @@ export interface MaintenancePlan {
name: string name: string
projectId: string projectId: string
projectName?: string projectName?: string
triggerType: 'MANUAL' | 'SCHEDULED' | 'AUTOMATIC' triggerType: 'PLAN' | 'INSPECTION' | 'FAULT' | 'MANUAL'
equipmentId?: string equipmentId?: string
equipmentName?: string equipmentName?: string
spaceNodeId?: string spaceNodeId?: string
@ -25,7 +25,7 @@ export interface MaintenancePlanForm {
id?: string id?: string
name: string name: string
projectId: string projectId: string
triggerType: 'MANUAL' | 'SCHEDULED' | 'AUTOMATIC' triggerType: 'PLAN' | 'INSPECTION' | 'FAULT' | 'MANUAL'
equipmentId?: string equipmentId?: string
spaceNodeId?: string spaceNodeId?: string
description?: string description?: string
@ -35,7 +35,7 @@ export interface MaintenancePlanForm {
// ==================== 维保任务相关类型 ==================== // ==================== 维保任务相关类型 ====================
export type TaskStatus = 'PENDING' | 'ACCEPTED' | 'IN_PROGRESS' | 'COMPLETED' | 'CANCELLED' export type TaskStatus = 'PENDING' | 'ASSIGNED' | 'IN_PROGRESS' | 'COMPLETED' | 'VERIFIED' | 'CANCELLED'
export interface MaintenanceTask { export interface MaintenanceTask {
id: string id: string

View File

@ -5,7 +5,7 @@ import type { ApiResponse } from '@/types'
export type WorkOrderSource = 'OWNER' | 'MAINTENANCE' | 'INSPECTION' | 'FAULT' | 'REGULATORY' | 'MANUAL' export type WorkOrderSource = 'OWNER' | 'MAINTENANCE' | 'INSPECTION' | 'FAULT' | 'REGULATORY' | 'MANUAL'
export type WorkOrderType = 'REPAIR' | 'INSPECTION' | 'SECURITY' | 'CLEANING' | 'PROPERTY' | 'CONSULTATION' export type WorkOrderType = 'REPAIR' | 'INSPECTION' | 'SECURITY' | 'CLEANING' | 'PROPERTY' | 'CONSULTATION'
export type WorkOrderPriority = 'LOW' | 'MEDIUM' | 'HIGH' | 'URGENT' export type WorkOrderPriority = 'LOW' | 'MEDIUM' | 'HIGH' | 'URGENT'
export type WorkOrderStatus = 'PENDING' | 'ASSIGNED' | 'IN_PROGRESS' | 'COMPLETED' | 'VERIFIED' | 'CANCELLED' export type WorkOrderStatus = 'PENDING' | 'ASSIGNED' | 'IN_PROGRESS' | 'SUSPENDED' | 'RETURNED' | 'COMPLETED' | 'VERIFIED' | 'CANCELLED'
export type TriggerType = 'PLAN' | 'INSPECTION' | 'FAULT' | 'MANUAL' export type TriggerType = 'PLAN' | 'INSPECTION' | 'FAULT' | 'MANUAL'
export interface WorkOrderItem { export interface WorkOrderItem {
@ -70,6 +70,8 @@ export interface WorkOrderStats {
completed: number completed: number
verified: number verified: number
cancelled: number cancelled: number
suspended: number
returned: number
completedToday: number completedToday: number
createdToday: number createdToday: number
overdue: number overdue: number
@ -80,6 +82,16 @@ export interface WorkOrderStats {
byPriority: Record<string, number> byPriority: Record<string, number>
} }
export interface PageResponse<T> {
content: T[]
page: number
size: number
totalElements: number
totalPages: number
first: boolean
last: boolean
}
// ==================== API 函数 ==================== // ==================== API 函数 ====================
export function getWorkOrders(params?: { export function getWorkOrders(params?: {
projectId?: string projectId?: string
@ -87,9 +99,13 @@ export function getWorkOrders(params?: {
source?: WorkOrderSource source?: WorkOrderSource
type?: WorkOrderType type?: WorkOrderType
status?: WorkOrderStatus status?: WorkOrderStatus
priority?: WorkOrderPriority
assignedTo?: string assignedTo?: string
keyword?: string
page?: number
size?: number
}) { }) {
return request.get<ApiResponse<WorkOrder[]>>('/api/wo/work-orders', { params }) return request.get<ApiResponse<PageResponse<WorkOrder>>>('/api/wo/work-orders', { params })
} }
export function getWorkOrder(id: string) { export function getWorkOrder(id: string) {
@ -128,6 +144,18 @@ export function cancelWorkOrder(id: string) {
return request.post(`/api/wo/work-orders/${id}/cancel`) return request.post(`/api/wo/work-orders/${id}/cancel`)
} }
export function suspendWorkOrder(id: string) {
return request.post(`/api/wo/work-orders/${id}/suspend`)
}
export function resumeWorkOrder(id: string) {
return request.post(`/api/wo/work-orders/${id}/resume`)
}
export function returnWorkOrder(id: string) {
return request.post(`/api/wo/work-orders/${id}/return`)
}
export function getWorkOrderStats() { export function getWorkOrderStats() {
return request.get<ApiResponse<WorkOrderStats>>('/api/wo/work-orders/stats') return request.get<ApiResponse<WorkOrderStats>>('/api/wo/work-orders/stats')
} }
@ -170,6 +198,8 @@ export const STATUS_OPTIONS = [
{ value: 'PENDING', label: '待分配' }, { value: 'PENDING', label: '待分配' },
{ value: 'ASSIGNED', label: '已派单' }, { value: 'ASSIGNED', label: '已派单' },
{ value: 'IN_PROGRESS', label: '执行中' }, { value: 'IN_PROGRESS', label: '执行中' },
{ value: 'SUSPENDED', label: '已挂起' },
{ value: 'RETURNED', label: '已退回' },
{ value: 'COMPLETED', label: '已完成' }, { value: 'COMPLETED', label: '已完成' },
{ value: 'VERIFIED', label: '已验收' }, { value: 'VERIFIED', label: '已验收' },
{ value: 'CANCELLED', label: '已取消' } { value: 'CANCELLED', label: '已取消' }
@ -179,6 +209,8 @@ export const STATUS_COLOR_MAP: Record<WorkOrderStatus, string> = {
'PENDING': 'default', 'PENDING': 'default',
'ASSIGNED': 'blue', 'ASSIGNED': 'blue',
'IN_PROGRESS': 'orange', 'IN_PROGRESS': 'orange',
'SUSPENDED': 'purple',
'RETURNED': 'volcano',
'COMPLETED': 'green', 'COMPLETED': 'green',
'VERIFIED': 'cyan', 'VERIFIED': 'cyan',
'CANCELLED': 'red' 'CANCELLED': 'red'

View File

@ -81,10 +81,14 @@ export interface Permission {
code: string code: string
name: string name: string
type: string type: string
path?: string
component?: string
icon?: string
resource?: string resource?: string
method?: string method?: string
description?: string description?: string
sortOrder?: number sortOrder?: number
visible?: boolean
} }
export interface Project { export interface Project {

View File

@ -87,6 +87,7 @@ export interface SpaceNodeTree extends SpaceNode {
export interface SpaceNodeCreateForm { export interface SpaceNodeCreateForm {
projectId: string projectId: string
code?: string
name: string name: string
fullName?: string fullName?: string
shortName?: string shortName?: string

View File

@ -116,9 +116,12 @@ const fetchDashboardData = async () => {
// //
const workOrderRes = await getWorkOrders({ const workOrderRes = await getWorkOrders({
status: 'PENDING' status: 'PENDING',
}).catch(() => ({ data: { data: [] } })) page: 0,
pendingWorkOrders.value = (workOrderRes.data?.data || []).slice(0, 5) size: 5
}).catch(() => ({ data: { data: { content: [], totalElements: 0 } } }))
const workOrderPageData = workOrderRes.data?.data
pendingWorkOrders.value = (workOrderPageData?.content || workOrderPageData || []).slice(0, 5)
// 7 // 7
const today = new Date() const today = new Date()

View File

@ -54,7 +54,9 @@ const getPlanStatusLabel = (status: PlanStatus | undefined) => {
// //
const getPlanStatusColor = (status: PlanStatus | undefined) => { const getPlanStatusColor = (status: PlanStatus | undefined) => {
if (!status) return 'default' if (!status) return 'default'
return status === 'ACTIVE' ? 'green' : 'red' if (status === 'ACTIVE') return 'green'
if (status === 'SUSPENDED') return 'orange'
return 'red'
} }
// //

View File

@ -21,9 +21,10 @@ import { getProjectSelectorList } from '@/api/project'
// //
const triggerTypeMap: Record<string, { text: string; color: string }> = { const triggerTypeMap: Record<string, { text: string; color: string }> = {
MANUAL: { text: '手动', color: 'default' }, PLAN: { text: '计划触发', color: 'blue' },
SCHEDULED: { text: '定时', color: 'blue' }, INSPECTION: { text: '巡检触发', color: 'cyan' },
AUTOMATIC: { text: '自动', color: 'green' } FAULT: { text: '故障触发', color: 'red' },
MANUAL: { text: '手动创建', color: 'default' }
} }
// //
@ -43,9 +44,10 @@ const projectOptions = ref<{ value: string; label: string }[]>([])
// //
const triggerTypeOptions = [ const triggerTypeOptions = [
{ value: 'MANUAL', label: '手动' }, { value: 'PLAN', label: '计划触发' },
{ value: 'SCHEDULED', label: '定时' }, { value: 'INSPECTION', label: '巡检触发' },
{ value: 'AUTOMATIC', label: '自动' } { value: 'FAULT', label: '故障触发' },
{ value: 'MANUAL', label: '手动创建' }
] ]
// //
@ -73,7 +75,7 @@ const editingPlan = ref<MaintenancePlan | null>(null)
const formState = reactive<Record<string, any>>({ const formState = reactive<Record<string, any>>({
name: '', name: '',
projectId: '', projectId: '',
triggerType: 'MANUAL', triggerType: 'PLAN',
equipmentId: undefined, equipmentId: undefined,
spaceNodeId: undefined, spaceNodeId: undefined,
description: '', description: '',
@ -140,7 +142,7 @@ const handleAdd = () => {
modalTitle.value = '新建维保计划' modalTitle.value = '新建维保计划'
formState.name = '' formState.name = ''
formState.projectId = queryParams.projectId formState.projectId = queryParams.projectId
formState.triggerType = 'MANUAL' formState.triggerType = 'PLAN'
formState.equipmentId = undefined formState.equipmentId = undefined
formState.spaceNodeId = undefined formState.spaceNodeId = undefined
formState.description = '' formState.description = ''

View File

@ -24,10 +24,11 @@ import { getProjectSelectorList } from '@/api/project'
// //
const statusMap: Record<TaskStatus, { text: string; color: string; status: 'default' | 'processing' | 'success' | 'error' | 'warning' | 'default' }> = { const statusMap: Record<TaskStatus, { text: string; color: string; status: 'default' | 'processing' | 'success' | 'error' | 'warning' | 'default' }> = {
PENDING: { text: '待接受', color: 'default', status: 'default' }, PENDING: { text: '待分配', color: 'default', status: 'default' },
ACCEPTED: { text: '已接受', color: 'blue', status: 'processing' }, ASSIGNED: { text: '已派单', color: 'blue', status: 'processing' },
IN_PROGRESS: { text: '进行中', color: 'processing', status: 'processing' }, IN_PROGRESS: { text: '进行中', color: 'processing', status: 'processing' },
COMPLETED: { text: '已完成', color: 'success', status: 'success' }, COMPLETED: { text: '已完成', color: 'success', status: 'success' },
VERIFIED: { text: '已验收', color: 'success', status: 'success' },
CANCELLED: { text: '已取消', color: 'error', status: 'error' } CANCELLED: { text: '已取消', color: 'error', status: 'error' }
} }
@ -49,11 +50,12 @@ const projectOptions = ref<{ value: string; label: string }[]>([])
// //
const statusOptions = [ const statusOptions = [
{ value: 'PENDING', label: '待接受' }, { value: 'PENDING', label: '待分配' },
{ value: 'ACCEPTED', label: '已接受' }, { value: 'ASSIGNED', label: '已派单' },
{ value: 'IN_PROGRESS', label: '进行中' }, { value: 'IN_PROGRESS', label: '进行中' },
{ value: 'COMPLETED', label: '已完成' }, { value: 'COMPLETED', label: '已完成' },
{ value: 'CANCELLED', label: '取消' } { value: 'VERIFIED', label: '已验收' },
{ value: 'CANCELLED', label: '已取消' }
] ]
// //
@ -304,11 +306,10 @@ onMounted(() => {
size="small" size="small"
@click="handleAccept(record.id)" @click="handleAccept(record.id)"
> >
<CheckCircleOutlined /> 接受 <CheckCircleOutlined /> 派单
</Button> </Button>
<!-- 已接受状态显示开始按钮 -->
<Button <Button
v-if="record.status === 'ACCEPTED'" v-if="record.status === 'ASSIGNED'"
type="link" type="link"
size="small" size="small"
@click="handleStart(record.id)" @click="handleStart(record.id)"
@ -324,9 +325,8 @@ onMounted(() => {
> >
<CheckCircleOutlined /> 完成 <CheckCircleOutlined /> 完成
</Button> </Button>
<!-- 待接受已接受进行中状态显示取消按钮 -->
<Button <Button
v-if="['PENDING', 'ACCEPTED', 'IN_PROGRESS'].includes(record.status)" v-if="['PENDING', 'ASSIGNED', 'IN_PROGRESS'].includes(record.status)"
type="link" type="link"
size="small" size="small"
danger danger

View File

@ -14,7 +14,9 @@ import {
PlayCircleOutlined, PlayCircleOutlined,
SendOutlined, SendOutlined,
EyeOutlined, EyeOutlined,
SafetyCertificateOutlined SafetyCertificateOutlined,
PauseCircleOutlined,
RollbackOutlined
} from '@ant-design/icons-vue' } from '@ant-design/icons-vue'
import { import {
getWorkOrders, getWorkOrders,
@ -27,6 +29,9 @@ import {
completeWorkOrder, completeWorkOrder,
verifyWorkOrder, verifyWorkOrder,
cancelWorkOrder, cancelWorkOrder,
suspendWorkOrder,
resumeWorkOrder,
returnWorkOrder,
getWorkOrderStats, getWorkOrderStats,
getWorkOrderItems, getWorkOrderItems,
addWorkOrderItems, addWorkOrderItems,
@ -42,7 +47,8 @@ import {
type WorkOrderSource, type WorkOrderSource,
type WorkOrderType, type WorkOrderType,
type WorkOrderPriority, type WorkOrderPriority,
type WorkOrderStatus type WorkOrderStatus,
type PageResponse
} from '@/api/work-order' } from '@/api/work-order'
import { getProjectSelectorList } from '@/api/project' import { getProjectSelectorList } from '@/api/project'
import { getEquipmentList } from '@/api/equipment' import { getEquipmentList } from '@/api/equipment'
@ -120,6 +126,8 @@ const stats = reactive({
completed: 0, completed: 0,
verified: 0, verified: 0,
cancelled: 0, cancelled: 0,
suspended: 0,
returned: 0,
completedToday: 0, completedToday: 0,
createdToday: 0, createdToday: 0,
overdue: 0, overdue: 0,
@ -141,6 +149,8 @@ const fetchStats = async () => {
stats.completed = data.completed || 0 stats.completed = data.completed || 0
stats.verified = data.verified || 0 stats.verified = data.verified || 0
stats.cancelled = data.cancelled || 0 stats.cancelled = data.cancelled || 0
stats.suspended = data.suspended || 0
stats.returned = data.returned || 0
stats.completedToday = data.completedToday || 0 stats.completedToday = data.completedToday || 0
stats.createdToday = data.createdToday || 0 stats.createdToday = data.createdToday || 0
stats.overdue = data.overdue || 0 stats.overdue = data.overdue || 0
@ -190,34 +200,17 @@ const fetchWorkOrders = async () => {
projectId: queryParams.projectId, projectId: queryParams.projectId,
source: queryParams.source, source: queryParams.source,
type: queryParams.type, type: queryParams.type,
status: queryParams.status status: queryParams.status,
priority: queryParams.priority,
keyword: queryParams.keyword || undefined,
page: pagination.current - 1,
size: pagination.pageSize
}) })
const apiRes = response.data const apiRes = response.data
let data: WorkOrder[] = apiRes.data || apiRes || [] const pageData: PageResponse<WorkOrder> = apiRes.data || apiRes
// tableData.value = pageData.content || []
if (queryParams.source) { pagination.total = pageData.totalElements || 0
data = data.filter((t: WorkOrder) => t.source === queryParams.source)
}
if (queryParams.type) {
data = data.filter((t: WorkOrder) => t.type === queryParams.type)
}
if (queryParams.status) {
data = data.filter((t: WorkOrder) => t.status === queryParams.status)
}
if (queryParams.priority) {
data = data.filter((t: WorkOrder) => t.priority === queryParams.priority)
}
if (queryParams.keyword) {
const kw = queryParams.keyword.toLowerCase()
data = data.filter((t: WorkOrder) =>
t.workNo?.toLowerCase().includes(kw) ||
t.title?.toLowerCase().includes(kw)
)
}
tableData.value = data
pagination.total = data.length
} catch { } catch {
message.error('获取工单列表失败') message.error('获取工单列表失败')
} finally { } finally {
@ -247,6 +240,7 @@ const handleReset = () => {
const handlePageChange = (page: number, pageSize: number) => { const handlePageChange = (page: number, pageSize: number) => {
pagination.current = page pagination.current = page
pagination.pageSize = pageSize pagination.pageSize = pageSize
fetchWorkOrders()
} }
// //
@ -614,6 +608,58 @@ const handleCancel = (record: WorkOrder) => {
}) })
} }
// ========== ==========
const handleSuspend = (record: WorkOrder) => {
Modal.confirm({
title: '挂起工单',
content: '确定要挂起此工单吗?挂起后可随时恢复。',
onOk: async () => {
try {
await suspendWorkOrder(record.id!)
message.success('工单已挂起')
fetchWorkOrders()
} catch (error: unknown) {
message.error(getErrorMessage(error))
}
}
})
}
// ========== ==========
const handleResume = (record: WorkOrder) => {
Modal.confirm({
title: '恢复工单',
content: '确定要恢复此工单吗?',
onOk: async () => {
try {
await resumeWorkOrder(record.id!)
message.success('工单已恢复')
fetchWorkOrders()
} catch (error: unknown) {
message.error(getErrorMessage(error))
}
}
})
}
// ========== 退 ==========
const handleReturn = (record: WorkOrder) => {
Modal.confirm({
title: '退回工单',
content: '确定要退回此工单吗?退回后工单将变为待分配状态。',
okType: 'danger',
onOk: async () => {
try {
await returnWorkOrder(record.id!)
message.success('工单已退回')
fetchWorkOrders()
} catch (error: unknown) {
message.error(getErrorMessage(error))
}
}
})
}
onMounted(() => { onMounted(() => {
fetchProjects() fetchProjects()
fetchWorkOrders() fetchWorkOrders()
@ -783,18 +829,32 @@ onMounted(() => {
<Button type="link" size="small" @click="handleStart(record)"> <Button type="link" size="small" @click="handleStart(record)">
<PlayCircleOutlined /> 开始 <PlayCircleOutlined /> 开始
</Button> </Button>
<Button type="link" size="small" @click="handleSuspend(record)">
<PauseCircleOutlined /> 挂起
</Button>
<Button type="link" size="small" @click="handleReturn(record)">
<RollbackOutlined /> 退回
</Button>
</template> </template>
<template v-if="record.status === 'IN_PROGRESS'"> <template v-if="record.status === 'IN_PROGRESS'">
<Button type="link" size="small" @click="openCompleteDrawer(record)"> <Button type="link" size="small" @click="openCompleteDrawer(record)">
<CheckCircleOutlined /> 完成 <CheckCircleOutlined /> 完成
</Button> </Button>
<Button type="link" size="small" @click="handleSuspend(record)">
<PauseCircleOutlined /> 挂起
</Button>
</template>
<template v-if="record.status === 'SUSPENDED'">
<Button type="link" size="small" @click="handleResume(record)">
<PlayCircleOutlined /> 恢复
</Button>
</template> </template>
<template v-if="record.status === 'COMPLETED'"> <template v-if="record.status === 'COMPLETED'">
<Button type="link" size="small" @click="openVerifyDrawer(record)"> <Button type="link" size="small" @click="openVerifyDrawer(record)">
<SafetyCertificateOutlined /> 验收 <SafetyCertificateOutlined /> 验收
</Button> </Button>
</template> </template>
<template v-if="['PENDING', 'ASSIGNED', 'IN_PROGRESS'].includes(record.status)"> <template v-if="['PENDING', 'ASSIGNED', 'IN_PROGRESS', 'SUSPENDED'].includes(record.status)">
<Button type="link" danger size="small" @click="handleCancel(record)"> <Button type="link" danger size="small" @click="handleCancel(record)">
<CloseCircleOutlined /> 取消 <CloseCircleOutlined /> 取消
</Button> </Button>

View File

@ -92,9 +92,14 @@ const formState = reactive({
code: '', code: '',
name: '', name: '',
type: 'MENU', type: 'MENU',
path: '',
component: '',
icon: '',
resource: '', resource: '',
method: 'GET', method: 'GET',
description: '' description: '',
sortOrder: 0,
visible: true
}) })
/** /**
@ -175,9 +180,14 @@ const resetForm = () => {
formState.code = '' formState.code = ''
formState.name = '' formState.name = ''
formState.type = 'MENU' formState.type = 'MENU'
formState.path = ''
formState.component = ''
formState.icon = ''
formState.resource = '' formState.resource = ''
formState.method = 'GET' formState.method = 'GET'
formState.description = '' formState.description = ''
formState.sortOrder = 0
formState.visible = true
editingId.value = null editingId.value = null
} }
@ -201,9 +211,14 @@ const handleEdit = (record: Permission) => {
formState.code = record.code formState.code = record.code
formState.name = record.name formState.name = record.name
formState.type = record.type formState.type = record.type
formState.path = record.path || ''
formState.component = record.component || ''
formState.icon = record.icon || ''
formState.resource = record.resource || '' formState.resource = record.resource || ''
formState.method = record.method || 'GET' formState.method = record.method || 'GET'
formState.description = record.description || '' formState.description = record.description || ''
formState.sortOrder = record.sortOrder ?? 0
formState.visible = record.visible ?? true
drawerTitle.value = '编辑权限' drawerTitle.value = '编辑权限'
drawerVisible.value = true drawerVisible.value = true
} }
@ -390,6 +405,21 @@ onMounted(fetchPermissions)
<Form.Item label="类型" name="type"> <Form.Item label="类型" name="type">
<a-select v-model:value="formState.type" :options="typeOptions" /> <a-select v-model:value="formState.type" :options="typeOptions" />
</Form.Item> </Form.Item>
<Form.Item v-if="formState.type === 'MENU'" label="路由路径" name="path">
<a-input v-model:value="formState.path" placeholder="如: /system/users" />
</Form.Item>
<Form.Item v-if="formState.type === 'MENU'" label="组件路径" name="component">
<a-input v-model:value="formState.component" placeholder="如: system/Users" />
</Form.Item>
<Form.Item v-if="formState.type === 'MENU'" label="菜单图标" name="icon">
<a-input v-model:value="formState.icon" placeholder="如: SettingOutlined" />
</Form.Item>
<Form.Item v-if="formState.type === 'MENU'" label="排序序号" name="sortOrder">
<a-input-number v-model:value="formState.sortOrder" :min="0" style="width: 100%" />
</Form.Item>
<Form.Item v-if="formState.type === 'MENU'" label="是否可见" name="visible">
<a-switch v-model:checked="formState.visible" />
</Form.Item>
<Form.Item label="资源路径" name="resource"> <Form.Item label="资源路径" name="resource">
<a-input v-model:value="formState.resource" placeholder="如: /api/users" /> <a-input v-model:value="formState.resource" placeholder="如: /api/users" />
</Form.Item> </Form.Item>