From 8df992dda57335e60500854be6ec89fb0aa87c4b Mon Sep 17 00:00:00 2001
From: yumaojun03 <719118794@qq.com>
Date: Sun, 17 Aug 2025 09:49:26 +0800
Subject: [PATCH] =?UTF-8?q?=E5=BA=94=E8=AF=A5=E7=AE=A1=E7=90=86?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
devcloud/web/src/layout/DashboardLayout.vue | 12 +-
devcloud/web/src/layout/MenuLayout.vue | 101 ++++++---
.../web/src/layout/components/HeaderNav.vue | 18 +-
devcloud/web/src/pages/artifact/AssetPage.vue | 76 +++++++
.../web/src/pages/artifact/RegistryPage.vue | 116 +++++++++++
.../web/src/pages/dashboard/DashboardPage.vue | 4 +-
.../pages/{project => develop}/AppPage.vue | 0
.../{SprintPage.vue => PipelineTemplate.vue} | 0
.../src/pages/develop/VersionIteration.vue | 13 ++
.../web/src/pages/project/ProjectList.vue | 193 ++++++++++++++++++
.../pages/project/components/ProjectCard.vue | 131 ++++++++++++
.../project/components/ProjectFormModal.vue | 100 +++++++++
devcloud/web/src/pages/project/mockData.js | 193 ++++++++++++++++++
devcloud/web/src/router/index.js | 72 ++++++-
devcloud/web/src/storage/app.js | 28 +++
15 files changed, 998 insertions(+), 59 deletions(-)
create mode 100644 devcloud/web/src/pages/artifact/AssetPage.vue
create mode 100644 devcloud/web/src/pages/artifact/RegistryPage.vue
rename devcloud/web/src/pages/{project => develop}/AppPage.vue (100%)
rename devcloud/web/src/pages/develop/{SprintPage.vue => PipelineTemplate.vue} (100%)
create mode 100644 devcloud/web/src/pages/develop/VersionIteration.vue
create mode 100644 devcloud/web/src/pages/project/ProjectList.vue
create mode 100644 devcloud/web/src/pages/project/components/ProjectCard.vue
create mode 100644 devcloud/web/src/pages/project/components/ProjectFormModal.vue
create mode 100644 devcloud/web/src/pages/project/mockData.js
diff --git a/devcloud/web/src/layout/DashboardLayout.vue b/devcloud/web/src/layout/DashboardLayout.vue
index 61835e7..cd76db4 100644
--- a/devcloud/web/src/layout/DashboardLayout.vue
+++ b/devcloud/web/src/layout/DashboardLayout.vue
@@ -6,7 +6,7 @@
@@ -31,20 +31,18 @@
diff --git a/devcloud/web/src/pages/project/ProjectList.vue b/devcloud/web/src/pages/project/ProjectList.vue
new file mode 100644
index 0000000..214ec63
--- /dev/null
+++ b/devcloud/web/src/pages/project/ProjectList.vue
@@ -0,0 +1,193 @@
+
+
+
+
+
+
+
+ 新建项目空间
+
+
+
+
+
+
+
+ 活跃
+ 已归档
+ 规划中
+
+
+
+
+ 重置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/devcloud/web/src/pages/project/components/ProjectCard.vue b/devcloud/web/src/pages/project/components/ProjectCard.vue
new file mode 100644
index 0000000..2f489de
--- /dev/null
+++ b/devcloud/web/src/pages/project/components/ProjectCard.vue
@@ -0,0 +1,131 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 归档
+
+
+
+
+
+
+
+
+
diff --git a/devcloud/web/src/pages/project/components/ProjectFormModal.vue b/devcloud/web/src/pages/project/components/ProjectFormModal.vue
new file mode 100644
index 0000000..a66b41e
--- /dev/null
+++ b/devcloud/web/src/pages/project/components/ProjectFormModal.vue
@@ -0,0 +1,100 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 活跃
+ 已归档
+ 规划中
+
+
+
+
+
+
+
+
+
diff --git a/devcloud/web/src/pages/project/mockData.js b/devcloud/web/src/pages/project/mockData.js
new file mode 100644
index 0000000..190b9c3
--- /dev/null
+++ b/devcloud/web/src/pages/project/mockData.js
@@ -0,0 +1,193 @@
+// mockData.js
+
+/**
+ * 生成随机日期(最近365天内)
+ */
+const generateRandomDate = () => {
+ const now = new Date()
+ const past = new Date(now)
+ past.setDate(now.getDate() - 365)
+ return new Date(past.getTime() + Math.random() * (now.getTime() - past.getTime()))
+}
+
+/**
+ * 生成随机项目描述
+ */
+const generateDescription = (index) => {
+ const descriptors = [
+ '企业级应用开发项目',
+ '微服务架构重构项目',
+ '前端技术升级专项',
+ 'DevOps平台建设项目',
+ 'AI能力集成项目',
+ '大数据分析平台',
+ '移动端应用重设计',
+ '云原生迁移项目',
+ ]
+ const types = ['核心业务系统', '技术中台', '数据平台', '用户增长项目', '基础设施升级']
+ return `${types[index % types.length]} - ${descriptors[index % descriptors.length]}`
+}
+
+/**
+ * 模拟用户数据
+ */
+export const mockUsers = [
+ { id: 'user-1', name: '张管理员', role: 'admin' },
+ { id: 'user-2', name: '李开发', role: 'dev' },
+ { id: 'user-3', name: '王测试', role: 'qa' },
+ { id: 'user-4', name: '赵产品', role: 'product' },
+ { id: 'user-5', name: '刘架构', role: 'arch' },
+]
+
+/**
+ * 模拟项目数据
+ */
+export const mockProjects = Array.from({ length: 36 }, (_, i) => {
+ const statuses = ['active', 'archived', 'planning']
+ const status = statuses[i % 3]
+
+ return {
+ id: `project-${i + 1}`,
+ name: `研发项目 ${String(i + 1).padStart(2, '0')}`,
+ description: generateDescription(i),
+ status,
+ owner: mockUsers[i % mockUsers.length].id,
+ members: mockUsers.slice(0, (i % 4) + 1),
+ createTime: generateRandomDate().getTime(),
+ updateTime: generateRandomDate().getTime(),
+ stats: {
+ tasks: Math.floor(Math.random() * 50) + 10,
+ completed: Math.floor(Math.random() * 45),
+ progress: Math.floor(Math.random() * 100),
+ },
+ }
+})
+
+/**
+ * 项目状态映射
+ */
+export const projectStatusMap = {
+ active: { text: '活跃', color: '#00B42A' },
+ archived: { text: '已归档', color: '#86909C' },
+ planning: { text: '规划中', color: '#FF7D00' },
+}
+
+/**
+ * 获取项目状态信息
+ */
+export const getProjectStatusInfo = (status) => {
+ return projectStatusMap[status] || { text: '未知', color: '#86909C' }
+}
+
+/**
+ * 模拟API响应格式
+ */
+export const mockApiResponse = (data, options = {}) => {
+ return {
+ code: 200,
+ data,
+ message: 'success',
+ ...options,
+ }
+}
+
+/**
+ * 模拟获取项目列表API
+ */
+export const fetchProjects = (params = {}) => {
+ const { page = 1, pageSize = 10, search = '', status } = params
+
+ let filtered = [...mockProjects]
+
+ // 模拟筛选
+ if (search) {
+ const keyword = search.toLowerCase()
+ filtered = filtered.filter(
+ (p) =>
+ p.name.toLowerCase().includes(keyword) || p.description.toLowerCase().includes(keyword),
+ )
+ }
+
+ if (status) {
+ filtered = filtered.filter((p) => p.status === status)
+ }
+
+ // 模拟分页
+ const start = (page - 1) * pageSize
+ const end = start + pageSize
+ const pageData = filtered.slice(start, end)
+
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ resolve(
+ mockApiResponse({
+ list: pageData,
+ total: filtered.length,
+ page,
+ pageSize,
+ }),
+ )
+ }, 500) // 模拟网络延迟
+ })
+}
+
+/**
+ * 模拟获取项目详情API
+ */
+export const fetchProjectDetail = (id) => {
+ const project = mockProjects.find((p) => p.id === id)
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ if (project) {
+ resolve(mockApiResponse(project))
+ } else {
+ resolve(mockApiResponse(null, { code: 404, message: '项目不存在' }))
+ }
+ }, 300)
+ })
+}
+
+/**
+ * 模拟创建项目API
+ */
+export const createProject = (data) => {
+ const newProject = {
+ id: `project-${mockProjects.length + 1}`,
+ ...data,
+ createTime: Date.now(),
+ updateTime: Date.now(),
+ members: [mockUsers[0]],
+ stats: {
+ tasks: 0,
+ completed: 0,
+ progress: 0,
+ },
+ }
+
+ mockProjects.unshift(newProject)
+
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ resolve(mockApiResponse(newProject))
+ }, 400)
+ })
+}
+
+/**
+ * 模拟更新项目API
+ */
+export const updateProject = (id, data) => {
+ const index = mockProjects.findIndex((p) => p.id === id)
+
+ return new Promise((resolve) => {
+ setTimeout(() => {
+ if (index >= 0) {
+ const updated = { ...mockProjects[index], ...data, updateTime: Date.now() }
+ mockProjects.splice(index, 1, updated)
+ resolve(mockApiResponse(updated))
+ } else {
+ resolve(mockApiResponse(null, { code: 404, message: '项目不存在' }))
+ }
+ }, 400)
+ })
+}
diff --git a/devcloud/web/src/router/index.js b/devcloud/web/src/router/index.js
index fb4beb6..ac0b48c 100644
--- a/devcloud/web/src/router/index.js
+++ b/devcloud/web/src/router/index.js
@@ -39,29 +39,87 @@ const router = createRouter({
},
],
},
+ // 项目管理
{
path: '/project',
name: 'ProjectSystem',
- redirect: { name: 'AppPage' },
+ redirect: { name: 'ProjectList' },
component: MenuLayout,
+ meta: {
+ title: '项目管理',
+ },
children: [
{
- path: 'app',
- name: 'AppPage',
- component: () => import('@/pages/project/AppPage.vue'),
+ path: 'list',
+ name: 'ProjectList',
+ component: () => import('@/pages/project/ProjectList.vue'),
+ meta: {
+ title: '项目空间',
+ },
},
],
},
+ // 研发交付
{
path: '/develop',
name: 'DevelopSystem',
redirect: { name: 'SprintPage' },
component: MenuLayout,
+ meta: {
+ title: '研发交付',
+ },
children: [
{
- path: 'sprint',
- name: 'SprintPage',
- component: () => import('@/pages/develop/SprintPage.vue'),
+ path: 'app',
+ name: 'AppPage',
+ component: () => import('@/pages/develop/AppPage.vue'),
+ meta: {
+ title: '应用管理',
+ },
+ },
+ {
+ path: 'version_iteration',
+ name: 'VersionIteration',
+ component: () => import('@/pages/develop/VersionIteration.vue'),
+ meta: {
+ title: '版本迭代',
+ },
+ },
+ {
+ path: 'pipeline_template',
+ name: 'PipelineTemplate',
+ component: () => import('@/pages/develop/PipelineTemplate.vue'),
+ meta: {
+ title: '流水线模板',
+ },
+ },
+ ],
+ },
+ // 制品库
+ {
+ path: '/artifact',
+ name: 'ArtifactSystem',
+ redirect: { name: 'SprintPage' },
+ component: MenuLayout,
+ meta: {
+ title: '制品库',
+ },
+ children: [
+ {
+ path: 'registry',
+ name: 'RegistryPage',
+ component: () => import('@/pages/artifact/RegistryPage.vue'),
+ meta: {
+ title: '制品仓库',
+ },
+ },
+ {
+ path: 'asset',
+ name: 'AssetPage',
+ component: () => import('@/pages/artifact/AssetPage.vue'),
+ meta: {
+ title: '制品管理',
+ },
},
],
},
diff --git a/devcloud/web/src/storage/app.js b/devcloud/web/src/storage/app.js
index e69de29..98714cf 100644
--- a/devcloud/web/src/storage/app.js
+++ b/devcloud/web/src/storage/app.js
@@ -0,0 +1,28 @@
+import { useStorage } from '@vueuse/core'
+
+export default useStorage(
+ 'app',
+ {
+ current_system: 'DashBoard',
+ current_menu: {
+ DashBoard: {
+ sub_menu: '',
+ menu_item: '1',
+ },
+ ProjectSystem: {
+ sub_menu: '',
+ menu_item: '1',
+ },
+ DevelopSystem: {
+ sub_menu: '',
+ menu_item: '1',
+ },
+ ArtifactSystem: {
+ sub_menu: '',
+ menu_item: 'RegistryPage',
+ },
+ },
+ },
+ localStorage,
+ { mergeDefaults: true },
+)