Skip to content

组织机构

框架内置了组织机构功能,支持从第三方系统同步数据,为业务系统提供统一的组织数据。 本文主要对同步服务和扩展方式作出说明。

默认实现

默认情况下,框架仅从 HRM 系统接收以下信息:

名称说明
orgId编号
orgName名称
orgCode编码
orgTypeName类型
globalOrder全局排序号
operateTime修改时间
inUse状态
parentOrgId父编号
orgFullPath名称全路径

提示

3.3.2 起,同步服务内部会生成组织编码全路径信息,存储为 FullCode

提示

现在更推荐使用 /api/org/sync-raw 从网关接收上游接口原始数据。

OrgSyncService<T, D> v3.3.2+

OrgSyncService 是接收组织数据的默认服务实现类,它实现了 IOrgSyncService<D> 接口, 其中 T 为实体类型,D 为 DTO 类型。

数据关键处理逻辑和方法如下表所示。

步骤方法说明
1SyncData将接收到的数据分页传入下一步处理,每页50条
2DoSyncPagedData核心方法,根据传入的数据获取本地数据,然后依次决定要更新还是新增
3.1SearchOldToMap获取本地数据并转换为字典,以便后续判断数据是否存在
3.2DataNotChange当本地数据存在时,判断数据是否变化,未变化则跳过,不作更新。数据变化的判断依据为更新时间
3.3OnDataUpdate准备要更新的数据,填充属性
3.4OnDataAdd准备要新增的数据,填充属性
3.5OnDataSaving入库前的自定义操作
3.6OnDataSaved入库后的自定义操作
1.2OnSyncFinish数据处理完毕的自定义操作。上游数据有可能分多次传递,因此此方法也可能会产生多次调用。

提示

以上所有方法都支持重写,方便开发者扩展自己的处理逻辑。

字段扩展

如果默认的字段不能满足业务需要,可以进行字段扩展。关键在于定义新的实体类和 DTO 类。

实体

创建实体类,继承 Organization

csharp
/// <summary>
/// 自定义组织
/// </summary>
[Table("Organization")]
public class MyOrganization : Organization
{
    /// <summary>
    /// 示例字段
    /// </summary>
    public string Foo { get; set; }
}

DTO

创建 DTO 类以接收新增字段,继承 OrganizationSyncRawDto

csharp
/// <summary>
/// 自定义组织dto
/// </summary>
public class MyOrgSyncRawDto: OrganizationSyncRawDto
{
    /// <summary>
    /// 示例字段
    /// </summary>
    public string Foo { get; set; }
}

DAL

与数据库交互需要与实体类对应的 DAL,因此也需要重新定义。

csharp
/// <summary>
/// 自定义组织dal
/// </summary>
public interface IMyOrgDal : IBaseDal<MyOrganization>
{
}

/// <summary>
/// 自定义组织dal
/// </summary>
[Repository]
public class MyOrganizationDal : BaseDal<MyOrganization>, IMyOrgDal
{
}

Controller

声明新的接口,使用新 DTO 类接收数据。

csharp
/// <summary>
/// 自定义组织同步
/// </summary>
/// <param name="syncService"></param>
[ApiController]
public class MyOrgController(IOrgSyncService<MyOrgSyncRawDto> syncService)
{
    /// <summary>
    /// 同步
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost("/api/my-org/sync-raw")]
    [Authorize(AuthenticationSchemes = "api,sign")]
    public Result SyncRaw(List<MyOrgSyncRawDto> input)
    {
        syncService.SyncData(input);
        return Result.Success();
    }
}

服务注册

最后,需要注册新的 DAL 服务和 Service 服务。

csharp
//  [startup.cs]
public override void ConfigureServices(IServiceCollection services)
{
    base.ConfigureServices(services);
    // 注册自定义服务
    services.AddScoped<IOrgSyncService<MyOrgSyncRawDto>, OrgSyncService<MyOrganization,MyOrgSyncRawDto>>();
    // 后续内容省略
}

业务逻辑扩展

如果需要更多个性化的操作,可以声明新服务类并重写方法。

服务实现

csharp
public class MyOrgSyncService(IUserDal userDal, IDataDictionaryService dict): OrgSyncService<MyOrganization, MyOrgSyncRawDto>(userDal)
{
    Dictionary<string,string> config;

    /// <inheritdoc/>
    public override void SyncData(List<MyOrgSyncRawDto> dto)
    {
        config = dict.ListByName("dict_foo", false).ToDictionary(t=> t.DicKey, t=> t.DicValue);
        base.SyncData(dto);
    }

    /// <inheritdoc/>
    protected override MyOrganization OnDataAdd(MyOrgSyncRawDto org)
    {
        // 框架逻辑
        MyOrganization entity = base.OnDataAdd(org);
        // 自定义
        entity.Foo = config.TryGetValue(org.Foo, out string val) ? val : "";
        return entity;
    }

    /// <inheritdoc/>
    protected override MyOrganization OnDataUpdate(MyOrgSyncRawDto org, MyOrganization old)
    {
        // 框架逻辑
        MyOrganization entity = base.OnDataUpdate(org, old);
        // 自定义
        entity.Foo = config.TryGetValue(org.Foo, out string val) ? val : "";
        return entity;
    }
}

在以上示例中,重写了几个关键方法。在 SyncData 方法中加载了字典数据,用于后续数据处理。 在 OnDataAddOnDataUpdate方法中使用字典数据填充自定义字段。

注意

上例中使用了构造函数注入依赖。也可以使用 [Autowired] 方式注入,但要注意在控制器中同样需要使用 [Autowired] 注入服务。

服务注册

csharp
//  [startup.cs]
public override void ConfigureServices(IServiceCollection services)
{
    base.ConfigureServices(services);
    // 注册自定义服务
    services.AddScoped<IOrgSyncService<MyOrgSyncRawDto>, MyOrgSyncService<MyOrganization, MyOrgSyncRawDto>>();
    // 后续内容省略
}