需求: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")){//添加会员Codeclaims.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);//添加自定义claimList<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是读取不到的,需要转换一下。
保存的时候格式又要转回去,必须和接口数据保持一致才行