35 KiB
35 KiB
RMDC 项目详情页面前端详细设计说明书 (Frontend DDS)
文档名称: RMDC 项目详情页面前端设计文档
对应页面:
frontend/src/modules/admin/pages/admin/ProjectDetail.vue(管理员端)frontend/src/modules/admin/pages/user/UserProjectDetail.vue(用户端)
版本: v2.0
编制日期: 2026-01-15
文档修订历史
| 版本 | 日期 | 修订内容 |
|---|---|---|
| v1.0 | 2026-01-12 | 初始版本,基础页面架构设计 |
| v1.2 | 2026-01-14 | 完善模块设计规范、中间件卡片设计 |
| v2.0 | 2026-01-15 | 新增:查看/编辑状态分离、用户侧/管理侧差异化设计、工单关联与跳转机制、多工单场景处理、页面美化规范 |
1. 设计概述
1.1 设计背景
项目详情页面是 RMDC 系统的核心交互界面,需要支持复杂的生命周期管理流程,并满足不同角色用户的差异化需求。本设计文档详细定义了页面的功能逻辑、交互行为、组件结构和美化规范。
1.2 核心设计目标
| 目标 | 说明 |
|---|---|
| 状态分离 | 明确区分「只读查看模式」与「编辑修改模式」,防止误操作 |
| 角色差异化 | 超级管理员与普通用户看到的内容、操作权限不同,但尽量复用组件 |
| 生命周期可视化 | 清晰展示项目当前状态(INIT/DRAFTING/REVIEWING/RELEASED/MODIFYING/ARCHIVED) |
| 工单关联 | 支持项目详情页与工单详情页的双向跳转,处理多工单场景 |
| 美观专业 | 采用现代 Material Design 风格,注重留白、排版与微动效 |
| 高复用性 | 最大化组件复用,用户侧与管理侧共用核心表单组件 |
1.3 页面文件结构
frontend/src/modules/admin/
├── pages/
│ ├── admin/
│ │ └── ProjectDetail.vue # 超级管理员端项目详情
│ └── user/
│ └── UserProjectDetail.vue # 普通用户端项目详情(填写人视角)
├── components/
│ ├── BasicInfoForm.vue # 基本信息编辑表单
│ ├── BasicInfoReadonly.vue # 基本信息只读展示
│ ├── BusinessInfoReadonly.vue # 业务信息只读展示
│ ├── DeploymentBusinessForm.vue # 部署业务编辑表单
│ ├── DeploymentEnvironmentForm.vue # 部署环境编辑表单
│ ├── EnvironmentInfoReadonly.vue # 环境信息只读展示
│ ├── HostsInfoReadonly.vue # 主机信息只读展示
│ ├── HostsManagement.vue # 主机管理组件
│ ├── MiddlewareCardsGrid.vue # 中间件卡片网格
│ ├── MiddlewareInfoReadonly.vue # 中间件只读展示
│ ├── AuthorizationManagement.vue # 授权管理 (SuperAdmin Only)
│ ├── VersionHistory.vue # 版本历史 (SuperAdmin Only)
│ ├── SaveConfirmDialog.vue # 保存确认对话框
│ ├── ProjectBasicInfoCard.vue # 项目基本信息卡片
│ ├── CopyableField.vue # 可复制字段组件
│ └── index.ts # 组件统一导出
2. 页面架构设计
2.1 整体布局结构
页面采用 「固定头部 + 固定 Tab 导航 + 可滚动内容区域」 的三段式布局。
┌─────────────────────────────────────────────────────────────────────────┐
│ [固定区域] 生命周期状态提示横幅 (Alert Banner) │
├─────────────────────────────────────────────────────────────────────────┤
│ [固定区域] 页面头部 Header │
│ ┌─────────────────────────────────────┬─────────────────────────────┐ │
│ │ ← 返回 项目名称 │ [查看工单] [打回] [通过] │ │
│ │ Namespace | 省份 城市 │ [下载配置] [编辑/保存] │ │
│ │ 状态标签组 │ │ │
│ └─────────────────────────────────────┴─────────────────────────────┘ │
├─────────────────────────────────────────────────────────────────────────┤
│ [固定区域] Tab 导航栏 │
│ ┌─────────────────────────────────────────────────────────────────────┐│
│ │ 基本信息 | 部署业务 | 部署环境 | 主机管理 | 中间件 | 授权 | 版本历史 ││
│ └─────────────────────────────────────────────────────────────────────┘│
├─────────────────────────────────────────────────────────────────────────┤
│ [滚动区域] Tab 内容区域 │
│ ┌─────────────────────────────────────────────────────────────────────┐│
│ │ ││
│ │ 当前 Tab 对应的表单/只读内容 ││
│ │ ││
│ │ ││
│ └─────────────────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────────────────┘
2.2 CSS 布局实现
.project-detail-page {
height: 100%;
max-height: 100%;
overflow: hidden;
display: flex;
flex-direction: column;
}
.header-section {
flex-shrink: 0;
background: rgb(var(--v-theme-surface));
z-index: 1;
}
.content-area {
flex: 1 1 auto;
overflow-y: auto;
overflow-x: hidden;
min-height: 0; /* 关键:防止 Flex 子元素撑破父容器 */
padding-bottom: 24px;
}
3. 查看状态 vs 编辑状态
3.1 状态定义
| 状态 | 变量名 | 说明 |
|---|---|---|
| 查看状态 | isEditMode = false |
默认状态,展示只读组件 |
| 编辑状态 | isEditMode = true |
编辑模式,展示表单组件 |
3.2 查看状态 (默认)
3.2.1 展示形式
- 使用
*Readonly.vue系列组件展示数据 - 采用
v-row/v-col布局,键值对形式展示 - 关键字段(IP、URL、密码)支持一键复制
- 敏感字段(密码)默认脱敏显示
******
3.2.2 交互行为
| 交互 | 说明 |
|---|---|
| 一键复制 | 使用 CopyableField 组件,点击复制图标复制到剪贴板 |
| 密码查看 | 点击"小眼睛"图标切换明文/密文 |
| 链接跳转 | URL 字段支持点击新窗口打开 |
3.2.3 组件列表
| 组件名称 | 对应模块 | 说明 |
|---|---|---|
BasicInfoReadonly.vue |
基本信息 | 项目名、NS、省市、性质 |
BusinessInfoReadonly.vue |
部署业务 | 部署人、系统版本、入口URL |
EnvironmentInfoReadonly.vue |
部署环境 | 网络、IP、域名、主机统计 |
HostsInfoReadonly.vue |
主机管理 | 主机列表只读表格 |
MiddlewareInfoReadonly.vue |
中间件 | 中间件卡片只读展示 |
3.3 编辑状态
3.3.1 进入条件
- 点击 Header 的「编辑」按钮
- 用户必须具备编辑权限(基于角色和生命周期状态)
3.3.2 数据流
sequenceDiagram
participant User as 用户
participant View as 查看模式
participant Edit as 编辑模式
participant API as 后端API
User->>View: 点击[编辑]按钮
View->>Edit: isEditMode = true
Edit->>Edit: 深拷贝 masterData → editForm
Edit-->>User: 显示表单组件
User->>Edit: 修改字段
Edit->>Edit: computed hasChanges = true
User->>Edit: 点击[保存]
Edit->>Edit: 弹出 SaveConfirmDialog
User->>Edit: 确认保存
Edit->>API: 调用更新接口
API-->>Edit: 返回成功
Edit->>View: isEditMode = false, 刷新数据
3.3.3 退出保护
- 脏数据检测:通过
computed hasChanges检测是否有未保存的修改 - 退出确认:如有未保存修改,点击「取消」或切换页面时弹出确认对话框
const exitEditMode = () => {
if (hasChanges.value) {
exitConfirmDialog.value = true // 弹出确认对话框
} else {
isEditMode.value = false
}
}
3.3.4 编辑状态指示器
编辑模式下,Header 区域显示明显的「编辑模式」标签:
<v-chip v-if="isEditMode" color="info" variant="tonal" class="ml-2">
<v-icon start size="small">mdi-pencil</v-icon>
编辑模式
</v-chip>
4. 用户侧 vs 管理侧差异化设计
4.1 页面对照表
| 特性 | 管理员端 (ProjectDetail.vue) | 用户端 (UserProjectDetail.vue) |
|---|---|---|
| 默认模式 | 查看模式 | 根据工单状态决定 |
| 查看权限 | 所有模块 | ACL 授权模块 |
| 授权信息 Tab | ✅ 可见 | ❌ 不可见 |
| 版本历史 Tab | ✅ 可见 | ❌ 不可见 |
| 主机管理 Tab | ✅ 可见 | ❌ 不可见 |
| 基本信息 | 可编辑 | 只读(由管理员填写) |
| 编辑操作 | 直接保存(上帝模式) | 草稿 → 提交审核(工单流程) |
| 审批操作 | ✅ 通过/打回按钮 | ❌ 无 |
| 保存按钮 | 「保存修改」 | 「保存草稿」 |
| 提交按钮 | 无 | 「提交审核」 |
4.2 Tab 导航差异
管理员端 Tabs
<v-tabs v-model="activeTab">
<v-tab value="basic">基本信息</v-tab>
<v-tab value="business">部署业务</v-tab>
<v-tab value="environment">部署环境</v-tab>
<v-tab value="hosts">主机管理</v-tab>
<v-tab value="middlewares">中间件</v-tab>
<v-tab value="authorization" v-if="isSuperAdmin">授权信息</v-tab>
<v-tab value="version-history" v-if="isSuperAdmin">版本历史</v-tab>
</v-tabs>
用户端 Tabs
<v-tabs v-model="activeTab">
<v-tab value="basic">基本信息</v-tab>
<v-tab value="business">部署业务</v-tab>
<v-tab value="environment">部署环境</v-tab>
<v-tab value="middlewares">中间件</v-tab>
</v-tabs>
4.3 组件复用策略
graph TB
subgraph 共用组件
A[BasicInfoForm]
B[DeploymentBusinessForm]
C[DeploymentEnvironmentForm]
D[MiddlewareCardsGrid]
E[BasicInfoReadonly]
F[BusinessInfoReadonly]
G[EnvironmentInfoReadonly]
H[MiddlewareInfoReadonly]
end
subgraph 管理端专用
I[AuthorizationManagement]
J[VersionHistory]
K[HostsManagement]
L[SaveConfirmDialog]
end
subgraph 用户端专用
M[ProjectBasicInfoCard]
end
Admin[ProjectDetail.vue] --> A
Admin --> B
Admin --> C
Admin --> D
Admin --> E
Admin --> F
Admin --> G
Admin --> H
Admin --> I
Admin --> J
Admin --> K
Admin --> L
User[UserProjectDetail.vue] --> B
User --> C
User --> D
User --> M
4.4 权限控制逻辑
// 管理员端 - 编辑权限判断
const canEdit = computed(() => {
if (!masterData.value) return false
const status = masterData.value.lifecycle_status
// 超级管理员在已发布、变更中状态可以编辑
if (isSuperAdmin.value) {
return status === 'released' || status === 'modifying'
}
return false
})
// 用户端 - 编辑权限判断
const canEdit = computed(() => {
if (!workflowInfo.value) return true // 没有工单信息时默认可编辑
const status = workflowInfo.value.status
// 已分配、处理中、已打回状态可编辑
return ['assigned', 'in_progress', 'returned', 'draft_saved'].includes(status)
})
5. 项目生命周期状态展示
5.1 状态标签设计
项目详情页 Header 区域展示三类状态标签:
<div class="d-flex align-center gap-2">
<h1 class="text-h4 font-weight-bold">{{ masterData.project_name }}</h1>
<!-- 1. 连接状态 -->
<v-chip :color="getStatusColor(masterData.status)" size="small" variant="tonal">
{{ PROJECT_STATUS[masterData.status] }}
</v-chip>
<!-- 2. 生命周期状态 -->
<v-chip :color="getLifecycleStatusColor(masterData.lifecycle_status)"
size="small" variant="tonal">
<v-icon start size="small">{{ getLifecycleStatusIcon(masterData.lifecycle_status) }}</v-icon>
{{ LIFECYCLE_STATUS[masterData.lifecycle_status] }}
</v-chip>
<!-- 3. 认证状态 -->
<v-chip :color="masterData.project_certification === 'official' ? 'success' : 'warning'"
size="small" variant="tonal">
{{ PROJECT_CERTIFICATION[masterData.project_certification] }}
</v-chip>
<!-- 4. 编辑模式指示器 -->
<v-chip v-if="isEditMode" color="info" variant="tonal">
<v-icon start size="small">mdi-pencil</v-icon>
编辑模式
</v-chip>
</div>
5.2 生命周期状态配置
// 生命周期状态枚举
export const LIFECYCLE_STATUS = {
init: '初始化',
drafting: '填写中',
reviewing: '审核中',
released: '已发布',
modifying: '变更中',
archived: '已归档'
}
// 状态颜色映射
export const LIFECYCLE_STATUS_COLORS: Record<string, string> = {
init: 'grey',
drafting: 'info',
reviewing: 'warning',
released: 'success',
modifying: 'primary',
archived: 'grey-darken-1'
}
// 状态图标
const getLifecycleStatusIcon = (status: string): string => {
const icons: Record<string, string> = {
init: 'mdi-clock-outline',
drafting: 'mdi-pencil',
reviewing: 'mdi-eye',
released: 'mdi-check-circle',
modifying: 'mdi-sync',
archived: 'mdi-archive'
}
return icons[status] || 'mdi-help-circle'
}
5.3 生命周期提示横幅 (Alert Banner)
根据当前生命周期状态,在 Header 下方显示上下文提示:
interface LifecycleAlert {
type: 'info' | 'warning' | 'success' | 'error'
message: string
action?: {
text: string
handler: () => void
}
}
const lifecycleStatusAlert = computed((): LifecycleAlert | null => {
if (!masterData.value) return null
const status = masterData.value.lifecycle_status
switch (status) {
case 'init':
return {
type: 'info',
message: '项目已创建,等待指定填写人录入详细信息'
}
case 'drafting':
return {
type: 'info',
message: `项目详情正在由 ${masterData.value.detail_filler_name || '填写人'} 填写中`,
action: masterData.value.workflow_id ? {
text: '查看工单',
handler: () => router.push(`/admin/workflows/${masterData.value?.workflow_id}`)
} : undefined
}
case 'reviewing':
return {
type: 'warning',
message: '项目详情已提交,等待审核',
action: masterData.value.workflow_id ? {
text: '查看工单',
handler: () => router.push(`/admin/workflows/${masterData.value?.workflow_id}`)
} : undefined
}
case 'modifying':
return {
type: 'info',
message: '项目存在活跃的变更工单,主线数据不受影响',
action: masterData.value.workflow_id ? {
text: '查看工单',
handler: () => router.push(`/admin/workflows/${masterData.value?.workflow_id}`)
} : undefined
}
case 'archived':
return {
type: 'warning',
message: '项目已归档,仅保留历史数据'
}
default:
return null
}
})
6. 工单关联与跳转机制
6.1 工单与项目的关系
| 工单类型 | 生命周期状态 | 数量关系 | 说明 |
|---|---|---|---|
| 填写工单 (project_detail) | INIT → DRAFTING | 1:1 | 项目创建时只能有一个 |
| 修改工单 (project_modify) | RELEASED → MODIFYING | 1:N | 已发布项目可有多个 |
6.2 工单按钮显示逻辑
// 是否显示工单按钮
const showWorkflowButton = computed(() => {
if (!masterData.value?.workflow_id) return false
const status = masterData.value.lifecycle_status
// 在填写中、审核中、变更中状态显示工单按钮
return ['drafting', 'reviewing', 'modifying'].includes(status)
})
// 工单按钮文本
const workflowButtonText = computed(() => {
if (!masterData.value) return '查看工单'
const status = masterData.value.lifecycle_status
switch (status) {
case 'drafting':
return '查看填写工单'
case 'reviewing':
return '查看审核工单'
case 'modifying':
return '查看修改工单'
default:
return '查看工单'
}
})
6.3 多工单场景处理
当项目处于 MODIFYING 状态时,可能同时存在多个修改工单。需要设计专门的工单列表展示。
6.3.1 设计方案
方案一:下拉菜单选择
<v-menu v-if="multipleWorkflows">
<template v-slot:activator="{ props }">
<v-btn v-bind="props" color="info" variant="tonal" prepend-icon="mdi-sitemap">
查看工单 ({{ workflowCount }})
<v-icon end>mdi-chevron-down</v-icon>
</v-btn>
</template>
<v-list>
<v-list-item
v-for="wf in relatedWorkflows"
:key="wf.workflow_id"
@click="navigateToWorkflow(wf.workflow_id)"
>
<v-list-item-title>{{ wf.workflow_id }}</v-list-item-title>
<v-list-item-subtitle>
{{ wf.creator_name }} | {{ formatDate(wf.created_at) }}
</v-list-item-subtitle>
</v-list-item>
</v-list>
</v-menu>
方案二:工单列表对话框(推荐用于工单较多的场景)
<v-dialog v-model="workflowListDialog" max-width="600">
<v-card>
<v-card-title>
<v-icon start>mdi-sitemap</v-icon>
关联工单列表
</v-card-title>
<v-card-text>
<v-data-table
:headers="workflowHeaders"
:items="relatedWorkflows"
density="compact"
hover
>
<template v-slot:item.workflow_id="{ item }">
<a @click="navigateToWorkflow(item.workflow_id)">
{{ item.workflow_id }}
</a>
</template>
<template v-slot:item.status="{ item }">
<v-chip :color="getWorkflowStatusColor(item.status)" size="small">
{{ item.status_name }}
</v-chip>
</template>
</v-data-table>
</v-card-text>
</v-card>
</v-dialog>
6.4 从工单页面跳转回项目详情
工单详情页应提供「查看项目」按钮:
// 工单详情页
const navigateToProject = () => {
if (workflowDetail.value?.business_context?.project_id) {
router.push(`/admin/projects/${workflowDetail.value.business_context.project_id}`)
}
}
7. 模块详细设计规范
7.1 基本信息模块 (Basic Info)
| 字段 | 类型 | 只读模式 | 编辑模式 |
|---|---|---|---|
| 项目名称 | String | 文本展示 + 复制 | v-text-field |
| 命名空间 | String | 文本展示 + 复制 | disabled 不可编辑 |
| 省份 | Enum | 文本展示 | 级联选择器 |
| 城市 | Enum | 文本展示 | 级联选择器(依赖省份) |
| 项目性质 | Enum | 文本展示 | v-select |
| 行业组人员 | String | 文本展示 | v-text-field |
| 行业组电话 | String | 文本展示 | v-text-field |
| 项目描述 | String | 多行文本 | v-textarea |
7.2 部署业务模块 (Deployment Business)
| 字段 | 类型 | 只读模式 | 编辑模式 |
|---|---|---|---|
| 部署人姓名 | String | 文本展示 | v-text-field 或用户搜索 |
| 部署人电话 | String | 文本展示 | v-text-field |
| 部署系统 | Enum | 文本展示 | v-select |
| 系统版本 | String | 文本展示 | v-text-field |
| 业务入口 URL | String | 可点击链接 | v-text-field |
| 超管账号 | String | 文本展示 + 复制 | v-text-field |
| 超管密码 | Password | 脱敏 + 查看按钮 | v-text-field 密码输入 |
7.3 部署环境模块 (Deployment Environment)
| 字段 | 类型 | 只读模式 | 编辑模式 |
|---|---|---|---|
| 网络环境 | Enum | 文本展示 | v-select |
| 主公网 IP | String | 文本展示 + 复制 | v-text-field IP 校验 |
| 域名 URL | String | 可点击链接 | v-text-field |
| 启用 SSL | Boolean | 图标显示 | v-switch |
| 主机管理方式 | Enum | 文本展示 | v-select |
| 管理控制台 URL | String | 可点击链接 | v-text-field |
| 主机数量 | Number | 文本展示 | v-text-field type=number |
| CPU 总核数 | Number | 统计卡片 | v-text-field type=number |
| 内存总量 | Number | 统计卡片 | v-text-field type=number |
| 存储总量 | Number | 统计卡片 | v-text-field type=number |
7.4 中间件模块 (Middleware)
采用 卡片网格 (Card Grid) 设计:
7.4.1 数据结构
interface MiddlewareFormItem {
middleware_type: string
public_ip: string
public_port: number
internal_ip: string
internal_port: number
admin_user: string
admin_password?: string
}
7.4.2 只读模式
- 每个中间件一张卡片,响应式网格布局
- 卡片包含:类型图标 + 标题 + IP/Port 信息
- 图标映射逻辑:
const MIDDLEWARE_ICONS: Record<string, string> = {
'mysql': 'mdi-database',
'redis': 'mdi-database-clock',
'emqx': 'mdi-broadcast',
'minio': 'mdi-bucket',
'influxdb': 'mdi-chart-timeline-variant',
'nacos': 'mdi-cog-outline',
'k8s-dashboard': 'mdi-kubernetes'
}
7.4.3 编辑模式
- 现有卡片右上角显示「编辑」「删除」按钮
- 列表末尾显示「添加中间件」虚线框卡片
- 点击添加/编辑弹出对话框:
- 类型选择:
v-combobox支持预设 + 自定义 - 选择预设类型时自动填充默认端口
- 类型选择:
7.5 主机管理模块 (Hosts Management)
- 复用
HostsManagement.vue组件 - 支持表格展示所有主机信息
- 编辑模式支持添加/删除主机
7.6 授权信息模块 (Authorization) - SuperAdmin Only
| 功能 | 说明 |
|---|---|
| TOTP 密钥展示 | 二维码 + 文本形式 |
| 授权类型切换 | 永久/限时 |
| 授权天数设置 | 数字输入 |
| 下发授权 | 调用 Exchange-Hub 接口 |
| 撤销授权 | 调用 Exchange-Hub 接口 |
7.7 版本历史模块 (Version History) - SuperAdmin Only
| 功能 | 说明 |
|---|---|
| 版本列表 | 时间轴形式展示 |
| 版本详情 | 点击查看完整快照 |
| 版本对比 | 选择两个版本进行 Diff |
| 工单关联 | 点击跳转关联工单 |
8. 组件设计规范
8.1 CopyableField 组件
用于展示可复制的字段值:
<template>
<div class="copyable-field d-flex align-center gap-2">
<span class="field-value">{{ displayValue }}</span>
<v-btn
icon="mdi-content-copy"
size="x-small"
variant="text"
@click="copyToClipboard"
>
<v-tooltip activator="parent" location="top">复制</v-tooltip>
</v-btn>
</div>
</template>
8.2 SaveConfirmDialog 组件
保存前的确认对话框,展示变更差异:
<v-dialog v-model="visible" max-width="600">
<v-card>
<v-card-title class="bg-primary text-white">
<v-icon start>mdi-check-circle</v-icon>
确认保存修改
</v-card-title>
<v-card-text>
<v-alert type="info" variant="tonal" class="mb-4">
以下字段将被修改:
</v-alert>
<v-table density="compact">
<thead>
<tr>
<th>字段</th>
<th>修改前</th>
<th>修改后</th>
</tr>
</thead>
<tbody>
<tr v-for="item in diffItems" :key="item.field">
<td>{{ item.label }}</td>
<td class="text-error">{{ item.oldValue || '空' }}</td>
<td class="text-success">{{ item.newValue || '空' }}</td>
</tr>
</tbody>
</v-table>
</v-card-text>
<v-card-actions>
<v-spacer />
<v-btn variant="text" @click="cancel">取消</v-btn>
<v-btn color="primary" :loading="loading" @click="confirm">确认保存</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
8.3 DiffTextField 组件
编辑模式下显示与主线数据差异的输入框:
<template>
<v-text-field
v-model="inputValue"
:label="label"
:class="{ 'diff-highlight': hasDiff }"
:hint="hasDiff ? `主线值: ${masterValue}` : ''"
persistent-hint
>
<template v-slot:prepend-inner v-if="hasDiff">
<v-icon color="warning" size="small">mdi-alert-circle</v-icon>
</template>
</v-text-field>
</template>
<style scoped>
.diff-highlight :deep(.v-field__outline) {
--v-field-border-color: rgb(var(--v-theme-warning));
}
</style>
9. 交互时序图
9.1 管理员编辑保存流程
sequenceDiagram
participant Admin as 超级管理员
participant Page as ProjectDetail.vue
participant Dialog as SaveConfirmDialog
participant API as 后端API
Admin->>Page: 点击[编辑]按钮
Page->>Page: isEditMode = true
Page->>Page: editForm = deepClone(masterData)
Admin->>Page: 修改字段
Page->>Page: hasChanges = true
Admin->>Page: 点击[保存修改]
Page->>Page: 计算 diffItems
Page->>Dialog: 显示确认对话框
Admin->>Dialog: 确认保存
Dialog->>API: updateProject()
API-->>Dialog: 成功
Dialog->>Page: emit('confirm')
Page->>API: loadProject()
Page->>Page: isEditMode = false
Page-->>Admin: Snackbar: 保存成功
9.2 用户草稿提交流程
sequenceDiagram
participant User as 普通用户
participant Page as UserProjectDetail.vue
participant Dialog as SubmitDialog
participant API as 后端API
participant WF as 工单模块
User->>Page: 填写表单
User->>Page: 点击[保存草稿]
Page->>API: saveDraft()
API-->>Page: 草稿保存成功
User->>Page: 点击[提交审核]
Page->>Dialog: 显示确认对话框
User->>Dialog: 填写备注并确认
Dialog->>API: saveDraft() (最终版本)
Dialog->>API: submitProjectDetail()
API->>WF: 触发工单状态转换
WF-->>API: 成功
API-->>Dialog: 提交成功
Page-->>User: 跳转至工单详情页
9.3 管理员审批流程
sequenceDiagram
participant Admin as 超级管理员
participant Page as ProjectDetail.vue
participant Dialog as ApproveDialog/RejectDialog
participant API as 后端API
participant WF as 工单模块
Note over Page: lifecycle_status = reviewing
Admin->>Page: 查看待审核内容
alt 通过审批
Admin->>Page: 点击[通过]
Page->>Dialog: 显示审批对话框
Admin->>Dialog: 填写备注并确认
Dialog->>API: transitionWorkflow(approve)
API->>WF: 工单状态 → approved
WF-->>API: 回调更新项目状态
API-->>Dialog: 成功
Page->>API: updateProjectCertification('official')
Page-->>Admin: Snackbar: 审批通过
else 打回修改
Admin->>Page: 点击[打回]
Page->>Dialog: 显示打回对话框
Admin->>Dialog: 填写打回原因并确认
Dialog->>API: transitionWorkflow(return)
API->>WF: 工单状态 → returned
WF-->>API: 回调更新项目状态
API-->>Dialog: 成功
Page-->>Admin: Snackbar: 已打回
end
10. 视觉设计规范
10.1 色彩系统
| 用途 | 颜色 | Vuetify 类 |
|---|---|---|
| 主色调 | Deep Purple | color="primary" |
| 成功状态 | Green | color="success" |
| 警告状态 | Orange | color="warning" |
| 错误状态 | Red | color="error" |
| 信息状态 | Blue | color="info" |
| 页面背景 | Light Grey | bg-grey-lighten-4 |
| 卡片背景 | White | bg-white |
10.2 卡片设计
<v-card elevation="2" rounded="lg" class="pa-4">
<!-- 卡片内容 -->
</v-card>
- 圆角:
rounded-lg(8px) - 阴影:
elevation-2 - 内边距:
pa-4(16px) - Hover 效果:轻微上浮 + 阴影加深
10.3 排版规范
| 元素 | 字体样式 |
|---|---|
| 页面标题 | text-h4 font-weight-bold |
| 卡片标题 | text-h6 |
| 字段标签 | text-medium-emphasis text-body-2 |
| 字段值 | text-high-emphasis |
| 辅助文字 | text-caption text-grey |
10.4 间距规范
遵循 8px 网格系统:
| 间距 | Vuetify 类 | 值 |
|---|---|---|
| 紧凑 | pa-2 / ma-2 |
8px |
| 标准 | pa-4 / ma-4 |
16px |
| 宽松 | pa-6 / ma-6 |
24px |
| 组件间距 | gap-2 |
8px |
| 卡片间距 | gap-4 |
16px |
10.5 动画与过渡
| 场景 | 效果 |
|---|---|
| Tab 切换 | v-window 默认滑动过渡 |
| 模式切换 | v-expand-transition |
| 按钮 Hover | 0.2s 缓动 |
| 卡片 Hover | transform: translateY(-2px) |
| 加载状态 | v-skeleton-loader 骨架屏 |
11. 响应式设计
11.1 断点配置
遵循 Vuetify 默认断点:
| 断点 | 宽度范围 |
|---|---|
| xs | < 600px |
| sm | 600px - 960px |
| md | 960px - 1280px |
| lg | 1280px - 1920px |
| xl | > 1920px |
11.2 布局适配
<!-- 中间件卡片网格 -->
<v-row>
<v-col
v-for="mw in middlewares"
:key="mw.type"
cols="12"
sm="6"
md="4"
lg="3"
>
<MiddlewareCard :data="mw" />
</v-col>
</v-row>
11.3 移动端适配要点
- Tab 导航:使用
show-arrows支持左右滑动 - 操作按钮:使用
v-bottom-sheet或收起到菜单 - 表单布局:单列堆叠
- 表格:使用
mobile-breakpoint切换卡片视图
12. 数据类型定义
12.1 核心类型
// 项目详情
interface ProjectDetail {
id: number
project_id: string
project_name: string
namespace: string
province: string
city: string
project_nature: string
industry_group_member: string
industry_group_phone: string
description: string
status: string
lifecycle_status: string
project_certification: string
workflow_id: string
detail_filler_id: number
detail_filler_name: string
deployment_business: DeploymentBusiness | null
deployment_environment: DeploymentEnvironment | null
middlewares: Middleware[]
hosts: Host[]
draft_data: Record<string, unknown> | null
created_at: string
updated_at: string
}
// 表单数据类型
interface BasicFormData {
project_name: string
province: string
city: string
industry_group_member: string
industry_group_phone: string
project_nature: string
description: string
}
interface BusinessFormData {
deployer_name: string
deployer_phone: string
deploy_system: string
system_version: string
business_entry_url: string
super_admin_user: string
super_admin_password: string
}
interface EnvironmentFormData {
network_environment: string
main_public_ip: string
domain_url: string
enable_ssl: boolean
host_management_method: string
management_console_url: string
host_count: number
total_cpu: number
total_memory_gb: number
total_storage_gb: number
}
interface MiddlewareFormItem {
middleware_type: string
public_ip: string
public_port: number
internal_ip: string
internal_port: number
admin_user: string
admin_password?: string
}
// Diff 项
interface DiffItem {
field: string
label: string
oldValue: string | number | boolean
newValue: string | number | boolean
}
13. API 调用规范
13.1 项目管理 API
| 方法 | 路径 | 说明 |
|---|---|---|
| POST | /api/project/detail |
获取项目详情 |
| POST | /api/project/update |
更新项目信息 (Admin) |
| POST | /api/project/draft/save |
保存草稿 |
| POST | /api/project/draft/submit |
提交审核 |
| POST | /api/project/draft/discard |
放弃草稿 |
| POST | /api/project/export |
导出配置 |
13.2 调用示例
// 获取项目详情
const loadProject = async () => {
const res = await getProjectDetail(projectId.value)
if (res.code === 0) {
masterData.value = res.data
}
}
// 管理员保存修改
const confirmSave = async () => {
await updateProject(projectId.value, {
project_name: editForm.basic.project_name,
province: editForm.basic.province,
// ...
})
}
// 用户保存草稿
const handleSaveDraft = async () => {
const draftData = {
formData: { ...businessFormData.value, ...environmentFormData.value },
middlewareList: getMiddlewareList()
}
await saveDraft(projectId.value, draftData)
}
14. 附录
14.1 相关文档
| 文档 | 说明 |
|---|---|
| 项目管理 PRD | 产品需求文档 |
| 项目管理后端 DDS | 后端详细设计 |
| Vue3 TypeScript 规范 | 前端开发规范 |
| API 开发规范 | 接口设计规范 |
14.2 组件清单
| 组件 | 文件路径 | 说明 |
|---|---|---|
| BasicInfoForm | components/BasicInfoForm.vue |
基本信息编辑表单 |
| BasicInfoReadonly | components/BasicInfoReadonly.vue |
基本信息只读 |
| BusinessInfoReadonly | components/BusinessInfoReadonly.vue |
业务信息只读 |
| DeploymentBusinessForm | components/DeploymentBusinessForm.vue |
业务信息表单 |
| DeploymentEnvironmentForm | components/DeploymentEnvironmentForm.vue |
环境信息表单 |
| EnvironmentInfoReadonly | components/EnvironmentInfoReadonly.vue |
环境信息只读 |
| HostsInfoReadonly | components/HostsInfoReadonly.vue |
主机信息只读 |
| HostsManagement | components/HostsManagement.vue |
主机管理 |
| MiddlewareCardsGrid | components/MiddlewareCardsGrid.vue |
中间件卡片网格 |
| MiddlewareInfoReadonly | components/MiddlewareInfoReadonly.vue |
中间件只读 |
| AuthorizationManagement | components/AuthorizationManagement.vue |
授权管理 |
| VersionHistory | components/VersionHistory.vue |
版本历史 |
| SaveConfirmDialog | components/SaveConfirmDialog.vue |
保存确认对话框 |
| CopyableField | components/CopyableField.vue |
可复制字段 |
| ProjectBasicInfoCard | components/ProjectBasicInfoCard.vue |
项目基本信息卡片 |