diff --git a/devcloud/web/package-lock.json b/devcloud/web/package-lock.json
index e05b0c0..788c10c 100644
--- a/devcloud/web/package-lock.json
+++ b/devcloud/web/package-lock.json
@@ -11,6 +11,7 @@
"@vueuse/core": "^13.6.0",
"axios": "^1.11.0",
"vue": "^3.5.18",
+ "vue-echarts": "^7.0.3",
"vue-router": "^4.5.1"
},
"devDependencies": {
@@ -2388,6 +2389,24 @@
"node": ">= 0.4"
}
},
+ "node_modules/echarts": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmmirror.com/echarts/-/echarts-5.6.0.tgz",
+ "integrity": "sha512-oTbVTsXfKuEhxftHqL5xprgLoc0k7uScAwtryCgWF6hPYFLRwOUHiFmHGCBKP5NPFNkDVopOieyUqYGH8Fa3kA==",
+ "license": "Apache-2.0",
+ "peer": true,
+ "dependencies": {
+ "tslib": "2.3.0",
+ "zrender": "5.6.1"
+ }
+ },
+ "node_modules/echarts/node_modules/tslib": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
+ "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==",
+ "license": "0BSD",
+ "peer": true
+ },
"node_modules/electron-to-chromium": {
"version": "1.5.194",
"resolved": "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.5.194.tgz",
@@ -4647,6 +4666,51 @@
}
}
},
+ "node_modules/vue-demi": {
+ "version": "0.13.11",
+ "resolved": "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.13.11.tgz",
+ "integrity": "sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==",
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "vue-demi-fix": "bin/vue-demi-fix.js",
+ "vue-demi-switch": "bin/vue-demi-switch.js"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "@vue/composition-api": "^1.0.0-rc.1",
+ "vue": "^3.0.0-0 || ^2.6.0"
+ },
+ "peerDependenciesMeta": {
+ "@vue/composition-api": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vue-echarts": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmmirror.com/vue-echarts/-/vue-echarts-7.0.3.tgz",
+ "integrity": "sha512-/jSxNwOsw5+dYAUcwSfkLwKPuzTQ0Cepz1LxCOpj2QcHrrmUa/Ql0eQqMmc1rTPQVrh2JQ29n2dhq75ZcHvRDw==",
+ "license": "MIT",
+ "dependencies": {
+ "vue-demi": "^0.13.11"
+ },
+ "peerDependencies": {
+ "@vue/runtime-core": "^3.0.0",
+ "echarts": "^5.5.1",
+ "vue": "^2.7.0 || ^3.1.1"
+ },
+ "peerDependenciesMeta": {
+ "@vue/runtime-core": {
+ "optional": true
+ }
+ }
+ },
"node_modules/vue-eslint-parser": {
"version": "10.2.0",
"resolved": "https://registry.npmmirror.com/vue-eslint-parser/-/vue-eslint-parser-10.2.0.tgz",
@@ -4771,6 +4835,23 @@
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
+ },
+ "node_modules/zrender": {
+ "version": "5.6.1",
+ "resolved": "https://registry.npmmirror.com/zrender/-/zrender-5.6.1.tgz",
+ "integrity": "sha512-OFXkDJKcrlx5su2XbzJvj/34Q3m6PvyCZkVPHGYpcCJ52ek4U/ymZyfuV1nKE23AyBJ51E/6Yr0mhZ7xGTO4ag==",
+ "license": "BSD-3-Clause",
+ "peer": true,
+ "dependencies": {
+ "tslib": "2.3.0"
+ }
+ },
+ "node_modules/zrender/node_modules/tslib": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmmirror.com/tslib/-/tslib-2.3.0.tgz",
+ "integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==",
+ "license": "0BSD",
+ "peer": true
}
}
}
diff --git a/devcloud/web/package.json b/devcloud/web/package.json
index 9ef7bea..b4edd0f 100644
--- a/devcloud/web/package.json
+++ b/devcloud/web/package.json
@@ -17,6 +17,7 @@
"@vueuse/core": "^13.6.0",
"axios": "^1.11.0",
"vue": "^3.5.18",
+ "vue-echarts": "^7.0.3",
"vue-router": "^4.5.1"
},
"devDependencies": {
diff --git a/devcloud/web/src/layout/DashboardLayout.vue b/devcloud/web/src/layout/DashboardLayout.vue
new file mode 100644
index 0000000..61835e7
--- /dev/null
+++ b/devcloud/web/src/layout/DashboardLayout.vue
@@ -0,0 +1,154 @@
+
+
+
+
+
+
+
diff --git a/devcloud/web/src/layout/FrontendLayout.vue b/devcloud/web/src/layout/FrontendLayout.vue
new file mode 100644
index 0000000..03b1f9d
--- /dev/null
+++ b/devcloud/web/src/layout/FrontendLayout.vue
@@ -0,0 +1,192 @@
+
+
+
+
+
+
+
diff --git a/devcloud/web/src/layout/BackendLayout.vue b/devcloud/web/src/layout/MenuLayout.vue
similarity index 75%
rename from devcloud/web/src/layout/BackendLayout.vue
rename to devcloud/web/src/layout/MenuLayout.vue
index 5dc0d95..8481b9a 100644
--- a/devcloud/web/src/layout/BackendLayout.vue
+++ b/devcloud/web/src/layout/MenuLayout.vue
@@ -5,63 +5,21 @@
-
-
+
+
-
+
@@ -106,13 +64,86 @@
diff --git a/devcloud/web/src/pages/HomePage.vue b/devcloud/web/src/pages/HomePage.vue
deleted file mode 100644
index e9a5302..0000000
--- a/devcloud/web/src/pages/HomePage.vue
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
- Primary
- Secondary
- Dashed
- Outline
- Text
-
-
-
-
-
-
-
diff --git a/devcloud/web/src/pages/LoginPage.vue b/devcloud/web/src/pages/LoginPage.vue
index 52317d4..c9a8e79 100644
--- a/devcloud/web/src/pages/LoginPage.vue
+++ b/devcloud/web/src/pages/LoginPage.vue
@@ -93,7 +93,7 @@ const handleSubmit = async (data) => {
if (data.errors == null) {
const resp = await mcenter.Login(data.values);
token.value = resp;
- router.push({ name: 'HomePage' });
+ router.push({ name: 'DashBoard' });
}
};
diff --git a/devcloud/web/src/pages/dashboard/DashboardPage.vue b/devcloud/web/src/pages/dashboard/DashboardPage.vue
new file mode 100644
index 0000000..8528a6b
--- /dev/null
+++ b/devcloud/web/src/pages/dashboard/DashboardPage.vue
@@ -0,0 +1,337 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ metric.title }}
+
{{ metric.value }}
+
+ {{ metric.trend.value }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 最近一周
+ 最近一月
+ 最近三月
+
+
+
+
+
+
+
+
+
+
+ 查看全部
+
+
+
+
+
+
+
+
+ {{ pipeline.name }}
+
+
+
+ #{{ pipeline.id }}
+ {{ pipeline.duration }}
+
+
+
+ {{ pipeline.stage }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{{ activity.user }}
+
{{ activity.action }}
+
{{ activity.target }}
+
+ {{ activity.time }}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/devcloud/web/src/pages/dashboard/components/BuildStatusChar.vue b/devcloud/web/src/pages/dashboard/components/BuildStatusChar.vue
new file mode 100644
index 0000000..e3f901c
--- /dev/null
+++ b/devcloud/web/src/pages/dashboard/components/BuildStatusChar.vue
@@ -0,0 +1,9 @@
+
+ 构建状态图表
+
+
+
+
+
diff --git a/devcloud/web/src/pages/dashboard/components/DeployChart.vue b/devcloud/web/src/pages/dashboard/components/DeployChart.vue
new file mode 100644
index 0000000..3b1bcab
--- /dev/null
+++ b/devcloud/web/src/pages/dashboard/components/DeployChart.vue
@@ -0,0 +1,9 @@
+
+ 部署统计图表
+
+
+
+
+
diff --git a/devcloud/web/src/pages/develop/SprintPage.vue b/devcloud/web/src/pages/develop/SprintPage.vue
new file mode 100644
index 0000000..4acf9d9
--- /dev/null
+++ b/devcloud/web/src/pages/develop/SprintPage.vue
@@ -0,0 +1,13 @@
+
+
+ Succeeded
+ Processing
+ Pending
+
+
+
+
+
+
diff --git a/devcloud/web/src/pages/frontend/ProductPage.vue b/devcloud/web/src/pages/frontend/ProductPage.vue
new file mode 100644
index 0000000..89549be
--- /dev/null
+++ b/devcloud/web/src/pages/frontend/ProductPage.vue
@@ -0,0 +1,248 @@
+
+
+
+
+
+ 平台核心价值
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 功能特性
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ item.title }}
+
+
+ {{ item.description }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 免费试用
+ 预约演示
+
+
+
+
+
+
+
+
+
+
diff --git a/devcloud/web/src/pages/mpaas/ApplicatonPage.vue b/devcloud/web/src/pages/mpaas/ApplicatonPage.vue
deleted file mode 100644
index e86c941..0000000
--- a/devcloud/web/src/pages/mpaas/ApplicatonPage.vue
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/devcloud/web/src/pages/cmdb/SecretPage.vue b/devcloud/web/src/pages/project/AppPage.vue
similarity index 100%
rename from devcloud/web/src/pages/cmdb/SecretPage.vue
rename to devcloud/web/src/pages/project/AppPage.vue
diff --git a/devcloud/web/src/router/index.js b/devcloud/web/src/router/index.js
index 1cc5899..fb4beb6 100644
--- a/devcloud/web/src/router/index.js
+++ b/devcloud/web/src/router/index.js
@@ -1,35 +1,74 @@
import { createRouter, createWebHistory } from 'vue-router'
-import BackendLayout from '@/layout/BackendLayout.vue'
+import MenuLayout from '@/layout/MenuLayout.vue'
+import DashboardLayout from '@/layout/DashboardLayout.vue'
+import FrontendLayout from '@/layout/FrontendLayout.vue'
+import { beforeEach } from './interceptor'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/',
- name: 'HomePage',
- component: BackendLayout,
+ name: 'Frontend',
+ redirect: { name: 'ProductPage' },
+ component: () => FrontendLayout,
+ children: [
+ {
+ path: 'product',
+ name: 'ProductPage',
+ component: () => import('@/pages/frontend/ProductPage.vue'),
+ },
+ ],
},
{
path: '/login',
name: 'LoginPage',
- // route level code-splitting
- // this generates a separate chunk (About.[hash].js) for this route
- // which is lazy-loaded when the route is visited.
- component: () => import('../pages/LoginPage.vue'),
+ component: () => import('@/pages/LoginPage.vue'),
},
{
- path: '/cmdb',
- component: () => import('@/layout/BackendLayout.vue'),
+ path: '/person',
+ name: 'DashBoard',
+ redirect: { name: 'DashboardPage' },
+ component: DashboardLayout,
children: [
{
- path: 'secret',
- name: 'SecretPage',
- component: () => import('@/pages/cmdb/SecretPage.vue'),
+ path: 'dashboard',
+ name: 'DashboardPage',
+ component: () => import('@/pages/dashboard/DashboardPage.vue'),
+ },
+ ],
+ },
+ {
+ path: '/project',
+ name: 'ProjectSystem',
+ redirect: { name: 'AppPage' },
+ component: MenuLayout,
+ children: [
+ {
+ path: 'app',
+ name: 'AppPage',
+ component: () => import('@/pages/project/AppPage.vue'),
+ },
+ ],
+ },
+ {
+ path: '/develop',
+ name: 'DevelopSystem',
+ redirect: { name: 'SprintPage' },
+ component: MenuLayout,
+ children: [
+ {
+ path: 'sprint',
+ name: 'SprintPage',
+ component: () => import('@/pages/develop/SprintPage.vue'),
},
],
},
],
})
+// 导航守卫
+router.beforeEach(beforeEach)
+
export default router
diff --git a/devcloud/web/src/router/interceptor.js b/devcloud/web/src/router/interceptor.js
new file mode 100644
index 0000000..1d3a468
--- /dev/null
+++ b/devcloud/web/src/router/interceptor.js
@@ -0,0 +1,20 @@
+import token from '@/storage/token'
+
+var witheList = ['ProductPage', 'LoginPage']
+
+export var beforeEach = async (to) => {
+ // 白名单
+ for (var name of witheList) {
+ if (name === to.name) {
+ return true
+ }
+ }
+
+ // 检查用户是否已登录
+ if (token.value.access_token) {
+ return true
+ }
+
+ // 将用户重定向到登录页面
+ return { name: 'LoginPage' }
+}