【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. 添加实体类

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能够自动生成数据库表结构。

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。

第二条表示同步数据库。

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

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

建立Dto

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

建立实体类和Dto的映射

 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. 建立实体类的功能接口(增删查改),并实现接口。

建立接口:因为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。

添加查询视图模型,这里没有做特殊处理,直接使用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>
 45                             <th>@L("Remark")</th>
 46                             <th>@L("CreationTime")</th>
 47                             <th>@L("CreatorUserId")</th>
 48                             <th>@L("LastModificationTime")</th>
 49                             <th>@L("LastModifierUserId")</th>
 50                         </tr>
 51                     </thead>
 52                     <tbody>
 53                         @foreach (var viewModel in Model.EquipmentTypeList)
 54                         {
 55                             <tr>
 56                                 <td>@viewModel.Code</td>
 57                                 <td>@viewModel.Name</td>
 58                                 <td>@viewModel.BriefName</td>
 59                                 <td>@viewModel.Remark</td>
 60                                 <td>@viewModel.CreationTime</td>
 61                                 <td>@viewModel.CreatorUserId</td>
 62                                 <td>@viewModel.LastModificationTime</td>
 63                                 <td>@viewModel.LastModifierUserId</td>
 64
 65                                 <td class="dropdown">
 66                                     <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
 67                                         <i class="material-icons">menu</i>
 68                                     </a>
 69                                     <ul class="dropdown-menu pull-right">
 70                                         <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>
 71                                         <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>
 72                                     </ul>
 73                                 </td>
 74                             </tr>
 75                         }
 76                     </tbody>
 77                 </table>
 78                 <button type="button" class="btn btn-primary btn-circle waves-effect waves-circle waves-float pull-right" data-toggle="modal" data-target="#EquipmentTypeCreateModal">
 79                     <i class="material-icons">add</i>
 80                 </button>
 81             </div>
 82         </div>
 83     </div>
 84 </div>
 85
 86 <div class="modal fade" id="EquipmentTypeCreateModal" tabindex="-1" role="dialog" aria-labelledby="EquipmentTypeCreateModalLabel" data-backdrop="static">
 87     <div class="modal-dialog" role="document">
 88         <div class="modal-content">
 89             <form name="equipmentTypeCreateForm" role="form" novalidate class="form-validation">
 90                 <div class="modal-header">
 91                     <h4 class="modal-title">
 92                         <span>@L("CreateNewEquipmentType")</span>
 93                     </h4>
 94                 </div>
 95                 <div class="modal-body">
 96                     <div class="form-group form-float">
 97                         <div class="form-line">
 98                             <input class="form-control" type="text" name="Code" required maxlength="@EquipmentType.MaxCodeLength">
 99                             <label class="form-label">@L("Code")</label>
100                         </div>
101                     </div>
102                     <div class="form-group form-float">
103                         <div class="form-line">
104                             <input class="form-control" type="text" name="Name" required maxlength="@EquipmentType.MaxNameLength">
105                             <label class="form-label">@L("Name")</label>
106                         </div>
107                     </div>
108                     <div class="form-group form-float">
109                         <div class="form-line">
110                             <input class="form-control" type="text" name="BriefName" maxlength="@EquipmentType.MaxBriefNameLength">
111                             <label class="form-label">@L("BriefName")</label>
112                         </div>
113                     <div class="form-group form-float">
114                         <div class="form-line">
115                             <input class="form-control" type="text" name="Remark" maxlength="@EquipmentType.MaxRemarkLength">
116                             <label class="form-label">@L("Remark")</label>
117                         </div>
118                     </div>
119                 </div>
120                 <div class="modal-footer">
121                     <button type="button" class="btn btn-default waves-effect" data-dismiss="modal">@L("Cancel")</button>
122                     <button type="submit" class="btn btn-primary waves-effect">@L("Save")</button>
123                 </div>
124             </form>
125         </div>
126     </div>
127 </div>
128
129 <div class="modal fade" id="EquipmentTypeEditModal" tabindex="-1" role="dialog" aria-labelledby="EquipmentTypeEditModalLabel" data-backdrop="static">
130     <div class="modal-dialog" role="document">
131         <div class="modal-content">
132
133         </div>
134     </div>
135 </div>

编辑视图

 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>

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.equipmentType;
 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         _$form.find(‘button[type="submit"]‘).click(function (e) {
39             e.preventDefault();
40
41             if (!_$form.valid()) {
42                 return;
43             }
44
45             var equipmentType = _$form.serializeFormToObject(); //serializeFormToObject is defined in main.js
46
47             abp.ui.setBusy(_$modal);
48             _equipmentTypeService.create(equipmentType).done(function () {
49                 _$modal.modal(‘hide‘);
50                 location.reload(true); //reload page to see new equipmentType!
51             }).always(function () {
52                 abp.ui.clearBusy(_$modal);
53             });
54         });
55
56         _$modal.on(‘shown.bs.modal‘, function () {
57             _$modal.find(‘input:not([type=hidden]):first‘).focus();
58         });
59
60         function refreshequipmentTypeList() {
61             location.reload(true); //reload page to see new equipmentType!
62         }
63
64         function deleteequipmentType(equipmentTypeId, equipmentTypeName) {
65             abp.message.confirm(
66                 abp.utils.formatString(abp.localization.localize(‘AreYouSureWantToDelete‘, ‘oMES_APServer‘), equipmentTypeName),
67                 function (isConfirmed) {
68                     if (isConfirmed) {
69                         _equipmentTypeService.delete({
70                             id: equipmentTypeId
71                         }).done(function () {
72                             refreshequipmentTypeList();
73                         });
74                     }
75                 }
76             );
77         }
78     });
79 })();

编辑模型的脚本_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);

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功能的研究也会一点一点写出来。

原文地址:https://www.cnblogs.com/chrlee/p/11610299.html

时间: 2024-11-01 22:18:51

【ABP】从零开始学习ABP_001_新建实体功能的相关文章

从零开始学习jQuery (十) jQueryUI常用功能实战

原文:从零开始学习jQuery (十) jQueryUI常用功能实战 本系列文章导航 从零开始学习jQuery (一) 开天辟地入门篇 从零开始学习jQuery (二) 万能的选择器 从零开始学习jQuery (三) 管理jQuery包装集 从零开始学习jQuery (四) 使用jQuery操作元素的属性与样式 从零开始学习jQuery (五) 事件与事件对象 从零开始学习jQuery (六) jQuery中的Ajax 从零开始学习jQuery (七) jQuery动画-让页面动起来! 从零开始

从零开始学习CocoaPods安装和使用

从零开始学习CocoaPods安装和使用 转载: Code4App原创:http://code4app.com/article/cocoapods-install-usage http://m.ithao123.cn/content-9745764.html CocoaPods是什么? 当你开发iOS应用时,会经常使用到很多第三方开源类库,比如JSONKit,AFNetWorking等等.可能某个类库又用到其他类库,所以要使用它,必须得另外下载其他类库,而其他类库又用到其他类库,“子子孙孙无穷尽

Dynamics CRM2013 1:N关系 sub-grid中的“添加现有项”和“添加新建项”功能详解

CRM2013中sub-grid的样式和2011中有了较大的变化,2013和2011界面对比如下 在2011的时候按钮是在ribbon区,1:N的父子关系实体直接点击添加新纪录就可以,但2013就不行了点加号首先会有个下拉框把现有的子实体数据列出来,你可以选择现有的也可以新建 既然你的关系实体是1:N的父子实体,那子的存在肯定是依赖于与父实体的,所以这个地方就压根不存在关联现有实体一旦关联就会报错,所以纯碎新建的话这边的步骤就繁琐了,同时也会给用户带来迷惑 所以这个地方这种情况下完全没必要添加现

从零开始学习jQuery (十一) 实战表单验证与自动完成提示插件

原文:从零开始学习jQuery (十一) 实战表单验证与自动完成提示插件 本系列文章导航 从零开始学习jQuery (一) 开天辟地入门篇 从零开始学习jQuery (二) 万能的选择器 从零开始学习jQuery (三) 管理jQuery包装集 从零开始学习jQuery (四) 使用jQuery操作元素的属性与样式 从零开始学习jQuery (五) 事件与事件对象 从零开始学习jQuery (六) jQuery中的Ajax 从零开始学习jQuery (七) jQuery动画-让页面动起来! 从零

从零开始学习jQuery (一) 开天辟地入门篇

原文:从零开始学习jQuery (一) 开天辟地入门篇 本系列文章导航 从零开始学习jQuery (一) 开天辟地入门篇 从零开始学习jQuery (二) 万能的选择器 从零开始学习jQuery (三) 管理jQuery包装集 从零开始学习jQuery (四) 使用jQuery操作元素的属性与样式 从零开始学习jQuery (五) 事件与事件对象 从零开始学习jQuery (六) jQuery中的Ajax 从零开始学习jQuery (七) jQuery动画-让页面动起来! 从零开始学习jQuer

从零开始学习jQuery (八) 插播:jQuery实施方案

原文:从零开始学习jQuery (八) 插播:jQuery实施方案 本系列文章导航 从零开始学习jQuery (一) 开天辟地入门篇 从零开始学习jQuery (二) 万能的选择器 从零开始学习jQuery (三) 管理jQuery包装集 从零开始学习jQuery (四) 使用jQuery操作元素的属性与样式 从零开始学习jQuery (五) 事件与事件对象 从零开始学习jQuery (六) jQuery中的Ajax 从零开始学习jQuery (七) jQuery动画-让页面动起来! 从零开始学

从零开始学习jQuery (六) AJAX快餐

原文:从零开始学习jQuery (六) AJAX快餐 本系列文章导航 从零开始学习jQuery (一) 开天辟地入门篇 从零开始学习jQuery (二) 万能的选择器 从零开始学习jQuery (三) 管理jQuery包装集 从零开始学习jQuery (四) 使用jQuery操作元素的属性与样式 从零开始学习jQuery (五) 事件与事件对象 从零开始学习jQuery (六) jQuery中的Ajax 从零开始学习jQuery (七) jQuery动画-让页面动起来! 从零开始学习jQuery

从零开始学习jQuery (九) jQuery工具函数

原文:从零开始学习jQuery (九) jQuery工具函数 本系列文章导航 从零开始学习jQuery (一) 开天辟地入门篇 从零开始学习jQuery (二) 万能的选择器 从零开始学习jQuery (三) 管理jQuery包装集 从零开始学习jQuery (四) 使用jQuery操作元素的属性与样式 从零开始学习jQuery (五) 事件与事件对象 从零开始学习jQuery (六) jQuery中的Ajax 从零开始学习jQuery (七) jQuery动画-让页面动起来! 从零开始学习jQ

从零开始学习jQuery (七) jQuery动画-让页面动起来!

原文:从零开始学习jQuery (七) jQuery动画-让页面动起来! 本系列文章导航 从零开始学习jQuery (一) 开天辟地入门篇 从零开始学习jQuery (二) 万能的选择器 从零开始学习jQuery (三) 管理jQuery包装集 从零开始学习jQuery (四) 使用jQuery操作元素的属性与样式 从零开始学习jQuery (五) 事件与事件对象 从零开始学习jQuery (六) jQuery中的Ajax 从零开始学习jQuery (七) jQuery动画-让页面动起来! 从零