moyan-mfw-cli 0.1.2 → 1.1.2
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/dist/index.cjs +14 -6
- package/dist/index.js +14 -6
- package/dist/templates/business/backend/package.json.hbs +15 -6
- package/dist/templates/business/backend/src/app.modules.ts.hbs +1 -1
- package/dist/templates/business/frontend/index.html.hbs +373 -14
- package/dist/templates/business/frontend/package.json.hbs +11 -7
- package/dist/templates/business/frontend/src/main.ts.hbs +2 -6
- package/dist/templates/business/pnpm-workspace.yaml.hbs +12 -1
- package/dist/templates/extension/README.md.hbs +27 -27
- package/dist/templates/extension/backend/.env.hbs +10 -10
- package/dist/templates/extension/backend/src/index.ts.hbs +1 -1
- package/dist/templates/extension/backend/src/main.ts.hbs +34 -34
- package/dist/templates/extension/backend/src/{{name}}.module.ts.hbs +4 -4
- package/dist/templates/extension/frontend/api.build.cjs.hbs +8 -8
- package/dist/templates/extension/frontend/index.html.hbs +12 -12
- package/dist/templates/extension/frontend/src/env.d.ts.hbs +1 -1
- package/dist/templates/extension/frontend/src/index.ts.hbs +13 -13
- package/dist/templates/extension/frontend/src/main.ts.hbs +13 -13
- package/dist/templates/extension/frontend/vite.config.mts.hbs +30 -30
- package/dist/templates/extension/package.json.hbs +1 -1
- package/dist/templates/extension/shared/src/constants.ts.hbs +12 -12
- package/dist/templates/extension/shared/src/dict.ts.hbs +8 -8
- package/dist/templates/extension/shared/src/index.ts.hbs +10 -10
- package/dist/templates/extension/shared/src/paths.ts.hbs +5 -5
- package/dist/templates/extension/shared/src/permission-values.ts.hbs +3 -3
- package/dist/templates/extension/shared/src/types.ts.hbs +5 -5
- package/package.json +48 -52
package/dist/index.cjs
CHANGED
|
@@ -181,7 +181,10 @@ Use --force to overwrite.`));
|
|
|
181
181
|
process.exit(1);
|
|
182
182
|
}
|
|
183
183
|
}
|
|
184
|
-
|
|
184
|
+
if (!process.stdin.isTTY && !opts.yes) {
|
|
185
|
+
console.log(import_chalk.default.yellow("\u26A0 \u975E\u4EA4\u4E92\u5F0F\u7EC8\u7AEF\uFF0C\u5C06\u4F7F\u7528\u9ED8\u8BA4\u503C\u521B\u5EFA\uFF08\u4F7F\u7528 -y \u53EF\u8DF3\u8FC7\u6B64\u63D0\u793A\uFF09"));
|
|
186
|
+
}
|
|
187
|
+
const answers = opts.yes || !process.stdin.isTTY ? defaultExtensionAnswers(name, className) : await import_inquirer.default.prompt([
|
|
185
188
|
{ name: "displayName", message: "\u663E\u793A\u540D\u79F0:", default: className },
|
|
186
189
|
{ name: "description", message: "\u63CF\u8FF0:", default: "" },
|
|
187
190
|
{ name: "routePrefix", message: "\u8DEF\u7531\u524D\u7F00:", default: `/ext/${name}` },
|
|
@@ -259,7 +262,10 @@ Use --force to overwrite.`));
|
|
|
259
262
|
process.exit(1);
|
|
260
263
|
}
|
|
261
264
|
}
|
|
262
|
-
|
|
265
|
+
if (!process.stdin.isTTY && !opts.yes) {
|
|
266
|
+
console.log(import_chalk2.default.yellow("\u26A0 \u975E\u4EA4\u4E92\u5F0F\u7EC8\u7AEF\uFF0C\u5C06\u4F7F\u7528\u9ED8\u8BA4\u503C\u521B\u5EFA\uFF08\u4F7F\u7528 -y \u53EF\u8DF3\u8FC7\u6B64\u63D0\u793A\uFF09"));
|
|
267
|
+
}
|
|
268
|
+
const answers = opts.yes || !process.stdin.isTTY ? defaultBusinessAnswers(className) : await import_inquirer2.default.prompt([
|
|
263
269
|
{
|
|
264
270
|
name: "displayName",
|
|
265
271
|
message: "\u663E\u793A\u540D\u79F0:",
|
|
@@ -318,11 +324,13 @@ Use --force to overwrite.`));
|
|
|
318
324
|
${import_chalk2.default.bold("\u{1F4CB} \u540E\u7EED\u6B65\u9AA4:")}`);
|
|
319
325
|
console.log(` 1. cd ${path4.relative(process.cwd(), targetDir)}`);
|
|
320
326
|
console.log(` 2. \u7F16\u8F91 backend/.env \u914D\u7F6E\u6570\u636E\u5E93\u8FDE\u63A5`);
|
|
321
|
-
console.log(` 3.
|
|
322
|
-
console.log(` 4. pnpm --
|
|
323
|
-
console.log(` 5. pnpm --filter ${name}-
|
|
327
|
+
console.log(` 3. \u5728 MySQL \u4E2D\u521B\u5EFA\u6570\u636E\u5E93\uFF08\u9ED8\u8BA4 DB_NAME \u89C1 backend/.env\uFF09`);
|
|
328
|
+
console.log(` 4. pnpm install --no-frozen-lockfile && pnpm build`);
|
|
329
|
+
console.log(` 5. pnpm --filter ${name}-backend dev # \u542F\u52A8\u540E\u7AEF`);
|
|
330
|
+
console.log(` 6. pnpm --filter ${name}-frontend dev # \u542F\u52A8\u524D\u7AEF`);
|
|
324
331
|
console.log(`
|
|
325
|
-
${import_chalk2.default.
|
|
332
|
+
${import_chalk2.default.yellow("\u26A0 \u9996\u6B21\u5B89\u88C5\u8BF7\u4F7F\u7528 --no-frozen-lockfile\uFF0C\u5426\u5219\u4F1A\u56E0\u7F3A\u5C11 lock \u6587\u4EF6\u62A5\u9519")}`);
|
|
333
|
+
console.log(`${import_chalk2.default.gray("\u{1F4A1} \u6DFB\u52A0\u6269\u5C55\u6A21\u5757: \u5728 backend/src/app.modules.ts \u4E2D\u5F15\u5165\u6269\u5C55 Module")}`);
|
|
326
334
|
console.log(`${import_chalk2.default.gray("\u{1F4A1} \u6DFB\u52A0\u4E1A\u52A1\u6A21\u5757: \u5728 backend/src/modules/ \u4E0B\u521B\u5EFA\u65B0\u7684 NestJS \u6A21\u5757")}`);
|
|
327
335
|
});
|
|
328
336
|
|
package/dist/index.js
CHANGED
|
@@ -157,7 +157,10 @@ Use --force to overwrite.`));
|
|
|
157
157
|
process.exit(1);
|
|
158
158
|
}
|
|
159
159
|
}
|
|
160
|
-
|
|
160
|
+
if (!process.stdin.isTTY && !opts.yes) {
|
|
161
|
+
console.log(chalk.yellow("\u26A0 \u975E\u4EA4\u4E92\u5F0F\u7EC8\u7AEF\uFF0C\u5C06\u4F7F\u7528\u9ED8\u8BA4\u503C\u521B\u5EFA\uFF08\u4F7F\u7528 -y \u53EF\u8DF3\u8FC7\u6B64\u63D0\u793A\uFF09"));
|
|
162
|
+
}
|
|
163
|
+
const answers = opts.yes || !process.stdin.isTTY ? defaultExtensionAnswers(name, className) : await inquirer.prompt([
|
|
161
164
|
{ name: "displayName", message: "\u663E\u793A\u540D\u79F0:", default: className },
|
|
162
165
|
{ name: "description", message: "\u63CF\u8FF0:", default: "" },
|
|
163
166
|
{ name: "routePrefix", message: "\u8DEF\u7531\u524D\u7F00:", default: `/ext/${name}` },
|
|
@@ -235,7 +238,10 @@ Use --force to overwrite.`));
|
|
|
235
238
|
process.exit(1);
|
|
236
239
|
}
|
|
237
240
|
}
|
|
238
|
-
|
|
241
|
+
if (!process.stdin.isTTY && !opts.yes) {
|
|
242
|
+
console.log(chalk2.yellow("\u26A0 \u975E\u4EA4\u4E92\u5F0F\u7EC8\u7AEF\uFF0C\u5C06\u4F7F\u7528\u9ED8\u8BA4\u503C\u521B\u5EFA\uFF08\u4F7F\u7528 -y \u53EF\u8DF3\u8FC7\u6B64\u63D0\u793A\uFF09"));
|
|
243
|
+
}
|
|
244
|
+
const answers = opts.yes || !process.stdin.isTTY ? defaultBusinessAnswers(className) : await inquirer2.prompt([
|
|
239
245
|
{
|
|
240
246
|
name: "displayName",
|
|
241
247
|
message: "\u663E\u793A\u540D\u79F0:",
|
|
@@ -294,11 +300,13 @@ Use --force to overwrite.`));
|
|
|
294
300
|
${chalk2.bold("\u{1F4CB} \u540E\u7EED\u6B65\u9AA4:")}`);
|
|
295
301
|
console.log(` 1. cd ${path4.relative(process.cwd(), targetDir)}`);
|
|
296
302
|
console.log(` 2. \u7F16\u8F91 backend/.env \u914D\u7F6E\u6570\u636E\u5E93\u8FDE\u63A5`);
|
|
297
|
-
console.log(` 3.
|
|
298
|
-
console.log(` 4. pnpm --
|
|
299
|
-
console.log(` 5. pnpm --filter ${name}-
|
|
303
|
+
console.log(` 3. \u5728 MySQL \u4E2D\u521B\u5EFA\u6570\u636E\u5E93\uFF08\u9ED8\u8BA4 DB_NAME \u89C1 backend/.env\uFF09`);
|
|
304
|
+
console.log(` 4. pnpm install --no-frozen-lockfile && pnpm build`);
|
|
305
|
+
console.log(` 5. pnpm --filter ${name}-backend dev # \u542F\u52A8\u540E\u7AEF`);
|
|
306
|
+
console.log(` 6. pnpm --filter ${name}-frontend dev # \u542F\u52A8\u524D\u7AEF`);
|
|
300
307
|
console.log(`
|
|
301
|
-
${chalk2.
|
|
308
|
+
${chalk2.yellow("\u26A0 \u9996\u6B21\u5B89\u88C5\u8BF7\u4F7F\u7528 --no-frozen-lockfile\uFF0C\u5426\u5219\u4F1A\u56E0\u7F3A\u5C11 lock \u6587\u4EF6\u62A5\u9519")}`);
|
|
309
|
+
console.log(`${chalk2.gray("\u{1F4A1} \u6DFB\u52A0\u6269\u5C55\u6A21\u5757: \u5728 backend/src/app.modules.ts \u4E2D\u5F15\u5165\u6269\u5C55 Module")}`);
|
|
302
310
|
console.log(`${chalk2.gray("\u{1F4A1} \u6DFB\u52A0\u4E1A\u52A1\u6A21\u5757: \u5728 backend/src/modules/ \u4E0B\u521B\u5EFA\u65B0\u7684 NestJS \u6A21\u5757")}`);
|
|
303
311
|
});
|
|
304
312
|
|
|
@@ -12,17 +12,22 @@
|
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
14
|
"@nestjs/common": "catalog:",
|
|
15
|
+
"@nestjs/config": "catalog:",
|
|
15
16
|
"@nestjs/core": "catalog:",
|
|
17
|
+
"@nestjs/jwt": "catalog:",
|
|
16
18
|
"@nestjs/platform-express": "catalog:",
|
|
17
|
-
"@nestjs/typeorm": "catalog:",
|
|
18
19
|
"@nestjs/swagger": "catalog:",
|
|
19
|
-
"typeorm": "catalog:",
|
|
20
|
+
"@nestjs/typeorm": "catalog:",
|
|
21
|
+
"bcryptjs": "catalog:",
|
|
20
22
|
"class-transformer": "catalog:",
|
|
21
23
|
"class-validator": "catalog:",
|
|
24
|
+
"dotenv": "catalog:",
|
|
25
|
+
"multer": "catalog:",
|
|
26
|
+
"mysql2": "catalog:",
|
|
27
|
+
"redis": "catalog:",
|
|
22
28
|
"reflect-metadata": "catalog:",
|
|
23
29
|
"rxjs": "catalog:",
|
|
24
|
-
"
|
|
25
|
-
"dotenv": "catalog:",
|
|
30
|
+
"typeorm": "catalog:",
|
|
26
31
|
"moyan-mfw-base": "^1.0.0",
|
|
27
32
|
"moyan-mfw-extension-ad": "^0.1.0",
|
|
28
33
|
"{{name}}-shared": "workspace:*"
|
|
@@ -30,8 +35,12 @@
|
|
|
30
35
|
"devDependencies": {
|
|
31
36
|
"@nestjs/cli": "catalog:",
|
|
32
37
|
"@nestjs/schematics": "catalog:",
|
|
33
|
-
"
|
|
38
|
+
"@types/bcryptjs": "catalog:",
|
|
39
|
+
"@types/express": "catalog:",
|
|
40
|
+
"@types/multer": "catalog:",
|
|
41
|
+
"@types/node": "catalog:",
|
|
34
42
|
"ts-node": "catalog:",
|
|
35
|
-
"tsconfig-paths": "catalog:"
|
|
43
|
+
"tsconfig-paths": "catalog:",
|
|
44
|
+
"typescript": "catalog:"
|
|
36
45
|
}
|
|
37
46
|
}
|
|
@@ -1,35 +1,394 @@
|
|
|
1
1
|
<!doctype html>
|
|
2
|
-
<html lang="
|
|
2
|
+
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
6
|
<title>{{displayName}}</title>
|
|
7
|
+
<script>
|
|
8
|
+
(function() {
|
|
9
|
+
try {
|
|
10
|
+
var raw = localStorage.getItem('mfw:base-frontend:layout-preferences');
|
|
11
|
+
if (raw) {
|
|
12
|
+
var prefs = JSON.parse(raw);
|
|
13
|
+
if (prefs && prefs.styleConfig) {
|
|
14
|
+
var styleConfig = prefs.styleConfig;
|
|
15
|
+
if (styleConfig.colorMode === 'dark') {
|
|
16
|
+
document.documentElement.classList.add('dark');
|
|
17
|
+
var placeholder = document.getElementById('loading-placeholder');
|
|
18
|
+
if (placeholder) {
|
|
19
|
+
placeholder.setAttribute('data-dark', 'true');
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
var themeThemes = {
|
|
23
|
+
default: { primary: '#409eff', success: '#67c23a', warning: '#e6a23c', danger: '#f56c6c', info: '#909399' },
|
|
24
|
+
ocean: { primary: '#00a8cc', success: '#52c41a', warning: '#faad14', danger: '#ff4d4f', info: '#8c8c8c' },
|
|
25
|
+
graphite: { primary: '#5a5a5a', success: '#4a9c6d', warning: '#c9a227', danger: '#c45656', info: '#73767a' },
|
|
26
|
+
fintech: { primary: '#F59E0B', success: '#22C55E', warning: '#FBBF24', danger: '#EF4444', info: '#8B5CF6' },
|
|
27
|
+
tech: { primary: '#8B5CF6', success: '#10B981', warning: '#FBBF24', danger: '#F43F5E', info: '#6366F1' },
|
|
28
|
+
luxury: { primary: '#CA8A04', success: '#4ADE80', warning: '#FBBF24', danger: '#F87171', info: '#A8A29E' },
|
|
29
|
+
nature: { primary: '#059669', success: '#22C55E', warning: '#FBBF24', danger: '#EF4444', info: '#14B8A6' },
|
|
30
|
+
aurora: { primary: '#7c3aed', success: '#10b981', warning: '#f59e0b', danger: '#ef4444', info: '#6b7280', gradient: 'linear-gradient(135deg, #3b82f6 0%, #7c3aed 50%, #ec4899 100%)' },
|
|
31
|
+
sunset: { primary: '#f97316', success: '#22c55e', warning: '#eab308', danger: '#dc2626', info: '#78716c', gradient: 'linear-gradient(135deg, #fbbf24 0%, #f97316 50%, #dc2626 100%)' }
|
|
32
|
+
};
|
|
33
|
+
var themeName = styleConfig.themePackage || 'default';
|
|
34
|
+
var colors = themeThemes[themeName] || themeThemes['default'];
|
|
35
|
+
if (colors) {
|
|
36
|
+
var root = document.documentElement;
|
|
37
|
+
function hexToRgb(hex) {
|
|
38
|
+
var c = hex.replace('#', '');
|
|
39
|
+
return [parseInt(c.substring(0,2),16), parseInt(c.substring(2,4),16), parseInt(c.substring(4,6),16)];
|
|
40
|
+
}
|
|
41
|
+
function rgbToHex(r, g, b) {
|
|
42
|
+
var h = function(n) { var s = Math.round(Math.max(0,Math.min(255,n))).toString(16); return s.length===1?'0'+s:s; };
|
|
43
|
+
return '#'+h(r)+h(g)+h(b);
|
|
44
|
+
}
|
|
45
|
+
function mixWhite(color, level) {
|
|
46
|
+
var rgb = hexToRgb(color); var ratio = level / 10;
|
|
47
|
+
return rgbToHex(Math.round(255*ratio+rgb[0]*(1-ratio)), Math.round(255*ratio+rgb[1]*(1-ratio)), Math.round(255*ratio+rgb[2]*(1-ratio)));
|
|
48
|
+
}
|
|
49
|
+
function mixBlack(color, level) {
|
|
50
|
+
var rgb = hexToRgb(color); var ratio = level / 10;
|
|
51
|
+
return rgbToHex(Math.round(rgb[0]*(1-ratio)), Math.round(rgb[1]*(1-ratio)), Math.round(rgb[2]*(1-ratio)));
|
|
52
|
+
}
|
|
53
|
+
var lightLevels = [3, 5, 7, 8, 9];
|
|
54
|
+
var darkLevels = [2];
|
|
55
|
+
Object.keys(colors).forEach(function(key) {
|
|
56
|
+
var value = colors[key];
|
|
57
|
+
if (key === 'gradient') {
|
|
58
|
+
root.style.setProperty('--el-color-primary-gradient', value);
|
|
59
|
+
root.style.setProperty('--mfw-gradient-primary', value);
|
|
60
|
+
root.classList.add('mfw-theme-gradient');
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
root.style.setProperty('--el-color-' + key, value);
|
|
64
|
+
lightLevels.forEach(function(level) {
|
|
65
|
+
root.style.setProperty('--el-color-' + key + '-light-' + level, mixWhite(value, level));
|
|
66
|
+
});
|
|
67
|
+
darkLevels.forEach(function(level) {
|
|
68
|
+
root.style.setProperty('--el-color-' + key + '-dark-' + level, mixBlack(value, level));
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
} catch (e) {
|
|
75
|
+
console.warn('[Loading] Failed to read preferences:', e);
|
|
76
|
+
}
|
|
77
|
+
})();
|
|
78
|
+
</script>
|
|
7
79
|
<style>
|
|
8
|
-
* {
|
|
80
|
+
* {
|
|
81
|
+
margin: 0;
|
|
82
|
+
padding: 0;
|
|
83
|
+
box-sizing: border-box;
|
|
84
|
+
}
|
|
85
|
+
|
|
9
86
|
#loading-placeholder {
|
|
10
|
-
position: fixed;
|
|
11
|
-
|
|
87
|
+
position: fixed;
|
|
88
|
+
top: 0;
|
|
89
|
+
left: 0;
|
|
90
|
+
width: 100%;
|
|
91
|
+
height: 100%;
|
|
92
|
+
display: flex;
|
|
93
|
+
flex-direction: column;
|
|
94
|
+
align-items: center;
|
|
95
|
+
justify-content: center;
|
|
12
96
|
background: linear-gradient(135deg, #ffffff 0%, #f8fafc 50%, #ffffff 100%);
|
|
13
|
-
z-index: 9999;
|
|
97
|
+
z-index: 9999;
|
|
98
|
+
transition: opacity 0.5s ease, visibility 0.5s ease;
|
|
99
|
+
overflow: hidden;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
#loading-placeholder[data-dark="true"] {
|
|
103
|
+
background: linear-gradient(135deg, #0f172a 0%, #1e293b 50%, #0f172a 100%);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
#loading-placeholder.hidden {
|
|
107
|
+
opacity: 0;
|
|
108
|
+
visibility: hidden;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.loading-particles {
|
|
112
|
+
position: absolute;
|
|
113
|
+
width: 100%;
|
|
114
|
+
height: 100%;
|
|
115
|
+
overflow: hidden;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.particle {
|
|
119
|
+
position: absolute;
|
|
120
|
+
width: 4px;
|
|
121
|
+
height: 4px;
|
|
122
|
+
background: rgba(59, 130, 246, 0.4);
|
|
123
|
+
border-radius: 50%;
|
|
124
|
+
animation: float-particle linear infinite;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
#loading-placeholder[data-dark="true"] .particle {
|
|
128
|
+
background: rgba(59, 130, 246, 0.6);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.particle:nth-child(1) { left: 10%; animation-duration: 8s; animation-delay: 0s; }
|
|
132
|
+
.particle:nth-child(2) { left: 20%; animation-duration: 10s; animation-delay: 1s; }
|
|
133
|
+
.particle:nth-child(3) { left: 30%; animation-duration: 7s; animation-delay: 2s; }
|
|
134
|
+
.particle:nth-child(4) { left: 40%; animation-duration: 9s; animation-delay: 0.5s; }
|
|
135
|
+
.particle:nth-child(5) { left: 50%; animation-duration: 11s; animation-delay: 1.5s; }
|
|
136
|
+
.particle:nth-child(6) { left: 60%; animation-duration: 8s; animation-delay: 3s; }
|
|
137
|
+
.particle:nth-child(7) { left: 70%; animation-duration: 10s; animation-delay: 2.5s; }
|
|
138
|
+
.particle:nth-child(8) { left: 80%; animation-duration: 7s; animation-delay: 0.8s; }
|
|
139
|
+
.particle:nth-child(9) { left: 90%; animation-duration: 9s; animation-delay: 1.2s; }
|
|
140
|
+
.particle:nth-child(10) { left: 15%; animation-duration: 12s; animation-delay: 2.2s; }
|
|
141
|
+
.particle:nth-child(11) { left: 25%; animation-duration: 8s; animation-delay: 0.3s; }
|
|
142
|
+
.particle:nth-child(12) { left: 35%; animation-duration: 10s; animation-delay: 1.8s; }
|
|
143
|
+
.particle:nth-child(13) { left: 45%; animation-duration: 7s; animation-delay: 3.5s; }
|
|
144
|
+
.particle:nth-child(14) { left: 55%; animation-duration: 9s; animation-delay: 0.7s; }
|
|
145
|
+
.particle:nth-child(15) { left: 65%; animation-duration: 11s; animation-delay: 2.8s; }
|
|
146
|
+
.particle:nth-child(16) { left: 75%; animation-duration: 8s; animation-delay: 1.1s; }
|
|
147
|
+
.particle:nth-child(17) { left: 85%; animation-duration: 10s; animation-delay: 3.2s; }
|
|
148
|
+
.particle:nth-child(18) { left: 95%; animation-duration: 7s; animation-delay: 0.4s; }
|
|
149
|
+
|
|
150
|
+
@keyframes float-particle {
|
|
151
|
+
0% {
|
|
152
|
+
transform: translateY(100vh) scale(0);
|
|
153
|
+
opacity: 0;
|
|
154
|
+
}
|
|
155
|
+
10% {
|
|
156
|
+
opacity: 1;
|
|
157
|
+
}
|
|
158
|
+
90% {
|
|
159
|
+
opacity: 1;
|
|
160
|
+
}
|
|
161
|
+
100% {
|
|
162
|
+
transform: translateY(-100px) scale(1);
|
|
163
|
+
opacity: 0;
|
|
164
|
+
}
|
|
14
165
|
}
|
|
15
|
-
|
|
16
|
-
.
|
|
17
|
-
|
|
18
|
-
|
|
166
|
+
|
|
167
|
+
.loading-core {
|
|
168
|
+
position: relative;
|
|
169
|
+
width: 120px;
|
|
170
|
+
height: 120px;
|
|
171
|
+
display: flex;
|
|
172
|
+
align-items: center;
|
|
173
|
+
justify-content: center;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
.loading-ring {
|
|
177
|
+
position: absolute;
|
|
178
|
+
border-radius: 50%;
|
|
179
|
+
border: 2px solid transparent;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.loading-ring-1 {
|
|
183
|
+
width: 120px;
|
|
184
|
+
height: 120px;
|
|
19
185
|
border-top-color: #3b82f6;
|
|
186
|
+
border-right-color: #3b82f6;
|
|
187
|
+
animation: spin-clockwise 1.5s linear infinite;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
.loading-ring-2 {
|
|
191
|
+
width: 90px;
|
|
192
|
+
height: 90px;
|
|
193
|
+
border-bottom-color: #8b5cf6;
|
|
194
|
+
border-left-color: #8b5cf6;
|
|
195
|
+
animation: spin-counter-clockwise 1.2s linear infinite;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
.loading-ring-3 {
|
|
199
|
+
width: 60px;
|
|
200
|
+
height: 60px;
|
|
201
|
+
border-top-color: #06b6d4;
|
|
202
|
+
border-right-color: #06b6d4;
|
|
203
|
+
animation: spin-clockwise 0.9s linear infinite;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
.loading-center {
|
|
207
|
+
width: 30px;
|
|
208
|
+
height: 30px;
|
|
209
|
+
background: linear-gradient(135deg, #3b82f6, #8b5cf6, #06b6d4);
|
|
210
|
+
border-radius: 50%;
|
|
211
|
+
animation: pulse-glow 1.5s ease-in-out infinite;
|
|
212
|
+
box-shadow: 0 0 20px rgba(59, 130, 246, 0.5),
|
|
213
|
+
0 0 40px rgba(139, 92, 246, 0.3),
|
|
214
|
+
0 0 60px rgba(6, 182, 212, 0.2);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
@keyframes spin-clockwise {
|
|
218
|
+
to { transform: rotate(360deg); }
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
@keyframes spin-counter-clockwise {
|
|
222
|
+
to { transform: rotate(-360deg); }
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
@keyframes pulse-glow {
|
|
226
|
+
0%, 100% {
|
|
227
|
+
transform: scale(0.8);
|
|
228
|
+
opacity: 0.8;
|
|
229
|
+
}
|
|
230
|
+
50% {
|
|
231
|
+
transform: scale(1.2);
|
|
232
|
+
opacity: 1;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
.loading-text-container {
|
|
237
|
+
margin-top: 40px;
|
|
238
|
+
text-align: center;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
.loading-text {
|
|
242
|
+
font-family: 'Segoe UI', system-ui, -apple-system, sans-serif;
|
|
243
|
+
font-size: 16px;
|
|
244
|
+
font-weight: 500;
|
|
245
|
+
color: #1e293b;
|
|
246
|
+
letter-spacing: 2px;
|
|
247
|
+
animation: text-fade 2s ease-in-out infinite;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
#loading-placeholder[data-dark="true"] .loading-text {
|
|
251
|
+
color: #e2e8f0;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
.loading-dots {
|
|
255
|
+
display: inline-block;
|
|
256
|
+
margin-left: 4px;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.loading-dots span {
|
|
260
|
+
display: inline-block;
|
|
261
|
+
width: 6px;
|
|
262
|
+
height: 6px;
|
|
263
|
+
margin: 0 2px;
|
|
264
|
+
background: #3b82f6;
|
|
20
265
|
border-radius: 50%;
|
|
21
|
-
animation:
|
|
266
|
+
animation: dot-bounce 1.4s ease-in-out infinite;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
.loading-dots span:nth-child(1) { animation-delay: 0s; }
|
|
270
|
+
.loading-dots span:nth-child(2) { animation-delay: 0.2s; }
|
|
271
|
+
.loading-dots span:nth-child(3) { animation-delay: 0.4s; }
|
|
272
|
+
|
|
273
|
+
@keyframes text-fade {
|
|
274
|
+
0%, 100% { opacity: 0.6; }
|
|
275
|
+
50% { opacity: 1; }
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
@keyframes dot-bounce {
|
|
279
|
+
0%, 80%, 100% {
|
|
280
|
+
transform: translateY(0);
|
|
281
|
+
}
|
|
282
|
+
40% {
|
|
283
|
+
transform: translateY(-10px);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.loading-progress {
|
|
288
|
+
margin-top: 30px;
|
|
289
|
+
width: 200px;
|
|
290
|
+
height: 3px;
|
|
291
|
+
background: rgba(0, 0, 0, 0.1);
|
|
292
|
+
border-radius: 2px;
|
|
293
|
+
overflow: hidden;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
#loading-placeholder[data-dark="true"] .loading-progress {
|
|
297
|
+
background: rgba(255, 255, 255, 0.1);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
.loading-progress-bar {
|
|
301
|
+
height: 100%;
|
|
302
|
+
width: 0%;
|
|
303
|
+
background: linear-gradient(90deg, #3b82f6, #8b5cf6, #06b6d4);
|
|
304
|
+
border-radius: 2px;
|
|
305
|
+
animation: progress-fill 2s ease-in-out infinite;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
@keyframes progress-fill {
|
|
309
|
+
0% { width: 0%; }
|
|
310
|
+
50% { width: 70%; }
|
|
311
|
+
100% { width: 100%; }
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
@media (prefers-reduced-motion: reduce) {
|
|
315
|
+
.particle,
|
|
316
|
+
.loading-ring,
|
|
317
|
+
.loading-center,
|
|
318
|
+
.loading-text,
|
|
319
|
+
.loading-dots span,
|
|
320
|
+
.loading-progress-bar {
|
|
321
|
+
animation: none;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
.loading-center {
|
|
325
|
+
transform: scale(1);
|
|
326
|
+
opacity: 1;
|
|
327
|
+
}
|
|
22
328
|
}
|
|
23
|
-
@keyframes spin { to { transform: rotate(360deg); } }
|
|
24
|
-
.loading-text { margin-top: 16px; font-family: system-ui, sans-serif; font-size: 14px; color: #6b7280; }
|
|
25
329
|
</style>
|
|
26
330
|
</head>
|
|
27
331
|
<body>
|
|
28
332
|
<div id="app"></div>
|
|
29
333
|
<div id="loading-placeholder">
|
|
30
|
-
<div class="
|
|
31
|
-
|
|
334
|
+
<div class="loading-particles">
|
|
335
|
+
<div class="particle"></div>
|
|
336
|
+
<div class="particle"></div>
|
|
337
|
+
<div class="particle"></div>
|
|
338
|
+
<div class="particle"></div>
|
|
339
|
+
<div class="particle"></div>
|
|
340
|
+
<div class="particle"></div>
|
|
341
|
+
<div class="particle"></div>
|
|
342
|
+
<div class="particle"></div>
|
|
343
|
+
<div class="particle"></div>
|
|
344
|
+
<div class="particle"></div>
|
|
345
|
+
<div class="particle"></div>
|
|
346
|
+
<div class="particle"></div>
|
|
347
|
+
<div class="particle"></div>
|
|
348
|
+
<div class="particle"></div>
|
|
349
|
+
<div class="particle"></div>
|
|
350
|
+
<div class="particle"></div>
|
|
351
|
+
<div class="particle"></div>
|
|
352
|
+
<div class="particle"></div>
|
|
353
|
+
</div>
|
|
354
|
+
<div class="loading-core">
|
|
355
|
+
<div class="loading-ring loading-ring-1"></div>
|
|
356
|
+
<div class="loading-ring loading-ring-2"></div>
|
|
357
|
+
<div class="loading-ring loading-ring-3"></div>
|
|
358
|
+
<div class="loading-center"></div>
|
|
359
|
+
</div>
|
|
360
|
+
<div class="loading-text-container">
|
|
361
|
+
<div class="loading-text">
|
|
362
|
+
正在加载
|
|
363
|
+
<span class="loading-dots">
|
|
364
|
+
<span></span>
|
|
365
|
+
<span></span>
|
|
366
|
+
<span></span>
|
|
367
|
+
</span>
|
|
368
|
+
</div>
|
|
369
|
+
</div>
|
|
370
|
+
<div class="loading-progress">
|
|
371
|
+
<div class="loading-progress-bar"></div>
|
|
372
|
+
</div>
|
|
32
373
|
</div>
|
|
374
|
+
<script>
|
|
375
|
+
(function() {
|
|
376
|
+
try {
|
|
377
|
+
var raw = localStorage.getItem('mfw:base-frontend:layout-preferences');
|
|
378
|
+
if (raw) {
|
|
379
|
+
var prefs = JSON.parse(raw);
|
|
380
|
+
if (prefs && prefs.styleConfig && prefs.styleConfig.colorMode === 'dark') {
|
|
381
|
+
var placeholder = document.getElementById('loading-placeholder');
|
|
382
|
+
if (placeholder) {
|
|
383
|
+
placeholder.setAttribute('data-dark', 'true');
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
} catch (e) {
|
|
388
|
+
console.warn('[Loading] Failed to read color mode preference:', e);
|
|
389
|
+
}
|
|
390
|
+
})();
|
|
391
|
+
</script>
|
|
33
392
|
<script type="module" src="/src/main.ts"></script>
|
|
34
393
|
</body>
|
|
35
394
|
</html>
|
|
@@ -10,23 +10,27 @@
|
|
|
10
10
|
"typecheck": "vue-tsc --noEmit -p tsconfig.json"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"vue": "catalog:",
|
|
14
|
-
"vue-router": "catalog:",
|
|
15
|
-
"element-plus": "catalog:",
|
|
16
13
|
"@element-plus/icons-vue": "catalog:",
|
|
17
|
-
"pinia": "catalog:",
|
|
18
14
|
"@vueuse/core": "catalog:",
|
|
19
15
|
"axios": "catalog:",
|
|
16
|
+
"element-plus": "catalog:",
|
|
17
|
+
"md-editor-v3": "catalog:",
|
|
20
18
|
"moyan-mfw-base": "^1.0.0",
|
|
21
19
|
"moyan-mfw-extension-ad": "^0.1.0",
|
|
20
|
+
"pinia": "catalog:",
|
|
21
|
+
"quill": "catalog:",
|
|
22
|
+
"vue": "catalog:",
|
|
23
|
+
"vue-advanced-cropper": "catalog:",
|
|
24
|
+
"vue-router": "catalog:",
|
|
22
25
|
"{{name}}-shared": "workspace:*"
|
|
23
26
|
},
|
|
24
27
|
"devDependencies": {
|
|
25
|
-
"
|
|
28
|
+
"@types/node": "catalog:",
|
|
26
29
|
"@vitejs/plugin-vue": "catalog:",
|
|
27
30
|
"@vitejs/plugin-vue-jsx": "catalog:",
|
|
28
|
-
"vue-tsc": "catalog:",
|
|
29
31
|
"sass": "catalog:",
|
|
30
|
-
"typescript": "catalog:"
|
|
32
|
+
"typescript": "catalog:",
|
|
33
|
+
"vite": "catalog:",
|
|
34
|
+
"vue-tsc": "catalog:"
|
|
31
35
|
}
|
|
32
36
|
}
|
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
import { createBaseAdminApp
|
|
1
|
+
import { createBaseAdminApp } from 'moyan-mfw-base/frontend'
|
|
2
2
|
import { businessRoutes } from './router'
|
|
3
|
-
import { adRoutes } from 'moyan-mfw-extension-ad/frontend'
|
|
4
|
-
import { AD_EXTENSION_PERMISSION_VALUES } from 'moyan-mfw-extension-ad/shared'
|
|
5
3
|
import './permissions'
|
|
6
4
|
|
|
7
|
-
registerPermissionValues([...AD_EXTENSION_PERMISSION_VALUES])
|
|
8
|
-
|
|
9
5
|
const admin = createBaseAdminApp({
|
|
10
6
|
title: '{{displayName}}',
|
|
11
|
-
routes: [...businessRoutes
|
|
7
|
+
routes: [...businessRoutes],
|
|
12
8
|
layout: {
|
|
13
9
|
layoutMode: 'dual',
|
|
14
10
|
showTabs: true,
|
|
@@ -6,22 +6,32 @@ catalog:
|
|
|
6
6
|
'@element-plus/icons-vue': ^2.3.2
|
|
7
7
|
'@nestjs/cli': ^10.4.9
|
|
8
8
|
'@nestjs/common': ^10.4.22
|
|
9
|
+
'@nestjs/config': ^3.3.0
|
|
9
10
|
'@nestjs/core': ^10.4.22
|
|
11
|
+
'@nestjs/jwt': ^10.2.0
|
|
10
12
|
'@nestjs/platform-express': ^10.4.22
|
|
11
13
|
'@nestjs/schematics': ^10.1.4
|
|
12
14
|
'@nestjs/swagger': ^7.4.2
|
|
13
15
|
'@nestjs/typeorm': ^10.0.2
|
|
14
|
-
'@types/
|
|
16
|
+
'@types/bcryptjs': ^2.4.6
|
|
17
|
+
'@types/express': ^4.17.25
|
|
18
|
+
'@types/multer': ^2.1.0
|
|
19
|
+
'@types/node': ^22.19.15
|
|
15
20
|
'@vitejs/plugin-vue': ^5.2.4
|
|
16
21
|
'@vitejs/plugin-vue-jsx': ^5.1.5
|
|
17
22
|
'@vueuse/core': ^14.2.1
|
|
18
23
|
axios: ^1.6.5
|
|
24
|
+
bcryptjs: ^2.4.3
|
|
19
25
|
class-transformer: ^0.5.1
|
|
20
26
|
class-validator: ^0.14.4
|
|
21
27
|
dotenv: ^17.3.1
|
|
22
28
|
element-plus: ^2.13.5
|
|
29
|
+
md-editor-v3: ^6.4.2
|
|
30
|
+
multer: ^2.1.1
|
|
23
31
|
mysql2: ^3.11.5
|
|
24
32
|
pinia: ^2.3.0
|
|
33
|
+
quill: ^2.0.3
|
|
34
|
+
redis: ^4.7.0
|
|
25
35
|
reflect-metadata: ^0.1.14
|
|
26
36
|
rxjs: ^7.8.2
|
|
27
37
|
sass: ^1.70.0
|
|
@@ -31,5 +41,6 @@ catalog:
|
|
|
31
41
|
typescript: ^5.7.3
|
|
32
42
|
vite: ^5.4.21
|
|
33
43
|
vue: ^3.5.30
|
|
44
|
+
vue-advanced-cropper: ^2.8.8
|
|
34
45
|
vue-router: ^4.5.1
|
|
35
46
|
vue-tsc: ^2.2.12
|
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
# {{displayName}}
|
|
2
|
-
|
|
3
|
-
{{description}}
|
|
4
|
-
|
|
5
|
-
## 快速开始
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
# 安装依赖
|
|
9
|
-
pnpm install
|
|
10
|
-
|
|
11
|
-
# 启动后端开发服务器
|
|
12
|
-
pnpm dev:backend
|
|
13
|
-
|
|
14
|
-
# 启动前端开发服务器
|
|
15
|
-
pnpm dev:frontend
|
|
16
|
-
```
|
|
17
|
-
|
|
18
|
-
## 目录结构
|
|
19
|
-
|
|
20
|
-
```
|
|
21
|
-
extension-{{name}}/
|
|
22
|
-
├── src/
|
|
23
|
-
│ ├── backend/ # NestJS 后端
|
|
24
|
-
│ ├── frontend/ # Vue3 前端
|
|
25
|
-
│ └── shared/ # 共享类型与常量
|
|
26
|
-
├── database/migrations/
|
|
27
|
-
```
|
|
1
|
+
# {{displayName}}
|
|
2
|
+
|
|
3
|
+
{{description}}
|
|
4
|
+
|
|
5
|
+
## 快速开始
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# 安装依赖
|
|
9
|
+
pnpm install
|
|
10
|
+
|
|
11
|
+
# 启动后端开发服务器
|
|
12
|
+
pnpm dev:backend
|
|
13
|
+
|
|
14
|
+
# 启动前端开发服务器
|
|
15
|
+
pnpm dev:frontend
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## 目录结构
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
extension-{{name}}/
|
|
22
|
+
├── src/
|
|
23
|
+
│ ├── backend/ # NestJS 后端
|
|
24
|
+
│ ├── frontend/ # Vue3 前端
|
|
25
|
+
│ └── shared/ # 共享类型与常量
|
|
26
|
+
├── database/migrations/
|
|
27
|
+
```
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
DB_HOST=localhost
|
|
2
|
-
DB_PORT=3306
|
|
3
|
-
DB_USERNAME=root
|
|
4
|
-
DB_PASSWORD=root
|
|
5
|
-
DB_NAME=moyan_{{name}}
|
|
6
|
-
REDIS_HOST=localhost
|
|
7
|
-
REDIS_PORT=6379
|
|
8
|
-
JWT_SECRET=change-me-{{name}}-jwt-secret
|
|
9
|
-
JWT_EXPIRES_IN=7d
|
|
10
|
-
PORT=3001
|
|
1
|
+
DB_HOST=localhost
|
|
2
|
+
DB_PORT=3306
|
|
3
|
+
DB_USERNAME=root
|
|
4
|
+
DB_PASSWORD=root
|
|
5
|
+
DB_NAME=moyan_{{name}}
|
|
6
|
+
REDIS_HOST=localhost
|
|
7
|
+
REDIS_PORT=6379
|
|
8
|
+
JWT_SECRET=change-me-{{name}}-jwt-secret
|
|
9
|
+
JWT_EXPIRES_IN=7d
|
|
10
|
+
PORT=3001
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './{{name}}.module'
|
|
1
|
+
export * from './{{name}}.module'
|
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview {{displayName}}扩展包后端独立启动入口
|
|
3
|
-
*/
|
|
4
|
-
import { NestFactory } from '@nestjs/core'
|
|
5
|
-
import { {{pascalCase name}}Module } from './{{name}}.module'
|
|
6
|
-
import { createExtensionBackendApp } from 'moyan-mfw-base/backend'
|
|
7
|
-
|
|
8
|
-
async function bootstrap() {
|
|
9
|
-
const startTime = Date.now()
|
|
10
|
-
|
|
11
|
-
console.log('[{{pascalCase name}}] ====== Bootstrap Start ======')
|
|
12
|
-
console.log(`[{{pascalCase name}}] Node.js: ${process.version}`)
|
|
13
|
-
console.log(`[{{pascalCase name}}] ENV: ${process.env.NODE_ENV ?? 'development'}`)
|
|
14
|
-
console.log(`[{{pascalCase name}}] PORT: ${process.env.PORT ?? '3001 (default)'}`)
|
|
15
|
-
|
|
16
|
-
try {
|
|
17
|
-
const app = await createExtensionBackendApp({
|
|
18
|
-
name: '{{name}}',
|
|
19
|
-
module: {{pascalCase name}}Module,
|
|
20
|
-
})
|
|
21
|
-
|
|
22
|
-
const port = Number(process.env.PORT) || 3001
|
|
23
|
-
await app.listen(port)
|
|
24
|
-
|
|
25
|
-
const elapsed = ((Date.now() - startTime) / 1000).toFixed(2)
|
|
26
|
-
console.log(`\n[{{pascalCase name}}] ✅ Server listening on http://localhost:${port} (${elapsed}s)`)
|
|
27
|
-
} catch (error) {
|
|
28
|
-
console.error('\n[{{pascalCase name}}] ❌ Bootstrap failed:')
|
|
29
|
-
console.error(error)
|
|
30
|
-
process.exit(1)
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
bootstrap()
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview {{displayName}}扩展包后端独立启动入口
|
|
3
|
+
*/
|
|
4
|
+
import { NestFactory } from '@nestjs/core'
|
|
5
|
+
import { {{pascalCase name}}Module } from './{{name}}.module'
|
|
6
|
+
import { createExtensionBackendApp } from 'moyan-mfw-base/backend'
|
|
7
|
+
|
|
8
|
+
async function bootstrap() {
|
|
9
|
+
const startTime = Date.now()
|
|
10
|
+
|
|
11
|
+
console.log('[{{pascalCase name}}] ====== Bootstrap Start ======')
|
|
12
|
+
console.log(`[{{pascalCase name}}] Node.js: ${process.version}`)
|
|
13
|
+
console.log(`[{{pascalCase name}}] ENV: ${process.env.NODE_ENV ?? 'development'}`)
|
|
14
|
+
console.log(`[{{pascalCase name}}] PORT: ${process.env.PORT ?? '3001 (default)'}`)
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
const app = await createExtensionBackendApp({
|
|
18
|
+
name: '{{name}}',
|
|
19
|
+
module: {{pascalCase name}}Module,
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
const port = Number(process.env.PORT) || 3001
|
|
23
|
+
await app.listen(port)
|
|
24
|
+
|
|
25
|
+
const elapsed = ((Date.now() - startTime) / 1000).toFixed(2)
|
|
26
|
+
console.log(`\n[{{pascalCase name}}] ✅ Server listening on http://localhost:${port} (${elapsed}s)`)
|
|
27
|
+
} catch (error) {
|
|
28
|
+
console.error('\n[{{pascalCase name}}] ❌ Bootstrap failed:')
|
|
29
|
+
console.error(error)
|
|
30
|
+
process.exit(1)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
bootstrap()
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Module } from '@nestjs/common'
|
|
2
|
-
|
|
3
|
-
@Module({})
|
|
4
|
-
export class {{pascalCase name}}Module {}
|
|
1
|
+
import { Module } from '@nestjs/common'
|
|
2
|
+
|
|
3
|
+
@Module({})
|
|
4
|
+
export class {{pascalCase name}}Module {}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
// @ts-check
|
|
2
|
-
const { defineConfig } = require('moyan-api/config')
|
|
3
|
-
|
|
4
|
-
module.exports = defineConfig({
|
|
5
|
-
backendUrl: process.env.API_BASE_URL || 'http://localhost:3001',
|
|
6
|
-
outputDir: './src/apis',
|
|
7
|
-
namespace: '{{name}}',
|
|
8
|
-
})
|
|
1
|
+
// @ts-check
|
|
2
|
+
const { defineConfig } = require('moyan-api/config')
|
|
3
|
+
|
|
4
|
+
module.exports = defineConfig({
|
|
5
|
+
backendUrl: process.env.API_BASE_URL || 'http://localhost:3001',
|
|
6
|
+
outputDir: './src/apis',
|
|
7
|
+
namespace: '{{name}}',
|
|
8
|
+
})
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="zh-CN">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
-
<title>{{displayName}}</title>
|
|
7
|
-
</head>
|
|
8
|
-
<body>
|
|
9
|
-
<div id="app"></div>
|
|
10
|
-
<script type="module" src="/src/main.ts"></script>
|
|
11
|
-
</body>
|
|
12
|
-
</html>
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>{{displayName}}</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div id="app"></div>
|
|
10
|
+
<script type="module" src="/src/main.ts"></script>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
/// <reference types="vite/client" />
|
|
1
|
+
/// <reference types="vite/client" />
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview {{displayName}}扩展包前端入口
|
|
3
|
-
*/
|
|
4
|
-
import { buildExtensionRoutes } from 'moyan-mfw-base/frontend'
|
|
5
|
-
|
|
6
|
-
const allConfigs = import.meta.glob('./views/**/index.{ts,tsx}', {
|
|
7
|
-
eager: true,
|
|
8
|
-
import: 'default',
|
|
9
|
-
})
|
|
10
|
-
|
|
11
|
-
export const {{pascalCase name}}Routes = buildExtensionRoutes(allConfigs, '{{name}}', {
|
|
12
|
-
namespaceName: '{{displayName}}',
|
|
13
|
-
})
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview {{displayName}}扩展包前端入口
|
|
3
|
+
*/
|
|
4
|
+
import { buildExtensionRoutes } from 'moyan-mfw-base/frontend'
|
|
5
|
+
|
|
6
|
+
const allConfigs = import.meta.glob('./views/**/index.{ts,tsx}', {
|
|
7
|
+
eager: true,
|
|
8
|
+
import: 'default',
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
export const {{pascalCase name}}Routes = buildExtensionRoutes(allConfigs, '{{name}}', {
|
|
12
|
+
namespaceName: '{{displayName}}',
|
|
13
|
+
})
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview {{displayName}}扩展包前端自启动入口
|
|
3
|
-
*/
|
|
4
|
-
import 'moyan-mfw-base/frontend/styles/base-admin.scss'
|
|
5
|
-
import { createExtensionFrontendApp } from 'moyan-mfw-base/frontend'
|
|
6
|
-
import { {{pascalCase name}}Routes } from './index'
|
|
7
|
-
|
|
8
|
-
const app = createExtensionFrontendApp({
|
|
9
|
-
name: '{{displayName}}',
|
|
10
|
-
routes: {{pascalCase name}}Routes,
|
|
11
|
-
})
|
|
12
|
-
|
|
13
|
-
app.mount('#app')
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview {{displayName}}扩展包前端自启动入口
|
|
3
|
+
*/
|
|
4
|
+
import 'moyan-mfw-base/frontend/styles/base-admin.scss'
|
|
5
|
+
import { createExtensionFrontendApp } from 'moyan-mfw-base/frontend'
|
|
6
|
+
import { {{pascalCase name}}Routes } from './index'
|
|
7
|
+
|
|
8
|
+
const app = createExtensionFrontendApp({
|
|
9
|
+
name: '{{displayName}}',
|
|
10
|
+
routes: {{pascalCase name}}Routes,
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
app.mount('#app')
|
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
import { defineConfig } from 'vite';
|
|
2
|
-
import vue from '@vitejs/plugin-vue';
|
|
3
|
-
import vueJsx from '@vitejs/plugin-vue-jsx';
|
|
4
|
-
import { resolve } from 'path';
|
|
5
|
-
|
|
6
|
-
export default defineConfig({
|
|
7
|
-
root: '.',
|
|
8
|
-
plugins: [vue(), vueJsx()],
|
|
9
|
-
resolve: {
|
|
10
|
-
alias: {
|
|
11
|
-
'@': resolve(__dirname, 'src'),
|
|
12
|
-
'moyan-mfw-base/frontend/styles': resolve(__dirname, '../../../../base/src/frontend/src/styles'),
|
|
13
|
-
'moyan-mfw-base/frontend': resolve(__dirname, '../../../../base/src/frontend/src/index.ts'),
|
|
14
|
-
'moyan-mfw-base/shared': resolve(__dirname, '../../../../base/src/shared/src/index.ts'),
|
|
15
|
-
'moyan-mfw-extension-{{name}}/shared': resolve(__dirname, '../shared/src/index.ts'),
|
|
16
|
-
},
|
|
17
|
-
},
|
|
18
|
-
build: {
|
|
19
|
-
outDir: '../../dist/frontend',
|
|
20
|
-
lib: {
|
|
21
|
-
entry: resolve(__dirname, 'src/index.ts'),
|
|
22
|
-
formats: ['es'],
|
|
23
|
-
fileName: () => 'index.
|
|
24
|
-
},
|
|
25
|
-
rollupOptions: {
|
|
26
|
-
external: ['vue', 'vue-router', 'element-plus', '@element-plus/icons-vue', 'moyan-mfw-base/frontend', 'moyan-mfw-base/shared'],
|
|
27
|
-
output: { exports: 'named' },
|
|
28
|
-
},
|
|
29
|
-
},
|
|
30
|
-
});
|
|
1
|
+
import { defineConfig } from 'vite';
|
|
2
|
+
import vue from '@vitejs/plugin-vue';
|
|
3
|
+
import vueJsx from '@vitejs/plugin-vue-jsx';
|
|
4
|
+
import { resolve } from 'path';
|
|
5
|
+
|
|
6
|
+
export default defineConfig({
|
|
7
|
+
root: '.',
|
|
8
|
+
plugins: [vue(), vueJsx()],
|
|
9
|
+
resolve: {
|
|
10
|
+
alias: {
|
|
11
|
+
'@': resolve(__dirname, 'src'),
|
|
12
|
+
'moyan-mfw-base/frontend/styles': resolve(__dirname, '../../../../base/src/frontend/src/styles'),
|
|
13
|
+
'moyan-mfw-base/frontend': resolve(__dirname, '../../../../base/src/frontend/src/index.ts'),
|
|
14
|
+
'moyan-mfw-base/shared': resolve(__dirname, '../../../../base/src/shared/src/index.ts'),
|
|
15
|
+
'moyan-mfw-extension-{{name}}/shared': resolve(__dirname, '../shared/src/index.ts'),
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
build: {
|
|
19
|
+
outDir: '../../dist/frontend',
|
|
20
|
+
lib: {
|
|
21
|
+
entry: resolve(__dirname, 'src/index.ts'),
|
|
22
|
+
formats: ['es'],
|
|
23
|
+
fileName: () => 'index.mjs',
|
|
24
|
+
},
|
|
25
|
+
rollupOptions: {
|
|
26
|
+
external: ['vue', 'vue-router', 'element-plus', '@element-plus/icons-vue', 'moyan-mfw-base/frontend', 'moyan-mfw-base/shared'],
|
|
27
|
+
output: { exports: 'named' },
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"name": "moyan-mfw-extension-{{name}}", "version": "{{version}}", "description": "{{description}}", "private": true, "type": "module", "exports": {"./backend": {"import": "./src/backend/dist/index.js", "require": "./src/backend/dist/index.js", "types": "./src/backend/dist/index.d.ts"}, "./backend/*": {"import": "./src/backend/dist/*.js", "require": "./src/backend/dist/*", "types": "./src/backend/dist/*.d.ts"}, "./frontend": {"import": "./src/frontend/dist/index.mjs", "require": "./src/frontend/dist/index.
|
|
1
|
+
{"name": "moyan-mfw-extension-{{name}}", "version": "{{version}}", "description": "{{description}}", "private": true, "type": "module", "exports": {"./backend": {"import": "./src/backend/dist/index.js", "require": "./src/backend/dist/index.js", "types": "./src/backend/dist/index.d.ts"}, "./backend/*": {"import": "./src/backend/dist/*.js", "require": "./src/backend/dist/*", "types": "./src/backend/dist/*.d.ts"}, "./frontend": {"import": "./src/frontend/dist/index.mjs", "require": "./src/frontend/dist/index.mjs", "types": "./src/frontend/dist/index.d.ts"}, "./frontend/*": {"import": "./src/frontend/dist/*", "require": "./src/frontend/dist/*", "types": "./src/frontend/dist/*.d.ts"}, "./shared": {"import": "./src/shared/dist/index.js", "require": "./src/shared/dist/index.js", "types": "./src/shared/dist/index.d.ts"}, "./shared/*": {"import": "./src/shared/dist/*", "require": "./src/shared/dist/*", "types": "./src/shared/dist/*.d.ts"}}, "typesVersions": {"*": {"*": ["./src/*/dist/*.d.ts", "./src/*/dist/index.d.ts"]}}, "scripts": {"build:shared": "pnpm --filter @internal/{{name}}-shared build", "build:backend": "pnpm --filter moyan-mfw-base run build:shared && pnpm --filter moyan-mfw-base run build:backend && pnpm --filter @internal/{{name}}-backend build", "build:frontend": "pnpm --filter @internal/{{name}}-frontend build", "build": "pnpm run build:shared && pnpm run build:backend && pnpm run build:frontend", "dev:backend": "pnpm --filter @internal/{{name}}-backend dev", "dev:frontend": "pnpm --filter @internal/{{name}}-frontend dev", "typecheck:shared": "pnpm --filter @internal/{{name}}-shared typecheck", "typecheck:backend": "pnpm --filter @internal/{{name}}-backend typecheck", "typecheck:frontend": "pnpm --filter @internal/{{name}}-frontend typecheck", "typecheck": "pnpm run typecheck:shared && pnpm run typecheck:backend && pnpm run typecheck:frontend"}, "devDependencies": {"@internal/{{name}}-backend": "workspace:*", "@internal/{{name}}-frontend": "workspace:*", "@internal/{{name}}-shared": "workspace:*", "moyan-mfw-base": "workspace:*", "typescript": "catalog:"}}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview {{displayName}}常量定义
|
|
3
|
-
*/
|
|
4
|
-
export const LINK_TYPE = {
|
|
5
|
-
IMAGE: 'image',
|
|
6
|
-
URL: 'url',
|
|
7
|
-
} as const
|
|
8
|
-
export type LinkType = (typeof LINK_TYPE)[keyof typeof LINK_TYPE]
|
|
9
|
-
export const LINK_TYPE_LABELS: Record<LinkType, string> = {
|
|
10
|
-
image: '图片',
|
|
11
|
-
url: '链接',
|
|
12
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview {{displayName}}常量定义
|
|
3
|
+
*/
|
|
4
|
+
export const LINK_TYPE = {
|
|
5
|
+
IMAGE: 'image',
|
|
6
|
+
URL: 'url',
|
|
7
|
+
} as const
|
|
8
|
+
export type LinkType = (typeof LINK_TYPE)[keyof typeof LINK_TYPE]
|
|
9
|
+
export const LINK_TYPE_LABELS: Record<LinkType, string> = {
|
|
10
|
+
image: '图片',
|
|
11
|
+
url: '链接',
|
|
12
|
+
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview {{displayName}}字典定义
|
|
3
|
-
*/
|
|
4
|
-
import { DictMeta } from 'moyan-mfw-base/shared'
|
|
5
|
-
|
|
6
|
-
export const {{pascalCase name}}Dict: DictMeta[] = [
|
|
7
|
-
// TODO: 添加字典定义
|
|
8
|
-
]
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview {{displayName}}字典定义
|
|
3
|
+
*/
|
|
4
|
+
import { DictMeta } from 'moyan-mfw-base/shared'
|
|
5
|
+
|
|
6
|
+
export const {{pascalCase name}}Dict: DictMeta[] = [
|
|
7
|
+
// TODO: 添加字典定义
|
|
8
|
+
]
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @fileoverview {{displayName}}共享类型定义
|
|
3
|
-
*/
|
|
4
|
-
export type { LinkType } from './constants'
|
|
5
|
-
export { LINK_TYPE, LINK_TYPE_LABELS } from './constants'
|
|
6
|
-
export type { {{pascalCase name}}ItemType } from './types'
|
|
7
|
-
export { {{pascalCase name}}Dict } from './dict'
|
|
8
|
-
export { {{pascalCaseUpper name}}_PATHS } from './paths'
|
|
9
|
-
export { {{pascalCaseUpper name}}_EXTENSION_PERMISSION_VALUES } from './permission-values'
|
|
10
|
-
export type { {{pascalCase name}}PermissionName } from './permission-values'
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview {{displayName}}共享类型定义
|
|
3
|
+
*/
|
|
4
|
+
export type { LinkType } from './constants'
|
|
5
|
+
export { LINK_TYPE, LINK_TYPE_LABELS } from './constants'
|
|
6
|
+
export type { {{pascalCase name}}ItemType } from './types'
|
|
7
|
+
export { {{pascalCase name}}Dict } from './dict'
|
|
8
|
+
export { {{pascalCaseUpper name}}_PATHS } from './paths'
|
|
9
|
+
export { {{pascalCaseUpper name}}_EXTENSION_PERMISSION_VALUES } from './permission-values'
|
|
10
|
+
export type { {{pascalCase name}}PermissionName } from './permission-values'
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/** {{displayName}} 路径常量 */
|
|
2
|
-
export const {{pascalCaseUpper name}}_PATHS = {
|
|
3
|
-
LIST: '/{{name}}',
|
|
4
|
-
DETAIL: '/{{name}}/:id',
|
|
5
|
-
} as const
|
|
1
|
+
/** {{displayName}} 路径常量 */
|
|
2
|
+
export const {{pascalCaseUpper name}}_PATHS = {
|
|
3
|
+
LIST: '/{{name}}',
|
|
4
|
+
DETAIL: '/{{name}}/:id',
|
|
5
|
+
} as const
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
/** {{displayName}} 权限标签 */
|
|
2
|
-
export const {{pascalCaseUpper name}}_EXTENSION_PERMISSION_VALUES = [] as const
|
|
3
|
-
export type {{pascalCase name}}PermissionName = (typeof {{pascalCaseUpper name}}_EXTENSION_PERMISSION_VALUES)[number]
|
|
1
|
+
/** {{displayName}} 权限标签 */
|
|
2
|
+
export const {{pascalCaseUpper name}}_EXTENSION_PERMISSION_VALUES = [] as const
|
|
3
|
+
export type {{pascalCase name}}PermissionName = (typeof {{pascalCaseUpper name}}_EXTENSION_PERMISSION_VALUES)[number]
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/** {{displayName}} 业务类型定义 */
|
|
2
|
-
export interface {{pascalCase name}}Item {
|
|
3
|
-
id: number
|
|
4
|
-
// TODO: 添加业务字段
|
|
5
|
-
}
|
|
1
|
+
/** {{displayName}} 业务类型定义 */
|
|
2
|
+
export interface {{pascalCase name}}Item {
|
|
3
|
+
id: number
|
|
4
|
+
// TODO: 添加业务字段
|
|
5
|
+
}
|
package/package.json
CHANGED
|
@@ -1,52 +1,48 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "moyan-mfw-cli",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "MFW framework CLI — extension scaffolding, validation, and publishing tools",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"bin": {
|
|
7
|
-
"mfw": "./bin/mfw.js"
|
|
8
|
-
},
|
|
9
|
-
"exports": {
|
|
10
|
-
".": {
|
|
11
|
-
"types": "./dist/index.d.ts",
|
|
12
|
-
"import": "./dist/index.js",
|
|
13
|
-
"require": "./dist/index.cjs"
|
|
14
|
-
}
|
|
15
|
-
},
|
|
16
|
-
"files": [
|
|
17
|
-
"bin/",
|
|
18
|
-
"dist/",
|
|
19
|
-
"README.md",
|
|
20
|
-
"LICENSE"
|
|
21
|
-
],
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
"
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
"
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
"engines": {
|
|
50
|
-
"node": ">=20.0.0"
|
|
51
|
-
}
|
|
52
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "moyan-mfw-cli",
|
|
3
|
+
"version": "1.1.2",
|
|
4
|
+
"description": "MFW framework CLI — extension scaffolding, validation, and publishing tools",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"mfw": "./bin/mfw.js"
|
|
8
|
+
},
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"bin/",
|
|
18
|
+
"dist/",
|
|
19
|
+
"README.md",
|
|
20
|
+
"LICENSE"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"dev": "tsx watch src/index.ts",
|
|
24
|
+
"copy-templates": "node --input-type=module -e \"import fs from 'node:fs'; fs.cpSync('src/templates','dist/templates',{recursive:true})\"",
|
|
25
|
+
"build": "tsup src/index.ts --format esm,cjs --dts --clean && pnpm copy-templates",
|
|
26
|
+
"typecheck": "tsc --noEmit"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"commander": "^12.0.0",
|
|
30
|
+
"inquirer": "^9.2.0",
|
|
31
|
+
"chalk": "^5.3.0",
|
|
32
|
+
"handlebars": "^4.7.8",
|
|
33
|
+
"semver": "^7.6.0",
|
|
34
|
+
"glob": "^10.3.0",
|
|
35
|
+
"execa": "^9.3.0",
|
|
36
|
+
"prettier": "^3.4.0"
|
|
37
|
+
},
|
|
38
|
+
"devDependencies": {
|
|
39
|
+
"tsup": "^8.0.0",
|
|
40
|
+
"tsx": "^4.7.0",
|
|
41
|
+
"typescript": "^5.7.3",
|
|
42
|
+
"@types/inquirer": "^9.0.0",
|
|
43
|
+
"@types/prettier": "^3.0.0"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=20.0.0"
|
|
47
|
+
}
|
|
48
|
+
}
|