moyan-mfw-base 1.0.1 → 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/package.json +78 -81
- package/src/backend/dist/common/utils/encrypt.js +6 -36
- package/src/backend/dist/common/utils/encrypt.js.map +1 -1
- package/src/backend/dist/create-base-backend-app.js +10 -10
- package/src/backend/dist/database/clean-pc-permissions.js +5 -5
- package/src/backend/dist/database/run-migration-add-userrole-appid.js +9 -9
- package/src/backend/dist/database/seeds/dict.seeder.js +4 -4
- package/src/backend/dist/modules/sys/app/service/app-member.service.js +46 -46
- package/src/backend/dist/modules/sys/app/service/app.service.js +10 -10
- package/src/backend/dist/modules/sys/app-type/app-type.service.js +23 -23
- package/src/backend/dist/modules/sys/auth/auth.service.js +41 -41
- package/src/backend/dist/modules/sys/role/role.service.js +34 -34
- package/src/frontend/dist/{InstallWizard-Cqqin5JU.js → InstallWizard-B3Xzq66H.js} +2 -2
- package/src/frontend/dist/{InstallWizard-DKeMgS1B.cjs → InstallWizard-BYAo7KkS.cjs} +1 -1
- package/src/frontend/dist/components/picker/app-selector/index.d.ts +1 -1
- package/src/frontend/dist/components/picker/app-selector/index.d.ts.map +1 -1
- package/src/frontend/dist/{index-34vDODse.cjs → index-B9ZB147c.cjs} +1 -1
- package/src/frontend/dist/{index-Dx5Jku9n.cjs → index-BUIwu-aM.cjs} +1 -1
- package/src/frontend/dist/index-CTbpdABp.js +4 -0
- package/src/frontend/dist/{index-B6MM9sTP.cjs → index-CztOCmNJ.cjs} +2 -2
- package/src/frontend/dist/{index-qVj_T8U2.js → index-D-4k6--k.js} +31 -31
- package/src/frontend/dist/index-D3AX3lll.js +4 -0
- package/src/frontend/dist/index.js +1 -1
- package/src/frontend/dist/index.mjs +1 -1
- package/src/frontend/dist/style.css +2 -2
- package/src/frontend/dist/index-BpqZ1Env.js +0 -4
- package/src/frontend/dist/index-R3SBJKQV.js +0 -4
- package/src/shared/dist/core/extension-descriptor.d.ts +0 -20
- package/src/shared/dist/core/extension-descriptor.d.ts.map +0 -1
- package/src/shared/dist/core/extension-descriptor.js +0 -7
- package/src/shared/dist/core/extension-descriptor.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,81 +1,78 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "moyan-mfw-base",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "墨焱MFW核心框架",
|
|
5
|
-
"main": "./src/shared/dist/index.js",
|
|
6
|
-
"types": "./src/shared/dist/index.d.ts",
|
|
7
|
-
"exports": {
|
|
8
|
-
"./backend": {
|
|
9
|
-
"import": "./src/backend/dist/index.js",
|
|
10
|
-
"require": "./src/backend/dist/index.js",
|
|
11
|
-
"types": "./src/backend/dist/index.d.ts"
|
|
12
|
-
},
|
|
13
|
-
"./backend/*": {
|
|
14
|
-
"import": "./src/backend/dist/*.js",
|
|
15
|
-
"require": "./src/backend/dist/*",
|
|
16
|
-
"types": "./src/backend/dist/*.d.ts"
|
|
17
|
-
},
|
|
18
|
-
"./frontend": {
|
|
19
|
-
"import": "./src/frontend/dist/index.mjs",
|
|
20
|
-
"require": "./src/frontend/dist/index.js",
|
|
21
|
-
"types": "./src/frontend/dist/index.d.ts"
|
|
22
|
-
},
|
|
23
|
-
"./frontend/*": {
|
|
24
|
-
"import": "./src/frontend/dist/*",
|
|
25
|
-
"require": "./src/frontend/dist/*",
|
|
26
|
-
"types": "./src/frontend/dist/*.d.ts"
|
|
27
|
-
},
|
|
28
|
-
"./shared": {
|
|
29
|
-
"import": "./src/shared/dist/index.js",
|
|
30
|
-
"require": "./src/shared/dist/index.js",
|
|
31
|
-
"types": "./src/shared/dist/index.d.ts"
|
|
32
|
-
},
|
|
33
|
-
"./shared/*": {
|
|
34
|
-
"import": "./src/shared/dist/*",
|
|
35
|
-
"require": "./src/shared/dist/*",
|
|
36
|
-
"types": "./src/shared/dist/*.d.ts"
|
|
37
|
-
}
|
|
38
|
-
},
|
|
39
|
-
"typesVersions": {
|
|
40
|
-
"*": {
|
|
41
|
-
"*": [
|
|
42
|
-
"./src/*/dist/*.d.ts",
|
|
43
|
-
"./src/*/dist/index.d.ts"
|
|
44
|
-
]
|
|
45
|
-
}
|
|
46
|
-
},
|
|
47
|
-
"scripts": {
|
|
48
|
-
"build:shared": "pnpm --filter @internal/base-shared build",
|
|
49
|
-
"build:backend": "pnpm --filter @internal/base-backend build",
|
|
50
|
-
"build:frontend": "pnpm --filter @internal/base-frontend build",
|
|
51
|
-
"build": "pnpm run build:shared && pnpm run build:backend && pnpm run build:frontend",
|
|
52
|
-
"dev:backend": "pnpm --filter @internal/base-backend dev",
|
|
53
|
-
"dev:frontend": "pnpm --filter @internal/base-frontend dev",
|
|
54
|
-
"typecheck:shared": "pnpm --filter @internal/base-shared typecheck",
|
|
55
|
-
"typecheck:backend": "pnpm --filter @internal/base-backend typecheck",
|
|
56
|
-
"typecheck:frontend": "pnpm --filter @internal/base-frontend typecheck",
|
|
57
|
-
"typecheck": "pnpm run typecheck:shared && pnpm run typecheck:backend && pnpm run typecheck:frontend"
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
"
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
"
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
"node": ">=20.0.0"
|
|
80
|
-
}
|
|
81
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "moyan-mfw-base",
|
|
3
|
+
"version": "1.1.2",
|
|
4
|
+
"description": "墨焱MFW核心框架",
|
|
5
|
+
"main": "./src/shared/dist/index.js",
|
|
6
|
+
"types": "./src/shared/dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
"./backend": {
|
|
9
|
+
"import": "./src/backend/dist/index.js",
|
|
10
|
+
"require": "./src/backend/dist/index.js",
|
|
11
|
+
"types": "./src/backend/dist/index.d.ts"
|
|
12
|
+
},
|
|
13
|
+
"./backend/*": {
|
|
14
|
+
"import": "./src/backend/dist/*.js",
|
|
15
|
+
"require": "./src/backend/dist/*",
|
|
16
|
+
"types": "./src/backend/dist/*.d.ts"
|
|
17
|
+
},
|
|
18
|
+
"./frontend": {
|
|
19
|
+
"import": "./src/frontend/dist/index.mjs",
|
|
20
|
+
"require": "./src/frontend/dist/index.js",
|
|
21
|
+
"types": "./src/frontend/dist/index.d.ts"
|
|
22
|
+
},
|
|
23
|
+
"./frontend/*": {
|
|
24
|
+
"import": "./src/frontend/dist/*",
|
|
25
|
+
"require": "./src/frontend/dist/*",
|
|
26
|
+
"types": "./src/frontend/dist/*.d.ts"
|
|
27
|
+
},
|
|
28
|
+
"./shared": {
|
|
29
|
+
"import": "./src/shared/dist/index.js",
|
|
30
|
+
"require": "./src/shared/dist/index.js",
|
|
31
|
+
"types": "./src/shared/dist/index.d.ts"
|
|
32
|
+
},
|
|
33
|
+
"./shared/*": {
|
|
34
|
+
"import": "./src/shared/dist/*",
|
|
35
|
+
"require": "./src/shared/dist/*",
|
|
36
|
+
"types": "./src/shared/dist/*.d.ts"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"typesVersions": {
|
|
40
|
+
"*": {
|
|
41
|
+
"*": [
|
|
42
|
+
"./src/*/dist/*.d.ts",
|
|
43
|
+
"./src/*/dist/index.d.ts"
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build:shared": "pnpm --filter @internal/base-shared build",
|
|
49
|
+
"build:backend": "pnpm --filter @internal/base-backend build",
|
|
50
|
+
"build:frontend": "pnpm --filter @internal/base-frontend build",
|
|
51
|
+
"build": "pnpm run build:shared && pnpm run build:backend && pnpm run build:frontend",
|
|
52
|
+
"dev:backend": "pnpm --filter @internal/base-backend dev",
|
|
53
|
+
"dev:frontend": "pnpm --filter @internal/base-frontend dev",
|
|
54
|
+
"typecheck:shared": "pnpm --filter @internal/base-shared typecheck",
|
|
55
|
+
"typecheck:backend": "pnpm --filter @internal/base-backend typecheck",
|
|
56
|
+
"typecheck:frontend": "pnpm --filter @internal/base-frontend typecheck",
|
|
57
|
+
"typecheck": "pnpm run typecheck:shared && pnpm run typecheck:backend && pnpm run typecheck:frontend"
|
|
58
|
+
},
|
|
59
|
+
"license": "MIT",
|
|
60
|
+
"keywords": [
|
|
61
|
+
"moyan",
|
|
62
|
+
"mfw",
|
|
63
|
+
"admin",
|
|
64
|
+
"framework",
|
|
65
|
+
"nestjs",
|
|
66
|
+
"vue3"
|
|
67
|
+
],
|
|
68
|
+
"files": [
|
|
69
|
+
"src/backend/dist",
|
|
70
|
+
"src/frontend/dist",
|
|
71
|
+
"src/shared/dist",
|
|
72
|
+
"README.md",
|
|
73
|
+
"LICENSE"
|
|
74
|
+
],
|
|
75
|
+
"engines": {
|
|
76
|
+
"node": ">=20.0.0"
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -3,43 +3,13 @@
|
|
|
3
3
|
* @fileoverview 加密工具函数
|
|
4
4
|
* @description 提供密码加密、验证等加密相关功能
|
|
5
5
|
*/
|
|
6
|
-
var
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
-
}
|
|
12
|
-
Object.defineProperty(o, k2, desc);
|
|
13
|
-
}) : (function(o, m, k, k2) {
|
|
14
|
-
if (k2 === undefined) k2 = k;
|
|
15
|
-
o[k2] = m[k];
|
|
16
|
-
}));
|
|
17
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
-
}) : function(o, v) {
|
|
20
|
-
o["default"] = v;
|
|
21
|
-
});
|
|
22
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
-
var ownKeys = function(o) {
|
|
24
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
-
var ar = [];
|
|
26
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
-
return ar;
|
|
28
|
-
};
|
|
29
|
-
return ownKeys(o);
|
|
30
|
-
};
|
|
31
|
-
return function (mod) {
|
|
32
|
-
if (mod && mod.__esModule) return mod;
|
|
33
|
-
var result = {};
|
|
34
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
-
__setModuleDefault(result, mod);
|
|
36
|
-
return result;
|
|
37
|
-
};
|
|
38
|
-
})();
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
39
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
10
|
exports.hashPassword = hashPassword;
|
|
41
11
|
exports.verifyPassword = verifyPassword;
|
|
42
|
-
const
|
|
12
|
+
const bcryptjs_1 = __importDefault(require("bcryptjs"));
|
|
43
13
|
/**
|
|
44
14
|
* 默认盐值 rounds
|
|
45
15
|
* @description bcrypt 加密的盐值 rounds,值越大越安全但越慢
|
|
@@ -56,7 +26,7 @@ const SALT_ROUNDS = 10;
|
|
|
56
26
|
* ```
|
|
57
27
|
*/
|
|
58
28
|
async function hashPassword(password) {
|
|
59
|
-
return
|
|
29
|
+
return bcryptjs_1.default.hash(password, SALT_ROUNDS);
|
|
60
30
|
}
|
|
61
31
|
/**
|
|
62
32
|
* 密码验证
|
|
@@ -70,6 +40,6 @@ async function hashPassword(password) {
|
|
|
70
40
|
* ```
|
|
71
41
|
*/
|
|
72
42
|
async function verifyPassword(password, hash) {
|
|
73
|
-
return
|
|
43
|
+
return bcryptjs_1.default.compare(password, hash);
|
|
74
44
|
}
|
|
75
45
|
//# sourceMappingURL=encrypt.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"encrypt.js","sourceRoot":"","sources":["../../../src/common/utils/encrypt.ts"],"names":[],"mappings":";AAAA;;;GAGG
|
|
1
|
+
{"version":3,"file":"encrypt.js","sourceRoot":"","sources":["../../../src/common/utils/encrypt.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;;;AAoBH,oCAEC;AAaD,wCAKC;AAtCD,wDAA8B;AAE9B;;;GAGG;AACH,MAAM,WAAW,GAAG,EAAE,CAAC;AAEvB;;;;;;;;;GASG;AACI,KAAK,UAAU,YAAY,CAAC,QAAgB;IACjD,OAAO,kBAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;;;;;;GAUG;AACI,KAAK,UAAU,cAAc,CAClC,QAAgB,EAChB,IAAY;IAEZ,OAAO,kBAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;AACxC,CAAC"}
|
|
@@ -261,16 +261,16 @@ function setupCors(app, options, configService) {
|
|
|
261
261
|
* 打印启动消息
|
|
262
262
|
*/
|
|
263
263
|
function printStartupMessage(port, globalPrefix, configService) {
|
|
264
|
-
console.log(`
|
|
265
|
-
╔═══════════════════════════════════════════════════════════╗
|
|
266
|
-
║ ║
|
|
267
|
-
║ 🚀 Moyan MFW Backend is running! ║
|
|
268
|
-
║ ║
|
|
269
|
-
║ ➜ Local: http://localhost:${port}${globalPrefix} ║
|
|
270
|
-
║ ➜ Swagger: http://localhost:${port}/api-docs/sys ║
|
|
271
|
-
║ ➜ Environment: ${configService.get('env', 'development')} ║
|
|
272
|
-
║ ║
|
|
273
|
-
╚═══════════════════════════════════════════════════════════╝
|
|
264
|
+
console.log(`
|
|
265
|
+
╔═══════════════════════════════════════════════════════════╗
|
|
266
|
+
║ ║
|
|
267
|
+
║ 🚀 Moyan MFW Backend is running! ║
|
|
268
|
+
║ ║
|
|
269
|
+
║ ➜ Local: http://localhost:${port}${globalPrefix} ║
|
|
270
|
+
║ ➜ Swagger: http://localhost:${port}/api-docs/sys ║
|
|
271
|
+
║ ➜ Environment: ${configService.get('env', 'development')} ║
|
|
272
|
+
║ ║
|
|
273
|
+
╚═══════════════════════════════════════════════════════════╝
|
|
274
274
|
`);
|
|
275
275
|
}
|
|
276
276
|
//# sourceMappingURL=create-base-backend-app.js.map
|
|
@@ -19,11 +19,11 @@ async function clean() {
|
|
|
19
19
|
});
|
|
20
20
|
await dataSource.initialize();
|
|
21
21
|
// 删除所有 isAutoSync=0 的 PC 权限(排除 pc_root)
|
|
22
|
-
const result = await dataSource.query(`
|
|
23
|
-
DELETE FROM sys_permissions
|
|
24
|
-
WHERE permission_type = 'PC'
|
|
25
|
-
AND is_auto_sync = 0
|
|
26
|
-
AND perm_code != 'pc_root'
|
|
22
|
+
const result = await dataSource.query(`
|
|
23
|
+
DELETE FROM sys_permissions
|
|
24
|
+
WHERE permission_type = 'PC'
|
|
25
|
+
AND is_auto_sync = 0
|
|
26
|
+
AND perm_code != 'pc_root'
|
|
27
27
|
`);
|
|
28
28
|
process.stdout.write(`已删除 ${result.affectedRows} 条脏数据\n`);
|
|
29
29
|
await dataSource.destroy();
|
|
@@ -23,7 +23,7 @@ for (const p of envPaths) {
|
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
async function columnExists(conn, table, column) {
|
|
26
|
-
const [rows] = await conn.execute(`SELECT COUNT(*) as cnt FROM information_schema.COLUMNS
|
|
26
|
+
const [rows] = await conn.execute(`SELECT COUNT(*) as cnt FROM information_schema.COLUMNS
|
|
27
27
|
WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ? AND COLUMN_NAME = ?`, [process.env.DB_NAME || 'moyan_mfw', table, column]);
|
|
28
28
|
return rows[0].cnt > 0;
|
|
29
29
|
}
|
|
@@ -49,13 +49,13 @@ async function main() {
|
|
|
49
49
|
}
|
|
50
50
|
// ---- Step 2: 填充已有记录的 appId ----
|
|
51
51
|
process.stdout.write('Step 2: 填充已有记录的 appId...\n');
|
|
52
|
-
const [updateResult] = await connection.execute(`
|
|
53
|
-
UPDATE sys_user_roles ur
|
|
54
|
-
JOIN sys_app_members am ON am.userId = ur.userId
|
|
55
|
-
JOIN sys_roles r ON r.id = ur.roleId
|
|
56
|
-
SET ur.appId = am.appId
|
|
57
|
-
WHERE ur.appId IS NULL
|
|
58
|
-
AND (r.appId = am.appId OR r.appTypeId = (SELECT appTypeId FROM sys_apps WHERE id = am.appId))
|
|
52
|
+
const [updateResult] = await connection.execute(`
|
|
53
|
+
UPDATE sys_user_roles ur
|
|
54
|
+
JOIN sys_app_members am ON am.userId = ur.userId
|
|
55
|
+
JOIN sys_roles r ON r.id = ur.roleId
|
|
56
|
+
SET ur.appId = am.appId
|
|
57
|
+
WHERE ur.appId IS NULL
|
|
58
|
+
AND (r.appId = am.appId OR r.appTypeId = (SELECT appTypeId FROM sys_apps WHERE id = am.appId))
|
|
59
59
|
`);
|
|
60
60
|
process.stdout.write(` ✓ 已更新 ${updateResult.changedRows || 0} 条记录\n`);
|
|
61
61
|
// ---- Step 3: 删除无归属的歧义记录 ----
|
|
@@ -64,7 +64,7 @@ async function main() {
|
|
|
64
64
|
process.stdout.write(` ✓ 已删除 ${deleteResult.affectedRows || 0} 条记录\n`);
|
|
65
65
|
// ---- Step 4: appId 设为 NOT NULL(幂等) ----
|
|
66
66
|
process.stdout.write('Step 4: 设置 appId 为 NOT NULL...\n');
|
|
67
|
-
const [colInfo] = await connection.execute(`SELECT IS_NULLABLE FROM information_schema.COLUMNS
|
|
67
|
+
const [colInfo] = await connection.execute(`SELECT IS_NULLABLE FROM information_schema.COLUMNS
|
|
68
68
|
WHERE TABLE_SCHEMA = ? AND TABLE_NAME = 'sys_user_roles' AND COLUMN_NAME = 'appId'`, [process.env.DB_NAME || 'moyan_mfw']);
|
|
69
69
|
if (colInfo[0]?.IS_NULLABLE === 'NO') {
|
|
70
70
|
process.stdout.write(' ✓ appId 已是 NOT NULL,跳过\n');
|
|
@@ -6,14 +6,14 @@ const shared_1 = require("moyan-mfw-base/shared");
|
|
|
6
6
|
async function seedDicts(dataSource) {
|
|
7
7
|
const dicts = (0, shared_1.getAllDicts)();
|
|
8
8
|
for (const dict of dicts) {
|
|
9
|
-
await dataSource.query(`INSERT INTO sys_dict_types (id, dict_key, dict_name, module, created_at)
|
|
10
|
-
VALUES (UUID(), ?, ?, ?, NOW())
|
|
9
|
+
await dataSource.query(`INSERT INTO sys_dict_types (id, dict_key, dict_name, module, created_at)
|
|
10
|
+
VALUES (UUID(), ?, ?, ?, NOW())
|
|
11
11
|
ON DUPLICATE KEY UPDATE dict_name = VALUES(dict_name), module = VALUES(module)`, [dict.key, dict.label, dict.module ?? null]);
|
|
12
12
|
const [row] = await dataSource.query(`SELECT id FROM sys_dict_types WHERE dict_key = ?`, [dict.key]);
|
|
13
13
|
for (let i = 0; i < dict.items.length; i++) {
|
|
14
14
|
const item = dict.items[i];
|
|
15
|
-
await dataSource.query(`INSERT INTO sys_dict_items (id, dict_type_id, item_value, item_label, sort_order, created_at)
|
|
16
|
-
VALUES (UUID(), ?, ?, ?, ?, NOW())
|
|
15
|
+
await dataSource.query(`INSERT INTO sys_dict_items (id, dict_type_id, item_value, item_label, sort_order, created_at)
|
|
16
|
+
VALUES (UUID(), ?, ?, ?, ?, NOW())
|
|
17
17
|
ON DUPLICATE KEY UPDATE item_label = VALUES(item_label), sort_order = VALUES(sort_order)`, [row.id, String(item.value), item.label, i]);
|
|
18
18
|
}
|
|
19
19
|
}
|
|
@@ -65,8 +65,8 @@ let AppMemberService = class AppMemberService {
|
|
|
65
65
|
where: { id: app.appTypeId },
|
|
66
66
|
});
|
|
67
67
|
if (appType && appType.multiAppEnabled === 0) {
|
|
68
|
-
const sameTypeMembers = await this.dataSource.query(`SELECT sa.appName FROM sys_app_members sam
|
|
69
|
-
INNER JOIN sys_apps sa ON sa.id = sam.appId AND sa.deleteAt IS NULL
|
|
68
|
+
const sameTypeMembers = await this.dataSource.query(`SELECT sa.appName FROM sys_app_members sam
|
|
69
|
+
INNER JOIN sys_apps sa ON sa.id = sam.appId AND sa.deleteAt IS NULL
|
|
70
70
|
WHERE sam.userId = ? AND sa.appTypeId = ? AND sam.appId != ?`, [userId, app.appTypeId, appId]);
|
|
71
71
|
if (sameTypeMembers && sameTypeMembers.length > 0) {
|
|
72
72
|
throw new common_1.BadRequestException(`应用类型 "${appType.typeName}" 不支持多应用,该用户已是实例 "${sameTypeMembers[0].appName}" 的成员`);
|
|
@@ -110,52 +110,52 @@ let AppMemberService = class AppMemberService {
|
|
|
110
110
|
.sql(({ select, wheres, orderBy, limit }) => {
|
|
111
111
|
const whereClause = wheres?.main || '';
|
|
112
112
|
const roleScopeClause = wheres?.roleScope || '';
|
|
113
|
-
return `
|
|
114
|
-
WITH rj AS(
|
|
115
|
-
SELECT
|
|
116
|
-
ur.userId,
|
|
117
|
-
JSON_ARRAYAGG(
|
|
118
|
-
JSON_OBJECT(
|
|
119
|
-
'roleId', r.id,
|
|
120
|
-
'roleCode', r.roleCode,
|
|
121
|
-
'roleName', r.roleName,
|
|
122
|
-
'isBuiltin', r.isBuiltin
|
|
123
|
-
)
|
|
124
|
-
) AS roles
|
|
125
|
-
FROM sys_user_roles ur
|
|
126
|
-
INNER JOIN sys_roles r ON ur.roleId = r.id
|
|
127
|
-
WHERE ur.appId = '${appId}' ${roleScopeClause.replace('WHERE', 'AND')}
|
|
128
|
-
GROUP BY ur.userId
|
|
129
|
-
)
|
|
130
|
-
SELECT
|
|
131
|
-
${select}
|
|
132
|
-
FROM sys_app_members am
|
|
133
|
-
INNER JOIN sys_apps a ON a.id = am.appId
|
|
134
|
-
INNER JOIN sys_users u ON u.id = am.userId
|
|
135
|
-
LEFT JOIN rj ON rj.userId = am.userId
|
|
136
|
-
${whereClause}
|
|
137
|
-
${orderBy}
|
|
138
|
-
${limit}
|
|
113
|
+
return `
|
|
114
|
+
WITH rj AS(
|
|
115
|
+
SELECT
|
|
116
|
+
ur.userId,
|
|
117
|
+
JSON_ARRAYAGG(
|
|
118
|
+
JSON_OBJECT(
|
|
119
|
+
'roleId', r.id,
|
|
120
|
+
'roleCode', r.roleCode,
|
|
121
|
+
'roleName', r.roleName,
|
|
122
|
+
'isBuiltin', r.isBuiltin
|
|
123
|
+
)
|
|
124
|
+
) AS roles
|
|
125
|
+
FROM sys_user_roles ur
|
|
126
|
+
INNER JOIN sys_roles r ON ur.roleId = r.id
|
|
127
|
+
WHERE ur.appId = '${appId}' ${roleScopeClause.replace('WHERE', 'AND')}
|
|
128
|
+
GROUP BY ur.userId
|
|
129
|
+
)
|
|
130
|
+
SELECT
|
|
131
|
+
${select}
|
|
132
|
+
FROM sys_app_members am
|
|
133
|
+
INNER JOIN sys_apps a ON a.id = am.appId
|
|
134
|
+
INNER JOIN sys_users u ON u.id = am.userId
|
|
135
|
+
LEFT JOIN rj ON rj.userId = am.userId
|
|
136
|
+
${whereClause}
|
|
137
|
+
${orderBy}
|
|
138
|
+
${limit}
|
|
139
139
|
`;
|
|
140
140
|
})
|
|
141
|
-
.select(`
|
|
142
|
-
am.id,
|
|
143
|
-
am.userId,
|
|
144
|
-
am.appId,
|
|
145
|
-
am.createdAt,
|
|
146
|
-
u.nickname,
|
|
147
|
-
u.avatar,
|
|
148
|
-
u.email,
|
|
149
|
-
u.phone,
|
|
150
|
-
u.username,
|
|
151
|
-
a.appCode,
|
|
152
|
-
a.appName,
|
|
153
|
-
a.logo as appLogo,
|
|
154
|
-
a.ownerId,
|
|
155
|
-
a.sortOrder,
|
|
156
|
-
a.appTypeId,
|
|
157
|
-
COALESCE(rj.roles, JSON_ARRAY()) AS roles,
|
|
158
|
-
IF(a.ownerId = am.userId,1,0) isOwner
|
|
141
|
+
.select(`
|
|
142
|
+
am.id,
|
|
143
|
+
am.userId,
|
|
144
|
+
am.appId,
|
|
145
|
+
am.createdAt,
|
|
146
|
+
u.nickname,
|
|
147
|
+
u.avatar,
|
|
148
|
+
u.email,
|
|
149
|
+
u.phone,
|
|
150
|
+
u.username,
|
|
151
|
+
a.appCode,
|
|
152
|
+
a.appName,
|
|
153
|
+
a.logo as appLogo,
|
|
154
|
+
a.ownerId,
|
|
155
|
+
a.sortOrder,
|
|
156
|
+
a.appTypeId,
|
|
157
|
+
COALESCE(rj.roles, JSON_ARRAY()) AS roles,
|
|
158
|
+
IF(a.ownerId = am.userId,1,0) isOwner
|
|
159
159
|
`)
|
|
160
160
|
.defaultOrderBy('createdAt DESC')
|
|
161
161
|
.getData();
|
|
@@ -56,13 +56,13 @@ let AppService = class AppService {
|
|
|
56
56
|
* @returns 应用实例信息
|
|
57
57
|
*/
|
|
58
58
|
async findById(id) {
|
|
59
|
-
const result = await this.dataSource.query(`SELECT
|
|
60
|
-
app.*,
|
|
61
|
-
JSON_OBJECT('id', t.id, 'typeName', t.typeName, 'typeCode', t.typeCode) as appType,
|
|
62
|
-
JSON_OBJECT('id', u.id, 'username', u.username, 'nickname', u.nickname, 'avatar', u.avatar) as owner
|
|
63
|
-
FROM sys_apps app
|
|
64
|
-
LEFT JOIN sys_app_types t ON app.appTypeId = t.id
|
|
65
|
-
LEFT JOIN sys_users u ON app.ownerId = u.id AND u.deleteAt IS NULL
|
|
59
|
+
const result = await this.dataSource.query(`SELECT
|
|
60
|
+
app.*,
|
|
61
|
+
JSON_OBJECT('id', t.id, 'typeName', t.typeName, 'typeCode', t.typeCode) as appType,
|
|
62
|
+
JSON_OBJECT('id', u.id, 'username', u.username, 'nickname', u.nickname, 'avatar', u.avatar) as owner
|
|
63
|
+
FROM sys_apps app
|
|
64
|
+
LEFT JOIN sys_app_types t ON app.appTypeId = t.id
|
|
65
|
+
LEFT JOIN sys_users u ON app.ownerId = u.id AND u.deleteAt IS NULL
|
|
66
66
|
WHERE app.id = ? AND app.deleteAt IS NULL`, [id]);
|
|
67
67
|
if (!result || result.length === 0) {
|
|
68
68
|
throw new not_found_exception_1.NotFoundError('应用实例');
|
|
@@ -95,8 +95,8 @@ let AppService = class AppService {
|
|
|
95
95
|
const whereClause = wheres?.main || '';
|
|
96
96
|
return `SELECT ${select} FROM sys_apps app LEFT JOIN sys_app_types t ON app.appTypeId = t.id LEFT JOIN sys_users u ON app.ownerId = u.id ${whereClause} ${orderBy} ${limit}`;
|
|
97
97
|
})
|
|
98
|
-
.select(`app.*,
|
|
99
|
-
JSON_OBJECT('id', t.id, 'typeName', t.typeName, 'typeCode', t.typeCode) as appType,
|
|
98
|
+
.select(`app.*,
|
|
99
|
+
JSON_OBJECT('id', t.id, 'typeName', t.typeName, 'typeCode', t.typeCode) as appType,
|
|
100
100
|
JSON_OBJECT('id', u.id, 'username', u.username, 'nickname', u.nickname, 'avatar', u.avatar) as owner`)
|
|
101
101
|
.defaultOrderBy('app.sortOrder ASC, app.createdAt DESC')
|
|
102
102
|
.getData();
|
|
@@ -186,7 +186,7 @@ let AppService = class AppService {
|
|
|
186
186
|
}
|
|
187
187
|
app.ownerId = ownerId;
|
|
188
188
|
await manager.save(app);
|
|
189
|
-
await manager.query(`INSERT IGNORE INTO sys_app_members (id, appId, userId, createdAt, updateAt)
|
|
189
|
+
await manager.query(`INSERT IGNORE INTO sys_app_members (id, appId, userId, createdAt, updateAt)
|
|
190
190
|
VALUES (UUID(), ?, ?, NOW(), NOW())`, [app.id, ownerId]);
|
|
191
191
|
if (ownerRoles.length > 0) {
|
|
192
192
|
const insertValues = ownerRoles.map((r) => [
|
|
@@ -195,29 +195,29 @@ let AppTypeService = class AppTypeService {
|
|
|
195
195
|
if (!appType) {
|
|
196
196
|
throw new not_found_exception_1.NotFoundError('应用类型');
|
|
197
197
|
}
|
|
198
|
-
const rows = await this.dataSource.query(`SELECT
|
|
199
|
-
p.id,
|
|
200
|
-
p.permName,
|
|
201
|
-
p.permCode,
|
|
202
|
-
p.permDesc,
|
|
203
|
-
p.permissionType,
|
|
204
|
-
p.nodeType,
|
|
205
|
-
p.parentId,
|
|
206
|
-
p.routePath,
|
|
207
|
-
p.externalUrl,
|
|
208
|
-
p.iconName,
|
|
209
|
-
p.sortOrder,
|
|
210
|
-
p.isVisible,
|
|
211
|
-
p.isCache,
|
|
212
|
-
p.showMode,
|
|
213
|
-
p.permStatus,
|
|
214
|
-
p.isAutoSync,
|
|
215
|
-
p.permissionValue AS parentPermissionValue,
|
|
216
|
-
atp.permissionValue,
|
|
217
|
-
IF(atp.permissionId IS NULL, 0, 1) checked
|
|
218
|
-
FROM sys_permissions p
|
|
219
|
-
LEFT JOIN sys_app_type_permissions atp ON atp.permissionId = p.id AND atp.appTypeId = ?
|
|
220
|
-
WHERE p.deleteAt IS NULL
|
|
198
|
+
const rows = await this.dataSource.query(`SELECT
|
|
199
|
+
p.id,
|
|
200
|
+
p.permName,
|
|
201
|
+
p.permCode,
|
|
202
|
+
p.permDesc,
|
|
203
|
+
p.permissionType,
|
|
204
|
+
p.nodeType,
|
|
205
|
+
p.parentId,
|
|
206
|
+
p.routePath,
|
|
207
|
+
p.externalUrl,
|
|
208
|
+
p.iconName,
|
|
209
|
+
p.sortOrder,
|
|
210
|
+
p.isVisible,
|
|
211
|
+
p.isCache,
|
|
212
|
+
p.showMode,
|
|
213
|
+
p.permStatus,
|
|
214
|
+
p.isAutoSync,
|
|
215
|
+
p.permissionValue AS parentPermissionValue,
|
|
216
|
+
atp.permissionValue,
|
|
217
|
+
IF(atp.permissionId IS NULL, 0, 1) checked
|
|
218
|
+
FROM sys_permissions p
|
|
219
|
+
LEFT JOIN sys_app_type_permissions atp ON atp.permissionId = p.id AND atp.appTypeId = ?
|
|
220
|
+
WHERE p.deleteAt IS NULL
|
|
221
221
|
ORDER BY p.sortOrder ASC`, [appTypeId]);
|
|
222
222
|
const pcRows = rows.filter((r) => r.permissionType === permission_entity_1.PermissionType.PC);
|
|
223
223
|
const normalRows = rows.filter((r) => r.permissionType === permission_entity_1.PermissionType.NORMAL);
|
|
@@ -204,20 +204,20 @@ let AuthService = class AuthService {
|
|
|
204
204
|
* @returns 用户可访问的应用实例列表
|
|
205
205
|
*/
|
|
206
206
|
async getUserApps(userId) {
|
|
207
|
-
const sql = `
|
|
208
|
-
SELECT
|
|
209
|
-
sam.appId,
|
|
210
|
-
sa.appName,
|
|
211
|
-
sa.appCode,
|
|
212
|
-
sa.appTypeId,
|
|
213
|
-
sat.typeCode AS appTypeCode,
|
|
214
|
-
sat.typeName AS appTypeName,
|
|
215
|
-
IF(sa.ownerId = sam.userId, 'owner', 'member') AS role,
|
|
216
|
-
sa.logo
|
|
217
|
-
FROM sys_app_members sam
|
|
218
|
-
INNER JOIN sys_apps sa ON sa.id = sam.appId
|
|
219
|
-
INNER JOIN sys_app_types sat ON sat.id = sa.appTypeId
|
|
220
|
-
WHERE sam.userId = :userId AND sa.appStatus = 1
|
|
207
|
+
const sql = `
|
|
208
|
+
SELECT
|
|
209
|
+
sam.appId,
|
|
210
|
+
sa.appName,
|
|
211
|
+
sa.appCode,
|
|
212
|
+
sa.appTypeId,
|
|
213
|
+
sat.typeCode AS appTypeCode,
|
|
214
|
+
sat.typeName AS appTypeName,
|
|
215
|
+
IF(sa.ownerId = sam.userId, 'owner', 'member') AS role,
|
|
216
|
+
sa.logo
|
|
217
|
+
FROM sys_app_members sam
|
|
218
|
+
INNER JOIN sys_apps sa ON sa.id = sam.appId
|
|
219
|
+
INNER JOIN sys_app_types sat ON sat.id = sa.appTypeId
|
|
220
|
+
WHERE sam.userId = :userId AND sa.appStatus = 1
|
|
221
221
|
`;
|
|
222
222
|
return (0, sql_util_1.executeRawSql)(this.entityManager, sql, { userId });
|
|
223
223
|
}
|
|
@@ -228,33 +228,33 @@ let AuthService = class AuthService {
|
|
|
228
228
|
* @returns 用户权限菜单树
|
|
229
229
|
*/
|
|
230
230
|
async getUserPermissions(userId, appId) {
|
|
231
|
-
const sql = `
|
|
232
|
-
SELECT sa.appTypeId appTypeId FROM sys_apps sa WHERE sa.id = :appId ;
|
|
233
|
-
SELECT
|
|
234
|
-
sp.id,
|
|
235
|
-
sp.permCode,
|
|
236
|
-
sp.permName,
|
|
237
|
-
sp.permissionType,
|
|
238
|
-
sp.nodeType,
|
|
239
|
-
sp.parentId,
|
|
240
|
-
sp.routePath,
|
|
241
|
-
sp.externalUrl,
|
|
242
|
-
sp.iconName,
|
|
243
|
-
sp.sortOrder,
|
|
244
|
-
sp.isVisible,
|
|
245
|
-
sp.isCache,
|
|
246
|
-
sp.showMode,
|
|
247
|
-
BIT_OR(sp.permissionValue) permissionValue
|
|
248
|
-
FROM sys_user_roles sur
|
|
249
|
-
INNER JOIN sys_roles sr ON sur.roleId = sr.id
|
|
250
|
-
INNER JOIN sys_role_permissions srp ON srp.roleId = sr.id
|
|
251
|
-
INNER JOIN sys_permissions sp ON sp.id = srp.permissionId
|
|
252
|
-
WHERE
|
|
253
|
-
sur.userId = :userId AND
|
|
254
|
-
sur.appId = :appId AND
|
|
255
|
-
sp.isVisible = 1
|
|
256
|
-
GROUP BY sp.permCode
|
|
257
|
-
ORDER BY sp.sortOrder ASC;
|
|
231
|
+
const sql = `
|
|
232
|
+
SELECT sa.appTypeId appTypeId FROM sys_apps sa WHERE sa.id = :appId ;
|
|
233
|
+
SELECT
|
|
234
|
+
sp.id,
|
|
235
|
+
sp.permCode,
|
|
236
|
+
sp.permName,
|
|
237
|
+
sp.permissionType,
|
|
238
|
+
sp.nodeType,
|
|
239
|
+
sp.parentId,
|
|
240
|
+
sp.routePath,
|
|
241
|
+
sp.externalUrl,
|
|
242
|
+
sp.iconName,
|
|
243
|
+
sp.sortOrder,
|
|
244
|
+
sp.isVisible,
|
|
245
|
+
sp.isCache,
|
|
246
|
+
sp.showMode,
|
|
247
|
+
BIT_OR(sp.permissionValue) permissionValue
|
|
248
|
+
FROM sys_user_roles sur
|
|
249
|
+
INNER JOIN sys_roles sr ON sur.roleId = sr.id
|
|
250
|
+
INNER JOIN sys_role_permissions srp ON srp.roleId = sr.id
|
|
251
|
+
INNER JOIN sys_permissions sp ON sp.id = srp.permissionId
|
|
252
|
+
WHERE
|
|
253
|
+
sur.userId = :userId AND
|
|
254
|
+
sur.appId = :appId AND
|
|
255
|
+
sp.isVisible = 1
|
|
256
|
+
GROUP BY sp.permCode
|
|
257
|
+
ORDER BY sp.sortOrder ASC;
|
|
258
258
|
`;
|
|
259
259
|
const [appTypeIdResult, result] = await (0, sql_util_1.executeRawSql)(this.entityManager, sql, { userId, appId }, true);
|
|
260
260
|
const permissions = result.map((item) => item.permCode);
|