@kne/fastify-account 1.0.0-alpha.2 → 1.0.0-alpha.4
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 +47 -2
- package/index.js +10 -4
- package/libs/controllers/account.js +7 -6
- package/libs/controllers/admin.js +16 -15
- package/libs/controllers/adminPermission.js +42 -35
- package/libs/controllers/adminRole.js +13 -12
- package/libs/controllers/adminTenant.js +39 -36
- package/libs/controllers/tenant.js +7 -6
- package/libs/controllers/user.js +4 -3
- package/libs/models/admin-role.js +4 -8
- package/libs/models/application.js +16 -10
- package/libs/models/login-log.js +4 -8
- package/libs/models/permission.js +7 -9
- package/libs/models/tenant-application.js +8 -10
- package/libs/models/tenant-org.js +5 -9
- package/libs/models/tenant-permission.js +7 -9
- package/libs/models/tenant-role-application.js +13 -13
- package/libs/models/tenant-role-permission.js +9 -14
- package/libs/models/tenant-role.js +5 -9
- package/libs/models/tenant-share-group-permission.js +5 -9
- package/libs/models/tenant-share-group.js +5 -9
- package/libs/models/tenant-source-user-share-group.js +5 -9
- package/libs/models/tenant-token.js +7 -9
- package/libs/models/tenant-user-org.js +11 -10
- package/libs/models/tenant-user-role.js +11 -10
- package/libs/models/tenant-user-share-group.js +6 -10
- package/libs/models/tenant-user.js +35 -16
- package/libs/models/tenant.js +17 -9
- package/libs/models/user-account.js +17 -9
- package/libs/models/user.js +27 -17
- package/libs/models/verification-code.js +4 -8
- package/libs/services/account.js +26 -16
- package/libs/services/admin.js +14 -116
- package/libs/services/application.js +151 -0
- package/libs/services/permission.js +47 -145
- package/libs/services/tenant-invite.js +62 -0
- package/libs/services/tenant-org.js +84 -0
- package/libs/services/tenant-role.js +108 -0
- package/libs/services/tenant-user.js +486 -0
- package/libs/services/tenant.js +68 -669
- package/libs/services/user.js +63 -33
- package/package.json +3 -3
package/libs/services/tenant.js
CHANGED
|
@@ -1,595 +1,72 @@
|
|
|
1
1
|
const fp = require('fastify-plugin');
|
|
2
|
-
|
|
3
|
-
const { Unauthorized } = require('http-errors');
|
|
4
|
-
const transform = require('lodash/transform');
|
|
5
|
-
const groupBy = require('lodash/groupBy');
|
|
6
|
-
const pick = require('lodash/pick');
|
|
2
|
+
|
|
7
3
|
module.exports = fp(async (fastify, options) => {
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
const { models, services } = fastify.account;
|
|
5
|
+
|
|
6
|
+
const getTenantInstance = async ({ id }) => {
|
|
7
|
+
const tenant = await models.tenant.findOne({
|
|
11
8
|
where: {
|
|
12
|
-
|
|
9
|
+
uuid: id
|
|
13
10
|
}
|
|
14
11
|
});
|
|
15
|
-
|
|
16
|
-
const tenantList =
|
|
17
|
-
tenantUserList.length > 0
|
|
18
|
-
? await fastify.account.models.tenant.findAll({
|
|
19
|
-
where: {
|
|
20
|
-
id: {
|
|
21
|
-
[fastify.sequelize.Sequelize.Op.in]: tenantUserList.map(({ tenantId }) => tenantId)
|
|
22
|
-
},
|
|
23
|
-
status: 0
|
|
24
|
-
}
|
|
25
|
-
})
|
|
26
|
-
: [];
|
|
27
|
-
|
|
28
|
-
const currentTenantUser = user.currentTenantId && tenantUserList.find(({ tenantId }) => tenantId === user.currentTenantId);
|
|
29
|
-
const currentTenant = currentTenantUser && tenantList.find(({ id }) => id === currentTenantUser.tenantId);
|
|
30
|
-
|
|
31
|
-
return {
|
|
32
|
-
currentTenant,
|
|
33
|
-
currentTenantUser,
|
|
34
|
-
tenantList,
|
|
35
|
-
tenantUserList,
|
|
36
|
-
userInfo: user
|
|
37
|
-
};
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
const getTenantInfo = async ({ id }) => {
|
|
41
|
-
const tenant = await fastify.account.models.tenant.findByPk(id);
|
|
42
12
|
if (!tenant) {
|
|
43
13
|
throw new Error('租户不存在');
|
|
44
14
|
}
|
|
45
|
-
return tenant;
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
const getRoleList = async ({ tenantId, currentPage, perPage, filter }) => {
|
|
49
|
-
const queryFilter = {};
|
|
50
|
-
if (!isNil(filter?.type)) {
|
|
51
|
-
queryFilter.type = filter.type;
|
|
52
|
-
}
|
|
53
|
-
const { count, rows } = await fastify.account.models.tenantRole.findAndCountAll({
|
|
54
|
-
where: Object.assign({}, queryFilter, { tenantId }),
|
|
55
|
-
offset: currentPage * (currentPage - 1),
|
|
56
|
-
limit: perPage
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
return { pageData: rows, totalCount: count };
|
|
60
|
-
};
|
|
61
|
-
|
|
62
|
-
const addRole = async ({ tenantId, name, description }) => {
|
|
63
|
-
if (!(await fastify.account.models.tenant.findByPk(tenantId))) {
|
|
64
|
-
throw new Error('租户不存在');
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
return await fastify.account.models.tenantRole.create({
|
|
68
|
-
tenantId,
|
|
69
|
-
name,
|
|
70
|
-
description
|
|
71
|
-
});
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
const saveRole = async ({ id, ...otherInfo }) => {
|
|
75
|
-
const tenantRole = await fastify.account.models.tenantRole.findByPk(id, {
|
|
76
|
-
where: {
|
|
77
|
-
type: 0
|
|
78
|
-
}
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
if (!tenantRole) {
|
|
82
|
-
throw new Error('角色不存在');
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
['name', 'description'].forEach(name => {
|
|
86
|
-
if (otherInfo[name]) {
|
|
87
|
-
tenantRole[name] = otherInfo[name];
|
|
88
|
-
}
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
await tenantRole.save();
|
|
92
|
-
};
|
|
93
15
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
where: {
|
|
97
|
-
type: 0
|
|
98
|
-
}
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
if (!tenantRole) {
|
|
102
|
-
throw new Error('角色不存在');
|
|
16
|
+
if (tenant.status !== 0) {
|
|
17
|
+
throw new Error('租户已关闭');
|
|
103
18
|
}
|
|
104
|
-
|
|
105
|
-
if (
|
|
106
|
-
(await fastify.account.models.tenantUserRole.count({
|
|
107
|
-
where: {
|
|
108
|
-
tenantRoleId: tenantRole.id
|
|
109
|
-
}
|
|
110
|
-
})) > 0
|
|
111
|
-
) {
|
|
112
|
-
throw new Error('该角色已经被使用,请在租户用户种处理掉所有使用该角色的租户用户后重试');
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
if (tenantRole.type === 1) {
|
|
116
|
-
throw new Error('该角色为系统默认角色,不能删除');
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
await tenantRole.destroy();
|
|
120
|
-
};
|
|
121
|
-
|
|
122
|
-
const getTenantUserPermissionList = async ({ tenantRoleIds }) => {
|
|
123
|
-
const tenantRoleApplication = await fastify.account.models.tenantRoleApplication.findAll({
|
|
124
|
-
attributes: ['applicationId'],
|
|
125
|
-
where: {
|
|
126
|
-
roleId: {
|
|
127
|
-
[fastify.sequelize.Sequelize.Op.in]: tenantRoleIds
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
const applications = await fastify.account.models.application.findAll({
|
|
133
|
-
attributes: ['id', 'code', 'name'],
|
|
134
|
-
where: {
|
|
135
|
-
id: {
|
|
136
|
-
[fastify.sequelize.Sequelize.Op.in]: tenantRoleApplication.map(({ applicationId }) => applicationId)
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
const tenantRolePermission = await fastify.account.models.tenantRolePermission.findAll({
|
|
142
|
-
attributes: ['permissionId'],
|
|
143
|
-
include: {
|
|
144
|
-
attributes: ['code', 'name', 'isModule', 'paths'],
|
|
145
|
-
model: fastify.account.models.permission
|
|
146
|
-
},
|
|
147
|
-
where: {
|
|
148
|
-
roleId: {
|
|
149
|
-
[fastify.sequelize.Sequelize.Op.in]: tenantRoleIds
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
const permissions = await fastify.account.models.permission.findAll({
|
|
155
|
-
attributes: ['id', 'code', 'name', 'isModule', 'pid', 'applicationId', 'paths'],
|
|
156
|
-
where: {
|
|
157
|
-
[fastify.sequelize.Sequelize.Op.or]: [
|
|
158
|
-
{
|
|
159
|
-
id: {
|
|
160
|
-
[fastify.sequelize.Sequelize.Op.in]: tenantRolePermission.map(({ permissionId }) => permissionId)
|
|
161
|
-
}
|
|
162
|
-
},
|
|
163
|
-
{
|
|
164
|
-
isMust: true
|
|
165
|
-
}
|
|
166
|
-
]
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
const permissionMapping = transform(
|
|
171
|
-
await fastify.account.models.permission.findAll({
|
|
172
|
-
where: {
|
|
173
|
-
id: {
|
|
174
|
-
[fastify.sequelize.Sequelize.Op.in]: permissions.map(({ paths }) => paths).reduce((list, item) => [...list, ...(item || [])], [])
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
}),
|
|
178
|
-
(result, value) => {
|
|
179
|
-
result[value.id] = { code: value.code, name: value.name };
|
|
180
|
-
},
|
|
181
|
-
{}
|
|
182
|
-
);
|
|
183
|
-
|
|
184
|
-
const applicationsMapping = transform(
|
|
185
|
-
applications,
|
|
186
|
-
(result, value) => {
|
|
187
|
-
result[value.id] = value;
|
|
188
|
-
},
|
|
189
|
-
{}
|
|
190
|
-
);
|
|
191
|
-
|
|
192
|
-
const findEndChildren = permissions => {
|
|
193
|
-
const output = [];
|
|
194
|
-
const core = (list, node) => {
|
|
195
|
-
const { children, other } = groupBy(list, item => (item.pid === node.id ? 'children' : 'other'));
|
|
196
|
-
if (!(other && other.length > 0)) {
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
if (!(children && children.length > 0)) {
|
|
200
|
-
node.id !== 0 && output.push(node);
|
|
201
|
-
return;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
children.forEach(node => {
|
|
205
|
-
core(other, node);
|
|
206
|
-
});
|
|
207
|
-
return output;
|
|
208
|
-
};
|
|
209
|
-
core(permissions, { id: 0 });
|
|
210
|
-
return output;
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
const userPermissionList = findEndChildren(permissions).map(({ code, applicationId, paths }) => {
|
|
214
|
-
return `${applicationsMapping[applicationId].code}${
|
|
215
|
-
paths && paths.length > 0
|
|
216
|
-
? `:${paths
|
|
217
|
-
.map(id => {
|
|
218
|
-
return permissionMapping[id].code;
|
|
219
|
-
})
|
|
220
|
-
.join(':')}`
|
|
221
|
-
: ''
|
|
222
|
-
}:${code}`;
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
return {
|
|
226
|
-
applications: applications,
|
|
227
|
-
permissions: permissions.map(item =>
|
|
228
|
-
Object.assign(
|
|
229
|
-
{},
|
|
230
|
-
{
|
|
231
|
-
code: item.code,
|
|
232
|
-
name: item.name,
|
|
233
|
-
isModule: item.isModule,
|
|
234
|
-
paths: (item.paths || []).map(id => permissionMapping[id])
|
|
235
|
-
}
|
|
236
|
-
)
|
|
237
|
-
),
|
|
238
|
-
userPermissionList
|
|
239
|
-
};
|
|
19
|
+
return tenant;
|
|
240
20
|
};
|
|
241
21
|
|
|
242
|
-
const
|
|
243
|
-
|
|
244
|
-
throw new Unauthorized('没有找到当前绑定租户');
|
|
245
|
-
}
|
|
246
|
-
const tenant = await fastify.account.models.tenant.findByPk(user.currentTenantId, {
|
|
247
|
-
where: {
|
|
248
|
-
status: 0
|
|
249
|
-
}
|
|
250
|
-
});
|
|
251
|
-
if (!tenant) {
|
|
252
|
-
throw new Error('当前绑定租户不存在或者已经被关闭');
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
const tenantUser = await fastify.account.models.tenantUser.findOne({
|
|
256
|
-
attributes: ['id', 'avatar', 'description', 'phone', 'email'],
|
|
257
|
-
include: [
|
|
258
|
-
{
|
|
259
|
-
attributes: ['id', 'name'],
|
|
260
|
-
model: fastify.account.models.tenantOrg
|
|
261
|
-
},
|
|
262
|
-
{
|
|
263
|
-
attributes: ['id', 'name'],
|
|
264
|
-
model: fastify.account.models.tenantRole
|
|
265
|
-
}
|
|
266
|
-
],
|
|
267
|
-
where: {
|
|
268
|
-
tenantId: tenant.id,
|
|
269
|
-
userId: user.id,
|
|
270
|
-
status: 0
|
|
271
|
-
}
|
|
272
|
-
});
|
|
22
|
+
const getTenant = async ({ id }) => {
|
|
23
|
+
const tenant = await getTenantInstance({ id });
|
|
273
24
|
|
|
274
|
-
|
|
275
|
-
const defaultTenant = await fastify.account.models.tenantRole.findOne({
|
|
276
|
-
where: {
|
|
277
|
-
type: 1,
|
|
278
|
-
tenantId: tenant.id
|
|
279
|
-
}
|
|
280
|
-
});
|
|
281
|
-
|
|
282
|
-
if (!defaultTenant) {
|
|
283
|
-
throw new Error('租户默认角色未设置,请联系管理员');
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
const tenantRoleIds = tenantUser.tenantRoles.map(({ id }) => id);
|
|
287
|
-
tenantRoleIds.push(defaultTenant.id);
|
|
288
|
-
|
|
289
|
-
const { userPermissionList } = await getTenantUserPermissionList({ tenantRoleIds });
|
|
290
|
-
if (!tenantUser) {
|
|
291
|
-
throw new Error('当前租户用户不存在或者已经被关闭');
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
const outputTenantUser = Object.assign({}, tenantUser.get({ plain: true }));
|
|
295
|
-
outputTenantUser.tenantOrgs = outputTenantUser?.tenantOrgs.map(({ id, name }) => ({ id, name }));
|
|
296
|
-
outputTenantUser.tenantRoles = outputTenantUser?.tenantRoles.map(({ id, name }) => ({ id, name }));
|
|
297
|
-
return {
|
|
298
|
-
tenant: pick(tenant, ['id', 'name', 'description']),
|
|
299
|
-
tenantUser: Object.assign({}, outputTenantUser, {
|
|
300
|
-
permissions: userPermissionList
|
|
301
|
-
}),
|
|
302
|
-
user
|
|
303
|
-
};
|
|
25
|
+
return Object.assign({}, tenant.get({ plain: true }), { id: tenant.uuid });
|
|
304
26
|
};
|
|
305
27
|
|
|
306
28
|
const closeTenant = async ({ tenantId }) => {
|
|
307
|
-
const tenant = await
|
|
29
|
+
const tenant = await getTenant({ id: tenantId });
|
|
308
30
|
tenant.status = 12;
|
|
309
31
|
await tenant.save();
|
|
310
32
|
};
|
|
311
33
|
|
|
312
34
|
const openTenant = async ({ tenantId }) => {
|
|
313
|
-
const tenant = await
|
|
35
|
+
const tenant = await getTenant({ id: tenantId });
|
|
314
36
|
tenant.status = 0;
|
|
315
37
|
await tenant.save();
|
|
316
38
|
};
|
|
317
39
|
|
|
318
|
-
const
|
|
319
|
-
|
|
320
|
-
|
|
40
|
+
const saveTenant = async tenant => {
|
|
41
|
+
const currentTenant = await services.tenant.getTenantInstance({ id: tenant.id });
|
|
42
|
+
if (!currentTenant) {
|
|
43
|
+
throw new Error('租户不存在,请刷新以后重试');
|
|
321
44
|
}
|
|
322
|
-
|
|
323
|
-
return await fastify.account.models.tenantOrg.create({
|
|
324
|
-
name: org.name,
|
|
325
|
-
enName: org.enName,
|
|
326
|
-
tenantId: org.tenantId,
|
|
327
|
-
pid: org.pid
|
|
328
|
-
});
|
|
45
|
+
await currentTenant.update(tenant);
|
|
329
46
|
};
|
|
330
47
|
|
|
331
|
-
const
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
type: 0
|
|
335
|
-
}
|
|
336
|
-
});
|
|
337
|
-
|
|
338
|
-
if (!tenantOrg) {
|
|
339
|
-
throw new Error('该组织不存在');
|
|
340
|
-
}
|
|
341
|
-
if (
|
|
342
|
-
await fastify.account.models.tenantOrg.count({
|
|
343
|
-
where: {
|
|
344
|
-
name: otherInfo.name,
|
|
345
|
-
pid: otherInfo.pid,
|
|
346
|
-
tenantId: otherInfo.tenantId
|
|
347
|
-
}
|
|
348
|
-
})
|
|
349
|
-
) {
|
|
350
|
-
throw new Error('组织名称在同一父组织下有重复');
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
['name', 'enName', 'tenantId', 'pid'].forEach(name => {
|
|
354
|
-
if (otherInfo[name]) {
|
|
355
|
-
tenantOrg[name] = otherInfo[name];
|
|
356
|
-
}
|
|
357
|
-
});
|
|
358
|
-
|
|
359
|
-
await tenantOrg.save();
|
|
360
|
-
};
|
|
361
|
-
|
|
362
|
-
const deleteTenantOrg = async ({ id, tenantId }) => {
|
|
363
|
-
const tenantOrg = await fastify.account.models.tenantOrg.findByPk(id, {
|
|
364
|
-
where: {
|
|
365
|
-
type: 0
|
|
366
|
-
}
|
|
367
|
-
});
|
|
368
|
-
|
|
369
|
-
if (!tenantOrg) {
|
|
370
|
-
throw new Error('该组织不存在');
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
const { rows } = await fastify.account.models.tenantOrg.findAndCountAll({
|
|
374
|
-
where: { tenantId, pid: id }
|
|
375
|
-
});
|
|
376
|
-
|
|
377
|
-
if (rows?.length) {
|
|
378
|
-
throw new Error('组织下有用户或子组织无法删除');
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
await tenantOrg.destroy();
|
|
382
|
-
};
|
|
383
|
-
|
|
384
|
-
const getTenantOrgList = async ({ tenantId }) => {
|
|
385
|
-
const { count, rows } = await fastify.account.models.tenantOrg.findAndCountAll({
|
|
386
|
-
where: { tenantId }
|
|
387
|
-
});
|
|
388
|
-
|
|
389
|
-
return { pageData: rows, totalCount: count };
|
|
390
|
-
};
|
|
391
|
-
|
|
392
|
-
const getTenantUserList = async ({ tenantId }) => {
|
|
393
|
-
if (!(await fastify.account.models.tenant.findByPk(tenantId))) {
|
|
394
|
-
throw new Error('租户不存在');
|
|
395
|
-
}
|
|
396
|
-
const { count, rows } = await fastify.account.models.tenantUser.findAndCountAll({
|
|
397
|
-
include: [fastify.account.models.tenantRole, fastify.account.models.tenantOrg, fastify.account.models.user],
|
|
398
|
-
where: { tenantId }
|
|
399
|
-
});
|
|
400
|
-
|
|
401
|
-
return { pageData: rows, totalCount: count };
|
|
402
|
-
};
|
|
403
|
-
|
|
404
|
-
const saveTenantUserInfoValidate = async ({ tenantId, roleIds, orgIds, userId }) => {
|
|
405
|
-
await getTenantInfo({ id: tenantId });
|
|
406
|
-
if (
|
|
407
|
-
roleIds.length > 0 &&
|
|
408
|
-
(await fastify.account.models.tenantRole.count({
|
|
409
|
-
where: {
|
|
410
|
-
id: {
|
|
411
|
-
[fastify.sequelize.Sequelize.Op.in]: roleIds
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
})) < roleIds.length
|
|
415
|
-
) {
|
|
416
|
-
throw new Error('包含租户不存在的角色');
|
|
417
|
-
}
|
|
418
|
-
if (orgIds.length === 0) {
|
|
419
|
-
const tenantOrg = await fastify.account.models.tenantOrg.findOne({
|
|
420
|
-
where: {
|
|
421
|
-
pid: 0,
|
|
422
|
-
tenantId
|
|
423
|
-
}
|
|
424
|
-
});
|
|
425
|
-
if (!tenantOrg) {
|
|
426
|
-
throw new Error('租户根节点不存在');
|
|
427
|
-
}
|
|
428
|
-
orgIds = [tenantOrg.id];
|
|
48
|
+
const addTenant = async tenant => {
|
|
49
|
+
if (await models.tenant.count({ where: { name: tenant.name } })) {
|
|
50
|
+
throw new Error('租户名称不能重复');
|
|
429
51
|
}
|
|
430
52
|
|
|
431
|
-
if (
|
|
432
|
-
(await fastify.account.models.tenantOrg.count({
|
|
433
|
-
where: {
|
|
434
|
-
tenantId,
|
|
435
|
-
id: {
|
|
436
|
-
[fastify.sequelize.Sequelize.Op.in]: orgIds
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
})) < orgIds.length
|
|
440
|
-
) {
|
|
441
|
-
throw new Error('包含租户不存在组织');
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
if (!(await fastify.account.models.user.findByPk(userId))) {
|
|
445
|
-
throw new Error('用户不存在,应该先创建用户再创建租户用户');
|
|
446
|
-
}
|
|
447
|
-
};
|
|
448
|
-
|
|
449
|
-
const addTenantUser = async ({ tenantId, roleIds, orgIds, userId, ...tenantUser }) => {
|
|
450
|
-
const tenant = await getTenantInfo({ id: tenantId });
|
|
451
|
-
|
|
452
|
-
const currentAccountNumber = await fastify.account.models.tenantUser.count({
|
|
453
|
-
where: { tenantId }
|
|
454
|
-
});
|
|
455
|
-
|
|
456
|
-
if (currentAccountNumber >= tenant.accountNumber) {
|
|
457
|
-
throw new Error('租户用户数量已达上限');
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
await saveTenantUserInfoValidate({ tenantId, roleIds, orgIds, userId });
|
|
461
|
-
|
|
462
53
|
const t = await fastify.sequelize.instance.transaction();
|
|
463
|
-
|
|
464
|
-
if (
|
|
465
|
-
(await fastify.account.models.tenantUser.count({
|
|
466
|
-
where: {
|
|
467
|
-
userId,
|
|
468
|
-
tenantId
|
|
469
|
-
}
|
|
470
|
-
})) > 0
|
|
471
|
-
) {
|
|
472
|
-
throw new Error('该用户已经属于该租户,不能重复添加');
|
|
473
|
-
}
|
|
474
|
-
|
|
475
54
|
try {
|
|
476
|
-
const
|
|
55
|
+
const currentTenant = await models.tenant.create(tenant);
|
|
56
|
+
await models.tenantRole.create(
|
|
477
57
|
{
|
|
478
|
-
name:
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
description: tenantUser.description,
|
|
483
|
-
tenantId,
|
|
484
|
-
userId
|
|
58
|
+
name: '系统默认角色',
|
|
59
|
+
tenantId: currentTenant.uuid,
|
|
60
|
+
description: '创建租户时自动生成,可以设置权限,不可更改删除,所有租户用户默认拥有该角色',
|
|
61
|
+
type: 1
|
|
485
62
|
},
|
|
486
63
|
{ transaction: t }
|
|
487
64
|
);
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
tenantRoleId: roleId,
|
|
493
|
-
tenantId,
|
|
494
|
-
tenantUserId: currentTenantUser.id
|
|
495
|
-
};
|
|
496
|
-
}),
|
|
497
|
-
{ transaction: t }
|
|
498
|
-
));
|
|
499
|
-
|
|
500
|
-
await fastify.account.models.tenantUserOrg.bulkCreate(
|
|
501
|
-
orgIds.map(orgId => {
|
|
502
|
-
return {
|
|
503
|
-
tenantOrgId: orgId,
|
|
504
|
-
tenantId,
|
|
505
|
-
tenantUserId: currentTenantUser.id
|
|
506
|
-
};
|
|
507
|
-
}),
|
|
508
|
-
{ transaction: t }
|
|
509
|
-
);
|
|
510
|
-
|
|
511
|
-
await t.commit();
|
|
512
|
-
} catch (e) {
|
|
513
|
-
await t.rollback();
|
|
514
|
-
throw e;
|
|
515
|
-
}
|
|
516
|
-
};
|
|
517
|
-
|
|
518
|
-
const saveTenantUser = async ({ id, tenantId, roleIds, orgIds, userId, ...tenantUser }) => {
|
|
519
|
-
const currentTenantUser = await fastify.account.models.tenantUser.findByPk(id);
|
|
520
|
-
if (!currentTenantUser) {
|
|
521
|
-
throw new Error('租户用户不存在');
|
|
522
|
-
}
|
|
523
|
-
if (tenantId !== currentTenantUser.tenantId) {
|
|
524
|
-
throw new Error('租户Id和当前租户用户的租户Id不一致');
|
|
525
|
-
}
|
|
526
|
-
await saveTenantUserInfoValidate({ tenantId, roleIds, orgIds, userId: currentTenantUser.userId });
|
|
527
|
-
|
|
528
|
-
const tenantRoleIds = (
|
|
529
|
-
await fastify.account.models.tenantUserRole.findAll({
|
|
530
|
-
attributes: ['tenantRoleId'],
|
|
531
|
-
where: {
|
|
532
|
-
tenantId,
|
|
533
|
-
tenantUserId: currentTenantUser.id
|
|
534
|
-
}
|
|
535
|
-
})
|
|
536
|
-
).map(({ tenantRoleId }) => tenantRoleId);
|
|
537
|
-
|
|
538
|
-
const tenantOrgIds = (
|
|
539
|
-
await fastify.account.models.tenantUserOrg.findAll({
|
|
540
|
-
attributes: ['tenantOrgId'],
|
|
541
|
-
where: {
|
|
542
|
-
tenantId,
|
|
543
|
-
tenantUserId: currentTenantUser.id
|
|
544
|
-
}
|
|
545
|
-
})
|
|
546
|
-
).map(({ tenantOrgId }) => tenantOrgId);
|
|
547
|
-
|
|
548
|
-
const t = await fastify.sequelize.instance.transaction();
|
|
549
|
-
|
|
550
|
-
try {
|
|
551
|
-
['name', 'avatar', 'phone', 'email', 'description'].forEach(name => {
|
|
552
|
-
if (!isNil(tenantUser[name])) {
|
|
553
|
-
currentTenantUser[name] = tenantUser[name];
|
|
554
|
-
}
|
|
555
|
-
});
|
|
556
|
-
await currentTenantUser.save({ transaction: t });
|
|
557
|
-
// 修改角色
|
|
558
|
-
const needDeleteTenantRole = tenantRoleIds.filter(targetId => roleIds.indexOf(targetId) === -1);
|
|
559
|
-
const needAddTenantRole = roleIds.filter(targetId => tenantRoleIds.indexOf(targetId) === -1);
|
|
560
|
-
await fastify.account.models.tenantUserRole.destroy({
|
|
561
|
-
where: {
|
|
562
|
-
tenantId,
|
|
563
|
-
tenantUserId: currentTenantUser.id,
|
|
564
|
-
tenantRoleId: {
|
|
565
|
-
[fastify.sequelize.Sequelize.Op.in]: needDeleteTenantRole
|
|
566
|
-
}
|
|
567
|
-
},
|
|
568
|
-
transaction: t
|
|
569
|
-
});
|
|
570
|
-
await fastify.account.models.tenantUserRole.bulkCreate(
|
|
571
|
-
needAddTenantRole.map(tenantRoleId => {
|
|
572
|
-
return { tenantId, tenantUserId: currentTenantUser.id, tenantRoleId };
|
|
573
|
-
}),
|
|
574
|
-
{ transaction: t }
|
|
575
|
-
);
|
|
576
|
-
//修改组织
|
|
577
|
-
const needDeleteTenantOrg = tenantOrgIds.filter(targetId => orgIds.indexOf(targetId) === -1);
|
|
578
|
-
const needAddTenantOrg = orgIds.filter(targetId => tenantOrgIds.indexOf(targetId) === -1);
|
|
579
|
-
await fastify.account.models.tenantUserOrg.destroy({
|
|
580
|
-
where: {
|
|
581
|
-
tenantId,
|
|
582
|
-
tenantUserId: currentTenantUser.id,
|
|
583
|
-
tenantOrgId: {
|
|
584
|
-
[fastify.sequelize.Sequelize.Op.in]: needDeleteTenantOrg
|
|
585
|
-
}
|
|
65
|
+
await models.tenantOrg.create(
|
|
66
|
+
{
|
|
67
|
+
name: '根组织',
|
|
68
|
+
tenantId: currentTenant.uuid
|
|
586
69
|
},
|
|
587
|
-
transaction: t
|
|
588
|
-
});
|
|
589
|
-
await fastify.account.models.tenantUserOrg.bulkCreate(
|
|
590
|
-
needAddTenantOrg.map(tenantOrgId => {
|
|
591
|
-
return { tenantId, tenantUserId: currentTenantUser.id, tenantOrgId };
|
|
592
|
-
}),
|
|
593
70
|
{ transaction: t }
|
|
594
71
|
);
|
|
595
72
|
await t.commit();
|
|
@@ -599,135 +76,57 @@ module.exports = fp(async (fastify, options) => {
|
|
|
599
76
|
}
|
|
600
77
|
};
|
|
601
78
|
|
|
602
|
-
const
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
const t = await fastify.sequelize.instance.transaction();
|
|
610
|
-
|
|
611
|
-
try {
|
|
612
|
-
await fastify.account.models.tenantUserOrg.destroy({
|
|
613
|
-
where: {
|
|
614
|
-
tenantId,
|
|
615
|
-
tenantUserId: tenantUser.id
|
|
616
|
-
},
|
|
617
|
-
transaction: t
|
|
618
|
-
});
|
|
619
|
-
await fastify.account.models.tenantUserRole.destroy({
|
|
620
|
-
where: {
|
|
621
|
-
tenantId,
|
|
622
|
-
tenantUserId: tenantUser.id
|
|
623
|
-
},
|
|
624
|
-
transaction: t
|
|
625
|
-
});
|
|
626
|
-
await tenantUser.destroy({ transaction: t });
|
|
627
|
-
await t.commit();
|
|
628
|
-
} catch (e) {
|
|
629
|
-
await t.rollback();
|
|
630
|
-
throw e;
|
|
79
|
+
const getAllTenantList = async ({ filter, perPage, currentPage }) => {
|
|
80
|
+
const queryFilter = {};
|
|
81
|
+
if (filter?.name) {
|
|
82
|
+
queryFilter.name = {
|
|
83
|
+
[fastify.sequelize.Sequelize.Op.like]: `%${filter.name}%`
|
|
84
|
+
};
|
|
631
85
|
}
|
|
632
|
-
};
|
|
633
86
|
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
throw new Error('租户用户不存在');
|
|
87
|
+
if (filter?.serviceStartTime) {
|
|
88
|
+
queryFilter.serviceStartTime = {
|
|
89
|
+
[fastify.sequelize.Sequelize.Op.gt]: filter.serviceStartTime
|
|
90
|
+
};
|
|
639
91
|
}
|
|
640
|
-
tenantUser.status = 12;
|
|
641
|
-
|
|
642
|
-
await tenantUser.save();
|
|
643
|
-
};
|
|
644
92
|
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
throw new Error('租户用户不存在');
|
|
93
|
+
if (filter?.serviceEndTime) {
|
|
94
|
+
queryFilter.serviceEndTime = {
|
|
95
|
+
[fastify.sequelize.Sequelize.Op.lt]: filter.serviceEndTime
|
|
96
|
+
};
|
|
650
97
|
}
|
|
651
|
-
tenantUser.status = 0;
|
|
652
|
-
|
|
653
|
-
await tenantUser.save();
|
|
654
|
-
};
|
|
655
98
|
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
const { count, rows } = await fastify.account.models.tenantToken.findAndCountAll({
|
|
659
|
-
where: Object.assign({}, queryFilter, { tenantId, type: 10 }),
|
|
99
|
+
const { count, rows } = await models.tenant.findAndCountAll({
|
|
100
|
+
where: queryFilter,
|
|
660
101
|
offset: currentPage * (currentPage - 1),
|
|
661
102
|
limit: perPage
|
|
662
103
|
});
|
|
663
|
-
return { pageData: rows, totalCount: count };
|
|
664
|
-
};
|
|
665
|
-
|
|
666
|
-
const generateTenantToken = async ({ type, tenantId, info, tenantUserId }) => {
|
|
667
|
-
await getTenantInfo({ id: tenantId });
|
|
668
|
-
const token = fastify.jwt.sign({ tenantId });
|
|
669
|
-
return await fastify.account.models.tenantToken.create({
|
|
670
|
-
token,
|
|
671
|
-
tenantId,
|
|
672
|
-
info,
|
|
673
|
-
tenantUserId,
|
|
674
|
-
type
|
|
675
|
-
});
|
|
676
|
-
};
|
|
677
104
|
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
tenantId,
|
|
684
|
-
token
|
|
105
|
+
/*const res = await models.tenantUser.findAll({
|
|
106
|
+
attributes: ['tenantId', fastify.sequelize.instance.fn('count', fastify.sequelize.instance.col('tenantId'))],
|
|
107
|
+
where: {
|
|
108
|
+
tenantId: {
|
|
109
|
+
[fastify.sequelize.Sequelize.Op.in]: rows.map(({ id }) => id)
|
|
685
110
|
}
|
|
686
|
-
}
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
}
|
|
690
|
-
|
|
691
|
-
return fastify.jwt.decode(token);
|
|
692
|
-
};
|
|
693
|
-
|
|
694
|
-
const addInviteToken = async ({ info, tenantId, tenantUserId }) => {
|
|
695
|
-
return await generateTenantToken({ info, tenantId, tenantUserId, type: 10 });
|
|
696
|
-
};
|
|
697
|
-
|
|
698
|
-
const deleteInviteToken = async ({ id }) => {
|
|
699
|
-
const token = await fastify.account.models.tenantToken.findByPk(id);
|
|
700
|
-
if (!token) {
|
|
701
|
-
throw new Error('数据不存在');
|
|
702
|
-
}
|
|
111
|
+
},
|
|
112
|
+
group: 'tenantId'
|
|
113
|
+
});*/
|
|
703
114
|
|
|
704
|
-
|
|
115
|
+
return {
|
|
116
|
+
pageData: rows.map(item => {
|
|
117
|
+
return Object.assign({}, item.get({ pain: true }), { id: item.uuid });
|
|
118
|
+
}),
|
|
119
|
+
totalCount: count
|
|
120
|
+
};
|
|
705
121
|
};
|
|
706
122
|
|
|
707
|
-
|
|
708
|
-
|
|
123
|
+
services.tenant = {
|
|
124
|
+
getTenantInstance,
|
|
125
|
+
getTenant,
|
|
709
126
|
closeTenant,
|
|
710
127
|
openTenant,
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
addRole,
|
|
715
|
-
saveRole,
|
|
716
|
-
removeRole,
|
|
717
|
-
addTenantOrg,
|
|
718
|
-
deleteTenantOrg,
|
|
719
|
-
saveTenantOrg,
|
|
720
|
-
getTenantOrgList,
|
|
721
|
-
getTenantUserList,
|
|
722
|
-
addTenantUser,
|
|
723
|
-
saveTenantUser,
|
|
724
|
-
deleteTenantUser,
|
|
725
|
-
closeTenantUser,
|
|
726
|
-
openTenantUser,
|
|
727
|
-
getInviteList,
|
|
728
|
-
generateTenantToken,
|
|
729
|
-
decodeTenantToken,
|
|
730
|
-
addInviteToken,
|
|
731
|
-
deleteInviteToken
|
|
128
|
+
saveTenant,
|
|
129
|
+
addTenant,
|
|
130
|
+
getAllTenantList
|
|
732
131
|
};
|
|
733
132
|
});
|