@sys-designer/create-vue 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.
- package/README.md +52 -0
- package/cli.mjs +133 -0
- package/package.json +26 -0
- package/template/.env.development +13 -0
- package/template/.env.electron +13 -0
- package/template/.env.production +11 -0
- package/template/.eslintrc-auto-import.json +96 -0
- package/template/README.md +2 -0
- package/template/_gitignore +32 -0
- package/template/build/proxy.ts +34 -0
- package/template/build/utils.ts +71 -0
- package/template/common/routes.ts +7 -0
- package/template/index.css +10 -0
- package/template/index.html +23 -0
- package/template/package.json +51 -0
- package/template/public/favicon.ico +0 -0
- package/template/src/App.vue +18 -0
- package/template/src/assets/styles/reset.scss +0 -0
- package/template/src/assets/styles/vars.scss +0 -0
- package/template/src/env.d.ts +5 -0
- package/template/src/main.ts +13 -0
- package/template/src/router/index.ts +44 -0
- package/template/src/store/global.ts +60 -0
- package/template/src/store/index.ts +9 -0
- package/template/src/store/user.ts +61 -0
- package/template/src/types/auto-imports.d.ts +93 -0
- package/template/src/types/components.d.ts +22 -0
- package/template/src/utils/crypto.ts +160 -0
- package/template/src/utils/dsl.ts +101 -0
- package/template/src/utils/index.ts +30 -0
- package/template/src/utils/is.ts +122 -0
- package/template/src/utils/request.ts +51 -0
- package/template/src/views/index.vue +23 -0
- package/template/src/vite-env.d.ts +31 -0
- package/template/tsconfig.json +37 -0
- package/template/tsconfig.node.json +20 -0
- package/template/vite.config.ts +99 -0
package/README.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# @sys-designer/create-vue
|
|
2
|
+
|
|
3
|
+
基于 `sys-designer-vue-template` 的命令行脚手架,一键生成 Vue3 + Vite + TypeScript 项目。
|
|
4
|
+
|
|
5
|
+
## 使用方式
|
|
6
|
+
|
|
7
|
+
### 1. 通过 npm create(发布后,任意机器)
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm create @sys-designer/vue@latest my-app
|
|
11
|
+
# npm 会自动补全为 @sys-designer/create-vue 并执行
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
### 2. 本地全局使用(无需发布)
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
cd sys-designer-vue-cli
|
|
18
|
+
npm link
|
|
19
|
+
create-vue my-app
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
### 3. 直接运行(无需安装)
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npx @sys-designer/create-vue my-app
|
|
26
|
+
# 或
|
|
27
|
+
node sys-designer-vue-cli/cli.mjs my-app
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## 发布
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
cd sys-designer-vue-cli
|
|
34
|
+
npm publish # publishConfig.access=public 已配置,作用域包直接公开
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
> 发布需满足 npm 的 2FA 要求:在 npmjs.com 开启 Two-Factor Authentication(Publishing),
|
|
38
|
+
> 然后 `npm publish --otp=123456`(123456 为 Authenticator 当前动态码)。
|
|
39
|
+
|
|
40
|
+
## 参数
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
create-vue [project-name] [-d|--dir <dir>] [-h|--help]
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
- 不传 `project-name` 时会交互式询问。
|
|
47
|
+
- 生成后自动把模板 `package.json` 中的 `name` 替换为项目名。
|
|
48
|
+
|
|
49
|
+
## 自定义模板
|
|
50
|
+
|
|
51
|
+
编辑 `template/` 目录即可。模板文件中的 `{{projectName}}` 占位符会在生成时替换为项目名;
|
|
52
|
+
如需让某个文件在生成后变为 `.gitignore`,可将其命名为 `_gitignore`。
|
package/cli.mjs
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import readline from 'node:readline/promises';
|
|
6
|
+
import { stdin, stdout } from 'node:process';
|
|
7
|
+
|
|
8
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const TEMPLATE_DIR = path.join(__dirname, 'template');
|
|
10
|
+
|
|
11
|
+
const IGNORE_FILES = new Set(['.git', 'node_modules', 'pnpm-lock.yaml', 'package-lock.json', 'yarn.lock']);
|
|
12
|
+
// 需要替换占位符的文本文件后缀
|
|
13
|
+
const TEXT_EXT = new Set(['.js', '.mjs', '.cjs', '.ts', '.tsx', '.vue', '.json', '.html', '.css', '.scss', '.md', '.txt', '.yml', '.yaml', '.env']);
|
|
14
|
+
|
|
15
|
+
function toValidPackageName(input) {
|
|
16
|
+
return input
|
|
17
|
+
.trim()
|
|
18
|
+
.toLowerCase()
|
|
19
|
+
.replace(/[^a-z0-9@.\-_/]+/g, '-')
|
|
20
|
+
.replace(/^[-_]+|[-_]+$/g, '')
|
|
21
|
+
|| 'sys-designer-vue-app';
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function copyDir(src, dest, vars) {
|
|
25
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
26
|
+
for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
|
|
27
|
+
const name = entry.name;
|
|
28
|
+
if (IGNORE_FILES.has(name)) continue;
|
|
29
|
+
const srcPath = path.join(src, name);
|
|
30
|
+
const destPath = path.join(dest, name);
|
|
31
|
+
if (entry.isDirectory()) {
|
|
32
|
+
copyDir(srcPath, destPath, vars);
|
|
33
|
+
} else {
|
|
34
|
+
// 模板内若用了 .gitignore.template 之类的隐藏名,这里还原为 .gitignore
|
|
35
|
+
const finalDest = name.startsWith('_gitignore') ? path.join(dest, '.gitignore') : destPath;
|
|
36
|
+
if (TEXT_EXT.has(path.extname(name))) {
|
|
37
|
+
let content = fs.readFileSync(srcPath, 'utf-8');
|
|
38
|
+
// package.json 单独处理:把 name 替换为项目名,避免损坏 JSON
|
|
39
|
+
if (name === 'package.json') {
|
|
40
|
+
try {
|
|
41
|
+
const pkg = JSON.parse(content);
|
|
42
|
+
pkg.name = vars.projectName;
|
|
43
|
+
if (vars.author) pkg.author = vars.author;
|
|
44
|
+
content = JSON.stringify(pkg, null, 2) + '\n';
|
|
45
|
+
} catch {
|
|
46
|
+
/* 解析失败则走下方占位符替换 */
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
for (const [k, v] of Object.entries(vars)) {
|
|
50
|
+
content = content.split(`{{${k}}}`).join(v);
|
|
51
|
+
}
|
|
52
|
+
fs.writeFileSync(finalDest, content);
|
|
53
|
+
} else {
|
|
54
|
+
fs.copyFileSync(srcPath, finalDest);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function printHelp() {
|
|
61
|
+
console.log(`
|
|
62
|
+
Usage:
|
|
63
|
+
create-sys-designer-vue [project-name] [options]
|
|
64
|
+
|
|
65
|
+
Options:
|
|
66
|
+
-h, --help Show this help
|
|
67
|
+
-d, --dir <dir> Target directory (default: ./<project-name>)
|
|
68
|
+
|
|
69
|
+
Examples:
|
|
70
|
+
create-sys-designer-vue my-app
|
|
71
|
+
npm create sys-designer-vue@latest my-app
|
|
72
|
+
npx create-sys-designer-vue my-app
|
|
73
|
+
`);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async function main() {
|
|
77
|
+
const args = process.argv.slice(2);
|
|
78
|
+
if (args.some((a) => a === '-h' || a === '--help')) {
|
|
79
|
+
printHelp();
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
let projectName = '';
|
|
84
|
+
let targetDir = '';
|
|
85
|
+
for (let i = 0; i < args.length; i++) {
|
|
86
|
+
if (args[i] === '-d' || args[i] === '--dir') {
|
|
87
|
+
targetDir = args[++i];
|
|
88
|
+
} else if (!projectName) {
|
|
89
|
+
projectName = args[i];
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (!projectName) {
|
|
94
|
+
const rl = readline.createInterface({ input: stdin, output: stdout });
|
|
95
|
+
projectName = (await rl.question('Project name: ')).trim();
|
|
96
|
+
await rl.close();
|
|
97
|
+
}
|
|
98
|
+
if (!projectName) {
|
|
99
|
+
console.error('Error: project name is required.');
|
|
100
|
+
printHelp();
|
|
101
|
+
process.exit(1);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
const pkgName = toValidPackageName(projectName);
|
|
105
|
+
const destRoot = targetDir ? path.resolve(targetDir) : path.resolve(process.cwd(), pkgName);
|
|
106
|
+
|
|
107
|
+
if (fs.existsSync(destRoot) && fs.readdirSync(destRoot).length > 0) {
|
|
108
|
+
console.error(`Error: target directory "${destRoot}" is not empty.`);
|
|
109
|
+
process.exit(1);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
console.log(`\nScaffolding project in ${destRoot} ...`);
|
|
113
|
+
copyDir(TEMPLATE_DIR, destRoot, {
|
|
114
|
+
projectName: pkgName,
|
|
115
|
+
name: pkgName,
|
|
116
|
+
author: process.env.USER || process.env.USERNAME || '',
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
console.log(`
|
|
120
|
+
Done! Next steps:
|
|
121
|
+
|
|
122
|
+
cd ${path.relative(process.cwd(), destRoot) || '.'}
|
|
123
|
+
npm install # or: pnpm install
|
|
124
|
+
npm run dev
|
|
125
|
+
|
|
126
|
+
Happy coding! 🚀
|
|
127
|
+
`);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
main().catch((err) => {
|
|
131
|
+
console.error(err);
|
|
132
|
+
process.exit(1);
|
|
133
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sys-designer/create-vue",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Scaffold a sys-designer Vue3 + Vite + TS project from the command line.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"create-vue": "cli.mjs"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"cli.mjs",
|
|
11
|
+
"template"
|
|
12
|
+
],
|
|
13
|
+
"keywords": [
|
|
14
|
+
"vue",
|
|
15
|
+
"vite",
|
|
16
|
+
"scaffold",
|
|
17
|
+
"sys-designer"
|
|
18
|
+
],
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=16"
|
|
21
|
+
},
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# 只在开发模式中被载入
|
|
2
|
+
VITE_PORT = 3001
|
|
3
|
+
|
|
4
|
+
# 网站根目录
|
|
5
|
+
VITE_PUBLIC_PATH = ./
|
|
6
|
+
|
|
7
|
+
# API 接口地址
|
|
8
|
+
VITE_GLOB_API_URL =/api
|
|
9
|
+
|
|
10
|
+
VITE_PROXY=[["/api","http://localhost:11001/api/"]]
|
|
11
|
+
VITE_HOME_PAGE_URL=./workspace/index.html/#/desktop
|
|
12
|
+
VITE_GLOB_API_URL=https://www.sys-designer.com/api
|
|
13
|
+
VITE_PRODUCT=electron
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
{
|
|
2
|
+
"globals": {
|
|
3
|
+
"Component": true,
|
|
4
|
+
"ComponentPublicInstance": true,
|
|
5
|
+
"ComputedRef": true,
|
|
6
|
+
"DirectiveBinding": true,
|
|
7
|
+
"EffectScope": true,
|
|
8
|
+
"ExtractDefaultPropTypes": true,
|
|
9
|
+
"ExtractPropTypes": true,
|
|
10
|
+
"ExtractPublicPropTypes": true,
|
|
11
|
+
"InjectionKey": true,
|
|
12
|
+
"MaybeRef": true,
|
|
13
|
+
"MaybeRefOrGetter": true,
|
|
14
|
+
"PropType": true,
|
|
15
|
+
"Ref": true,
|
|
16
|
+
"VNode": true,
|
|
17
|
+
"WritableComputedRef": true,
|
|
18
|
+
"acceptHMRUpdate": true,
|
|
19
|
+
"computed": true,
|
|
20
|
+
"createApp": true,
|
|
21
|
+
"createPinia": true,
|
|
22
|
+
"customRef": true,
|
|
23
|
+
"defineAsyncComponent": true,
|
|
24
|
+
"defineComponent": true,
|
|
25
|
+
"defineStore": true,
|
|
26
|
+
"effectScope": true,
|
|
27
|
+
"getActivePinia": true,
|
|
28
|
+
"getCurrentInstance": true,
|
|
29
|
+
"getCurrentScope": true,
|
|
30
|
+
"h": true,
|
|
31
|
+
"inject": true,
|
|
32
|
+
"isProxy": true,
|
|
33
|
+
"isReactive": true,
|
|
34
|
+
"isReadonly": true,
|
|
35
|
+
"isRef": true,
|
|
36
|
+
"mapActions": true,
|
|
37
|
+
"mapGetters": true,
|
|
38
|
+
"mapState": true,
|
|
39
|
+
"mapStores": true,
|
|
40
|
+
"mapWritableState": true,
|
|
41
|
+
"markRaw": true,
|
|
42
|
+
"nextTick": true,
|
|
43
|
+
"onActivated": true,
|
|
44
|
+
"onBeforeMount": true,
|
|
45
|
+
"onBeforeRouteLeave": true,
|
|
46
|
+
"onBeforeRouteUpdate": true,
|
|
47
|
+
"onBeforeUnmount": true,
|
|
48
|
+
"onBeforeUpdate": true,
|
|
49
|
+
"onDeactivated": true,
|
|
50
|
+
"onErrorCaptured": true,
|
|
51
|
+
"onMounted": true,
|
|
52
|
+
"onRenderTracked": true,
|
|
53
|
+
"onRenderTriggered": true,
|
|
54
|
+
"onScopeDispose": true,
|
|
55
|
+
"onServerPrefetch": true,
|
|
56
|
+
"onUnmounted": true,
|
|
57
|
+
"onUpdated": true,
|
|
58
|
+
"onWatcherCleanup": true,
|
|
59
|
+
"provide": true,
|
|
60
|
+
"reactive": true,
|
|
61
|
+
"readonly": true,
|
|
62
|
+
"ref": true,
|
|
63
|
+
"resolveComponent": true,
|
|
64
|
+
"setActivePinia": true,
|
|
65
|
+
"setMapStoreSuffix": true,
|
|
66
|
+
"shallowReactive": true,
|
|
67
|
+
"shallowReadonly": true,
|
|
68
|
+
"shallowRef": true,
|
|
69
|
+
"storeToRefs": true,
|
|
70
|
+
"toRaw": true,
|
|
71
|
+
"toRef": true,
|
|
72
|
+
"toRefs": true,
|
|
73
|
+
"toValue": true,
|
|
74
|
+
"triggerRef": true,
|
|
75
|
+
"unref": true,
|
|
76
|
+
"useAttrs": true,
|
|
77
|
+
"useCssModule": true,
|
|
78
|
+
"useCssVars": true,
|
|
79
|
+
"useDialog": true,
|
|
80
|
+
"useId": true,
|
|
81
|
+
"useLink": true,
|
|
82
|
+
"useLoadingBar": true,
|
|
83
|
+
"useMessage": true,
|
|
84
|
+
"useModal": true,
|
|
85
|
+
"useModel": true,
|
|
86
|
+
"useNotification": true,
|
|
87
|
+
"useRoute": true,
|
|
88
|
+
"useRouter": true,
|
|
89
|
+
"useSlots": true,
|
|
90
|
+
"useTemplateRef": true,
|
|
91
|
+
"watch": true,
|
|
92
|
+
"watchEffect": true,
|
|
93
|
+
"watchPostEffect": true,
|
|
94
|
+
"watchSyncEffect": true
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Logs
|
|
2
|
+
logs
|
|
3
|
+
*.log
|
|
4
|
+
npm-debug.log*
|
|
5
|
+
yarn-debug.log*
|
|
6
|
+
yarn-error.log*
|
|
7
|
+
pnpm-debug.log*
|
|
8
|
+
|
|
9
|
+
# Dependencies
|
|
10
|
+
node_modules
|
|
11
|
+
.pnp
|
|
12
|
+
.pnp.js
|
|
13
|
+
|
|
14
|
+
# Build output
|
|
15
|
+
dist
|
|
16
|
+
dist-ssr
|
|
17
|
+
*.local
|
|
18
|
+
|
|
19
|
+
# Editor / OS
|
|
20
|
+
.vscode/*
|
|
21
|
+
!.vscode/extensions.json
|
|
22
|
+
.idea
|
|
23
|
+
.DS_Store
|
|
24
|
+
*.suo
|
|
25
|
+
*.ntvs*
|
|
26
|
+
*.njsproj
|
|
27
|
+
*.sln
|
|
28
|
+
*.sw?
|
|
29
|
+
|
|
30
|
+
# Env
|
|
31
|
+
.env.local
|
|
32
|
+
.env.*.local
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Used to parse the .env.development proxy configuration
|
|
3
|
+
*/
|
|
4
|
+
import type { ProxyOptions } from 'vite';
|
|
5
|
+
|
|
6
|
+
type ProxyItem = [string, string];
|
|
7
|
+
|
|
8
|
+
type ProxyList = ProxyItem[];
|
|
9
|
+
|
|
10
|
+
type ProxyTargetList = Record<string, ProxyOptions & { rewrite: (path: string) => string }>;
|
|
11
|
+
|
|
12
|
+
const httpsRE = /^https:\/\//;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Generate proxy
|
|
16
|
+
* @param list
|
|
17
|
+
*/
|
|
18
|
+
export function createProxy(list: ProxyList = []) {
|
|
19
|
+
const ret: ProxyTargetList = {};
|
|
20
|
+
for (const [prefix, target] of list) {
|
|
21
|
+
const isHttps = httpsRE.test(target);
|
|
22
|
+
|
|
23
|
+
// https://github.com/http-party/node-http-proxy#options
|
|
24
|
+
ret[prefix] = {
|
|
25
|
+
target: target,
|
|
26
|
+
changeOrigin: true,
|
|
27
|
+
ws: true,
|
|
28
|
+
rewrite: (path) => path.replace(new RegExp(`^${prefix}`), ''),
|
|
29
|
+
// https is require secure=false
|
|
30
|
+
...(isHttps ? { secure: false } : {}),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
return ret;
|
|
34
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import dotenv from 'dotenv';
|
|
4
|
+
|
|
5
|
+
export function isDevFn(mode: string): boolean {
|
|
6
|
+
return mode === 'development';
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function isProdFn(mode: string): boolean {
|
|
10
|
+
return mode === 'production';
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Whether to generate package preview
|
|
15
|
+
*/
|
|
16
|
+
export function isReportMode(): boolean {
|
|
17
|
+
return process.env.REPORT === 'true';
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Read all environment variable configuration files to process.env
|
|
21
|
+
export function wrapperEnv(envConf: Recordable): ViteEnv {
|
|
22
|
+
const ret: any = {};
|
|
23
|
+
|
|
24
|
+
for (const envName of Object.keys(envConf)) {
|
|
25
|
+
let realName = envConf[envName].replace(/\\n/g, '\n');
|
|
26
|
+
realName = realName === 'true' ? true : realName === 'false' ? false : realName;
|
|
27
|
+
|
|
28
|
+
if (envName === 'VITE_PORT') {
|
|
29
|
+
realName = Number(realName);
|
|
30
|
+
}
|
|
31
|
+
if (envName === 'VITE_PROXY') {
|
|
32
|
+
try {
|
|
33
|
+
realName = JSON.parse(realName);
|
|
34
|
+
} catch (error) { }
|
|
35
|
+
}
|
|
36
|
+
ret[envName] = realName;
|
|
37
|
+
process.env[envName] = realName;
|
|
38
|
+
}
|
|
39
|
+
return ret;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Get the environment variables starting with the specified prefix
|
|
44
|
+
* @param match prefix
|
|
45
|
+
* @param confFiles ext
|
|
46
|
+
*/
|
|
47
|
+
export function getEnvConfig(match = 'VITE_GLOB_', confFiles = ['.env', '.env.production']) {
|
|
48
|
+
let envConfig = {};
|
|
49
|
+
confFiles.forEach((item) => {
|
|
50
|
+
try {
|
|
51
|
+
const env = dotenv.parse(fs.readFileSync(path.resolve(process.cwd(), item)));
|
|
52
|
+
envConfig = { ...envConfig, ...env };
|
|
53
|
+
} catch (error) { }
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
Object.keys(envConfig).forEach((key) => {
|
|
57
|
+
const reg = new RegExp(`^(${match})`);
|
|
58
|
+
if (!reg.test(key)) {
|
|
59
|
+
Reflect.deleteProperty(envConfig, key);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
return envConfig;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Get user root directory
|
|
67
|
+
* @param dir file path
|
|
68
|
+
*/
|
|
69
|
+
export function getRootPath(...dir: string[]) {
|
|
70
|
+
return path.resolve(process.cwd(), ...dir);
|
|
71
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
|
|
6
|
+
<meta name="renderer" content="webkit" />
|
|
7
|
+
<meta name="description" content="一体化开发平台">
|
|
8
|
+
<meta name="keywords" content="一体化开发平台,IDesign Platform">
|
|
9
|
+
<meta name="author" content="idesign platform">
|
|
10
|
+
<meta
|
|
11
|
+
name="viewport"
|
|
12
|
+
content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=0"
|
|
13
|
+
/>
|
|
14
|
+
<link rel="icon" href="./favicon.ico" />
|
|
15
|
+
<title>Sys-Designer 一体化开发平台</title>
|
|
16
|
+
<link rel="stylesheet" href="./index.css" />
|
|
17
|
+
</head>
|
|
18
|
+
<body>
|
|
19
|
+
<div id="app">
|
|
20
|
+
</div>
|
|
21
|
+
<script type="module" src="/src/main.ts"></script>
|
|
22
|
+
</body>
|
|
23
|
+
</html>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sys-designer-vue-template",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "vite --mode development",
|
|
7
|
+
"build": "tsc && vite build --mode production",
|
|
8
|
+
"build:electron": "tsc && vite build --mode electron ",
|
|
9
|
+
"build:test": "tsc && vite build --mode test",
|
|
10
|
+
"preview": "vite preview",
|
|
11
|
+
"lint": "eslint . --ext .vue,.ts,.tsx --fix",
|
|
12
|
+
"lint:check": "eslint . --ext .vue,.ts,.tsx"
|
|
13
|
+
},
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@vicons/ionicons5": "^0.13.0",
|
|
16
|
+
"@vicons/material": "^0.13.0",
|
|
17
|
+
"axios": "^1.7.7",
|
|
18
|
+
"crypto-js": "^4.2.0",
|
|
19
|
+
"dayjs": "^1.11.13",
|
|
20
|
+
"js-cookie": "^3.0.5",
|
|
21
|
+
"lodash": "^4.17.21",
|
|
22
|
+
"naive-ui": "^2.40.1",
|
|
23
|
+
"node-forge": "^1.4.0",
|
|
24
|
+
"pinia": "^2.2.4",
|
|
25
|
+
"pinia-plugin-persistedstate": "^4.7.1",
|
|
26
|
+
"vue": "^3.5.10",
|
|
27
|
+
"vue-router": "^4.4.5"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/crypto-js": "^4.2.2",
|
|
31
|
+
"@types/js-cookie": "^3.0.6",
|
|
32
|
+
"@types/lodash": "^4.17.10",
|
|
33
|
+
"@types/node": "^22.7.5",
|
|
34
|
+
"@types/node-forge": "^1.3.14",
|
|
35
|
+
"@vitejs/plugin-vue": "^5.1.4",
|
|
36
|
+
"dotenv": "^17.4.2",
|
|
37
|
+
"eslint": "^9.12.0",
|
|
38
|
+
"eslint-plugin-vue": "^9.28.0",
|
|
39
|
+
"mockjs": "^1.1.0",
|
|
40
|
+
"prettier": "^3.3.3",
|
|
41
|
+
"sass": "^1.79.4",
|
|
42
|
+
"terser": "^5.34.0",
|
|
43
|
+
"typescript": "^5.6.3",
|
|
44
|
+
"unplugin-auto-import": "^0.18.3",
|
|
45
|
+
"unplugin-vue-components": "^0.27.4",
|
|
46
|
+
"vite": "^6.0.0",
|
|
47
|
+
"vite-plugin-compression": "^0.5.1",
|
|
48
|
+
"vite-plugin-html": "^3.2.2",
|
|
49
|
+
"vite-plugin-mock": "^3.0.2"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<n-config-provider :locale="zhCN" :date-locale="dateZhCN">
|
|
3
|
+
<n-message-provider>
|
|
4
|
+
<n-dialog-provider >
|
|
5
|
+
<n-notification-provider>
|
|
6
|
+
<n-loading-bar-provider>
|
|
7
|
+
<router-view />
|
|
8
|
+
</n-loading-bar-provider>
|
|
9
|
+
</n-notification-provider>
|
|
10
|
+
</n-dialog-provider>
|
|
11
|
+
</n-message-provider>
|
|
12
|
+
</n-config-provider>
|
|
13
|
+
</template>
|
|
14
|
+
|
|
15
|
+
<script setup lang="ts">
|
|
16
|
+
import { zhCN, dateZhCN } from 'naive-ui';
|
|
17
|
+
|
|
18
|
+
</script>
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createApp } from 'vue'
|
|
2
|
+
import App from './App.vue'
|
|
3
|
+
import router from './router'
|
|
4
|
+
import { createPinia } from 'pinia'
|
|
5
|
+
import '@/assets/styles/reset.scss'
|
|
6
|
+
|
|
7
|
+
const app = createApp(App)
|
|
8
|
+
const pinia = createPinia()
|
|
9
|
+
|
|
10
|
+
app.use(pinia);
|
|
11
|
+
app.use(router);
|
|
12
|
+
|
|
13
|
+
app.mount('#app')
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
|
|
2
|
+
import { routes } from '@common/routes';
|
|
3
|
+
|
|
4
|
+
export const constantRoutes: RouteRecordRaw[] = [
|
|
5
|
+
...routes,
|
|
6
|
+
{
|
|
7
|
+
path: '/:pathMatch(.*)*',
|
|
8
|
+
redirect: '/',
|
|
9
|
+
}
|
|
10
|
+
]
|
|
11
|
+
|
|
12
|
+
const router = createRouter({
|
|
13
|
+
history: createWebHistory(),
|
|
14
|
+
routes: constantRoutes
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
// 全局路由守卫
|
|
18
|
+
// router.beforeEach(async (to, from, next) => {
|
|
19
|
+
// // const token = getToken()
|
|
20
|
+
// // const userStore = useUserStore()
|
|
21
|
+
// const whiteList = ['/login']
|
|
22
|
+
|
|
23
|
+
// // if (token) {
|
|
24
|
+
// // if (to.path === '/login') {
|
|
25
|
+
// // next('/')
|
|
26
|
+
// // } else {
|
|
27
|
+
// // if (!userStore.userInfo.id) {
|
|
28
|
+
// // await userStore.getUserInfo()
|
|
29
|
+
// // next({ ...to, replace: true })
|
|
30
|
+
// // } else {
|
|
31
|
+
// // next()
|
|
32
|
+
// // }
|
|
33
|
+
// // }
|
|
34
|
+
// // } else {
|
|
35
|
+
// // if (whiteList.includes(to.path)) {
|
|
36
|
+
// // next()
|
|
37
|
+
// // } else {
|
|
38
|
+
// // next('/login')
|
|
39
|
+
// // }
|
|
40
|
+
// // }
|
|
41
|
+
// next();
|
|
42
|
+
// });
|
|
43
|
+
|
|
44
|
+
export default router
|