• 【ABP】从零开始学习ABP_001_新建实体功能


    上一篇文章中介绍了如何下载、运行ABP Zero示例项目,这个示例项目可以直接作为模板进行二次开发,很适合做企业开发框架。

    本未介绍基于ABP Zero示例项目,如何新建一个自定义的实体。

    此处以EquipmentType(设备类型)为例,建立一个简单的实体。

    以下是之前添加一个简单实体类的效果:

    主页

     公司列表

     新建公司

    编辑公司

    删除公司


    建立方法

    按ABP的标准格式,完整建立一个实体,映射到数据库,作为一个基础资料,并通过前端进行增删查改功能,最小步骤如下:

    1. 新增实体类。
    2. 添加数据库映射。
    3. 同步到数据库。
    4. 新建Dto,建立Dto与实体类的映射。
    5. 建立实体类的功能接口(增删查改),并实现接口。
    6. 添加视图模型ViewModel。
    7. 添加控制器。
    8. 添加视图。
    9. 添加js脚本。
    10. 添加前端菜单(入口)。
    11. 添加权限管理。

    1. 添加实体类

    在core层添加实体类

    1 namespace oMES_APServer.Equipments
    2 {
    3     public class EquipmentType : MESBase.MESBaseEntity
    4     {
    5 
    6     }
    7 }

    这里我把MES会用到的常规属性单独建了一个基类,并继承ABP全属性基类FullAuditedEntity

     1 using Abp.Domain.Entities;
     2 using Abp.Domain.Entities.Auditing;
     3 using System.ComponentModel.DataAnnotations;
     4 
     5 namespace oMES_APServer.MESBase
     6 {
     7     public class MESBaseEntity : FullAuditedEntity<int>, IPassivable
     8     {
     9 
    10         public const int MaxCodeLength = 64;
    11         public const int MaxNameLength = 256;
    12         public const int MaxBriefNameLength = 64;
    13         public const int MaxRemarkLength = 64;
    14 
    15         [Required]
    16         [StringLength(MaxCodeLength)]
    17         public string Code { get; set; }
    18 
    19         [Required]
    20         [StringLength(MaxNameLength)]
    21         public string Name { get; set; }
    22 
    23         [StringLength(64)]
    24         public string BriefName { get; set; }
    25 
    26         [StringLength(512)]
    27         public string Remark { get; set; }
    28         public bool IsActive { get; set; }
    29 
    30     }
    31 }

    2. 添加数据库映射

    在EFCore层添加以下代码:为了让EFCore能够自动生成数据库表结构。

    public DbSet<EquipmentType> equipmentTypes { get; set; }

     

    modelBuilder.Entity<EquipmentType>().ToTable("EquipmentType").HasAlternateKey(x => x.Code).HasName("UK_EquipmentType_Code");

    其中.HasAlternateKey表示建立唯一键,.HasName表示键的名称。

     

     1 using Microsoft.EntityFrameworkCore;
     2 using Abp.Zero.EntityFrameworkCore;
     3 using oMES_APServer.Authorization.Roles;
     4 using oMES_APServer.Authorization.Users;
     5 using oMES_APServer.MultiTenancy;
     6 using oMES_APServer.Companies;
     7 using oMES_APServer.Equipments;
     8 
     9 namespace oMES_APServer.EntityFrameworkCore
    10 {
    11     public class oMES_APServerDbContext : AbpZeroDbContext<Tenant, Role, User, oMES_APServerDbContext>
    12     {
    13         /* Define a DbSet for each entity of the application */
    14         public oMES_APServerDbContext(DbContextOptions<oMES_APServerDbContext> options)
    15             : base(options)
    16         {
    17         }
    18 
    19         /*添加自定义实体类的数据库映射*/
    20         public DbSet<Company> companies { get; set; }
    21         public DbSet<Department> departments { get; set; }
    22         public DbSet<EquipmentType> equipmentTypes { get; set; }
    23 
    24         protected override void OnModelCreating(ModelBuilder modelBuilder)
    25         {
    26             base.OnModelCreating(modelBuilder);
    27 
    28             modelBuilder.Entity<Company>().ToTable("Company")
    29                 .HasAlternateKey(x=>x.Code).HasName("UK_Company_Code");
    30             modelBuilder.Entity<Department>().ToTable("Department")
    31                 .HasAlternateKey(x => x.Code).HasName("UK_Department_Code");
    32             modelBuilder.Entity<EquipmentType>().ToTable("EquipmentType")
    33                 .HasAlternateKey(x => x.Code).HasName("UK_EquipmentType_Code");
    34         }
    35 
    36     }
    37 }

    3. 同步到数据库。

    依次执行以下两条指令:

    1. add-migration add-EquipmentType
    2. update-database

    第一条表示,新建同步映射,映射名称为add-EquipmentType。

    第二条表示同步数据库。

     

    执行时,出现上述报错,不要慌,重新生成一下项目,应该有报错,解决完项目报错再执行,就可以了。

    执行时注意默认项目需要选择EFCore项目。

    4. 新建Dto,建立Dto与实体类的映射

    在Application层建立Dto

    1 namespace oMES_APServer.Equipments.Dto
    2 {
    3     public class EquipmentTypeDto : MESBaseDto.MESBaseEntityDto
    4     {
    5 
    6     }
    7 }

    在Dtos同级目录下,建立实体类和Dto的映射 EquipmentTypeMapProfile

     1 using AutoMapper;
     2 
     3 namespace oMES_APServer.Equipments.Dto
     4 {
     5     public class EquipmentTypeMapProfile : Profile
     6     {
     7         public EquipmentTypeMapProfile()
     8         {
     9             CreateMap<EquipmentType, EquipmentTypeDto>();
    10             CreateMap<EquipmentTypeDto, EquipmentType>();
    11             CreateMap<EquipmentTypeDto, EquipmentType>()
    12                 .ForMember(x => x.CreationTime, opt => opt.Ignore());
    13         }
    14     }
    15 }

    引申:

    ABP Zero的Dto类文件夹中,会有一个 PagedxxxResultRequestDto.cs类,这个是用于按给定条件查找数据列表,并进行分页的类。目前还没有学习到,所以仅按照现有的实体类进行仿照编程,不做额外处理。

     1 using Abp.Application.Services.Dto;
     2 
     3 namespace oMES_APServer.Equipments.Dto
     4 {
     5     public class PagedEquipmentTypeResultRequestDto : PagedResultRequestDto
     6     {
     7 
     8         public string Code { get; set; }
     9 
    10         public string Name { get; set; }
    11 
    12         public bool? IsActive { get; set; }
    13 
    14     }
    15 }

    5. 建立实体类的功能接口(增删查改),并实现接口。

    在Application层中建立接口:因为ABP接口已经实现了基础功能(增删查改)的方法定义,所以直接继承IAsyncCrudAppService即可,写法参照已有的User相关类。

     1 using Abp.Application.Services;
     2 using oMES_APServer.Companies.Dto;
     3 
     4 namespace oMES_APServer.Equipments
     5 {
     6     public interface IEquipmentTypesAppService : IAsyncCrudAppService<CompanyDto, int, PagedCompanyResultRequestDto, CompanyDto, CompanyDto>
     7     {
     8 
     9     }
    10 }

    自定义实现基础接口:

     1 using System.Collections.Generic;
     2 using System.Linq;
     3 using System.Threading.Tasks;
     4 using Abp.Application.Services;
     5 using Abp.Application.Services.Dto;
     6 using Abp.Domain.Repositories;
     7 using Abp.Domain.Uow;
     8 using Abp.Extensions;
     9 using Abp.Linq.Extensions;
    10 using Abp.UI;
    11 using Microsoft.EntityFrameworkCore;
    12 using oMES_APServer.Equipments.Dto;
    13 
    14 namespace oMES_APServer.Equipments
    15 {
    16     public class EquipmentTypesAppService : AsyncCrudAppService<EquipmentType, EquipmentTypeDto, int, PagedEquipmentTypeResultRequestDto, EquipmentTypeDto, EquipmentTypeDto>, IEquipmentTypeAppService
    17     {
    18         private readonly IRepository<EquipmentType> _equipmentTypeRepository;
    19 
    20         public EquipmentTypesAppService(IRepository<EquipmentType> equipmentTypeRepository)
    21             : base(equipmentTypeRepository)
    22         {
    23             _equipmentTypeRepository = equipmentTypeRepository;
    24 
    25             LocalizationSourceName = oMES_APServerConsts.LocalizationSourceName;
    26         }
    27 
    28         public override async Task<EquipmentTypeDto> Get(EntityDto<int> input)
    29         {
    30             var equipmentType = await _equipmentTypeRepository
    31                 .GetAsync(input.Id);
    32 
    33             return ObjectMapper.Map<EquipmentTypeDto>(equipmentType);
    34         }
    35 
    36         public override async Task<PagedResultDto<EquipmentTypeDto>> GetAll(PagedEquipmentTypeResultRequestDto input)
    37         {
    38             var equipmentTypes = Repository.GetAll()
    39                 .WhereIf(!input.Name.IsNullOrWhiteSpace(), x => x.Name.Contains(input.Name))
    40                 .WhereIf(!input.Code.IsNullOrWhiteSpace(), x => x.Code.Contains(input.Code))
    41                 .WhereIf(input.IsActive.HasValue, x => x.IsActive == input.IsActive)
    42                 .OrderBy(x => x.Code);
    43 
    44             return await Task.FromResult(new PagedResultDto<EquipmentTypeDto>(equipmentTypes.CountAsync().Result,
    45                 ObjectMapper.Map<List<EquipmentTypeDto>>(equipmentTypes)
    46             ));
    47         }
    48 
    49         public override async Task<EquipmentTypeDto> Create(EquipmentTypeDto input)
    50         {
    51 
    52             //判断CODE是否已存在
    53             var model = await Repository.GetAllIncluding().FirstOrDefaultAsync(x => x.Code == input.Code);
    54             if (model != null)
    55             {
    56                 throw new UserFriendlyException(L("EquipmentType code already exists"));
    57             }
    58 
    59             //检查是否已被软删除,已经软删除的数据,无法通过
    60             using (UnitOfWorkManager.Current.DisableFilter(AbpDataFilters.SoftDelete))
    61             {
    62                 //判断CODE是否已存在
    63                 var model0 = await Repository.GetAllIncluding().FirstOrDefaultAsync(x => x.Code == input.Code);
    64                 if (model0 != null)
    65                 {
    66                     throw new UserFriendlyException(L("EquipmentType code is deleted"));
    67                 }
    68             }
    69 
    70             var entity = ObjectMapper.Map<EquipmentType>(input);
    71             await _equipmentTypeRepository.InsertAsync(entity);
    72             return MapToEntityDto(entity);
    73         }
    74 
    75         public override async Task<EquipmentTypeDto> Update(EquipmentTypeDto input)
    76         {
    77             var entity = await _equipmentTypeRepository.GetAsync(input.Id);
    78 
    79             ObjectMapper.Map(input, entity);
    80 
    81             await _equipmentTypeRepository.UpdateAsync(entity);
    82 
    83             return MapToEntityDto(entity);
    84         }
    85 
    86         public override async Task Delete(EntityDto<int> input)
    87         {
    88             var entity = await _equipmentTypeRepository.GetAsync(input.Id);
    89             await _equipmentTypeRepository.DeleteAsync(entity);
    90         }
    91 
    92     }
    93 }

    其中,创建的代码如下:在基类中,我们设置了Code字段为唯一键,所以需要先确定Code不存在

     1 public override async Task<EquipmentTypeDto> Create(EquipmentTypeDto input)
     2         {
     3 
     4             //判断CODE是否已存在
     5             var model = await Repository.GetAllIncluding().FirstOrDefaultAsync(x => x.Code == input.Code);
     6             if (model != null)
     7             {
     8                 throw new UserFriendlyException(L("EquipmentType code already exists"));
     9             }
    10 
    11             //检查是否已被软删除,已经软删除的数据,无法通过
    12             using (UnitOfWorkManager.Current.DisableFilter(AbpDataFilters.SoftDelete))
    13             {
    14                 //判断CODE是否已存在
    15                 var model0 = await Repository.GetAllIncluding().FirstOrDefaultAsync(x => x.Code == input.Code);
    16                 if (model0 != null)
    17                 {
    18                     throw new UserFriendlyException(L("EquipmentType code is deleted"));
    19                 }
    20             }
    21 
    22             var entity = ObjectMapper.Map<EquipmentType>(input);
    23             await _equipmentTypeRepository.InsertAsync(entity);
    24             return MapToEntityDto(entity);
    25         }

    ABP的全属性类FullAuditedEntity中,预置了软删除功能,如果一条数据被软删除了(IsDeleted字段为1),那么直接查找是招不到的。

    需要临时关闭软删除的过滤器,才能找到:在using中,使用正常的查询代码,就能查到已被软删除的数据。

     1 //检查是否已被软删除,已经软删除的数据,无法通过
     2             using (UnitOfWorkManager.Current.DisableFilter(AbpDataFilters.SoftDelete))
     3             {
     4                 //判断CODE是否已存在
     5                 var model0 = await Repository.GetAllIncluding().FirstOrDefaultAsync(x => x.Code == input.Code);
     6                 if (model0 != null)
     7                 {
     8                     throw new UserFriendlyException(L("EquipmentType code is deleted"));
     9                 }
    10             }

    6. 添加视图模型ViewModel。

     在MVC层

    添加查询视图模型,这里没有做特殊处理,直接使用Dto

     1 using oMES_APServer.Equipments.Dto;
     2 using System.Collections.Generic;
     3 
     4 namespace oMES_APServer.Web.Models.EquipmentTypes
     5 {
     6     public class EquipmentTypeListViewModel
     7     {
     8         public IReadOnlyList<EquipmentTypeDto> EquipmentTypes { get; set; }
     9     }
    10 }

    添加编辑视图模型

    1 using oMES_APServer.Equipments.Dto;
    2 
    3 namespace oMES_APServer.Web.Models.EquipmentTypes
    4 {
    5     public class EditEquipmentTypeModalViewModel
    6     {
    7         public EquipmentTypeDto EquipmentType { get; set; }
    8     }
    9 }

     7. 添加控制器。

    控制器中添加两个方法Index和Edit.

     1 using System.Threading.Tasks;
     2 using Abp.Application.Services.Dto;
     3 using Microsoft.AspNetCore.Mvc;
     4 using oMES_APServer.Controllers;
     5 using oMES_APServer.Equipments;
     6 using oMES_APServer.Equipments.Dto;
     7 using oMES_APServer.Web.Models.EquipmentTypes;
     8 
     9 namespace oMES_APServer.Web.Mvc.Controllers
    10 {
    11     public class EquipmentTypesController : oMES_APServerControllerBase
    12     {
    13 
    14         private readonly IEquipmentTypeAppService _equipmentTypeAppService;
    15 
    16         public EquipmentTypesController(IEquipmentTypeAppService equipmentTypeAppService)
    17         {
    18             _equipmentTypeAppService = equipmentTypeAppService;
    19         }
    20 
    21         public async Task<IActionResult> Index()
    22         {
    23             var modelDto = (await _equipmentTypeAppService
    24                 .GetAll(new PagedEquipmentTypeResultRequestDto { MaxResultCount = int.MaxValue })
    25                 ).Items;
    26             var viewModel = new EquipmentTypeListViewModel
    27             {
    28                 EquipmentTypeList = modelDto
    29             };
    30             return View(viewModel);
    31         }
    32 
    33         public async Task<ActionResult> EditEquipmentTypeModal(int id)
    34         {
    35             var modelDto = await _equipmentTypeAppService.Get(new EntityDto(id));
    36             var editViewModel = new EditEquipmentTypeModalViewModel
    37             {
    38                 EquipmentType = modelDto
    39             };
    40             return View("_EditEquipmentTypeModal", editViewModel);
    41         }
    42 
    43     }
    44 }

    8. 添加视图。

    视图由user中相关视图复制而来,将名称user更改为equipmentType相关即可使用。

    查看&新建视图

      1 @using oMES_APServer.Web.Startup
      2 @using oMES_APServer.Equipments
      3 @model oMES_APServer.Web.Models.EquipmentTypes.EquipmentTypeListViewModel
      4 @{
      5     ViewBag.CurrentPageName = PageNames.EquipmentTypes;
      6 }
      7 @section scripts
      8 {
      9     <environment names="Development">
     10         <script src="~/view-resources/Views/EquipmentTypes/Index.js" asp-append-version="true"></script>
     11     </environment>
     12 
     13     <environment names="Staging,Production">
     14         <script src="~/view-resources/Views/EquipmentTypes/Index.js" asp-append-version="true"></script>
     15     </environment>
     16 }
     17 <div class="row clearfix">
     18     <div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
     19         <div class="card">
     20             <div class="header">
     21                 <h2>
     22                     @L("EquipmentType")
     23                 </h2>
     24                 <ul class="header-dropdown m-r--5">
     25                     <li class="dropdown">
     26                         <a href="javascript:void(0);" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
     27                             <i class="material-icons">more_vert</i>
     28                         </a>
     29                         <ul class="dropdown-menu pull-right">
     30                             <li><a id="RefreshButton" href="javascript:void(0);" class="waves-effect waves-block"><i class="material-icons">refresh</i>@L("Refresh")</a></li>
     31                         </ul>
     32                     </li>
     33                 </ul>
     34             </div>
     35             <div class="body table-responsive">
     36                 <table class="table">
     37                     <thead>
     38                         <tr>
     39                             <th>@L("Code")</th>
     40                             <th>@L("Name")</th>
     41                             <th>@L("BriefName")</th>
     42                             <th>@L("Remark")</th>
     43                             <th>@L("CreationTime")</th>
     44                             <th>@L("CreatorUserId")</th>
     45                             <th>@L("LastModificationTime")</th>
     46                             <th>@L("LastModifierUserId")</th>
     47                         </tr>
     48                     </thead>
     49                     <tbody>
     50                         @foreach (var viewModel in Model.EquipmentTypeList)
     51                         {
     52                             <tr>
     53                                 <td>@viewModel.Code</td>
     54                                 <td>@viewModel.Name</td>
     55                                 <td>@viewModel.BriefName</td>
     56                                 <td>@viewModel.Remark</td>
     57                                 <td>@viewModel.CreationTime</td>
     58                                 <td>@viewModel.CreatorUserId</td>
     59                                 <td>@viewModel.LastModificationTime</td>
     60                                 <td>@viewModel.LastModifierUserId</td>
     61 
     62                                 <td class="dropdown">
     63                                     <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
     64                                         <i class="material-icons">menu</i>
     65                                     </a>
     66                                     <ul class="dropdown-menu pull-right">
     67                                         <li><a href="#" class="waves-effect waves-block edit-equipmentType" data-equipmentType-id="@viewModel.Id" data-toggle="modal" data-target="#EquipmentTypeEditModal"><i class="material-icons">edit</i>@L("Edit")</a></li>
     68                                         <li><a href="#" class="waves-effect waves-block delete-equipmentType" data-equipmentType-id="@viewModel.Id" data-equipmentType-name="@viewModel.Name"><i class="material-icons">delete_sweep</i>@L("Delete")</a></li>
     69                                     </ul>
     70                                 </td>
     71                             </tr>
     72                         }
     73                     </tbody>
     74                 </table>
     75                 <button type="button" class="btn btn-primary btn-circle waves-effect waves-circle waves-float pull-right" data-toggle="modal" data-target="#EquipmentTypeCreateModal">
     76                     <i class="material-icons">add</i>
     77                 </button>
     78             </div>
     79         </div>
     80     </div>
     81 </div>
     82 
     83 <div class="modal fade" id="EquipmentTypeCreateModal" tabindex="-1" role="dialog" aria-labelledby="EquipmentTypeCreateModalLabel" data-backdrop="static">
     84     <div class="modal-dialog" role="document">
     85         <div class="modal-content">
     86             <form name="equipmentTypeCreateForm" role="form" novalidate class="form-validation">
     87                 <div class="modal-header">
     88                     <h4 class="modal-title">
     89                         <span>@L("CreateNewEquipmentType")</span>
     90                     </h4>
     91                 </div>
     92                 <div class="modal-body">
     93                     <div class="form-group form-float">
     94                         <div class="form-line">
     95                             <input class="form-control" type="text" name="Code" required maxlength="@EquipmentType.MaxCodeLength">
     96                             <label class="form-label">@L("Code")</label>
     97                         </div>
     98                     </div>
     99                     <div class="form-group form-float">
    100                         <div class="form-line">
    101                             <input class="form-control" type="text" name="Name" required maxlength="@EquipmentType.MaxNameLength">
    102                             <label class="form-label">@L("Name")</label>
    103                         </div>
    104                     </div>
    105                     <div class="form-group form-float">
    106                         <div class="form-line">
    107                             <input class="form-control" type="text" name="BriefName" maxlength="@EquipmentType.MaxBriefNameLength">
    108                             <label class="form-label">@L("BriefName")</label>
    109                         </div>
    110                     <div class="form-group form-float">
    111                         <div class="form-line">
    112                             <input class="form-control" type="text" name="Remark" maxlength="@EquipmentType.MaxRemarkLength">
    113                             <label class="form-label">@L("Remark")</label>
    114                         </div>
    115                     </div>
    116                 </div>
    117                 <div class="modal-footer">
    118                     <button type="button" class="btn btn-default waves-effect" data-dismiss="modal">@L("Cancel")</button>
    119                     <button type="submit" class="btn btn-primary waves-effect">@L("Save")</button>
    120                 </div>
    121             </form>
    122         </div>
    123     </div>
    124 </div>
    125 
    126 <div class="modal fade" id="EquipmentTypeEditModal" tabindex="-1" role="dialog" aria-labelledby="EquipmentTypeEditModalLabel" data-backdrop="static">
    127     <div class="modal-dialog" role="document">
    128         <div class="modal-content">
    129 
    130         </div>
    131     </div>
    132 </div>
    Index.cshtml

    编辑视图

     1 @using oMES_APServer.Web.Models.Common.Modals
     2 @model oMES_APServer.Web.Models.EquipmentTypes.EditEquipmentTypeModalViewModel
     3 @{
     4     Layout = null;
     5 }
     6 @Html.Partial("~/Views/Shared/Modals/_ModalHeader.cshtml", new ModalHeaderViewModel(L("EditEquipmentType")))
     7 
     8 <div class="modal-body">
     9     <form name="EquipmentTypeEditForm" role="form" novalidate class="form-validation">
    10         <input type="hidden" name="Id" value="@Model.EquipmentType.Id" />
    11         <ul class="nav nav-tabs tab-nav-right" role="tablist">
    12             <li role="presentation" class="active"><a href="#edit-equipmentType-details" data-toggle="tab">@L("EquipmentTypeDetails")</a></li>
    13         </ul>
    14         <div class="tab-content">
    15             <div role="tabpanel" class="tab-pane animated fadeIn active" id="edit-equipmentType-details">
    16 
    17                 <div class="row clearfix" style="margin-top:10px;">
    18                     <div class="col-sm-12">
    19                         <div class="form-group form-float">
    20                             <div class="form-line">
    21                                 <input id="code" type="text" name="Code" value="@Model.EquipmentType.Code" required maxlength="32" minlength="2" class="validate form-control">
    22                                 <label for="code" class="form-label">@L("Code")</label>
    23                             </div>
    24                         </div>
    25                     </div>
    26                 </div>
    27 
    28                 <div class="row clearfix" style="margin-top:10px;">
    29                     <div class="col-sm-12">
    30                         <div class="form-group form-float">
    31                             <div class="form-line">
    32                                 <input id="name" type="text" name="Name" value="@Model.EquipmentType.Name" required maxlength="32" minlength="2" class="validate form-control">
    33                                 <label for="name" class="form-label">@L("Name")</label>
    34                             </div>
    35                         </div>
    36                     </div>
    37                 </div>
    38 
    39                 <div class="row clearfix" style="margin-top:10px;">
    40                     <div class="col-sm-12">
    41                         <div class="form-group form-float">
    42                             <div class="form-line">
    43                                 <input id="briefname" type="text" name="BriefName" value="@Model.EquipmentType.BriefName" maxlength="32" minlength="2" class="validate form-control">
    44                                 <label for="briefname" class="form-label">@L("BriefName")</label>
    45                             </div>
    46                         </div>
    47                     </div>
    48                 </div>
    49 
    50                 <div class="row clearfix" style="margin-top:10px;">
    51                     <div class="col-sm-12">
    52                         <div class="form-group form-float">
    53                             <div class="form-line">
    54                                 <input id="remark" type="text" name="Remark" value="@Model.EquipmentType.Remark" maxlength="32" minlength="2" class="validate form-control">
    55                                 <label for="remark" class="form-label">@L("Remark")</label>
    56                             </div>
    57                         </div>
    58                     </div>
    59                 </div>
    60 
    61             </div>
    62         </div>
    63     </form>
    64 </div>
    65 
    66 @Html.Partial("~/Views/Shared/Modals/_ModalFooterWithSaveAndCancel.cshtml")
    67 
    68 <script src="~/view-resources/Views/EquipmentTypes/_EditEquipmentTypeModal.js" asp-append-version="true"></script>
    _EditEquipmentTypeModal.cshtml

    9. 添加js脚本。

    视图中添加了js脚本,此处添加合适的js脚本,此脚本由user.js复制而来,更改为equipmentType即可使用。

    添加的位置如上述视图中代码所示:"~/view-resources/Views/EquipmentTypes/_EditEquipmentTypeModal.js"

    index.js如下

     1 (function () {
     2     $(function () {
     3 
     4         var _equipmentTypeService = abp.services.app.equipmentTypes;
     5         var _$modal = $('#EquipmentTypeCreateModal');
     6         var _$form = _$modal.find('form');
     7 
     8         _$form.validate();
     9 
    10         $('#RefreshButton').click(function () {
    11             refreshequipmentTypeList();
    12         });
    13 
    14         //删除方法
    15         $('.delete-equipmentType').click(function () {
    16             var equipmentTypeId = $(this).attr("data-equipmentType-id");
    17             var tenancyName = $(this).attr('data-equipmentType-name');
    18 
    19             deleteequipmentType(equipmentTypeId, tenancyName);
    20         });
    21 
    22         //编辑方法
    23         $('.edit-equipmentType').click(function (e) {
    24             var equipmentTypeId = $(this).attr("data-equipmentType-id");
    25 
    26             e.preventDefault();
    27             $.ajax({
    28                 url: abp.appPath + 'equipmentTypes/EditEquipmentTypeModal?equipmentTypeId=' + equipmentTypeId,
    29                 type: 'POST',
    30                 contentType: 'application/html',
    31                 success: function (content) {
    32                     $('#EquipmentTypeEditModal div.modal-content').html(content);
    33                 },
    34                 error: function (e) { }
    35             });
    36         });
    37 
    38         //新增
    39         _$form.find('button[type="submit"]').click(function (e) {
    40             e.preventDefault();
    41 
    42             if (!_$form.valid()) {
    43                 return;
    44             }
    45 
    46             var equipmentType = _$form.serializeFormToObject(); //serializeFormToObject is defined in main.js
    47 
    48             abp.ui.setBusy(_$modal);
    49             _equipmentTypeService.create(equipmentType).done(function () {
    50                 _$modal.modal('hide');
    51                 location.reload(true); //reload page to see new equipmentType!
    52             }).always(function () {
    53                 abp.ui.clearBusy(_$modal);
    54             });
    55         });
    56 
    57         _$modal.on('shown.bs.modal', function () {
    58             _$modal.find('input:not([type=hidden]):first').focus();
    59         });
    60 
    61         function refreshequipmentTypeList() {
    62             location.reload(true); //reload page to see new equipmentType!
    63         }
    64 
    65         function deleteequipmentType(equipmentTypeId, equipmentTypeName) {
    66             abp.message.confirm(
    67                 abp.utils.formatString(abp.localization.localize('AreYouSureWantToDelete', 'oMES_APServer'), equipmentTypeName),
    68                 function (isConfirmed) {
    69                     if (isConfirmed) {
    70                         _equipmentTypeService.delete({
    71                             id: equipmentTypeId
    72                         }).done(function () {
    73                             refreshequipmentTypeList();
    74                         });
    75                     }
    76                 }
    77             );
    78         }
    79     });
    80 })();
    Index.js

    编辑模型的脚本_EditEquipmentTypeModal.js如下

     1 (function ($) {
     2 
     3     var _equipmentTypeService = abp.services.app.equipmentType;
     4     var _$modal = $('#EquipmentTypeEditModal');
     5     var _$form = $('form[name=EquipmentTypeEditForm]');
     6 
     7     function save() {
     8 
     9         if (!_$form.valid()) {
    10             return;
    11         }
    12 
    13         var equipmentType = _$form.serializeFormToObject(); //serializeFormToObject is defined in main.js
    14         
    15 
    16         abp.ui.setBusy(_$form);
    17         _equipmentTypeService.update(equipmentType).done(function () {
    18                 _$modal.modal('hide');
    19                 location.reload(true); //reload page to see edited equipmentType!
    20             }).always(function () {
    21                 abp.ui.clearBusy(_$modal);
    22             });
    23     }
    24 
    25     //Handle save button click
    26     _$form.closest('div.modal-content').find(".save-button").click(function (e) {
    27         e.preventDefault();
    28         save();
    29     });
    30 
    31     //Handle enter key
    32     _$form.find('input').on('keypress', function (e) {
    33         if (e.which === 13) {
    34             e.preventDefault();
    35             save();
    36         }
    37     });
    38 
    39     $.AdminBSB.input.activate(_$form);
    40 
    41     _$modal.on('shown.bs.modal', function () {
    42         _$form.find('input[type=text]:first').focus();
    43     });
    44 })(jQuery);
    _EditEquipmentTypeModal.js

    10. 添加前端菜单(入口)。

    菜单需在startup文件夹 xxxNavigationProvider类中,添加.AddItem代码。

    .AddItem放置的顺序不同,界面中的显示顺序就不同。

     1 using Abp.Application.Navigation;
     2 using Abp.Localization;
     3 using oMES_APServer.Authorization;
     4 
     5 namespace oMES_APServer.Web.Startup
     6 {
     7     /// <summary>
     8     /// This class defines menus for the application.
     9     /// </summary>
    10     public class oMES_APServerNavigationProvider : NavigationProvider
    11     {
    12         public override void SetNavigation(INavigationProviderContext context)
    13         {
    14             context.Manager.MainMenu
    15                 .AddItem(
    16                     new MenuItemDefinition(
    17                         PageNames.EquipmentTypes,
    18                         L("EquipmentTypes"),
    19                         url: "EquipmentTypes",
    20                         icon: "info"
    21                     )
    22                 )
    以下省略
    MenuItemDefinition的各参数看名字就能理解,从上到下依次是:
    菜单名称,
    菜单显示名称,
    url:链接,即控制器名称
    icon:图标名称,会根据名称自动查找对应的图标文件。

    11. 添加权限管理。

    通常的权限管理方式为:人员->角色->权限。

    即为人员分配角色,为角色分配权限,这样就避免了多人相同权限时,重复分配的工作。

    此处将设备管理功能(菜单)分配给对应的角色。

    需要添加如下代码:

    1、添加权限名称

     1 namespace oMES_APServer.Authorization
     2 {
     3     public static class PermissionNames
     4     {
     5         public const string Pages_Tenants = "Pages.Tenants";
     6         public const string Pages_Users = "Pages.Users";
     7         public const string Pages_Roles = "Pages.Roles";
     8         //添加自定义权限名称
     9         public const string Pages_Companies = "Pages.Companies";
    10         public const string Pages_Departments = "Pages.Departments";
    11 
    12         public const string Pages_EquipmentTypes = "Pages.EquipmentTypes";
    13     }
    14 }

    2、系统权限列表中,添加该权限名称

     1 using Abp.Authorization;
     2 using Abp.Localization;
     3 using Abp.MultiTenancy;
     4 
     5 namespace oMES_APServer.Authorization
     6 {
     7     public class oMES_APServerAuthorizationProvider : AuthorizationProvider
     8     {
     9         public override void SetPermissions(IPermissionDefinitionContext context)
    10         {
    11             context.CreatePermission(PermissionNames.Pages_Users, L("Users"));
    12             context.CreatePermission(PermissionNames.Pages_Roles, L("Roles"));
    13             context.CreatePermission(PermissionNames.Pages_Tenants, L("Tenants"), multiTenancySides: MultiTenancySides.Host);
    14 
    15             //添加自定义权限
    16             context.CreatePermission(PermissionNames.Pages_Companies, L("Companies"));
    17             context.CreatePermission(PermissionNames.Pages_Departments, L("Departments"));
    18             context.CreatePermission(PermissionNames.Pages_EquipmentTypes, L("EquipmentTypes"));
    19         }
    20 
    21         private static ILocalizableString L(string name)
    22         {
    23             return new LocalizableString(name, oMES_APServerConsts.LocalizationSourceName);
    24         }
    25     }
    26 }

    3、菜单中添加权限控制

     requiredPermissionName: PermissionNames.Pages_Companies

    4、控制器中添加权限控制

    [AbpAuthorize(PermissionNames.Pages_EquipmentTypes)]

    5、应用服务方法中添加权限控制

    [AbpAuthorize(PermissionNames.Pages_EquipmentTypes)]

    添加完成后,运行程序,角色管理中,就可以单独选择该功能的权限了。

    12. 文本翻译。

    ABP的翻译方法在xxx.Core项目Localization文件夹中

    默认支持9种语言。

    添加中文翻译,只需在xxx-zh-Hans.xml文件中添加相应字段即可。

    这要注意一下:xml中的子项,如果name值相同的话,会报错。所以每次添加新翻译时,先检查一下name值是否重复。

    如下添加即可:

    到此,一个基础资料的基础功能就完成了。

    之后会继续完善所有的基础功能,中间有对ABP功能的研究也会一点一点写出来。

  • 相关阅读:
    AJAX传输图片文件
    和内嵌的iframe进行通讯
    ts的特殊数据类型
    Angular RxJs:针对异步数据流编程工具
    Angular路由使用
    RBAC基于角色的权限管理模型
    Java中的实体类--Serializable接口、transient 关键字
    字符串问题----将整数字符串转换成整数值
    字符串问题----判断两个字符串是否互为旋转词
    字符串问题----去掉字符串中连续出现K个0的子串
  • 原文地址:https://www.cnblogs.com/chrlee/p/11610299.html
Copyright © 2020-2023  润新知