gridsum-vue3-pc 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/LICENSE +21 -0
  3. package/README.md +88 -0
  4. package/bin/create-vue3-pc.mjs +545 -0
  5. package/package.json +68 -0
  6. package/template/base/.dockerignore +12 -0
  7. package/template/base/.env +5 -0
  8. package/template/base/.env.production +5 -0
  9. package/template/base/.eslintrc.cjs +22 -0
  10. package/template/base/.husky/commit-msg +1 -0
  11. package/template/base/.husky/pre-commit +1 -0
  12. package/template/base/.lintstagedrc +7 -0
  13. package/template/base/.prettierrc +5 -0
  14. package/template/base/.stylelintrc.cjs +6 -0
  15. package/template/base/.vscode/settings.json +26 -0
  16. package/template/base/CHANGELOG.md +6 -0
  17. package/template/base/Dockerfile +19 -0
  18. package/template/base/README.md +87 -0
  19. package/template/base/commitlint.config.cjs +1 -0
  20. package/template/base/index.html +15 -0
  21. package/template/base/mock/user.js +393 -0
  22. package/template/base/nginx.conf +27 -0
  23. package/template/base/package.json +47 -0
  24. package/template/base/public/favicon.svg +9 -0
  25. package/template/base/public/logo.svg +9 -0
  26. package/template/base/src/App.vue +20 -0
  27. package/template/base/src/assets/index.css +83 -0
  28. package/template/base/src/assets/logo.png +0 -0
  29. package/template/base/src/components/LanguageSwitch.vue +65 -0
  30. package/template/base/src/components/basic-layout.vue +484 -0
  31. package/template/base/src/composables/useCrud.ts +172 -0
  32. package/template/base/src/env.d.ts +28 -0
  33. package/template/base/src/env.ts +24 -0
  34. package/template/base/src/locales/en.json +153 -0
  35. package/template/base/src/locales/index.ts +32 -0
  36. package/template/base/src/locales/zh.json +153 -0
  37. package/template/base/src/main.ts +27 -0
  38. package/template/base/src/router/index.ts +91 -0
  39. package/template/base/src/services/http.ts +64 -0
  40. package/template/base/src/services/user.ts +23 -0
  41. package/template/base/src/store/modules/user.ts +45 -0
  42. package/template/base/src/views/Admin.vue +326 -0
  43. package/template/base/src/views/Home.vue +382 -0
  44. package/template/base/src/views/Login.vue +1252 -0
  45. package/template/base/src/views/Role.vue +269 -0
  46. package/template/base/src/views/User.vue +332 -0
  47. package/template/base/src/views/error/Forbidden.vue +62 -0
  48. package/template/base/src/views/error/NotFound.vue +60 -0
  49. package/template/base/src/views/error/ServerError.vue +62 -0
  50. package/template/base/tests/e2e/example.spec.ts +7 -0
  51. package/template/base/tests/unit/user.test.ts +15 -0
  52. package/template/base/vite.config.ts +52 -0
  53. package/template/cicd-github/.github/workflows/ci.yml +123 -0
  54. package/template/cicd-gitlab/.gitlab-ci.yml +103 -0
  55. package/template/cicd-jenkins/Jenkinsfile +107 -0
  56. package/template/ts/shims-vue.d.ts +5 -0
  57. package/template/ts/tsconfig.json +23 -0
@@ -0,0 +1,60 @@
1
+ <template>
2
+ <div class="error-page">
3
+ <div class="error-content">
4
+ <div class="error-icon">
5
+ <svg viewBox="0 0 80 80" width="80" height="80">
6
+ <circle cx="40" cy="40" r="36" fill="none" stroke="#409eff" stroke-width="3" opacity="0.2" />
7
+ <circle cx="40" cy="40" r="36" fill="none" stroke="#409eff" stroke-width="3"
8
+ stroke-dasharray="226" stroke-dashoffset="56" transform="rotate(-90 40 40)" />
9
+ <text x="40" y="46" text-anchor="middle" font-size="20" font-weight="700" fill="#409eff">404</text>
10
+ </svg>
11
+ </div>
12
+ <h1 class="error-title">{{ $t('error.notFoundTitle') }}</h1>
13
+ <p class="error-desc">{{ $t('error.notFoundDesc') }}</p>
14
+ <el-button type="primary" round @click="$router.push('/')">
15
+ {{ $t('error.backHome') }}
16
+ </el-button>
17
+ </div>
18
+ </div>
19
+ </template>
20
+
21
+ <style scoped>
22
+ .error-page {
23
+ display: flex;
24
+ align-items: center;
25
+ justify-content: center;
26
+ min-height: 100%;
27
+ padding: 40px;
28
+ }
29
+
30
+ .error-content {
31
+ text-align: center;
32
+ max-width: 420px;
33
+ }
34
+
35
+ .error-icon {
36
+ margin-bottom: 24px;
37
+ }
38
+
39
+ .error-title {
40
+ font-size: 24px;
41
+ font-weight: 600;
42
+ color: #1a1a2e;
43
+ margin: 0 0 12px;
44
+ }
45
+
46
+ .error-desc {
47
+ font-size: 14px;
48
+ color: #909399;
49
+ margin: 0 0 32px;
50
+ line-height: 1.6;
51
+ }
52
+
53
+ html.dark .error-title {
54
+ color: #c9d1d9;
55
+ }
56
+
57
+ html.dark .error-desc {
58
+ color: #8b949e;
59
+ }
60
+ </style>
@@ -0,0 +1,62 @@
1
+ <template>
2
+ <div class="error-page">
3
+ <div class="error-content">
4
+ <div class="error-icon">
5
+ <svg viewBox="0 0 80 80" width="80" height="80">
6
+ <circle cx="40" cy="40" r="36" fill="none" stroke="#f56c6c" stroke-width="3" opacity="0.2" />
7
+ <circle cx="40" cy="40" r="36" fill="none" stroke="#f56c6c" stroke-width="3"
8
+ stroke-dasharray="226" stroke-dashoffset="56" transform="rotate(-90 40 40)" />
9
+ <line x1="30" y1="30" x2="50" y2="50" stroke="#f56c6c" stroke-width="3" stroke-linecap="round" />
10
+ <line x1="50" y1="30" x2="30" y2="50" stroke="#f56c6c" stroke-width="3" stroke-linecap="round" />
11
+ <text x="40" y="70" text-anchor="middle" font-size="18" font-weight="700" fill="#f56c6c">500</text>
12
+ </svg>
13
+ </div>
14
+ <h1 class="error-title">{{ $t('error.serverErrorTitle') }}</h1>
15
+ <p class="error-desc">{{ $t('error.serverErrorDesc') }}</p>
16
+ <el-button type="primary" round @click="$router.push('/')">
17
+ {{ $t('error.backHome') }}
18
+ </el-button>
19
+ </div>
20
+ </div>
21
+ </template>
22
+
23
+ <style scoped>
24
+ .error-page {
25
+ display: flex;
26
+ align-items: center;
27
+ justify-content: center;
28
+ min-height: 100%;
29
+ padding: 40px;
30
+ }
31
+
32
+ .error-content {
33
+ text-align: center;
34
+ max-width: 420px;
35
+ }
36
+
37
+ .error-icon {
38
+ margin-bottom: 24px;
39
+ }
40
+
41
+ .error-title {
42
+ font-size: 24px;
43
+ font-weight: 600;
44
+ color: #1a1a2e;
45
+ margin: 0 0 12px;
46
+ }
47
+
48
+ .error-desc {
49
+ font-size: 14px;
50
+ color: #909399;
51
+ margin: 0 0 32px;
52
+ line-height: 1.6;
53
+ }
54
+
55
+ html.dark .error-title {
56
+ color: #c9d1d9;
57
+ }
58
+
59
+ html.dark .error-desc {
60
+ color: #8b949e;
61
+ }
62
+ </style>
@@ -0,0 +1,7 @@
1
+ import { test, expect } from '@playwright/test';
2
+
3
+ test('首页加载', async ({ page }) => {
4
+ await page.goto('http://localhost:3000/');
5
+ await page.waitForSelector('.dashboard');
6
+ await expect(page.locator('.dashboard')).toBeVisible();
7
+ });
@@ -0,0 +1,15 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { login } from '@/services/user';
3
+
4
+ describe('用户服务', () => {
5
+ it('应能调用登录接口', async () => {
6
+ try {
7
+ const res = await login('admin', 'admin');
8
+ expect(res).toHaveProperty('code');
9
+ expect(res.code).toBe(0);
10
+ } catch {
11
+ // 测试环境无后端,捕获预期异常
12
+ expect(true).toBe(true);
13
+ }
14
+ });
15
+ });
@@ -0,0 +1,52 @@
1
+ import { defineConfig, loadEnv } from 'vite';
2
+ import vue from '@vitejs/plugin-vue';
3
+ import { fileURLToPath, URL } from 'node:url';
4
+ import { viteMockServe } from 'vite-plugin-mock';
5
+
6
+ export default defineConfig(({ mode }) => {
7
+ const env = loadEnv(mode, process.cwd());
8
+
9
+ return {
10
+ plugins: [
11
+ vue(),
12
+ viteMockServe({
13
+ mockPath: 'mock',
14
+ enable: env.VITE_APP_MOCK === 'true',
15
+ }),
16
+ ],
17
+ resolve: {
18
+ alias: {
19
+ '@': fileURLToPath(new URL('./src', import.meta.url)),
20
+ },
21
+ },
22
+ css: {
23
+ preprocessorOptions: {
24
+ scss: {
25
+ api: 'modern-compiler',
26
+ },
27
+ },
28
+ },
29
+ server: {
30
+ port: Number(env.VITE_APP_PORT) || 3000,
31
+ open: true,
32
+ proxy: {
33
+ '/api': {
34
+ target: env.VITE_APP_API_BASE_URL || 'http://localhost:8080',
35
+ changeOrigin: true,
36
+ },
37
+ },
38
+ },
39
+ build: {
40
+ target: 'es2015',
41
+ cssTarget: 'chrome80',
42
+ rollupOptions: {
43
+ output: {
44
+ manualChunks: {
45
+ 'element-plus': ['element-plus'],
46
+ 'vue-vendor': ['vue', 'vue-router', 'pinia'],
47
+ },
48
+ },
49
+ },
50
+ },
51
+ };
52
+ });
@@ -0,0 +1,123 @@
1
+ name: CI/CD
2
+
3
+ on:
4
+ push:
5
+ branches: [main, develop]
6
+ pull_request:
7
+ branches: [main]
8
+ workflow_dispatch:
9
+
10
+ env:
11
+ NODE_VERSION: '20'
12
+
13
+ jobs:
14
+ lint:
15
+ name: Lint
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+ - name: Setup Node.js
20
+ uses: actions/setup-node@v4
21
+ with:
22
+ node-version: ${{ env.NODE_VERSION }}
23
+ cache: 'npm'
24
+ - name: Install dependencies
25
+ run: npm ci
26
+ - name: Run lint
27
+ run: npm run lint
28
+
29
+ test:
30
+ name: Test
31
+ runs-on: ubuntu-latest
32
+ needs: lint
33
+ steps:
34
+ - uses: actions/checkout@v4
35
+ - name: Setup Node.js
36
+ uses: actions/setup-node@v4
37
+ with:
38
+ node-version: ${{ env.NODE_VERSION }}
39
+ cache: 'npm'
40
+ - name: Install dependencies
41
+ run: npm ci
42
+ - name: Run tests
43
+ run: npm run test
44
+
45
+ build-dev:
46
+ name: Build Dev
47
+ runs-on: ubuntu-latest
48
+ needs: test
49
+ if: github.ref == 'refs/heads/develop'
50
+ steps:
51
+ - uses: actions/checkout@v4
52
+ - name: Setup Node.js
53
+ uses: actions/setup-node@v4
54
+ with:
55
+ node-version: ${{ env.NODE_VERSION }}
56
+ cache: 'npm'
57
+ - name: Install dependencies
58
+ run: npm ci
59
+ - name: Build
60
+ run: npm run build
61
+ env:
62
+ VITE_APP_ENV: development
63
+ - name: Upload artifact
64
+ uses: actions/upload-artifact@v4
65
+ with:
66
+ name: dist-dev
67
+ path: dist
68
+
69
+ build-prod:
70
+ name: Build Prod
71
+ runs-on: ubuntu-latest
72
+ needs: test
73
+ if: github.ref == 'refs/heads/main'
74
+ steps:
75
+ - uses: actions/checkout@v4
76
+ - name: Setup Node.js
77
+ uses: actions/setup-node@v4
78
+ with:
79
+ node-version: ${{ env.NODE_VERSION }}
80
+ cache: 'npm'
81
+ - name: Install dependencies
82
+ run: npm ci
83
+ - name: Build
84
+ run: npm run build
85
+ env:
86
+ VITE_APP_ENV: production
87
+ - name: Upload artifact
88
+ uses: actions/upload-artifact@v4
89
+ with:
90
+ name: dist-prod
91
+ path: dist
92
+
93
+ deploy-dev:
94
+ name: Deploy Dev
95
+ runs-on: ubuntu-latest
96
+ needs: build-dev
97
+ if: github.ref == 'refs/heads/develop'
98
+ steps:
99
+ - name: Download artifact
100
+ uses: actions/download-artifact@v4
101
+ with:
102
+ name: dist-dev
103
+ path: dist
104
+ - name: Deploy to dev server
105
+ run: |
106
+ echo "Deploying to dev server..."
107
+ # 添加部署命令
108
+
109
+ deploy-prod:
110
+ name: Deploy Prod
111
+ runs-on: ubuntu-latest
112
+ needs: build-prod
113
+ if: github.ref == 'refs/heads/main'
114
+ steps:
115
+ - name: Download artifact
116
+ uses: actions/download-artifact@v4
117
+ with:
118
+ name: dist-prod
119
+ path: dist
120
+ - name: Deploy to prod server
121
+ run: |
122
+ echo "Deploying to prod server..."
123
+ # 添加部署命令
@@ -0,0 +1,103 @@
1
+ stages:
2
+ - lint
3
+ - test
4
+ - build
5
+ - deploy
6
+
7
+ variables:
8
+ NODE_VERSION: "20"
9
+ NPM_CONFIG_CACHE: $CI_PROJECT_DIR/.npm
10
+
11
+ cache:
12
+ key: $CI_COMMIT_REF_SLUG
13
+ paths:
14
+ - .npm/
15
+ - node_modules/
16
+
17
+ lint:
18
+ stage: lint
19
+ image: node:$NODE_VERSION-alpine
20
+ script:
21
+ - npm ci
22
+ - npm run lint
23
+ only:
24
+ - main
25
+ - develop
26
+ - merge_requests
27
+
28
+ test:
29
+ stage: test
30
+ image: node:$NODE_VERSION-alpine
31
+ script:
32
+ - npm ci
33
+ - npm run test
34
+ only:
35
+ - main
36
+ - develop
37
+ - merge_requests
38
+
39
+ build-dev:
40
+ stage: build
41
+ image: node:$NODE_VERSION-alpine
42
+ script:
43
+ - npm ci
44
+ - npm run build
45
+ - echo "Build completed"
46
+ artifacts:
47
+ paths:
48
+ - dist/
49
+ expire_in: 1 hour
50
+ environment:
51
+ name: development
52
+ only:
53
+ - develop
54
+ tags:
55
+ - docker
56
+
57
+ build-prod:
58
+ stage: build
59
+ image: node:$NODE_VERSION-alpine
60
+ script:
61
+ - npm ci
62
+ - npm run build
63
+ - echo "Build completed"
64
+ artifacts:
65
+ paths:
66
+ - dist/
67
+ expire_in: 1 hour
68
+ environment:
69
+ name: production
70
+ only:
71
+ - main
72
+ tags:
73
+ - docker
74
+
75
+ deploy-dev:
76
+ stage: deploy
77
+ image: alpine:latest
78
+ script:
79
+ - echo "Deploying to development server..."
80
+ # 添加部署到开发服务器的命令
81
+ environment:
82
+ name: development
83
+ only:
84
+ - develop
85
+ needs:
86
+ - build-dev
87
+ tags:
88
+ - docker
89
+
90
+ deploy-prod:
91
+ stage: deploy
92
+ image: alpine:latest
93
+ script:
94
+ - echo "Deploying to production server..."
95
+ # 添加部署到生产服务器的命令
96
+ environment:
97
+ name: production
98
+ only:
99
+ - main
100
+ needs:
101
+ - build-prod
102
+ tags:
103
+ - docker
@@ -0,0 +1,107 @@
1
+ pipeline {
2
+ agent any
3
+
4
+ environment {
5
+ NODE_VERSION = '20'
6
+ DEV_SERVER = 'dev-server.example.com'
7
+ PROD_SERVER = 'prod-server.example.com'
8
+ }
9
+
10
+ options {
11
+ timeout(time: 30, unit: 'MINUTES')
12
+ disableConcurrentBuilds()
13
+ buildDiscarder(logRotator(numToKeepStr: '10'))
14
+ }
15
+
16
+ stages {
17
+ stage('Install') {
18
+ steps {
19
+ echo 'Installing dependencies...'
20
+ sh 'npm ci'
21
+ }
22
+ }
23
+
24
+ stage('Lint') {
25
+ steps {
26
+ echo 'Running lint...'
27
+ sh 'npm run lint'
28
+ }
29
+ }
30
+
31
+ stage('Test') {
32
+ steps {
33
+ echo 'Running tests...'
34
+ sh 'npm run test'
35
+ }
36
+ }
37
+
38
+ stage('Build Dev') {
39
+ when {
40
+ branch 'develop'
41
+ }
42
+ steps {
43
+ echo 'Building for development...'
44
+ sh 'npm run build'
45
+ archiveArtifacts artifacts: 'dist/**/*', fingerprint: true
46
+ }
47
+ }
48
+
49
+ stage('Build Prod') {
50
+ when {
51
+ branch 'main'
52
+ }
53
+ steps {
54
+ echo 'Building for production...'
55
+ sh 'npm run build'
56
+ archiveArtifacts artifacts: 'dist/**/*', fingerprint: true
57
+ }
58
+ }
59
+
60
+ stage('Deploy Dev') {
61
+ when {
62
+ branch 'develop'
63
+ }
64
+ steps {
65
+ echo "Deploying to development server: ${DEV_SERVER}"
66
+ script {
67
+ def distDir = "${WORKSPACE}/dist"
68
+ sh """
69
+ echo "Syncing files to dev server..."
70
+ # 添加部署到开发服务器的命令
71
+ # 例如: rsync -avz -e ssh --delete ${distDir}/ user@${DEV_SERVER}:/var/www/html/
72
+ """
73
+ }
74
+ }
75
+ }
76
+
77
+ stage('Deploy Prod') {
78
+ when {
79
+ branch 'main'
80
+ }
81
+ steps {
82
+ echo "Deploying to production server: ${PROD_SERVER}"
83
+ script {
84
+ def distDir = "${WORKSPACE}/dist"
85
+ sh """
86
+ echo "Syncing files to prod server..."
87
+ # 添加部署到生产服务器的 命令
88
+ # 例如: rsync -avz -e ssh --delete ${distDir}/ user@${PROD_SERVER}:/var/www/html/
89
+ """
90
+ }
91
+ }
92
+ }
93
+ }
94
+
95
+ post {
96
+ always {
97
+ echo 'Cleaning workspace...'
98
+ cleanWs()
99
+ }
100
+ success {
101
+ echo 'Pipeline completed successfully!'
102
+ }
103
+ failure {
104
+ echo 'Pipeline failed!'
105
+ }
106
+ }
107
+ }
@@ -0,0 +1,5 @@
1
+ declare module '*.vue' {
2
+ import { DefineComponent } from 'vue';
3
+ const component: DefineComponent<{}, {}, any>;
4
+ export default component;
5
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "useDefineForClassFields": true,
5
+ "module": "esnext",
6
+ "moduleResolution": "Bundler",
7
+ "strict": true,
8
+ "skipLibCheck": true,
9
+ "forceConsistentCasingInFileNames": true,
10
+ "jsx": "preserve",
11
+ "sourceMap": true,
12
+ "resolveJsonModule": true,
13
+ "esModuleInterop": true,
14
+ "isolatedModules": true,
15
+ "lib": ["ESNext", "DOM", "DOM.Iterable"],
16
+ "baseUrl": ".",
17
+ "paths": {
18
+ "@/*": ["src/*"]
19
+ }
20
+ },
21
+ "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
22
+ "exclude": ["node_modules", "dist"]
23
+ }