需求:abp框架原有的abpusers表字段无法满足业务需求,需要新增字段来解决。
1、在domain程序集下新建AppUser表
该类用来定义新增的字段,不需要继承任何父类,如下所示:
- public class AppUser
- {
- ///
- /// 会员Code
- ///
- [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
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
() - .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
1.在Admin.HttpApi程序集下LoginController类中给toekn中Claim添加自定义字段
-
-
- ///
- /// 在CurrentUser对象的Claims中添加扩展字段
- ///
- private List
SetUserClaims(IdentityUser userInfo) - {
-
- List
claims = new List(); - 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
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是读取不到的,需要转换一下。
保存的时候格式又要转回去,必须和接口数据保持一致才行