@kne/fastify-account 1.0.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1436 -0
- package/index.js +54 -0
- package/libs/controllers/account.js +189 -0
- package/libs/controllers/admin.js +153 -0
- package/libs/controllers/adminPermission.js +230 -0
- package/libs/controllers/adminRole.js +145 -0
- package/libs/controllers/adminTenant.js +461 -0
- package/libs/controllers/tenant.js +22 -0
- package/libs/controllers/user.js +12 -0
- package/libs/models/admin-role.js +19 -0
- package/libs/models/application.js +36 -0
- package/libs/models/login-log.js +15 -0
- package/libs/models/permission.js +53 -0
- package/libs/models/tenant-application.js +28 -0
- package/libs/models/tenant-org.js +30 -0
- package/libs/models/tenant-permission.js +28 -0
- package/libs/models/tenant-role-application.js +32 -0
- package/libs/models/tenant-role-permission.js +32 -0
- package/libs/models/tenant-role.js +27 -0
- package/libs/models/tenant-share-group-permission.js +22 -0
- package/libs/models/tenant-share-group.js +22 -0
- package/libs/models/tenant-source-user-share-group.js +22 -0
- package/libs/models/tenant-token.js +32 -0
- package/libs/models/tenant-user-org.js +22 -0
- package/libs/models/tenant-user-role.js +22 -0
- package/libs/models/tenant-user-share-group.js +22 -0
- package/libs/models/tenant-user.js +56 -0
- package/libs/models/tenant.js +38 -0
- package/libs/models/user-account.js +26 -0
- package/libs/models/user.js +50 -0
- package/libs/models/verification-code.js +26 -0
- package/libs/services/account.js +200 -0
- package/libs/services/admin.js +183 -0
- package/libs/services/permission.js +465 -0
- package/libs/services/tenant.js +576 -0
- package/libs/services/user.js +108 -0
- package/package.json +61 -0
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
const fp = require('fastify-plugin');
|
|
2
|
+
const isNil = require('lodash/isNil');
|
|
3
|
+
module.exports = fp(async (fastify, options) => {
|
|
4
|
+
const addApplication = async application => {
|
|
5
|
+
return fastify.account.models.application.create(application);
|
|
6
|
+
};
|
|
7
|
+
const saveApplication = async ({ id, ...others }) => {
|
|
8
|
+
const application = await fastify.account.models.application.findByPk(id);
|
|
9
|
+
if (!application) {
|
|
10
|
+
throw new Error('应用不存在');
|
|
11
|
+
}
|
|
12
|
+
['name', 'code', 'avatar', 'url', 'description'].forEach(name => {
|
|
13
|
+
if (!isNil(others[name])) {
|
|
14
|
+
application[name] = others[name];
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
await application.save();
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const deleteApplication = async ({ id }) => {
|
|
22
|
+
const application = await fastify.account.models.application.findByPk(id);
|
|
23
|
+
if (!application) {
|
|
24
|
+
throw new Error('应用不存在');
|
|
25
|
+
}
|
|
26
|
+
if (
|
|
27
|
+
(await fastify.account.models.tenantApplication.count({
|
|
28
|
+
where: {
|
|
29
|
+
applicationId: application.id
|
|
30
|
+
}
|
|
31
|
+
})) > 0
|
|
32
|
+
) {
|
|
33
|
+
throw new Error('应用已经开放给其他租户使用,不能删除');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const permissionIdList = (
|
|
37
|
+
await fastify.account.models.permission.findAll({
|
|
38
|
+
where: { applicationId: application.id }
|
|
39
|
+
})
|
|
40
|
+
).map(({ id }) => id);
|
|
41
|
+
|
|
42
|
+
const t = await fastify.sequelize.instance.transaction();
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
await fastify.account.models.tenantPermission.destroy(
|
|
46
|
+
{
|
|
47
|
+
where: {
|
|
48
|
+
permissionId: {
|
|
49
|
+
[fastify.sequelize.Sequelize.Op.in]: permissionIdList
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
{ transaction: t }
|
|
54
|
+
);
|
|
55
|
+
|
|
56
|
+
await fastify.account.models.tenantRolePermission.destroy(
|
|
57
|
+
{
|
|
58
|
+
where: {
|
|
59
|
+
permissionId: {
|
|
60
|
+
[fastify.sequelize.Sequelize.Op.in]: permissionIdList
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
{ transaction: t }
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
await fastify.account.models.permission.destroy({
|
|
68
|
+
where: {
|
|
69
|
+
applicationId: application.id
|
|
70
|
+
},
|
|
71
|
+
transaction: t
|
|
72
|
+
});
|
|
73
|
+
await application.destroy({ transaction: t });
|
|
74
|
+
await t.commit();
|
|
75
|
+
} catch (e) {
|
|
76
|
+
await t.rollback();
|
|
77
|
+
throw e;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
const getApplicationList = async ({ tenantId }) => {
|
|
82
|
+
const query = {};
|
|
83
|
+
if (tenantId) {
|
|
84
|
+
const tenant = await fastify.account.models.tenant.findByPk(tenantId);
|
|
85
|
+
if (!tenant) {
|
|
86
|
+
throw new Error('租户不存在');
|
|
87
|
+
}
|
|
88
|
+
const tenantApplications = await fastify.account.models.tenantApplication.findAll({
|
|
89
|
+
where: { tenantId }
|
|
90
|
+
});
|
|
91
|
+
query.id = {
|
|
92
|
+
[fastify.sequelize.Sequelize.Op.in]: tenantApplications.map(({ applicationId }) => applicationId)
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
return await fastify.account.models.application.findAll({
|
|
96
|
+
where: query
|
|
97
|
+
});
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const addPermission = async ({ applicationId, pid, code, name, type, isModule, isMust, description }) => {
|
|
101
|
+
if (!(await fastify.account.models.application.findByPk(applicationId))) {
|
|
102
|
+
throw new Error('应用不存在');
|
|
103
|
+
}
|
|
104
|
+
const paths = [];
|
|
105
|
+
if (pid > 0) {
|
|
106
|
+
const parentNode = await fastify.account.models.permission.findByPk(pid);
|
|
107
|
+
if (!parentNode) {
|
|
108
|
+
throw new Error('未找到父级');
|
|
109
|
+
}
|
|
110
|
+
paths.push(...parentNode.paths, parentNode.id);
|
|
111
|
+
}
|
|
112
|
+
if (
|
|
113
|
+
(await fastify.account.models.permission.count({
|
|
114
|
+
where: {
|
|
115
|
+
pid,
|
|
116
|
+
code,
|
|
117
|
+
applicationId
|
|
118
|
+
}
|
|
119
|
+
})) > 0
|
|
120
|
+
) {
|
|
121
|
+
throw new Error('同一级权限code不能重复');
|
|
122
|
+
}
|
|
123
|
+
return await fastify.account.models.permission.create({
|
|
124
|
+
applicationId,
|
|
125
|
+
code,
|
|
126
|
+
description,
|
|
127
|
+
name,
|
|
128
|
+
type,
|
|
129
|
+
pid,
|
|
130
|
+
isModule,
|
|
131
|
+
isMust,
|
|
132
|
+
paths
|
|
133
|
+
});
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const getPermissionList = async ({ applicationId, tenantId }) => {
|
|
137
|
+
const query = {};
|
|
138
|
+
if (tenantId) {
|
|
139
|
+
const tenant = await fastify.account.models.tenant.findByPk(tenantId);
|
|
140
|
+
if (!tenant) {
|
|
141
|
+
throw new Error('租户不存在');
|
|
142
|
+
}
|
|
143
|
+
const tenantPermissions = await fastify.account.models.tenantPermission.findAll({
|
|
144
|
+
where: { tenantId }
|
|
145
|
+
});
|
|
146
|
+
query[fastify.sequelize.Sequelize.Op.or] = [
|
|
147
|
+
{
|
|
148
|
+
id: {
|
|
149
|
+
[fastify.sequelize.Sequelize.Op.in]: tenantPermissions.map(({ permissionId }) => permissionId)
|
|
150
|
+
}
|
|
151
|
+
},
|
|
152
|
+
{ isMust: 1 }
|
|
153
|
+
];
|
|
154
|
+
}
|
|
155
|
+
return await fastify.account.models.permission.findAll({
|
|
156
|
+
where: Object.assign({}, { applicationId }, query)
|
|
157
|
+
});
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const deletePermission = async ({ id }) => {
|
|
161
|
+
const currentPermission = await fastify.account.models.permission.findByPk(id);
|
|
162
|
+
|
|
163
|
+
if (!currentPermission) {
|
|
164
|
+
throw new Error('权限不存在');
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const permissionList = await fastify.account.models.permission.findAll({
|
|
168
|
+
where: {
|
|
169
|
+
applicationId: currentPermission.applicationId
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
const childrenNode = permissionList.filter(({ paths }) => {
|
|
174
|
+
return paths.indexOf(currentPermission.id) > -1;
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
const permissionIdList = [currentPermission.id, ...childrenNode.map(({ id }) => id)];
|
|
178
|
+
|
|
179
|
+
const t = await fastify.sequelize.instance.transaction();
|
|
180
|
+
try {
|
|
181
|
+
await fastify.account.models.tenantPermission.destroy({
|
|
182
|
+
where: {
|
|
183
|
+
permissionId: {
|
|
184
|
+
[fastify.sequelize.Sequelize.Op.in]: permissionIdList
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
transaction: t
|
|
188
|
+
});
|
|
189
|
+
await fastify.account.models.tenantRolePermission.destroy({
|
|
190
|
+
where: {
|
|
191
|
+
permissionId: {
|
|
192
|
+
[fastify.sequelize.Sequelize.Op.in]: permissionIdList
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
transaction: t
|
|
196
|
+
});
|
|
197
|
+
await fastify.account.models.permission.destroy({
|
|
198
|
+
where: {
|
|
199
|
+
id: {
|
|
200
|
+
[fastify.sequelize.Sequelize.Op.in]: permissionIdList
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
transaction: t
|
|
204
|
+
});
|
|
205
|
+
await t.commit();
|
|
206
|
+
} catch (e) {
|
|
207
|
+
await t.rollback();
|
|
208
|
+
throw e;
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
const savePermission = async permission => {
|
|
213
|
+
const currentPermission = await fastify.account.models.permission.findByPk(permission.id);
|
|
214
|
+
|
|
215
|
+
if (!permission) {
|
|
216
|
+
throw new Error('权限不存在');
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
['name', 'type', 'isMust', 'description'].forEach(name => {
|
|
220
|
+
if (!isNil(permission[name])) {
|
|
221
|
+
currentPermission[name] = permission[name];
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
await currentPermission.save();
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
const saveTenantPermissionList = async ({ tenantId, applications, permissions }) => {
|
|
229
|
+
if (!(await fastify.account.models.tenant.findByPk(tenantId))) {
|
|
230
|
+
throw new Error('租户不存在');
|
|
231
|
+
}
|
|
232
|
+
const currentApplications = await fastify.account.models.tenantApplication.findAll({
|
|
233
|
+
where: { tenantId }
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
const currentApplicationIds = currentApplications.map(({ applicationId }) => applicationId);
|
|
237
|
+
|
|
238
|
+
const currentPermissions = await fastify.account.models.tenantPermission.findAll({
|
|
239
|
+
where: { tenantId }
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
const currentPermissionIds = currentPermissions.map(({ permissionId }) => permissionId);
|
|
243
|
+
|
|
244
|
+
const t = await fastify.sequelize.instance.transaction();
|
|
245
|
+
try {
|
|
246
|
+
//先删除,后添加
|
|
247
|
+
const needDeleteApplications = currentApplications.filter(item => applications.indexOf(item.applicationId) === -1).map(({ applicationId }) => applicationId);
|
|
248
|
+
const needAddApplications = applications.filter(applicationId => currentApplicationIds.indexOf(applicationId) === -1);
|
|
249
|
+
const needDeletePermissions = currentPermissions.filter(item => permissions.indexOf(item.permissionId) === -1).map(({ permissionId }) => permissionId);
|
|
250
|
+
const needAddPermissions = permissions.filter(permissionId => currentPermissionIds.indexOf(permissionId) === -1);
|
|
251
|
+
|
|
252
|
+
await fastify.account.models.tenantRoleApplication.destroy({
|
|
253
|
+
where: {
|
|
254
|
+
applicationId: {
|
|
255
|
+
[fastify.sequelize.Sequelize.Op.in]: needDeleteApplications
|
|
256
|
+
},
|
|
257
|
+
tenantId
|
|
258
|
+
},
|
|
259
|
+
transaction: t
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
await fastify.account.models.tenantRolePermission.destroy({
|
|
263
|
+
where: {
|
|
264
|
+
permissionId: {
|
|
265
|
+
[fastify.sequelize.Sequelize.Op.in]: needDeletePermissions
|
|
266
|
+
},
|
|
267
|
+
tenantId
|
|
268
|
+
},
|
|
269
|
+
transaction: t
|
|
270
|
+
});
|
|
271
|
+
|
|
272
|
+
await fastify.account.models.tenantApplication.destroy({
|
|
273
|
+
where: {
|
|
274
|
+
applicationId: {
|
|
275
|
+
[fastify.sequelize.Sequelize.Op.in]: needDeleteApplications
|
|
276
|
+
},
|
|
277
|
+
tenantId
|
|
278
|
+
},
|
|
279
|
+
transaction: t
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
await fastify.account.models.tenantPermission.destroy({
|
|
283
|
+
where: {
|
|
284
|
+
permissionId: {
|
|
285
|
+
[fastify.sequelize.Sequelize.Op.in]: needDeletePermissions
|
|
286
|
+
},
|
|
287
|
+
tenantId
|
|
288
|
+
},
|
|
289
|
+
transaction: t
|
|
290
|
+
});
|
|
291
|
+
|
|
292
|
+
needAddApplications.length > 0 &&
|
|
293
|
+
(await fastify.account.models.tenantApplication.bulkCreate(
|
|
294
|
+
needAddApplications.map(applicationId => {
|
|
295
|
+
return { tenantId, applicationId };
|
|
296
|
+
}),
|
|
297
|
+
{ transaction: t }
|
|
298
|
+
));
|
|
299
|
+
|
|
300
|
+
needAddPermissions.length > 0 &&
|
|
301
|
+
(await fastify.account.models.tenantPermission.bulkCreate(
|
|
302
|
+
needAddPermissions.map(permissionId => {
|
|
303
|
+
return { tenantId, permissionId };
|
|
304
|
+
}),
|
|
305
|
+
{ transaction: t }
|
|
306
|
+
));
|
|
307
|
+
|
|
308
|
+
await t.commit();
|
|
309
|
+
} catch (e) {
|
|
310
|
+
await t.rollback();
|
|
311
|
+
throw e;
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
const saveRolePermissionList = async ({ roleId, applications, permissions }) => {
|
|
316
|
+
const role = await fastify.account.models.tenantRole.findByPk(roleId);
|
|
317
|
+
if (!role) {
|
|
318
|
+
throw new Error('角色不存在');
|
|
319
|
+
}
|
|
320
|
+
if (!(await fastify.account.models.tenant.findByPk(role.tenantId))) {
|
|
321
|
+
throw new Error('租户不存在');
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
const tenantId = role.tenantId;
|
|
325
|
+
|
|
326
|
+
const tenantApplications = await fastify.account.models.tenantApplication.findAll({
|
|
327
|
+
attributes: ['applicationId'],
|
|
328
|
+
where: { tenantId }
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
const tenantPermissions = await fastify.account.models.tenantPermission.findAll({
|
|
332
|
+
attributes: ['permissionId'],
|
|
333
|
+
where: { tenantId }
|
|
334
|
+
});
|
|
335
|
+
|
|
336
|
+
const tenantApplicationIds = tenantApplications.map(({ applicationId }) => applicationId);
|
|
337
|
+
const tenantPermissionIds = tenantPermissions.map(({ permissionId }) => permissionId);
|
|
338
|
+
|
|
339
|
+
const currentApplications = await fastify.account.models.tenantRoleApplication.findAll({
|
|
340
|
+
where: {
|
|
341
|
+
roleId: role.id,
|
|
342
|
+
tenantId,
|
|
343
|
+
applicationId: {
|
|
344
|
+
[fastify.sequelize.Sequelize.Op.in]: tenantApplicationIds
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
const currentPermissions = await fastify.account.models.tenantRolePermission.findAll({
|
|
350
|
+
where: {
|
|
351
|
+
roleId: role.id,
|
|
352
|
+
tenantId,
|
|
353
|
+
permissionId: { [fastify.sequelize.Sequelize.Op.in]: tenantPermissionIds }
|
|
354
|
+
}
|
|
355
|
+
});
|
|
356
|
+
|
|
357
|
+
const currentApplicationIds = currentApplications.map(({ applicationId }) => applicationId);
|
|
358
|
+
const currentPermissionIds = currentPermissions.map(({ permissionId }) => permissionId);
|
|
359
|
+
|
|
360
|
+
const t = await fastify.sequelize.instance.transaction();
|
|
361
|
+
|
|
362
|
+
try {
|
|
363
|
+
//先删除,后添加
|
|
364
|
+
const needDeleteApplications = currentApplicationIds.filter(applicationId => applications.indexOf(applicationId) === -1);
|
|
365
|
+
const needAddApplications = applications.filter(applicationId => currentApplicationIds.indexOf(applicationId) === -1 && tenantApplicationIds.indexOf(applicationId) > -1);
|
|
366
|
+
const needDeletePermissions = currentPermissionIds.filter(permissionId => permissions.indexOf(permissionId) === -1);
|
|
367
|
+
const needAddPermissions = permissions.filter(permissionId => currentPermissionIds.indexOf(permissionId) === -1 && tenantPermissionIds.indexOf(permissionId) > -1);
|
|
368
|
+
|
|
369
|
+
needDeleteApplications.length > 0 &&
|
|
370
|
+
(await fastify.account.models.tenantRoleApplication.destroy({
|
|
371
|
+
where: {
|
|
372
|
+
applicationId: {
|
|
373
|
+
[fastify.sequelize.Sequelize.Op.in]: needDeleteApplications
|
|
374
|
+
},
|
|
375
|
+
tenantId
|
|
376
|
+
},
|
|
377
|
+
transaction: t
|
|
378
|
+
}));
|
|
379
|
+
|
|
380
|
+
needDeletePermissions.length > 0 &&
|
|
381
|
+
(await fastify.account.models.tenantRolePermission.destroy({
|
|
382
|
+
where: {
|
|
383
|
+
permissionId: {
|
|
384
|
+
[fastify.sequelize.Sequelize.Op.in]: needDeletePermissions
|
|
385
|
+
},
|
|
386
|
+
tenantId
|
|
387
|
+
},
|
|
388
|
+
transaction: t
|
|
389
|
+
}));
|
|
390
|
+
|
|
391
|
+
needAddApplications.length > 0 &&
|
|
392
|
+
(await fastify.account.models.tenantRoleApplication.bulkCreate(
|
|
393
|
+
needAddApplications.map(applicationId => {
|
|
394
|
+
return {
|
|
395
|
+
tenantId,
|
|
396
|
+
roleId,
|
|
397
|
+
applicationId
|
|
398
|
+
};
|
|
399
|
+
}),
|
|
400
|
+
{ transaction: t }
|
|
401
|
+
));
|
|
402
|
+
|
|
403
|
+
needAddPermissions.length > 0 &&
|
|
404
|
+
(await fastify.account.models.tenantRolePermission.bulkCreate(
|
|
405
|
+
needAddPermissions.map(permissionId => {
|
|
406
|
+
return {
|
|
407
|
+
tenantId,
|
|
408
|
+
roleId,
|
|
409
|
+
permissionId
|
|
410
|
+
};
|
|
411
|
+
}),
|
|
412
|
+
{ transaction: t }
|
|
413
|
+
));
|
|
414
|
+
|
|
415
|
+
await t.commit();
|
|
416
|
+
} catch (e) {
|
|
417
|
+
await t.rollback();
|
|
418
|
+
throw e;
|
|
419
|
+
}
|
|
420
|
+
};
|
|
421
|
+
|
|
422
|
+
const getTenantPermissionList = async ({ tenantId }) => {
|
|
423
|
+
await fastify.account.services.tenant.getTenantInfo({ id: tenantId });
|
|
424
|
+
|
|
425
|
+
const applications = await fastify.account.models.tenantApplication.findAll({
|
|
426
|
+
where: { tenantId, status: 0 }
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
const permissions = await fastify.account.models.tenantPermission.findAll({
|
|
430
|
+
where: { tenantId, status: 0 }
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
return { applications, permissions };
|
|
434
|
+
};
|
|
435
|
+
|
|
436
|
+
const getRolePermissionList = async ({ roleId }) => {
|
|
437
|
+
const role = await fastify.account.models.tenantRole.findByPk(roleId);
|
|
438
|
+
if (!role) {
|
|
439
|
+
throw new Error('角色不存在');
|
|
440
|
+
}
|
|
441
|
+
const applications = await fastify.account.models.tenantRoleApplication.findAll({
|
|
442
|
+
where: { roleId: role.id, tenantId: role.tenantId }
|
|
443
|
+
});
|
|
444
|
+
const permissions = await fastify.account.models.tenantRolePermission.findAll({
|
|
445
|
+
where: { roleId: role.id, tenantId: role.tenantId }
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
return { applications, permissions };
|
|
449
|
+
};
|
|
450
|
+
|
|
451
|
+
fastify.account.services.permission = {
|
|
452
|
+
addApplication,
|
|
453
|
+
saveApplication,
|
|
454
|
+
deleteApplication,
|
|
455
|
+
getApplicationList,
|
|
456
|
+
addPermission,
|
|
457
|
+
getPermissionList,
|
|
458
|
+
deletePermission,
|
|
459
|
+
savePermission,
|
|
460
|
+
saveTenantPermissionList,
|
|
461
|
+
saveRolePermissionList,
|
|
462
|
+
getTenantPermissionList,
|
|
463
|
+
getRolePermissionList
|
|
464
|
+
};
|
|
465
|
+
});
|