@nocobase/plugin-departments 2.1.0-beta.2 → 2.1.0-beta.21
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/LICENSE +201 -0
- package/README.md +99 -1
- package/dist/client/collections/departments.d.ts +34 -0
- package/dist/client/index.js +1 -1
- package/dist/externalVersion.js +12 -11
- package/dist/server/actions/users.d.ts +0 -1
- package/dist/server/actions/users.js +2 -31
- package/dist/server/collections/departments.d.ts +12 -0
- package/dist/server/collections/departments.js +17 -2
- package/dist/server/collections/users.js +1 -1
- package/dist/server/department-data-sync-resource.d.ts +2 -0
- package/dist/server/department-data-sync-resource.js +42 -2
- package/dist/server/middlewares/set-main-department.js +26 -62
- package/dist/server/migrations/20260417120000-add-parent-id-field.d.ts +13 -0
- package/dist/server/migrations/20260417120000-add-parent-id-field.js +57 -0
- package/dist/server/migrations/migrate-main-department-id-20250828100101.js +1 -1
- package/dist/server/plugin.js +10 -6
- package/dist/server/sync-user-main-department.d.ts +19 -0
- package/dist/server/sync-user-main-department.js +74 -0
- package/package.json +5 -2
- package/LICENSE.txt +0 -172
|
@@ -17,4 +17,3 @@
|
|
|
17
17
|
import { Context, Next } from '@nocobase/actions';
|
|
18
18
|
export declare const listExcludeDept: (ctx: Context, next: Next) => Promise<void>;
|
|
19
19
|
export declare const setDepartments: (ctx: Context, next: Next) => Promise<void>;
|
|
20
|
-
export declare const setMainDepartment: (ctx: Context, next: Next) => Promise<void>;
|
|
@@ -27,8 +27,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
27
27
|
var users_exports = {};
|
|
28
28
|
__export(users_exports, {
|
|
29
29
|
listExcludeDept: () => listExcludeDept,
|
|
30
|
-
setDepartments: () => setDepartments
|
|
31
|
-
setMainDepartment: () => setMainDepartment
|
|
30
|
+
setDepartments: () => setDepartments
|
|
32
31
|
});
|
|
33
32
|
module.exports = __toCommonJS(users_exports);
|
|
34
33
|
var import_actions = require("@nocobase/actions");
|
|
@@ -102,36 +101,8 @@ const setDepartments = async (ctx, next) => {
|
|
|
102
101
|
});
|
|
103
102
|
await next();
|
|
104
103
|
};
|
|
105
|
-
const setMainDepartment = async (ctx, next) => {
|
|
106
|
-
const { userId, departmentId } = ctx.action.params.values || {};
|
|
107
|
-
const repo = ctx.db.getRepository("users");
|
|
108
|
-
const throughRepo = ctx.db.getRepository("departmentsUsers");
|
|
109
|
-
await ctx.db.sequelize.transaction(async (t) => {
|
|
110
|
-
await repo.update({
|
|
111
|
-
filterByTk: userId,
|
|
112
|
-
values: { mainDepartmentId: departmentId },
|
|
113
|
-
transaction: t
|
|
114
|
-
});
|
|
115
|
-
const existingAssoc = await throughRepo.findOne({
|
|
116
|
-
filter: { userId, departmentId },
|
|
117
|
-
transaction: t
|
|
118
|
-
});
|
|
119
|
-
if (!existingAssoc) {
|
|
120
|
-
await throughRepo.create({
|
|
121
|
-
values: {
|
|
122
|
-
userId,
|
|
123
|
-
departmentId,
|
|
124
|
-
isOwner: false
|
|
125
|
-
},
|
|
126
|
-
transaction: t
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
await next();
|
|
131
|
-
};
|
|
132
104
|
// Annotate the CommonJS export names for ESM import in node:
|
|
133
105
|
0 && (module.exports = {
|
|
134
106
|
listExcludeDept,
|
|
135
|
-
setDepartments
|
|
136
|
-
setMainDepartment
|
|
107
|
+
setDepartments
|
|
137
108
|
});
|
|
@@ -33,5 +33,17 @@ export declare const ownersField: {
|
|
|
33
33
|
};
|
|
34
34
|
};
|
|
35
35
|
};
|
|
36
|
+
export declare const parentIdField: {
|
|
37
|
+
type: string;
|
|
38
|
+
name: string;
|
|
39
|
+
interface: string;
|
|
40
|
+
isForeignKey: boolean;
|
|
41
|
+
uiSchema: {
|
|
42
|
+
type: string;
|
|
43
|
+
title: string;
|
|
44
|
+
'x-component': string;
|
|
45
|
+
'x-read-pretty': boolean;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
36
48
|
declare const _default: import("@nocobase/database").CollectionOptions;
|
|
37
49
|
export default _default;
|
|
@@ -27,7 +27,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
27
27
|
var departments_exports = {};
|
|
28
28
|
__export(departments_exports, {
|
|
29
29
|
default: () => departments_default,
|
|
30
|
-
ownersField: () => ownersField
|
|
30
|
+
ownersField: () => ownersField,
|
|
31
|
+
parentIdField: () => parentIdField
|
|
31
32
|
});
|
|
32
33
|
module.exports = __toCommonJS(departments_exports);
|
|
33
34
|
var import_database = require("@nocobase/database");
|
|
@@ -58,6 +59,18 @@ const ownersField = {
|
|
|
58
59
|
}
|
|
59
60
|
}
|
|
60
61
|
};
|
|
62
|
+
const parentIdField = {
|
|
63
|
+
type: "bigInt",
|
|
64
|
+
name: "parentId",
|
|
65
|
+
interface: "integer",
|
|
66
|
+
isForeignKey: true,
|
|
67
|
+
uiSchema: {
|
|
68
|
+
type: "number",
|
|
69
|
+
title: "parentId",
|
|
70
|
+
"x-component": "InputNumber",
|
|
71
|
+
"x-read-pretty": true
|
|
72
|
+
}
|
|
73
|
+
};
|
|
61
74
|
var departments_default = (0, import_database.defineCollection)({
|
|
62
75
|
name: "departments",
|
|
63
76
|
migrationRules: ["overwrite"],
|
|
@@ -94,6 +107,7 @@ var departments_default = (0, import_database.defineCollection)({
|
|
|
94
107
|
"x-component": "Input"
|
|
95
108
|
}
|
|
96
109
|
},
|
|
110
|
+
parentIdField,
|
|
97
111
|
{
|
|
98
112
|
type: "boolean",
|
|
99
113
|
name: "isLeaf"
|
|
@@ -167,5 +181,6 @@ var departments_default = (0, import_database.defineCollection)({
|
|
|
167
181
|
});
|
|
168
182
|
// Annotate the CommonJS export names for ESM import in node:
|
|
169
183
|
0 && (module.exports = {
|
|
170
|
-
ownersField
|
|
184
|
+
ownersField,
|
|
185
|
+
parentIdField
|
|
171
186
|
});
|
|
@@ -16,6 +16,8 @@ export declare class DepartmentDataSyncResource extends UserDataResource {
|
|
|
16
16
|
get deptRepo(): import("@nocobase/database").Repository<any, any>;
|
|
17
17
|
get deptUserRepo(): import("@nocobase/database").Repository<any, any>;
|
|
18
18
|
getFlteredSourceDepartment(sourceDepartment: FormatDepartment): lodash.Omit<FormatDepartment, string>;
|
|
19
|
+
updateDepartmentIsLeaf(parentId: PrimaryKey | null | undefined): Promise<void>;
|
|
20
|
+
markDepartmentAsNonLeaf(parentId: PrimaryKey | null | undefined): Promise<void>;
|
|
19
21
|
update(record: OriginRecord, resourcePks: PrimaryKey[]): Promise<RecordResourceChanged[]>;
|
|
20
22
|
create(record: OriginRecord): Promise<RecordResourceChanged[]>;
|
|
21
23
|
getDepartmentIdsBySourceUks(sourceUks: PrimaryKey[], sourceName: string): Promise<any>;
|
|
@@ -59,7 +59,6 @@ class DepartmentDataSyncResource extends import_plugin_user_data_sync.UserDataRe
|
|
|
59
59
|
"uid",
|
|
60
60
|
"createdAt",
|
|
61
61
|
"updatedAt",
|
|
62
|
-
"sort",
|
|
63
62
|
"createdById",
|
|
64
63
|
"updatedById",
|
|
65
64
|
"isDeleted",
|
|
@@ -68,6 +67,33 @@ class DepartmentDataSyncResource extends import_plugin_user_data_sync.UserDataRe
|
|
|
68
67
|
];
|
|
69
68
|
return import_lodash.default.omit(sourceDepartment, deleteProps);
|
|
70
69
|
}
|
|
70
|
+
async updateDepartmentIsLeaf(parentId) {
|
|
71
|
+
if (!parentId) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
const hasChild = await this.deptRepo.count({
|
|
75
|
+
filter: {
|
|
76
|
+
parentId
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
await this.deptRepo.update({
|
|
80
|
+
filterByTk: parentId,
|
|
81
|
+
values: {
|
|
82
|
+
isLeaf: !hasChild
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
async markDepartmentAsNonLeaf(parentId) {
|
|
87
|
+
if (!parentId) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
await this.deptRepo.update({
|
|
91
|
+
filterByTk: parentId,
|
|
92
|
+
values: {
|
|
93
|
+
isLeaf: false
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
}
|
|
71
97
|
async update(record, resourcePks) {
|
|
72
98
|
const { dataType, metaData, sourceName } = record;
|
|
73
99
|
if (dataType === "user") {
|
|
@@ -267,7 +293,9 @@ class DepartmentDataSyncResource extends import_plugin_user_data_sync.UserDataRe
|
|
|
267
293
|
}
|
|
268
294
|
async updateDepartment(department, sourceDepartment, sourceName) {
|
|
269
295
|
if (sourceDepartment.isDeleted) {
|
|
296
|
+
const parentId = department.get("parentId");
|
|
270
297
|
await department.destroy();
|
|
298
|
+
await this.updateDepartmentIsLeaf(parentId);
|
|
271
299
|
return;
|
|
272
300
|
}
|
|
273
301
|
let dataChanged = false;
|
|
@@ -286,17 +314,22 @@ class DepartmentDataSyncResource extends import_plugin_user_data_sync.UserDataRe
|
|
|
286
314
|
async createDepartment(sourceDepartment, sourceName) {
|
|
287
315
|
const filteredSourceDepartment = this.getFlteredSourceDepartment(sourceDepartment);
|
|
288
316
|
const department = await this.deptRepo.create({
|
|
289
|
-
values:
|
|
317
|
+
values: {
|
|
318
|
+
isLeaf: true,
|
|
319
|
+
...filteredSourceDepartment
|
|
320
|
+
}
|
|
290
321
|
});
|
|
291
322
|
await this.updateParentDepartment(department, sourceDepartment.parentUid, sourceName);
|
|
292
323
|
return department.id;
|
|
293
324
|
}
|
|
294
325
|
async updateParentDepartment(department, parentUid, sourceName) {
|
|
295
326
|
var _a;
|
|
327
|
+
const oldParentId = department.get("parentId");
|
|
296
328
|
if (!parentUid) {
|
|
297
329
|
const parentDepartment = await department.getParent();
|
|
298
330
|
if (parentDepartment) {
|
|
299
331
|
await department.setParent(null);
|
|
332
|
+
await this.updateDepartmentIsLeaf(oldParentId);
|
|
300
333
|
}
|
|
301
334
|
} else {
|
|
302
335
|
const syncDepartmentRecord = await this.syncRecordRepo.findOne({
|
|
@@ -314,18 +347,25 @@ class DepartmentDataSyncResource extends import_plugin_user_data_sync.UserDataRe
|
|
|
314
347
|
});
|
|
315
348
|
if (!parentDepartment) {
|
|
316
349
|
await department.setParent(null);
|
|
350
|
+
await this.updateDepartmentIsLeaf(oldParentId);
|
|
317
351
|
return;
|
|
318
352
|
}
|
|
319
353
|
const parent = await department.getParent();
|
|
320
354
|
if (parent) {
|
|
321
355
|
if (parentDepartment.id !== parent.id) {
|
|
322
356
|
await department.setParent(parentDepartment);
|
|
357
|
+
await Promise.all([
|
|
358
|
+
this.updateDepartmentIsLeaf(oldParentId),
|
|
359
|
+
this.markDepartmentAsNonLeaf(parentDepartment.id)
|
|
360
|
+
]);
|
|
323
361
|
}
|
|
324
362
|
} else {
|
|
325
363
|
await department.setParent(parentDepartment);
|
|
364
|
+
await this.markDepartmentAsNonLeaf(parentDepartment.id);
|
|
326
365
|
}
|
|
327
366
|
} else {
|
|
328
367
|
await department.setParent(null);
|
|
368
|
+
await this.updateDepartmentIsLeaf(oldParentId);
|
|
329
369
|
}
|
|
330
370
|
}
|
|
331
371
|
}
|
|
@@ -29,73 +29,37 @@ __export(set_main_department_exports, {
|
|
|
29
29
|
setMainDepartment: () => setMainDepartment
|
|
30
30
|
});
|
|
31
31
|
module.exports = __toCommonJS(set_main_department_exports);
|
|
32
|
+
var import_sync_user_main_department = require("../sync-user-main-department");
|
|
33
|
+
const normalizeIds = (values = []) => values.map((value) => typeof value === "object" && value ? value.id ?? value : value).filter((value) => value !== null && value !== void 0);
|
|
34
|
+
const syncUsersMainDepartment = async (ctx, userIds) => {
|
|
35
|
+
const uniqUserIds = [...new Set(normalizeIds(userIds))];
|
|
36
|
+
for (const userId of uniqUserIds) {
|
|
37
|
+
await (0, import_sync_user_main_department.syncUserMainDepartment)(ctx.db, userId, ctx.transaction);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
32
40
|
const setMainDepartment = async (ctx, next) => {
|
|
33
|
-
var _a, _b;
|
|
34
|
-
await next();
|
|
35
41
|
const { associatedName, resourceName, associatedIndex, actionName, values, filterByTk } = ctx.action.params;
|
|
36
|
-
|
|
37
|
-
|
|
42
|
+
let affectedDepartmentMemberUserIds = [];
|
|
43
|
+
if (associatedName === "departments" && resourceName === "members" && actionName === "set") {
|
|
38
44
|
const throughRepo = ctx.db.getRepository("departmentsUsers");
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
return;
|
|
50
|
-
}
|
|
51
|
-
if (actionName === "remove") {
|
|
52
|
-
for (const userId of values) {
|
|
53
|
-
const user = await userRepo.findOne({ filterByTk: userId, fields: ["id", "mainDepartmentId"] });
|
|
54
|
-
if ((user == null ? void 0 : user.mainDepartmentId) === Number(associatedIndex)) {
|
|
55
|
-
const firstDept = await throughRepo.findOne({
|
|
56
|
-
filter: { userId }
|
|
57
|
-
});
|
|
58
|
-
await userRepo.update({
|
|
59
|
-
filterByTk: userId,
|
|
60
|
-
values: { mainDepartmentId: firstDept ? firstDept.departmentId : null }
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
45
|
+
const currentMembers = await throughRepo.find({
|
|
46
|
+
fields: ["userId"],
|
|
47
|
+
filter: { departmentId: associatedIndex },
|
|
48
|
+
transaction: ctx.transaction
|
|
49
|
+
});
|
|
50
|
+
affectedDepartmentMemberUserIds = currentMembers.map((member) => {
|
|
51
|
+
var _a;
|
|
52
|
+
return ((_a = member.get) == null ? void 0 : _a.call(member, "userId")) ?? member.userId;
|
|
53
|
+
});
|
|
65
54
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if (user == null ? void 0 : user.mainDepartmentId) {
|
|
72
|
-
const existingAssoc = await throughRepo.findOne({
|
|
73
|
-
filter: { userId: associatedIndex, departmentId: user.mainDepartmentId }
|
|
74
|
-
});
|
|
75
|
-
hasValidMain = !!existingAssoc;
|
|
76
|
-
}
|
|
77
|
-
if (!hasValidMain) {
|
|
78
|
-
const firstDept = await throughRepo.findOne({
|
|
79
|
-
filter: { userId: associatedIndex }
|
|
80
|
-
});
|
|
81
|
-
await userRepo.update({
|
|
82
|
-
filterByTk: associatedIndex,
|
|
83
|
-
values: { mainDepartmentId: firstDept ? firstDept.departmentId : null }
|
|
84
|
-
});
|
|
85
|
-
}
|
|
55
|
+
await next();
|
|
56
|
+
if (associatedName === "departments" && resourceName === "members" && ["add", "remove", "set"].includes(actionName)) {
|
|
57
|
+
const affectedUserIds = actionName === "set" ? [...affectedDepartmentMemberUserIds, ...values || []] : values || [];
|
|
58
|
+
await syncUsersMainDepartment(ctx, affectedUserIds);
|
|
59
|
+
return;
|
|
86
60
|
}
|
|
87
|
-
if (
|
|
88
|
-
|
|
89
|
-
const throughRepo = ctx.db.getRepository("departmentsUsers");
|
|
90
|
-
const userId = associatedIndex ?? filterByTk ?? ((_b = (_a = ctx.body) == null ? void 0 : _a.data) == null ? void 0 : _b.id);
|
|
91
|
-
if (!userId) return;
|
|
92
|
-
const deptUsers = await throughRepo.find({ filter: { userId } });
|
|
93
|
-
if (deptUsers.length === 1) {
|
|
94
|
-
await userRepo.update({
|
|
95
|
-
filterByTk: userId,
|
|
96
|
-
values: { mainDepartmentId: deptUsers[0].departmentId }
|
|
97
|
-
});
|
|
98
|
-
}
|
|
61
|
+
if (associatedName === "users" && resourceName === "departments" && ["add", "remove", "set"].includes(actionName)) {
|
|
62
|
+
await syncUsersMainDepartment(ctx, [associatedIndex ?? filterByTk]);
|
|
99
63
|
}
|
|
100
64
|
};
|
|
101
65
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
import { Migration } from '@nocobase/server';
|
|
10
|
+
export default class extends Migration {
|
|
11
|
+
on: string;
|
|
12
|
+
up(): Promise<void>;
|
|
13
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __defProp = Object.defineProperty;
|
|
11
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
+
var __export = (target, all) => {
|
|
15
|
+
for (var name in all)
|
|
16
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
17
|
+
};
|
|
18
|
+
var __copyProps = (to, from, except, desc) => {
|
|
19
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
20
|
+
for (let key of __getOwnPropNames(from))
|
|
21
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
22
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
23
|
+
}
|
|
24
|
+
return to;
|
|
25
|
+
};
|
|
26
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
|
+
var add_parent_id_field_exports = {};
|
|
28
|
+
__export(add_parent_id_field_exports, {
|
|
29
|
+
default: () => add_parent_id_field_default
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(add_parent_id_field_exports);
|
|
32
|
+
var import_server = require("@nocobase/server");
|
|
33
|
+
var import_departments = require("../collections/departments");
|
|
34
|
+
class add_parent_id_field_default extends import_server.Migration {
|
|
35
|
+
on = "afterLoad";
|
|
36
|
+
async up() {
|
|
37
|
+
const fieldRepo = this.db.getRepository("fields");
|
|
38
|
+
if (!fieldRepo) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
const field = await fieldRepo.findOne({
|
|
42
|
+
filter: {
|
|
43
|
+
collectionName: "departments",
|
|
44
|
+
name: "parentId"
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
if (field) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
await fieldRepo.create({
|
|
51
|
+
values: {
|
|
52
|
+
collectionName: "departments",
|
|
53
|
+
...import_departments.parentIdField
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -32,7 +32,7 @@ module.exports = __toCommonJS(migrate_main_department_id_20250828100101_exports)
|
|
|
32
32
|
var import_server = require("@nocobase/server");
|
|
33
33
|
class migrate_main_department_id_20250828100101_default extends import_server.Migration {
|
|
34
34
|
on = "afterLoad";
|
|
35
|
-
appVersion = "<2.
|
|
35
|
+
appVersion = "<2.1.0";
|
|
36
36
|
async up() {
|
|
37
37
|
await this.db.sequelize.transaction(async (transaction) => {
|
|
38
38
|
var _a, _b;
|
package/dist/server/plugin.js
CHANGED
|
@@ -37,6 +37,7 @@ var import_users2 = require("./collections/users");
|
|
|
37
37
|
var import_middlewares = require("./middlewares");
|
|
38
38
|
var import_department = require("./models/department");
|
|
39
39
|
var import_department_data_sync_resource = require("./department-data-sync-resource");
|
|
40
|
+
var import_sync_user_main_department = require("./sync-user-main-department");
|
|
40
41
|
class PluginDepartmentsServer extends import_server.Plugin {
|
|
41
42
|
afterAdd() {
|
|
42
43
|
}
|
|
@@ -54,12 +55,11 @@ class PluginDepartmentsServer extends import_server.Plugin {
|
|
|
54
55
|
this.registerErrorHandler();
|
|
55
56
|
this.app.resourceManager.registerActionHandlers({
|
|
56
57
|
"users:listExcludeDept": import_users.listExcludeDept,
|
|
57
|
-
"users:setMainDepartment": import_users.setMainDepartment,
|
|
58
58
|
"departments:aggregateSearch": import_departments.aggregateSearch,
|
|
59
59
|
"departments:setOwner": import_departments.setOwner,
|
|
60
60
|
"departments:removeOwner": import_departments.removeOwner
|
|
61
61
|
});
|
|
62
|
-
this.app.acl.allow("users", ["
|
|
62
|
+
this.app.acl.allow("users", ["listExcludeDept"], "loggedIn");
|
|
63
63
|
this.app.acl.registerSnippet({
|
|
64
64
|
name: `pm.${this.name}`,
|
|
65
65
|
actions: [
|
|
@@ -67,7 +67,6 @@ class PluginDepartmentsServer extends import_server.Plugin {
|
|
|
67
67
|
"roles:list",
|
|
68
68
|
"users:list",
|
|
69
69
|
"users:listExcludeDept",
|
|
70
|
-
"users:setMainDepartment",
|
|
71
70
|
"users.departments:*",
|
|
72
71
|
"roles.departments:*",
|
|
73
72
|
"departments.members:*"
|
|
@@ -90,16 +89,22 @@ class PluginDepartmentsServer extends import_server.Plugin {
|
|
|
90
89
|
this.app.resourceManager.use(import_middlewares.updateDepartmentIsLeaf);
|
|
91
90
|
this.app.resourceManager.use(import_middlewares.resetUserDepartmentsCache);
|
|
92
91
|
this.app.resourceManager.use(import_middlewares.setMainDepartment);
|
|
93
|
-
this.app.db.on("departmentsUsers.afterSave", async (model) => {
|
|
92
|
+
this.app.db.on("departmentsUsers.afterSave", async (model, options) => {
|
|
94
93
|
const cache = this.app.cache;
|
|
94
|
+
await (0, import_sync_user_main_department.syncUserMainDepartment)(this.app.db, model.get("userId"), options == null ? void 0 : options.transaction);
|
|
95
95
|
await cache.del(`departments:${model.get("userId")}`);
|
|
96
96
|
});
|
|
97
|
-
this.app.db.on("departmentsUsers.afterDestroy", async (model) => {
|
|
97
|
+
this.app.db.on("departmentsUsers.afterDestroy", async (model, options) => {
|
|
98
98
|
const cache = this.app.cache;
|
|
99
|
+
await (0, import_sync_user_main_department.syncUserMainDepartment)(this.app.db, model.get("userId"), options == null ? void 0 : options.transaction);
|
|
99
100
|
await cache.del(`departments:${model.get("userId")}`);
|
|
100
101
|
});
|
|
102
|
+
this.app.db.on("users.afterSaveWithAssociations", async (model, options) => {
|
|
103
|
+
await (0, import_sync_user_main_department.syncUserMainDepartment)(this.app.db, model.get("id"), options == null ? void 0 : options.transaction);
|
|
104
|
+
});
|
|
101
105
|
this.app.db.on("users.beforeSave", async (model, options) => {
|
|
102
106
|
var _a;
|
|
107
|
+
const submittedDepartments = (_a = options == null ? void 0 : options.values) == null ? void 0 : _a.departments;
|
|
103
108
|
const mainDepartmentId = model.get("mainDepartmentId");
|
|
104
109
|
if (!mainDepartmentId) {
|
|
105
110
|
return;
|
|
@@ -118,7 +123,6 @@ class PluginDepartmentsServer extends import_server.Plugin {
|
|
|
118
123
|
return;
|
|
119
124
|
}
|
|
120
125
|
}
|
|
121
|
-
const submittedDepartments = (_a = options == null ? void 0 : options.values) == null ? void 0 : _a.departments;
|
|
122
126
|
if (Array.isArray(submittedDepartments)) {
|
|
123
127
|
const included = submittedDepartments.some((d) => {
|
|
124
128
|
const id = typeof d === "object" ? d && (d.id ?? d) : d;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* This file is part of the NocoBase (R) project.
|
|
11
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
12
|
+
* Authors: NocoBase Team.
|
|
13
|
+
*
|
|
14
|
+
* This program is offered under a commercial license.
|
|
15
|
+
* For more information, see <https://www.nocobase.com/agreement>
|
|
16
|
+
*/
|
|
17
|
+
import type { Database } from '@nocobase/database';
|
|
18
|
+
import type { Transaction } from 'sequelize';
|
|
19
|
+
export declare const syncUserMainDepartment: (db: Database, userId: number | string, transaction?: Transaction) => Promise<void>;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
var __defProp = Object.defineProperty;
|
|
11
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
12
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
13
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
14
|
+
var __export = (target, all) => {
|
|
15
|
+
for (var name in all)
|
|
16
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
17
|
+
};
|
|
18
|
+
var __copyProps = (to, from, except, desc) => {
|
|
19
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
20
|
+
for (let key of __getOwnPropNames(from))
|
|
21
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
22
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
23
|
+
}
|
|
24
|
+
return to;
|
|
25
|
+
};
|
|
26
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
|
+
var sync_user_main_department_exports = {};
|
|
28
|
+
__export(sync_user_main_department_exports, {
|
|
29
|
+
syncUserMainDepartment: () => syncUserMainDepartment
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(sync_user_main_department_exports);
|
|
32
|
+
const syncUserMainDepartment = async (db, userId, transaction) => {
|
|
33
|
+
if (!userId) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const userRepo = db.getRepository("users");
|
|
37
|
+
const throughRepo = db.getRepository("departmentsUsers");
|
|
38
|
+
const user = await userRepo.findOne({
|
|
39
|
+
filterByTk: userId,
|
|
40
|
+
fields: ["id", "mainDepartmentId"],
|
|
41
|
+
transaction
|
|
42
|
+
});
|
|
43
|
+
if (!user) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
const currentMainDepartmentId = user.get("mainDepartmentId");
|
|
47
|
+
const currentMainDepartment = currentMainDepartmentId && await throughRepo.findOne({
|
|
48
|
+
filter: {
|
|
49
|
+
userId,
|
|
50
|
+
departmentId: currentMainDepartmentId
|
|
51
|
+
},
|
|
52
|
+
transaction
|
|
53
|
+
});
|
|
54
|
+
if (currentMainDepartment) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
const firstDepartment = await throughRepo.findOne({
|
|
58
|
+
filter: { userId },
|
|
59
|
+
transaction
|
|
60
|
+
});
|
|
61
|
+
const nextMainDepartmentId = firstDepartment ? firstDepartment.get("departmentId") : null;
|
|
62
|
+
if (currentMainDepartmentId === nextMainDepartmentId) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
await userRepo.update({
|
|
66
|
+
filterByTk: userId,
|
|
67
|
+
values: { mainDepartmentId: nextMainDepartmentId },
|
|
68
|
+
transaction
|
|
69
|
+
});
|
|
70
|
+
};
|
|
71
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
72
|
+
0 && (module.exports = {
|
|
73
|
+
syncUserMainDepartment
|
|
74
|
+
});
|
package/package.json
CHANGED
|
@@ -6,11 +6,13 @@
|
|
|
6
6
|
"description": "Organize users by departments, set hierarchical relationships, link roles to control permissions, and use departments as variables in workflows and expressions.",
|
|
7
7
|
"description.ru-RU": "Организация пользователей по подразделениям, установление иерархических связей, привязка ролей для управления правами и использование подразделений в качестве переменных в рабочих процессах и выражениях.",
|
|
8
8
|
"description.zh-CN": "以部门来组织用户,设定上下级关系,绑定角色控制权限,并支持作为变量用于工作流和表达式。",
|
|
9
|
-
"version": "2.1.0-beta.
|
|
9
|
+
"version": "2.1.0-beta.21",
|
|
10
10
|
"main": "dist/server/index.js",
|
|
11
11
|
"peerDependencies": {
|
|
12
12
|
"@nocobase/actions": "2.x",
|
|
13
13
|
"@nocobase/client": "2.x",
|
|
14
|
+
"@nocobase/plugin-acl": "2.x",
|
|
15
|
+
"@nocobase/plugin-error-handler": "2.x",
|
|
14
16
|
"@nocobase/plugin-user-data-sync": "2.x",
|
|
15
17
|
"@nocobase/server": "2.x",
|
|
16
18
|
"@nocobase/test": "2.x"
|
|
@@ -18,5 +20,6 @@
|
|
|
18
20
|
"keywords": [
|
|
19
21
|
"Users & permissions"
|
|
20
22
|
],
|
|
21
|
-
"gitHead": "
|
|
23
|
+
"gitHead": "324bd82f33fca58e98711688a17ceb65c186b65e",
|
|
24
|
+
"license": "Apache-2.0"
|
|
22
25
|
}
|