feat: user sync support custom fields and department owner (#5158)

This commit is contained in:
Zhi Chen 2024-09-02 09:10:19 +08:00 committed by GitHub
parent 71c547f1a7
commit 472190b7d5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 84 additions and 25 deletions

View File

@ -17,7 +17,7 @@ export type FormatUser = {
email?: string; email?: string;
nickname?: string; nickname?: string;
phone?: string; phone?: string;
departments?: string[]; departments?: (string | FormatUserDepartment)[];
isDeleted?: boolean; isDeleted?: boolean;
[key: string]: any; [key: string]: any;
}; };
@ -30,6 +30,11 @@ export type FormatDepartment = {
[key: string]: any; [key: string]: any;
}; };
export type FormatUserDepartment = {
uid: string;
isOwner?: boolean;
};
export type UserDataRecord = FormatUser | FormatDepartment; export type UserDataRecord = FormatUser | FormatDepartment;
export type SyncDataType = 'user' | 'department'; export type SyncDataType = 'user' | 'department';

View File

@ -119,4 +119,52 @@ describe('user data sync', () => {
expect(user2).toBeTruthy(); expect(user2).toBeTruthy();
expect(user2.nickname).toBe('test2'); expect(user2.nickname).toBe('test2');
}); });
it('should update user custom field', async () => {
const userCollection = db.getCollection('users');
userCollection.addField('customField', { type: 'string' });
await db.sync({
alter: true,
});
await resourceManager.updateOrCreate({
sourceName: 'test',
dataType: 'user',
matchKey: 'email',
records: [
{
uid: '1',
nickname: 'test',
email: 'test@nocobase.com',
customField: 'test',
},
],
});
const user = await db.getRepository('users').findOne({
filter: {
email: 'test@nocobase.com',
},
});
expect(user).toBeTruthy();
expect(user.customField).toBe('test');
await resourceManager.updateOrCreate({
sourceName: 'test',
dataType: 'user',
matchKey: 'email',
records: [
{
uid: '1',
nickname: 'test',
email: 'test@nocobase.com',
customField: 'test2',
},
],
});
const user2 = await db.getRepository('users').findOne({
filter: {
id: user.id,
},
});
expect(user2).toBeTruthy();
expect(user2.customField).toBe('test2');
});
}); });

View File

@ -182,7 +182,7 @@ export default class PluginUsersServer extends Plugin {
}); });
const userDataSyncPlugin = this.app.pm.get('user-data-sync') as PluginUserDataSyncServer; const userDataSyncPlugin = this.app.pm.get('user-data-sync') as PluginUserDataSyncServer;
if (userDataSyncPlugin) { if (userDataSyncPlugin && userDataSyncPlugin.enabled) {
userDataSyncPlugin.resourceManager.registerResource(new UserDataSyncResource(this.db, this.app.logger)); userDataSyncPlugin.resourceManager.registerResource(new UserDataSyncResource(this.db, this.app.logger));
} }
} }

View File

@ -8,6 +8,8 @@
*/ */
import { Model } from '@nocobase/database'; import { Model } from '@nocobase/database';
import lodash from 'lodash';
import { import {
FormatUser, FormatUser,
OriginRecord, OriginRecord,
@ -24,7 +26,24 @@ export class UserDataSyncResource extends UserDataResource {
get userRepo() { get userRepo() {
return this.db.getRepository('users'); return this.db.getRepository('users');
} }
getFlteredSourceUser(sourceUser: FormatUser) {
const deleteProps = [
'id',
'uid',
'createdAt',
'updatedAt',
'appLang',
'resetToken',
'systemSettings',
'password',
'sort',
'createdById',
'updatedById',
'isDeleted',
'departments',
];
return lodash.omit(sourceUser, deleteProps);
}
async updateUser(user: Model, sourceUser: FormatUser) { async updateUser(user: Model, sourceUser: FormatUser) {
if (sourceUser.isDeleted) { if (sourceUser.isDeleted) {
// 删除用户 // 删除用户
@ -39,22 +58,13 @@ export class UserDataSyncResource extends UserDataResource {
return; return;
} }
let dataChanged = false; let dataChanged = false;
if (sourceUser.username !== undefined && user.username !== sourceUser.username) { const filteredSourceUser = this.getFlteredSourceUser(sourceUser);
user.username = sourceUser.username; lodash.forOwn(filteredSourceUser, (value, key) => {
dataChanged = true; if (user[key] !== value) {
} user[key] = value;
if (sourceUser.phone !== undefined && user.phone !== sourceUser.phone) {
user.phone = sourceUser.phone;
dataChanged = true;
}
if (sourceUser.email !== undefined && user.email !== sourceUser.email) {
user.email = sourceUser.email;
dataChanged = true;
}
if (sourceUser.nickname !== undefined && user.nickname !== sourceUser.nickname) {
user.nickname = sourceUser.nickname;
dataChanged = true; dataChanged = true;
} }
});
if (dataChanged) { if (dataChanged) {
await user.save(); await user.save();
} }
@ -88,13 +98,9 @@ export class UserDataSyncResource extends UserDataResource {
if (user) { if (user) {
await this.updateUser(user, sourceUser); await this.updateUser(user, sourceUser);
} else { } else {
const filteredSourceUser = this.getFlteredSourceUser(sourceUser);
user = await this.userRepo.create({ user = await this.userRepo.create({
values: { values: filteredSourceUser,
nickname: sourceUser.nickname,
phone: sourceUser.phone,
email: sourceUser.email,
username: sourceUser.username,
},
}); });
} }
return [{ resourcesPk: user.id, isDeleted: false }]; return [{ resourcesPk: user.id, isDeleted: false }];