abp vnext 通过Claim扩展用户表字段

需求:abp框架原有的abpusers表字段无法满足业务需求,需要新增字段来解决。

实现步骤如下

一.向abpusres表添加字段

1、在domain程序集下新建AppUser表

该类用来定义新增的字段,不需要继承任何父类,如下所示:

   public class AppUser
    {
        /// <summary>
        /// 会员Code
        /// </summary>
        [MaxLength(50)]
        public string MemberCode { get; set; }

    }

2.在EntityFrameworkCore程序集添加MyAppEfCoreEntityExtensionMappings类,

类名可以随意,但是按照惯例,一般以“项目名”+EfCoreEntityExtensionMappings命名。该类主要用来配置为IdentityUser新增字段,代码如下:

    public class DemoEfCoreEntityExtensionMappings
    {
        private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner();

        public static void Configure()
        {

            OneTimeRunner.Run(() =>
            {

                ObjectExtensionManager.Instance.MapEfCoreProperty<IdentityUser, string>(nameof(AppUser.MemberCode), b => { b.HasMaxLength(50); });

            });
        }
    }

3.在DemoEntityFrameworkCore程序集下的DemoEntityFrameworkCoreModule模块中配置PreConfigureServices

    public override void PreConfigureServices(ServiceConfigurationContext context)
    {
        DemoEfCoreEntityExtensionMappings.Configure();

        base.PreConfigureServices(context);
    }

4.在Admin.HttpApi.Host程序集配置AdminHttpApiHostMigrationsDbContextFactory类中的CreateDbContext

同上一步,在DbContextFactory中进行同样配置,一些情况下我们需要通过DbContextFactory来获取DbContext,如不配置此项,将会导致获取的DbContext中内容不一致。

   public DemoDbContext CreateDbContext(string[] args)
    {
        var configuration = BuildConfiguration();

        var builder = new DbContextOptionsBuilder<DemoDbContext>()
            .UseMySql(configuration.GetConnectionString("Default"), MySqlServerVersion.LatestSupportedServerVersion,
                option => { option.MigrationsAssembly("Demo.Admin.HttpApi.Host"); });
         //添加扩展配置
        DemoEfCoreEntityExtensionMappings.Configure();

        return new DemoDbContext(builder.Options);
    }

5.在Application.Contracts层配置用户表相关Dto的扩展字段

public static class DemoDtoExtensions
{
    private static readonly OneTimeRunner OneTimeRunner = new OneTimeRunner();

    public static void Configure()
    {
        OneTimeRunner.Run(() =>
        {
            ObjectExtensionManager.Instance
                .AddOrUpdateProperty<string>(
                    new[]
                    {
                        typeof(IdentityUserDto),
                        typeof(IdentityUserCreateDto),
                        typeof(IdentityUserUpdateDto),
                        typeof(ProfileDto),
                        typeof(UpdateProfileDto)
                    },
                    "MemberCode"
                );
        });
    }
}

6、在模块类ApplicationContractsModule中进行配置

为了是上一步配置生效,还需要在MyAppApplicationContractsModule中进行如下配置:

   public override void PreConfigureServices(ServiceConfigurationContext context)
    {
        DemoDtoExtensions.Configure();

        base.PreConfigureServices(context);
    }

7、通过EF Core将MemberCode字段添加到abpUsers表中

     1)生成迁移脚本

           add-migration   add_abpUusers_MemberCode

     2)  将迁移脚本sql更新到数据库

          update-database

二.向CurrentUser会话中Claim赋值

1.在Admin.HttpApi程序集下LoginController类中给toekn中Claim添加自定义字段



    /// <summary>
    /// 在CurrentUser对象的Claims中添加扩展字段
    /// </summary>
    private List<Claim> SetUserClaims(IdentityUser userInfo)
    {

        List<Claim> claims = new List<Claim>();
       if (userInfo.ExtraProperties.ContainsKey("MemberCode"))
        {
        //添加会员Code
        claims.Add(new Claim(MemberCode,userInfo.ExtraProperties["MemberCode"].ToString()));
        }
        return claims;
    }
    
    //在abp框架生成的方法中添加
    private async Task<string> GetToken(IdentityUser user, string[] roles)
    {
        var claims = await CreateJwtClaims(user, roles);
        //添加自定义claim
       List<Claim> customClaims = SetUserClaims(userInfo);
        if (!customClaims.IsNullOrEmpty())
        {
            claims.AddRange(customClaims);
        }

           //...
    }

2.在程序集中使用

 //获取abpuser表中扩展字段MemberCode值
 var storeCode = CurrentUser.FindClaimValue("MemberCode");

三、前端账号管理添加扩展字段

1.账号管理列表 

//修改vben-admin\src\views\identity\user\datas\TableData.ts列表参数配置 
{
      title: '会员Code',
      dataIndex: 'extraProperties.MemberCode',
      align: 'left',
      width: 270,
      sorter: true,
      slots: { customRender: 'MemberCode' },  //通过自定义插槽在列表中显示
    },
//(修改vben-admin\src\views\identity\user\components\UserTable.vue列表参数配置) 
<BasicTable @register="registerTable">

      <template #MemberCode="{ record }">
        {{ record.extraProperties.MemberCode}}
      </template>
       
    </BasicTable>

 

2.修改列表添加扩展字段

//修改vben-admin\src\views\identity\user\datas\ModalData.ts配置
    {
      tab: t('AbpIdentity.UserInformations'),
      field: 'memberCode',
      component: 'Input',
      label: '会员Code',
      colProps: { span: 24 },
    },

//在弹框打开事件里,通过useForm回调函数setFieldsValue设置会员code值
 const [registerModal, { closeModal }] = useModalInner(async (val) => {
      const formEl = unref(formElRef);
      formEl?.setFieldsValue({
        memberCode: val.extraProperties.MemberCode,
 
      });
    });



//保存时需要将会员Code值按后台api接口存在
    handleSubmit() {
      const formEl = unref(this.formElRef);
      const param = formEl?.getFieldsValue();
      if (param) {
        param.extraProperties = { MemberCode: param.MemberCode};
      }

      formEl?.validate().then(() => {
        this.handleSaveUser(param).then(() => {
          this.$emit('change');
          this.closeModal();
        });
      });
    },

注:表单组件对JSON数据格式读取只能读取一层,像val.extraProperties.MemberCode是读取不到的,需要转换一下。

保存的时候格式又要转回去,必须和接口数据保持一致才行

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值