From 04053d4530759f33073efa9d82721bafa316382f Mon Sep 17 00:00:00 2001
From: wxd <123@qq.com>
Date: Fri, 9 May 2025 17:17:44 +0800
Subject: [PATCH] 050903
---
.../MenuInfos/CreateMenuInfoDto.cs | 41 +
.../MenuInfos/GetMyMenuInfoListDto.cs | 42 +
.../MenuInfos/MenuInfoDto.cs | 49 +
.../MenuInfos/MenuInfoIdInputDto.cs | 11 +
.../MenuInfos/MenuInfoTreeDto.cs | 46 +
.../MenuInfos/UpdateMenuInfoDto.cs | 44 +
.../RoleMenuInfos/GetRoleMenuInfoIdsDto.cs | 24 +
.../SetUserMenuInfoRequestDto.cs | 20 +
.../MenuInfos/MenuInfoAppService.cs | 358 +++
.../RoleMenuInfos/RoleMenuInfoAppService.cs | 92 +
.../LanguageConverter.cs | 69 +
.../MenuInfos/MenuInfo.cs | 84 +
.../MenuInfos/MenuInfoManager.cs | 72 +
.../RoleMenuInfos/RoleMenuInfo.cs | 30 +
.../Shentun.ProjectManager.Domain.csproj | 2 +
.../Configures/MenuInfoConfigure.cs | 29 +
.../Configures/RoleMenuInfoConfigure.cs | 27 +
.../ProjectManagerDbContext.cs | 4 +-
...nsert_menu_info_role_menu_info.Designer.cs | 2290 +++++++++++++++++
...9085622_insert_menu_info_role_menu_info.cs | 60 +
.../ProjectManagerDbContextModelSnapshot.cs | 228 +-
21 files changed, 3561 insertions(+), 61 deletions(-)
create mode 100644 src/Shentun.ProjectManager.Application.Contracts/MenuInfos/CreateMenuInfoDto.cs
create mode 100644 src/Shentun.ProjectManager.Application.Contracts/MenuInfos/GetMyMenuInfoListDto.cs
create mode 100644 src/Shentun.ProjectManager.Application.Contracts/MenuInfos/MenuInfoDto.cs
create mode 100644 src/Shentun.ProjectManager.Application.Contracts/MenuInfos/MenuInfoIdInputDto.cs
create mode 100644 src/Shentun.ProjectManager.Application.Contracts/MenuInfos/MenuInfoTreeDto.cs
create mode 100644 src/Shentun.ProjectManager.Application.Contracts/MenuInfos/UpdateMenuInfoDto.cs
create mode 100644 src/Shentun.ProjectManager.Application.Contracts/RoleMenuInfos/GetRoleMenuInfoIdsDto.cs
create mode 100644 src/Shentun.ProjectManager.Application.Contracts/RoleMenuInfos/SetUserMenuInfoRequestDto.cs
create mode 100644 src/Shentun.ProjectManager.Application/MenuInfos/MenuInfoAppService.cs
create mode 100644 src/Shentun.ProjectManager.Application/RoleMenuInfos/RoleMenuInfoAppService.cs
create mode 100644 src/Shentun.ProjectManager.Domain/LanguageConverter.cs
create mode 100644 src/Shentun.ProjectManager.Domain/MenuInfos/MenuInfo.cs
create mode 100644 src/Shentun.ProjectManager.Domain/MenuInfos/MenuInfoManager.cs
create mode 100644 src/Shentun.ProjectManager.Domain/RoleMenuInfos/RoleMenuInfo.cs
create mode 100644 src/Shentun.ProjectManager.EntityFrameworkCore/Configures/MenuInfoConfigure.cs
create mode 100644 src/Shentun.ProjectManager.EntityFrameworkCore/Configures/RoleMenuInfoConfigure.cs
create mode 100644 src/Shentun.ProjectManager.EntityFrameworkCore/Migrations/20250509085622_insert_menu_info_role_menu_info.Designer.cs
create mode 100644 src/Shentun.ProjectManager.EntityFrameworkCore/Migrations/20250509085622_insert_menu_info_role_menu_info.cs
diff --git a/src/Shentun.ProjectManager.Application.Contracts/MenuInfos/CreateMenuInfoDto.cs b/src/Shentun.ProjectManager.Application.Contracts/MenuInfos/CreateMenuInfoDto.cs
new file mode 100644
index 0000000..a82785d
--- /dev/null
+++ b/src/Shentun.ProjectManager.Application.Contracts/MenuInfos/CreateMenuInfoDto.cs
@@ -0,0 +1,41 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Text;
+
+namespace Shentun.ProjectManager.MenuInfos
+{
+ public class CreateMenuInfoDto
+ {
+ ///
+ /// 名称
+ ///
+ public string DisplayName { get; set; }
+
+
+ ///
+ /// 路由地址
+ ///
+ public string? RouteUrl { get; set; }
+
+
+ ///
+ /// 菜单图标
+ ///
+ public string? IconName { get; set; }
+
+ ///
+ /// 父id
+ ///
+ public Guid? ParentId { get; set; }
+
+
+ ///
+ /// 菜单类型 0 一级菜单 1 带路径的菜单 2 按钮
+ ///
+ public char MenuType { get; set; } = '1';
+
+
+
+ }
+}
diff --git a/src/Shentun.ProjectManager.Application.Contracts/MenuInfos/GetMyMenuInfoListDto.cs b/src/Shentun.ProjectManager.Application.Contracts/MenuInfos/GetMyMenuInfoListDto.cs
new file mode 100644
index 0000000..56f9f23
--- /dev/null
+++ b/src/Shentun.ProjectManager.Application.Contracts/MenuInfos/GetMyMenuInfoListDto.cs
@@ -0,0 +1,42 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Shentun.ProjectManager.MenuInfos
+{
+ public class GetMyMenuInfoListDto
+ {
+ public Guid Id { get; set; }
+
+ ///
+ /// 名称
+ ///
+ public string DisplayName { get; set; }
+
+
+ ///
+ /// 路由地址
+ ///
+ public string? RouteUrl { get; set; }
+
+
+ ///
+ /// 菜单图标
+ ///
+ public string? IconName { get; set; }
+
+
+ ///
+ /// 父id
+ ///
+ public Guid? ParentId { get; set; }
+
+ public int DisplayOrder { get; set; }
+
+
+ ///
+ /// 菜单类型 0 一级菜单 1 带路径的菜单 2 按钮
+ ///
+ public char MenuType { get; set; }
+ }
+}
diff --git a/src/Shentun.ProjectManager.Application.Contracts/MenuInfos/MenuInfoDto.cs b/src/Shentun.ProjectManager.Application.Contracts/MenuInfos/MenuInfoDto.cs
new file mode 100644
index 0000000..5e3b9ae
--- /dev/null
+++ b/src/Shentun.ProjectManager.Application.Contracts/MenuInfos/MenuInfoDto.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Shentun.ProjectManager.MenuInfos
+{
+ public class MenuInfoDto : AuditedEntityDtoName
+ {
+ ///
+ /// 名称
+ ///
+ public string DisplayName { get; set; }
+
+
+ ///
+ /// 路由地址
+ ///
+ public string? RouteUrl { get; set; }
+
+
+ ///
+ /// 菜单图标
+ ///
+ public string? IconName { get; set; }
+
+ ///
+ /// 自定义简码
+ ///
+ public string SimpleCode { get; set; }
+
+ ///
+ /// 父id
+ ///
+ public Guid? ParentId { get; set; }
+
+ public int DisplayOrder { get; set; }
+
+ ///
+ /// 是否启用
+ ///
+ public char IsActive { get; set; }
+
+ ///
+ /// 菜单类型 0 一级菜单 1 带路径的菜单 2 按钮
+ ///
+ public char MenuType { get; set; }
+
+ }
+}
diff --git a/src/Shentun.ProjectManager.Application.Contracts/MenuInfos/MenuInfoIdInputDto.cs b/src/Shentun.ProjectManager.Application.Contracts/MenuInfos/MenuInfoIdInputDto.cs
new file mode 100644
index 0000000..8aa0585
--- /dev/null
+++ b/src/Shentun.ProjectManager.Application.Contracts/MenuInfos/MenuInfoIdInputDto.cs
@@ -0,0 +1,11 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Shentun.ProjectManager.MenuInfos
+{
+ public class MenuInfoIdInputDto
+ {
+ public Guid MenuInfoId { get; set; }
+ }
+}
diff --git a/src/Shentun.ProjectManager.Application.Contracts/MenuInfos/MenuInfoTreeDto.cs b/src/Shentun.ProjectManager.Application.Contracts/MenuInfos/MenuInfoTreeDto.cs
new file mode 100644
index 0000000..d2e322b
--- /dev/null
+++ b/src/Shentun.ProjectManager.Application.Contracts/MenuInfos/MenuInfoTreeDto.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Shentun.ProjectManager.MenuInfos
+{
+ public class MenuInfoTreeDto
+ {
+ //组织Id
+ public Guid Id { get; set; }
+ //名称
+ public string DisplayName { get; set; }
+
+ ///
+ /// 路由地址
+ ///
+ public string RouteUrl { get; set; }
+
+
+ ///
+ /// 菜单图标
+ ///
+ public string IconName { get; set; }
+
+ //父节点Id
+ public Guid? ParentId { get; set; }
+
+
+ public int DisplayOrder { get; set; }
+
+ public char IsActive { get; set; }
+
+
+ ///
+ /// 菜单类型 0 一级菜单 1 带路径的菜单 2 按钮
+ ///
+ public char MenuType { get; set; }
+
+ ///
+ /// 拼音简码
+ ///
+ public string SimpleCode { get; set; }
+
+ public List TreeChildren { get; set; }
+ }
+}
diff --git a/src/Shentun.ProjectManager.Application.Contracts/MenuInfos/UpdateMenuInfoDto.cs b/src/Shentun.ProjectManager.Application.Contracts/MenuInfos/UpdateMenuInfoDto.cs
new file mode 100644
index 0000000..1fc66f9
--- /dev/null
+++ b/src/Shentun.ProjectManager.Application.Contracts/MenuInfos/UpdateMenuInfoDto.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Text;
+
+namespace Shentun.ProjectManager.MenuInfos
+{
+ public class UpdateMenuInfoDto
+ {
+ public Guid Id { get; set; }
+
+ ///
+ /// 名称
+ ///
+ public string DisplayName { get; set; }
+
+
+ ///
+ /// 路由地址
+ ///
+ public string? RouteUrl { get; set; }
+
+
+ ///
+ /// 菜单图标
+ ///
+ public string? IconName { get; set; }
+
+ ///
+ /// 是否启用
+ ///
+ public char IsActive { get; set; }
+
+ ///
+ /// 排序值
+ ///
+ public int? DisplayOrder { get; set; }
+
+ ///
+ /// 菜单类型 0 一级菜单 1 带路径的菜单 2 按钮
+ ///
+ public char MenuType { get; set; }
+ }
+}
diff --git a/src/Shentun.ProjectManager.Application.Contracts/RoleMenuInfos/GetRoleMenuInfoIdsDto.cs b/src/Shentun.ProjectManager.Application.Contracts/RoleMenuInfos/GetRoleMenuInfoIdsDto.cs
new file mode 100644
index 0000000..106976e
--- /dev/null
+++ b/src/Shentun.ProjectManager.Application.Contracts/RoleMenuInfos/GetRoleMenuInfoIdsDto.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Shentun.ProjectManager.RoleMenuInfos
+{
+ public class GetRoleMenuInfoIdsDto
+ {
+ ///
+ /// 菜单ID
+ ///
+ public Guid MenuInfoId { get; set; }
+
+ ///
+ /// 上级ID
+ ///
+ public Guid? ParentId { get; set; }
+
+ ///
+ /// 菜单名称
+ ///
+ public string DisplayName { get; set; }
+ }
+}
diff --git a/src/Shentun.ProjectManager.Application.Contracts/RoleMenuInfos/SetUserMenuInfoRequestDto.cs b/src/Shentun.ProjectManager.Application.Contracts/RoleMenuInfos/SetUserMenuInfoRequestDto.cs
new file mode 100644
index 0000000..6234838
--- /dev/null
+++ b/src/Shentun.ProjectManager.Application.Contracts/RoleMenuInfos/SetUserMenuInfoRequestDto.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Text;
+
+namespace Shentun.ProjectManager.RoleMenuInfos
+{
+ public class SetRoleMenuInfoRequestDto
+ {
+ ///
+ /// 角色ID
+ ///
+ public Guid RoleId { get; set; }
+
+ ///
+ /// 对应的菜单ID集合
+ ///
+ public List MenuInfoIds { get; set; } = new List();
+ }
+}
diff --git a/src/Shentun.ProjectManager.Application/MenuInfos/MenuInfoAppService.cs b/src/Shentun.ProjectManager.Application/MenuInfos/MenuInfoAppService.cs
new file mode 100644
index 0000000..076c520
--- /dev/null
+++ b/src/Shentun.ProjectManager.Application/MenuInfos/MenuInfoAppService.cs
@@ -0,0 +1,358 @@
+using AutoMapper.Internal.Mappers;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Configuration;
+using Shentun.ProjectManager.Models;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Volo.Abp.Application.Services;
+using Volo.Abp.Domain.Entities;
+using Volo.Abp.Domain.Repositories;
+using Volo.Abp.Identity;
+using Volo.Abp.Users;
+using Volo.Abp;
+using Shentun.ProjectManager.MyUsers;
+
+namespace Shentun.ProjectManager.MenuInfos
+{
+ ///
+ /// 后台菜单
+ ///
+ [ApiExplorerSettings(GroupName = "Bus")]
+ [Authorize]
+ public class MenuInfoAppService : ApplicationService
+ {
+ private readonly IRepository _menuInfoRepository;
+ private readonly IRepository _roleMenuInfoRepository;
+ private readonly ICurrentUser _currentUser;
+ private readonly IIdentityUserRepository _userRepository;
+ private readonly IRepository _identityUserRepository;
+ private readonly IConfiguration _configuration;
+ private readonly MenuInfoManager _menuInfoManager;
+ private readonly CacheService _cacheService;
+ public MenuInfoAppService(
+ IRepository menuInfoRepository,
+ IRepository roleMenuInfoRepository,
+ ICurrentUser currentUser,
+ MenuInfoManager menuInfoManager,
+ IIdentityUserRepository userRepository,
+ IRepository identityUserRepository,
+ IConfiguration configuration,
+ CacheService cacheService)
+ {
+ _menuInfoRepository = menuInfoRepository;
+ _menuInfoManager = menuInfoManager;
+ _roleMenuInfoRepository = roleMenuInfoRepository;
+ _currentUser = currentUser;
+ _userRepository = userRepository;
+ _identityUserRepository = identityUserRepository;
+ _configuration = configuration;
+ _cacheService = cacheService;
+ }
+
+
+ ///
+ /// 查询菜单数据 根据ID
+ ///
+ ///
+ ///
+ [HttpPost("api/app/MenuInfo/GetMenuInfo")]
+ public async Task GetMenuInfoAsync(MenuInfoIdInputDto input)
+ {
+ var entity = await _menuInfoRepository.GetAsync(input.MenuInfoId);
+ var dto = ObjectMapper.Map(entity);
+
+ dto.CreatorName =await _cacheService.GetNameAsync(dto.CreatorId);
+ dto.LastModifierName = await _cacheService.GetNameAsync(dto.LastModifierId);
+ return dto;
+ }
+
+ ///
+ /// 创建后台菜单
+ ///
+ ///
+ ///
+ [HttpPost("api/app/MenuInfo/CreatetMenuInfo")]
+ public async Task CreatetMenuInfoAsync(CreateMenuInfoDto input)
+ {
+ var createEntity = ObjectMapper.Map(input);
+ var entity = await _menuInfoManager.CreatetMenuInfoAsync(createEntity);
+ entity = await _menuInfoRepository.InsertAsync(entity);
+ var dto = ObjectMapper.Map(entity);
+ return dto;
+ }
+
+ ///
+ /// 修改后台菜单
+ ///
+ ///
+ ///
+ [HttpPost("api/app/MenuInfo/UpdateMenuInfo")]
+ public async Task UpdateMenuInfoAsync( UpdateMenuInfoDto input)
+ {
+ var entity = await _menuInfoRepository.GetAsync(input.Id);
+ var sourceEntity = ObjectMapper.Map(input);
+ _menuInfoManager.UpdateMenuInfoAsync(sourceEntity, entity);
+ entity = await _menuInfoRepository.UpdateAsync(entity);
+ var dto = ObjectMapper.Map(entity);
+ return dto;
+ }
+
+
+ ///
+ /// 删除
+ ///
+ ///
+ ///
+ ///
+ [HttpPost("api/app/MenuInfo/DeleteMenuInfo")]
+ public async Task DeleteMenuInfoAsync(MenuInfoIdInputDto input)
+ {
+
+ //判断是否有下级节点
+ if ((await _menuInfoRepository.GetQueryableAsync()).Where(m => m.ParentId == input.MenuInfoId).Count() > 0)
+ throw new UserFriendlyException("当前菜单有下级节点,不能删除");
+
+ //删除角色选择的对应的菜单数据
+ await _roleMenuInfoRepository.DeleteAsync(d => d.MenuInfoId == input.MenuInfoId);
+
+ //删除菜单
+ await _menuInfoRepository.DeleteAsync(input.MenuInfoId);
+ }
+
+
+ ///
+ /// 获取当前用户的树型菜单结果
+ ///
+ ///
+ [HttpPost("api/app/MenuInfo/GetMyMenuInfoTreeList")]
+ public async Task> GetMyMenuInfoTreeListAsync()
+ {
+
+ var dataList = await _menuInfoRepository.GetQueryableAsync();
+ string AdminId = _configuration.GetValue("AdminId");
+ if (_currentUser.Id.Value != Guid.Parse(AdminId))
+ {
+ var userRoles = await _userRepository.GetRolesAsync(_currentUser.Id.Value); //获取当前用户的角色
+ if (!userRoles.Any())
+ return new List();
+ var userMenuInfoList = await _roleMenuInfoRepository.GetListAsync(m => userRoles.Select(s => s.Id).Contains(m.RoleId)); //当前持有的菜单项
+ if (!userMenuInfoList.Any())
+ return new List();
+ dataList = dataList.Where(m => userMenuInfoList.Select(s => s.MenuInfoId).Distinct().Contains(m.Id));
+ }
+ var items = from p in dataList.OrderBy(o => o.DisplayOrder).ThenBy(o => o.DisplayName)
+ select new MenuInfoTreeDto()
+ {
+ Id = p.Id,
+ ParentId = p.ParentId,
+ DisplayOrder = p.DisplayOrder,
+ IconName = p.IconName,
+ IsActive = p.IsActive,
+ RouteUrl = p.RouteUrl,
+ DisplayName = p.DisplayName,
+ SimpleCode = p.SimpleCode,
+ MenuType = p.MenuType
+ };
+ return GetMenuInfoTree(items.ToList(), null);
+ }
+
+
+
+ ///
+ /// 获取树型菜单结果
+ ///
+ ///
+ [HttpPost("api/app/MenuInfo/GetMenuInfoTreeList")]
+ public async Task> GetMenuInfoTreeListAsync()
+ {
+ var dataList = await _menuInfoRepository.GetQueryableAsync();
+ var items = from p in dataList.OrderBy(o => o.DisplayOrder).ThenBy(o => o.DisplayName)
+ select new MenuInfoTreeDto()
+ {
+ Id = p.Id,
+ ParentId = p.ParentId,
+ DisplayOrder = p.DisplayOrder,
+ IconName = p.IconName,
+ IsActive = p.IsActive,
+ RouteUrl = p.RouteUrl,
+ DisplayName = p.DisplayName,
+ SimpleCode = p.SimpleCode,
+ MenuType = p.MenuType
+ };
+ return GetMenuInfoTree(items.ToList(), null);
+ }
+
+
+ ///
+ /// 获取当前用户的菜单列表
+ ///
+ ///
+ [HttpPost("api/app/MenuInfo/GetMyMenuInfoList")]
+ public async Task> GetMyMenuInfoListAsync()
+ {
+ var query = await _menuInfoRepository.GetQueryableAsync();
+
+ query = query.Where(m => m.IsActive == 'Y');
+
+ string AdminId = _configuration.GetValue("AdminId");
+
+ if (_currentUser.Id.Value != Guid.Parse(AdminId))
+ {
+ var userRoles = await _userRepository.GetRolesAsync(_currentUser.Id.Value); //获取当前用户的角色
+ if (!userRoles.Any())
+ return new List();
+ var userMenuInfoList = await _roleMenuInfoRepository.GetListAsync(m => userRoles.Select(s => s.Id).Contains(m.RoleId)); //当前持有的菜单项
+ if (!userMenuInfoList.Any())
+ return new List();
+ query = query.Where(m => userMenuInfoList.Select(s => s.MenuInfoId).Distinct().Contains(m.Id));
+ }
+
+
+ var entlistdto = query.Select(s => new GetMyMenuInfoListDto
+ {
+ DisplayName = s.DisplayName,
+ DisplayOrder = s.DisplayOrder,
+ IconName = s.IconName,
+ Id = s.Id,
+ MenuType = s.MenuType,
+ ParentId = s.ParentId,
+ RouteUrl = s.RouteUrl,
+ }).OrderBy(o => o.ParentId).ThenBy(o => o.DisplayOrder).ToList();
+
+ return entlistdto;
+ }
+
+
+ ///
+ /// 获取指定用户的菜单列表
+ ///
+ ///
+ [HttpPost("api/app/MenuInfo/GetMyMenuInfoListInUser")]
+ public async Task> GetMyMenuInfoListInUserAsync(AbpUserIdInputDto input)
+ {
+ var query = from a in await _menuInfoRepository.GetQueryableAsync()
+ join b in await _identityUserRepository.GetQueryableAsync() on a.CreatorId equals b.Id into bb
+ from ab in bb.DefaultIfEmpty()
+ join c in await _identityUserRepository.GetQueryableAsync() on a.LastModifierId equals c.Id into cc
+ from ac in cc.DefaultIfEmpty()
+ select new
+ {
+ a,
+ LastModifierName = ac != null ? ac.Surname : "",
+ CreatorName = ab != null ? ab.Surname : ""
+ };
+
+ var userRoles = await _userRepository.GetRolesAsync(input.AbpUserId); //获取当前用户的角色
+ if (!userRoles.Any())
+ return new List();
+ var userMenuInfoList = await _roleMenuInfoRepository.GetListAsync(m => userRoles.Select(s => s.Id).Contains(m.RoleId)); //当前持有的菜单项
+ if (!userMenuInfoList.Any())
+ return new List();
+ query = query.Where(m => userMenuInfoList.Select(s => s.MenuInfoId).Distinct().Contains(m.a.Id));
+
+
+
+ var entlistdto = query.Select(s => new MenuInfoDto
+ {
+ CreationTime = s.a.CreationTime,
+ CreatorId = s.a.CreatorId,
+ DisplayName = s.a.DisplayName,
+ DisplayOrder = s.a.DisplayOrder,
+ IconName = s.a.IconName,
+ Id = s.a.Id,
+ IsActive = s.a.IsActive,
+ LastModifierId = s.a.LastModifierId,
+ LastModificationTime = s.a.LastModificationTime,
+ MenuType = s.a.MenuType,
+ ParentId = s.a.ParentId,
+ RouteUrl = s.a.RouteUrl,
+ SimpleCode = s.a.SimpleCode,
+ CreatorName = s.CreatorName,
+ LastModifierName = s.LastModifierName
+ }).OrderBy(o => o.DisplayOrder).ThenBy(o => o.DisplayName).ToList();
+
+ return entlistdto;
+ }
+
+
+
+ ///
+ /// 获取菜单列表
+ ///
+ ///
+ [HttpPost("api/app/MenuInfo/GetMenuInfoList")]
+ public async Task> GetMenuInfoListAsync()
+ {
+
+ var query = from a in await _menuInfoRepository.GetQueryableAsync()
+ join b in await _identityUserRepository.GetQueryableAsync() on a.CreatorId equals b.Id into bb
+ from ab in bb.DefaultIfEmpty()
+ join c in await _identityUserRepository.GetQueryableAsync() on a.LastModifierId equals c.Id into cc
+ from ac in cc.DefaultIfEmpty()
+ select new
+ {
+ a,
+ LastModifierName = ac != null ? ac.Surname : "",
+ CreatorName = ab != null ? ab.Surname : ""
+ };
+
+
+ var entlistdto = query.Select(s => new MenuInfoDto
+ {
+ CreationTime = s.a.CreationTime,
+ CreatorId = s.a.CreatorId,
+ DisplayName = s.a.DisplayName,
+ DisplayOrder = s.a.DisplayOrder,
+ IconName = s.a.IconName,
+ Id = s.a.Id,
+ IsActive = s.a.IsActive,
+ LastModifierId = s.a.LastModifierId,
+ LastModificationTime = s.a.LastModificationTime,
+ MenuType = s.a.MenuType,
+ ParentId = s.a.ParentId,
+ RouteUrl = s.a.RouteUrl,
+ SimpleCode = s.a.SimpleCode,
+ CreatorName = s.CreatorName,
+ LastModifierName = s.LastModifierName
+ }).OrderBy(o => o.DisplayOrder).ThenBy(o => o.DisplayName).ToList();
+
+ return entlistdto;
+
+
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ private List GetMenuInfoTree(List items, Guid? ParentId)
+ {
+ return (from p in items
+ where p.ParentId == ParentId
+ let subs = GetMenuInfoTree(items, p.Id)
+ select new MenuInfoTreeDto()
+ {
+ Id = p.Id,
+ ParentId = p.ParentId,
+ DisplayOrder = p.DisplayOrder,
+ IconName = p.IconName,
+ IsActive = p.IsActive,
+ RouteUrl = p.RouteUrl,
+ DisplayName = p.DisplayName,
+ SimpleCode = p.SimpleCode,
+ MenuType = p.MenuType,
+ TreeChildren = subs.ToList()
+ }
+ ).ToList();
+ }
+
+
+
+ }
+}
diff --git a/src/Shentun.ProjectManager.Application/RoleMenuInfos/RoleMenuInfoAppService.cs b/src/Shentun.ProjectManager.Application/RoleMenuInfos/RoleMenuInfoAppService.cs
new file mode 100644
index 0000000..ba34753
--- /dev/null
+++ b/src/Shentun.ProjectManager.Application/RoleMenuInfos/RoleMenuInfoAppService.cs
@@ -0,0 +1,92 @@
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using Shentun.ProjectManager.Models;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Volo.Abp.Application.Services;
+using Volo.Abp.Domain.Repositories;
+
+namespace Shentun.ProjectManager.RoleMenuInfos
+{
+ ///
+ /// 角色对菜单的权限控制
+ ///
+ [ApiExplorerSettings(GroupName = "Bus")]
+ [Authorize]
+ public class RoleMenuInfoAppService : ApplicationService
+ {
+ private readonly IRepository _roleMenuInfoRepository;
+ private readonly IRepository _menuInfoRepository;
+
+ public RoleMenuInfoAppService(
+ IRepository roleMenuInfoRepository,
+ IRepository menuInfoRepository)
+ {
+ this._roleMenuInfoRepository = roleMenuInfoRepository;
+ this._menuInfoRepository = menuInfoRepository;
+ }
+
+
+ ///
+ /// 获取角色对应的菜单选项
+ ///
+ /// 角色ID
+ ///
+ [HttpPost("api/app/RoleMenuInfo/GetRoleMenuInfoList")]
+ public async Task> GetRoleMenuInfoListAsync(Guid RoleId)
+ {
+ var query = from a in await _roleMenuInfoRepository.GetQueryableAsync()
+ join b in await _menuInfoRepository.GetQueryableAsync() on a.MenuInfoId equals b.Id into bb
+ from ab in bb.DefaultIfEmpty()
+ where a.RoleId == RoleId
+ orderby ab.DisplayOrder ascending
+ select ab;
+
+ var entlistdto = query.Select(s => new GetRoleMenuInfoIdsDto
+ {
+ DisplayName = s.DisplayName,
+ MenuInfoId = s.Id,
+ ParentId = s.ParentId
+ }).ToList();
+
+ return entlistdto;
+
+ }
+
+
+ ///
+ /// 设置角色的菜单权限
+ ///
+ ///
+ ///
+ [HttpPost("api/app/RoleMenuInfo/SetRoleMenuInfo")]
+ public async Task SetRoleMenuInfoAsync(SetRoleMenuInfoRequestDto input)
+ {
+ //删除原有配置
+ await _roleMenuInfoRepository.DeleteAsync(m => m.RoleId == input.RoleId);
+
+ List roleMenuInfoList = new List();
+
+ if (input.MenuInfoIds.Any())
+ {
+ //增加新配置
+ foreach (var item in input.MenuInfoIds)
+ {
+ roleMenuInfoList.Add(new RoleMenuInfo
+ {
+ RoleId = input.RoleId,
+ MenuInfoId = item
+ });
+ }
+
+ await _roleMenuInfoRepository.InsertManyAsync(roleMenuInfoList);
+
+ }
+ }
+
+
+ }
+}
diff --git a/src/Shentun.ProjectManager.Domain/LanguageConverter.cs b/src/Shentun.ProjectManager.Domain/LanguageConverter.cs
new file mode 100644
index 0000000..3697c93
--- /dev/null
+++ b/src/Shentun.ProjectManager.Domain/LanguageConverter.cs
@@ -0,0 +1,69 @@
+using Microsoft.International.Converters.PinYinConverter;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Shentun.ProjectManager
+{
+ public class LanguageConverter
+ {
+ #region 新版
+
+
+ ///
+ /// 汉字转首字母
+ ///
+ ///
+ ///
+ public static string GetPYSimpleCode(string strChinese)
+ {
+
+ try
+ {
+ if (strChinese.Length != 0)
+ {
+ StringBuilder fullSpell = new StringBuilder();
+ for (int i = 0; i < strChinese.Length; i++)
+ {
+ var chr = strChinese[i];
+ fullSpell.Append(GetSpell(chr)[0]);
+ }
+
+ return fullSpell.ToString().ToUpper();
+ }
+ }
+ catch (Exception e)
+ {
+
+ Console.WriteLine("首字母转化出错!" + e.Message);
+ }
+
+ return string.Empty;
+ }
+
+ private static string GetSpell(char chr)
+ {
+ var coverchr = NPinyin.Pinyin.GetPinyin(chr);
+
+ bool isChineses = ChineseChar.IsValidChar(coverchr[0]);
+ if (isChineses)
+ {
+ ChineseChar chineseChar = new ChineseChar(coverchr[0]);
+ foreach (string value in chineseChar.Pinyins)
+ {
+ if (!string.IsNullOrEmpty(value))
+ {
+ return value.Remove(value.Length - 1, 1);
+ }
+ }
+ }
+
+ return coverchr;
+
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Shentun.ProjectManager.Domain/MenuInfos/MenuInfo.cs b/src/Shentun.ProjectManager.Domain/MenuInfos/MenuInfo.cs
new file mode 100644
index 0000000..083e368
--- /dev/null
+++ b/src/Shentun.ProjectManager.Domain/MenuInfos/MenuInfo.cs
@@ -0,0 +1,84 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Xml.Linq;
+using Volo.Abp.Domain.Entities.Auditing;
+using Volo.Abp.Domain.Entities;
+
+
+namespace Shentun.ProjectManager.Models
+{
+ ///
+ /// 菜单栏目
+ ///
+ public class MenuInfo : AuditedEntity, IDisplayOrder, IDisplayName, IHasConcurrencyStamp
+ {
+
+ protected MenuInfo()
+ {
+
+ }
+
+ public MenuInfo(Guid id) : base(id)
+ {
+
+ }
+
+ ///
+ /// 名称
+ ///
+ [StringLength(20)]
+ public string DisplayName { get; set; }
+
+
+ ///
+ /// 路由地址
+ ///
+ [StringLength(100)]
+ public string? RouteUrl { get; set; }
+
+
+ ///
+ /// 菜单图标
+ ///
+ [StringLength(50)]
+ public string? IconName { get; set; }
+
+ ///
+ /// 自定义简码
+ ///
+ [StringLength(20)]
+ public string SimpleCode { get; set; }
+
+ ///
+ /// 父id
+ ///
+ public Guid? ParentId { get; set; }
+
+
+ public int DisplayOrder { get; set; }
+
+ ///
+ /// 是否启用
+ ///
+ public char IsActive { get; set; }
+
+
+
+ ///
+ /// 菜单类型 0 一级菜单 1 带路径的菜单 2 按钮
+ ///
+ public char MenuType { get; set; }
+
+
+ public string ConcurrencyStamp { get; set; }
+
+
+
+
+ }
+}
diff --git a/src/Shentun.ProjectManager.Domain/MenuInfos/MenuInfoManager.cs b/src/Shentun.ProjectManager.Domain/MenuInfos/MenuInfoManager.cs
new file mode 100644
index 0000000..937ecd1
--- /dev/null
+++ b/src/Shentun.ProjectManager.Domain/MenuInfos/MenuInfoManager.cs
@@ -0,0 +1,72 @@
+using Shentun.ProjectManager.Models;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Volo.Abp.Domain.Repositories;
+using Volo.Abp.Domain.Services;
+
+namespace Shentun.ProjectManager.MenuInfos
+{
+ public class MenuInfoManager : DomainService
+ {
+ private readonly IRepository _menuInfoRepository;
+
+ public MenuInfoManager(
+ IRepository menuInfoRepository
+ )
+ {
+ _menuInfoRepository = menuInfoRepository;
+ }
+
+ ///
+ /// 创建
+ ///
+ ///
+ ///
+ public async Task CreatetMenuInfoAsync(MenuInfo entity)
+ {
+
+ var menuInfoList = await _menuInfoRepository.GetListAsync(m => m.ParentId == entity.ParentId);
+ int MaxDisplayOrder = 0;
+ if (menuInfoList.Any())
+ MaxDisplayOrder = menuInfoList.Max(o => o.DisplayOrder);
+ entity.DisplayOrder = MaxDisplayOrder + 1;
+ entity.IsActive = 'Y';
+ entity.SimpleCode = LanguageConverter.GetPYSimpleCode(entity.DisplayName);
+ return entity;
+ }
+
+
+ ///
+ /// 修改
+ ///
+ /// 参数实体
+ /// 待修改的实体
+ ///
+ public void UpdateMenuInfoAsync(MenuInfo sourceEntity, MenuInfo targetEntity)
+ {
+
+ if (sourceEntity.DisplayName != targetEntity.DisplayName)
+ {
+ targetEntity.DisplayName = sourceEntity.DisplayName;
+ targetEntity.SimpleCode = LanguageConverter.GetPYSimpleCode(targetEntity.DisplayName);
+ }
+
+ if (sourceEntity.DisplayOrder != 0)
+ {
+ targetEntity.DisplayOrder = sourceEntity.DisplayOrder;
+ }
+ targetEntity.IsActive = sourceEntity.IsActive;
+ targetEntity.IconName = sourceEntity.IconName;
+ targetEntity.RouteUrl = sourceEntity.RouteUrl;
+ targetEntity.MenuType = sourceEntity.MenuType;
+
+
+ }
+
+
+
+ }
+}
diff --git a/src/Shentun.ProjectManager.Domain/RoleMenuInfos/RoleMenuInfo.cs b/src/Shentun.ProjectManager.Domain/RoleMenuInfos/RoleMenuInfo.cs
new file mode 100644
index 0000000..33f0c69
--- /dev/null
+++ b/src/Shentun.ProjectManager.Domain/RoleMenuInfos/RoleMenuInfo.cs
@@ -0,0 +1,30 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Volo.Abp.Domain.Entities;
+
+namespace Shentun.ProjectManager.Models
+{
+ ///
+ /// 角色对应的后台菜单权限
+ ///
+ public class RoleMenuInfo : Entity
+ {
+
+ [Key]
+ public Guid RoleId { get; set; }
+ [Key]
+ public Guid MenuInfoId { get; set; }
+
+
+ public override object[] GetKeys()
+ {
+ return new object[] { RoleId, MenuInfoId };
+ }
+
+ }
+}
diff --git a/src/Shentun.ProjectManager.Domain/Shentun.ProjectManager.Domain.csproj b/src/Shentun.ProjectManager.Domain/Shentun.ProjectManager.Domain.csproj
index 5925c89..3e26304 100644
--- a/src/Shentun.ProjectManager.Domain/Shentun.ProjectManager.Domain.csproj
+++ b/src/Shentun.ProjectManager.Domain/Shentun.ProjectManager.Domain.csproj
@@ -12,6 +12,8 @@
+
+
diff --git a/src/Shentun.ProjectManager.EntityFrameworkCore/Configures/MenuInfoConfigure.cs b/src/Shentun.ProjectManager.EntityFrameworkCore/Configures/MenuInfoConfigure.cs
new file mode 100644
index 0000000..f61e575
--- /dev/null
+++ b/src/Shentun.ProjectManager.EntityFrameworkCore/Configures/MenuInfoConfigure.cs
@@ -0,0 +1,29 @@
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+using Microsoft.EntityFrameworkCore;
+using Shentun.ProjectManager.Models;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Shentun.ProjectManager.Configures
+{
+ internal class MenuInfoConfigure : IEntityTypeConfiguration
+ {
+ public void Configure(EntityTypeBuilder entity)
+ {
+ entity.HasComment("菜单栏目").ToTable("menu_info");
+ entity.Property(t => t.DisplayName).HasComment("名称").IsRequired();
+ entity.Property(t => t.SimpleCode).HasComment("自定义简码").IsRequired();
+ entity.Property(t => t.ParentId).HasComment("父id");
+ entity.Property(e => e.Id).IsFixedLength().IsRequired();
+ entity.Property(e => e.DisplayOrder).HasDefaultValue("999999").IsRequired();
+ entity.Property(e => e.MenuType).HasDefaultValue("1").IsRequired();
+ entity.Property(e => e.ParentId).IsFixedLength();
+ entity.Property(t => t.RouteUrl).HasComment("路由地址");
+ entity.Property(t => t.IconName).HasComment("菜单图标");
+ entity.Property(t => t.IsActive).HasComment("是否启用").IsRequired().HasDefaultValueSql("'Y'");
+ }
+ }
+}
diff --git a/src/Shentun.ProjectManager.EntityFrameworkCore/Configures/RoleMenuInfoConfigure.cs b/src/Shentun.ProjectManager.EntityFrameworkCore/Configures/RoleMenuInfoConfigure.cs
new file mode 100644
index 0000000..a306e02
--- /dev/null
+++ b/src/Shentun.ProjectManager.EntityFrameworkCore/Configures/RoleMenuInfoConfigure.cs
@@ -0,0 +1,27 @@
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+using Microsoft.EntityFrameworkCore;
+using Shentun.ProjectManager.Models;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Shentun.ProjectManager.Configures
+{
+
+ internal class RoleMenuInfoDbMapping : IEntityTypeConfiguration
+ {
+ public void Configure(EntityTypeBuilder entity)
+ {
+ entity.HasComment("角色对应菜单权限").ToTable("role_menu_info");
+ entity.HasKey(e => new { e.RoleId, e.MenuInfoId })
+ .HasName("pk_role_menuinfo");
+
+
+ entity.Property(e => e.RoleId).IsFixedLength();
+ entity.Property(e => e.MenuInfoId).IsFixedLength();
+
+ }
+ }
+}
diff --git a/src/Shentun.ProjectManager.EntityFrameworkCore/EntityFrameworkCore/ProjectManagerDbContext.cs b/src/Shentun.ProjectManager.EntityFrameworkCore/EntityFrameworkCore/ProjectManagerDbContext.cs
index 973e1d0..a436636 100644
--- a/src/Shentun.ProjectManager.EntityFrameworkCore/EntityFrameworkCore/ProjectManagerDbContext.cs
+++ b/src/Shentun.ProjectManager.EntityFrameworkCore/EntityFrameworkCore/ProjectManagerDbContext.cs
@@ -26,7 +26,7 @@ using Volo.Abp.SettingManagement;
using Volo.Abp.FeatureManagement;
using Volo.Abp.EntityFrameworkCore.Modeling;
using Shentun.ProjectManager.Models;
-
+
namespace Shentun.ProjectManager.EntityFrameworkCore;
@@ -110,7 +110,9 @@ public class ProjectManagerDbContext :
public DbSet projectStaffFeedbacks { get; set; } = null!;
+ public DbSet roleMenuInfos { get; set; } = null!;
+ public DbSet menuInfos { get; set; } = null!;
#endregion
diff --git a/src/Shentun.ProjectManager.EntityFrameworkCore/Migrations/20250509085622_insert_menu_info_role_menu_info.Designer.cs b/src/Shentun.ProjectManager.EntityFrameworkCore/Migrations/20250509085622_insert_menu_info_role_menu_info.Designer.cs
new file mode 100644
index 0000000..eabdc92
--- /dev/null
+++ b/src/Shentun.ProjectManager.EntityFrameworkCore/Migrations/20250509085622_insert_menu_info_role_menu_info.Designer.cs
@@ -0,0 +1,2290 @@
+//
+using System;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+using Shentun.ProjectManager.EntityFrameworkCore;
+using Volo.Abp.EntityFrameworkCore;
+
+#nullable disable
+
+namespace Shentun.ProjectManager.Migrations
+{
+ [DbContext(typeof(ProjectManagerDbContext))]
+ [Migration("20250509085622_insert_menu_info_role_menu_info")]
+ partial class insert_menu_info_role_menu_info
+ {
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("_Abp_DatabaseProvider", EfCoreDatabaseProvider.PostgreSql)
+ .HasAnnotation("ProductVersion", "6.0.5")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("Shentun.ProjectManager.Models.MenuInfo", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid")
+ .HasColumnName("id")
+ .IsFixedLength();
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("character varying(40)")
+ .HasColumnName("concurrency_stamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("creation_time");
+
+ b.Property("CreatorId")
+ .HasColumnType("uuid")
+ .HasColumnName("creator_id");
+
+ b.Property("DisplayName")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)")
+ .HasColumnName("display_name")
+ .HasComment("名称");
+
+ b.Property("DisplayOrder")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasDefaultValue(999999)
+ .HasColumnName("display_order");
+
+ b.Property("IconName")
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)")
+ .HasColumnName("icon_name")
+ .HasComment("菜单图标");
+
+ b.Property("IsActive")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("character(1)")
+ .HasColumnName("is_active")
+ .HasDefaultValueSql("'Y'")
+ .HasComment("是否启用");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("last_modification_time");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uuid")
+ .HasColumnName("last_modifier_id");
+
+ b.Property("MenuType")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("character(1)")
+ .HasDefaultValue('1')
+ .HasColumnName("menu_type");
+
+ b.Property("ParentId")
+ .HasColumnType("uuid")
+ .HasColumnName("parent_id")
+ .IsFixedLength()
+ .HasComment("父id");
+
+ b.Property("RouteUrl")
+ .HasMaxLength(100)
+ .HasColumnType("character varying(100)")
+ .HasColumnName("route_url")
+ .HasComment("路由地址");
+
+ b.Property("SimpleCode")
+ .IsRequired()
+ .HasMaxLength(20)
+ .HasColumnType("character varying(20)")
+ .HasColumnName("simple_code")
+ .HasComment("自定义简码");
+
+ b.HasKey("Id")
+ .HasName("pk_menu_info");
+
+ b.ToTable("menu_info", (string)null);
+
+ b.HasComment("菜单栏目");
+ });
+
+ modelBuilder.Entity("Shentun.ProjectManager.Models.Project", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property("CompletionProgress")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("smallint")
+ .HasDefaultValue((short)0)
+ .HasColumnName("completion_progress")
+ .HasComment("完成进度 0-100 整数");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("character varying(40)")
+ .HasColumnName("concurrency_stamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("creation_time");
+
+ b.Property("CreatorId")
+ .HasColumnType("uuid")
+ .HasColumnName("creator_id");
+
+ b.Property("DemandContent")
+ .HasMaxLength(2000)
+ .HasColumnType("character varying(2000)")
+ .HasColumnName("demand_content")
+ .HasComment("需求内容");
+
+ b.Property("DisplayName")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)")
+ .HasColumnName("display_name")
+ .HasComment("名称");
+
+ b.Property("FinishTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("finish_time")
+ .HasComment("实际完成时间");
+
+ b.Property("IsActive")
+ .ValueGeneratedOnAdd()
+ .HasMaxLength(1)
+ .HasColumnType("character(1)")
+ .HasColumnName("is_active")
+ .HasDefaultValueSql("'Y'")
+ .HasComment("是否启用");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("last_modification_time");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uuid")
+ .HasColumnName("last_modifier_id");
+
+ b.Property("ParentId")
+ .HasColumnType("uuid")
+ .HasColumnName("parent_id")
+ .HasComment("父项目id");
+
+ b.Property("PlanEndTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("plan_end_time")
+ .HasComment("计划结束时间");
+
+ b.Property("PlanStartTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("plan_start_time")
+ .HasComment("计划开始时间");
+
+ b.Property("ShortName")
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)")
+ .HasColumnName("short_name")
+ .HasComment("简称");
+
+ b.HasKey("Id")
+ .HasName("pk_project");
+
+ b.ToTable("project", (string)null);
+
+ b.HasComment("项目表");
+ });
+
+ modelBuilder.Entity("Shentun.ProjectManager.Models.ProjectFile", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("character varying(40)")
+ .HasColumnName("concurrency_stamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("creation_time");
+
+ b.Property("CreatorId")
+ .HasColumnType("uuid")
+ .HasColumnName("creator_id");
+
+ b.Property("DisplayName")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)")
+ .HasColumnName("display_name")
+ .HasComment("名称");
+
+ b.Property("EncryUser")
+ .HasColumnType("uuid")
+ .HasColumnName("encry_user")
+ .HasComment("加密用户Id");
+
+ b.Property("FileData")
+ .HasColumnType("bytea")
+ .HasColumnName("file_data")
+ .HasComment("文件二进制数据");
+
+ b.Property("IsEncry")
+ .ValueGeneratedOnAdd()
+ .HasMaxLength(1)
+ .HasColumnType("character(1)")
+ .HasColumnName("is_encry")
+ .HasDefaultValueSql("'N'")
+ .HasComment("是否加密");
+
+ b.Property("IsLock")
+ .ValueGeneratedOnAdd()
+ .HasMaxLength(1)
+ .HasColumnType("character(1)")
+ .HasColumnName("is_lock")
+ .HasDefaultValueSql("'N'")
+ .HasComment("是否锁定");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("last_modification_time");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uuid")
+ .HasColumnName("last_modifier_id");
+
+ b.Property("LockUser")
+ .HasColumnType("uuid")
+ .HasColumnName("lock_user")
+ .HasComment("加锁用户id");
+
+ b.Property("ParentId")
+ .HasColumnType("uuid")
+ .HasColumnName("parent_id")
+ .HasComment("父项目文件id");
+
+ b.Property("ProjectFolderId")
+ .HasColumnType("uuid")
+ .HasColumnName("project_folder_id")
+ .HasComment("项目文件夹id");
+
+ b.HasKey("Id")
+ .HasName("pk_project_file");
+
+ b.ToTable("project_file", (string)null);
+
+ b.HasComment("项目文件表");
+ });
+
+ modelBuilder.Entity("Shentun.ProjectManager.Models.ProjectFolder", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("character varying(40)")
+ .HasColumnName("concurrency_stamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("creation_time");
+
+ b.Property("CreatorId")
+ .HasColumnType("uuid")
+ .HasColumnName("creator_id");
+
+ b.Property("DisplayName")
+ .IsRequired()
+ .HasMaxLength(50)
+ .HasColumnType("character varying(50)")
+ .HasColumnName("display_name")
+ .HasComment("名称");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("last_modification_time");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uuid")
+ .HasColumnName("last_modifier_id");
+
+ b.Property("ParentId")
+ .HasColumnType("uuid")
+ .HasColumnName("parent_id")
+ .HasComment("父项目文件夹id");
+
+ b.Property("ProjectId")
+ .HasColumnType("uuid")
+ .HasColumnName("project_id")
+ .HasComment("项目id");
+
+ b.HasKey("Id")
+ .HasName("pk_project_folder");
+
+ b.ToTable("project_folder", (string)null);
+
+ b.HasComment("项目文件夹表");
+ });
+
+ modelBuilder.Entity("Shentun.ProjectManager.Models.ProjectStaff", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property("CompletionProgress")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("smallint")
+ .HasDefaultValue((short)0)
+ .HasColumnName("completion_progress")
+ .HasComment("完成进度 0-100 整数");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("character varying(40)")
+ .HasColumnName("concurrency_stamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("creation_time");
+
+ b.Property("CreatorId")
+ .HasColumnType("uuid")
+ .HasColumnName("creator_id");
+
+ b.Property("DemandContent")
+ .HasMaxLength(2000)
+ .HasColumnType("character varying(2000)")
+ .HasColumnName("demand_content")
+ .HasComment("需求内容");
+
+ b.Property("FinishTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("finish_time")
+ .HasComment("实际完成时间");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("last_modification_time");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uuid")
+ .HasColumnName("last_modifier_id");
+
+ b.Property("PlanEndTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("plan_end_time")
+ .HasComment("计划结束时间");
+
+ b.Property("PlanStartTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("plan_start_time")
+ .HasComment("计划开始时间");
+
+ b.Property("ProjectId")
+ .HasColumnType("uuid")
+ .HasColumnName("project_id")
+ .HasComment("项目id");
+
+ b.Property("RoleId")
+ .HasColumnType("uuid")
+ .HasColumnName("role_id")
+ .HasComment("角色id");
+
+ b.Property("UserId")
+ .HasColumnType("uuid")
+ .HasColumnName("user_id")
+ .HasComment("用户id");
+
+ b.HasKey("Id")
+ .HasName("pk_project_staff");
+
+ b.ToTable("project_staff", (string)null);
+
+ b.HasComment("项目人员表");
+ });
+
+ modelBuilder.Entity("Shentun.ProjectManager.Models.ProjectStaffFeedback", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("character varying(40)")
+ .HasColumnName("concurrency_stamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("creation_time");
+
+ b.Property("CreatorId")
+ .HasColumnType("uuid")
+ .HasColumnName("creator_id");
+
+ b.Property("FeedbackContent")
+ .IsRequired()
+ .HasMaxLength(1000)
+ .HasColumnType("character varying(1000)")
+ .HasColumnName("feedback_content")
+ .HasComment("反馈内容");
+
+ b.Property("FeedbackFlag")
+ .ValueGeneratedOnAdd()
+ .HasMaxLength(1)
+ .HasColumnType("character(1)")
+ .HasColumnName("feedback_flag")
+ .HasDefaultValueSql("'0'")
+ .HasComment("反馈类型 (0.反馈 1.建议 2.日志)");
+
+ b.Property("FeedbackTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("feedback_time")
+ .HasComment("反馈时间");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("last_modification_time");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uuid")
+ .HasColumnName("last_modifier_id");
+
+ b.Property("ProjectStaffId")
+ .HasColumnType("uuid")
+ .HasColumnName("project_staff_id")
+ .HasComment("项目人员id");
+
+ b.HasKey("Id")
+ .HasName("pk_project_staff_feedback");
+
+ b.ToTable("project_staff_feedback", (string)null);
+
+ b.HasComment("人员反馈、建议、日志表");
+ });
+
+ modelBuilder.Entity("Shentun.ProjectManager.Models.RoleMenuInfo", b =>
+ {
+ b.Property("RoleId")
+ .HasColumnType("uuid")
+ .HasColumnName("role_id")
+ .IsFixedLength();
+
+ b.Property("MenuInfoId")
+ .HasColumnType("uuid")
+ .HasColumnName("menu_info_id")
+ .IsFixedLength();
+
+ b.HasKey("RoleId", "MenuInfoId")
+ .HasName("pk_role_menuinfo");
+
+ b.ToTable("role_menu_info", (string)null);
+
+ b.HasComment("角色对应菜单权限");
+ });
+
+ modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property("ApplicationName")
+ .HasMaxLength(96)
+ .HasColumnType("character varying(96)")
+ .HasColumnName("application_name");
+
+ b.Property("BrowserInfo")
+ .HasMaxLength(512)
+ .HasColumnType("character varying(512)")
+ .HasColumnName("browser_info");
+
+ b.Property("ClientId")
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)")
+ .HasColumnName("client_id");
+
+ b.Property("ClientIpAddress")
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)")
+ .HasColumnName("client_ip_address");
+
+ b.Property("ClientName")
+ .HasMaxLength(128)
+ .HasColumnType("character varying(128)")
+ .HasColumnName("client_name");
+
+ b.Property("Comments")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)")
+ .HasColumnName("comments");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("character varying(40)")
+ .HasColumnName("concurrency_stamp");
+
+ b.Property("CorrelationId")
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)")
+ .HasColumnName("correlation_id");
+
+ b.Property("Exceptions")
+ .HasColumnType("text")
+ .HasColumnName("exceptions");
+
+ b.Property("ExecutionDuration")
+ .HasColumnType("integer")
+ .HasColumnName("execution_duration");
+
+ b.Property("ExecutionTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("execution_time");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("text")
+ .HasColumnName("extra_properties");
+
+ b.Property("HttpMethod")
+ .HasMaxLength(16)
+ .HasColumnType("character varying(16)")
+ .HasColumnName("http_method");
+
+ b.Property("HttpStatusCode")
+ .HasColumnType("integer")
+ .HasColumnName("http_status_code");
+
+ b.Property("ImpersonatorTenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("impersonator_tenant_id");
+
+ b.Property("ImpersonatorTenantName")
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)")
+ .HasColumnName("impersonator_tenant_name");
+
+ b.Property("ImpersonatorUserId")
+ .HasColumnType("uuid")
+ .HasColumnName("impersonator_user_id");
+
+ b.Property("ImpersonatorUserName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)")
+ .HasColumnName("impersonator_user_name");
+
+ b.Property("TenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("tenant_id");
+
+ b.Property("TenantName")
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)")
+ .HasColumnName("tenant_name");
+
+ b.Property("Url")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)")
+ .HasColumnName("url");
+
+ b.Property("UserId")
+ .HasColumnType("uuid")
+ .HasColumnName("user_id");
+
+ b.Property("UserName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)")
+ .HasColumnName("user_name");
+
+ b.HasKey("Id")
+ .HasName("pk_abp_audit_logs");
+
+ b.HasIndex("TenantId", "ExecutionTime");
+
+ b.HasIndex("TenantId", "UserId", "ExecutionTime");
+
+ b.ToTable("abp_audit_logs", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLogAction", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property("AuditLogId")
+ .HasColumnType("uuid")
+ .HasColumnName("audit_log_id");
+
+ b.Property("ExecutionDuration")
+ .HasColumnType("integer")
+ .HasColumnName("execution_duration");
+
+ b.Property("ExecutionTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("execution_time");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("text")
+ .HasColumnName("extra_properties");
+
+ b.Property("MethodName")
+ .HasMaxLength(128)
+ .HasColumnType("character varying(128)")
+ .HasColumnName("method_name");
+
+ b.Property("Parameters")
+ .HasMaxLength(2000)
+ .HasColumnType("character varying(2000)")
+ .HasColumnName("parameters");
+
+ b.Property("ServiceName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)")
+ .HasColumnName("service_name");
+
+ b.Property("TenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("tenant_id");
+
+ b.HasKey("Id")
+ .HasName("pk_abp_audit_log_actions");
+
+ b.HasIndex("AuditLogId");
+
+ b.HasIndex("TenantId", "ServiceName", "MethodName", "ExecutionTime");
+
+ b.ToTable("abp_audit_log_actions", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.AuditLogging.EntityChange", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property("AuditLogId")
+ .HasColumnType("uuid")
+ .HasColumnName("audit_log_id");
+
+ b.Property("ChangeTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("change_time");
+
+ b.Property("ChangeType")
+ .HasColumnType("smallint")
+ .HasColumnName("change_type");
+
+ b.Property("EntityId")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("character varying(128)")
+ .HasColumnName("entity_id");
+
+ b.Property("EntityTenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("entity_tenant_id");
+
+ b.Property("EntityTypeFullName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("character varying(128)")
+ .HasColumnName("entity_type_full_name");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("text")
+ .HasColumnName("extra_properties");
+
+ b.Property("TenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("tenant_id");
+
+ b.HasKey("Id")
+ .HasName("pk_abp_entity_changes");
+
+ b.HasIndex("AuditLogId");
+
+ b.HasIndex("TenantId", "EntityTypeFullName", "EntityId");
+
+ b.ToTable("abp_entity_changes", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.AuditLogging.EntityPropertyChange", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property("EntityChangeId")
+ .HasColumnType("uuid")
+ .HasColumnName("entity_change_id");
+
+ b.Property("NewValue")
+ .HasMaxLength(512)
+ .HasColumnType("character varying(512)")
+ .HasColumnName("new_value");
+
+ b.Property("OriginalValue")
+ .HasMaxLength(512)
+ .HasColumnType("character varying(512)")
+ .HasColumnName("original_value");
+
+ b.Property("PropertyName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("character varying(128)")
+ .HasColumnName("property_name");
+
+ b.Property("PropertyTypeFullName")
+ .IsRequired()
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)")
+ .HasColumnName("property_type_full_name");
+
+ b.Property("TenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("tenant_id");
+
+ b.HasKey("Id")
+ .HasName("pk_abp_entity_property_changes");
+
+ b.HasIndex("EntityChangeId");
+
+ b.ToTable("abp_entity_property_changes", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.BackgroundJobs.BackgroundJobRecord", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("character varying(40)")
+ .HasColumnName("concurrency_stamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("creation_time");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("text")
+ .HasColumnName("extra_properties");
+
+ b.Property("IsAbandoned")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("boolean")
+ .HasDefaultValue(false)
+ .HasColumnName("is_abandoned");
+
+ b.Property("JobArgs")
+ .IsRequired()
+ .HasMaxLength(1048576)
+ .HasColumnType("character varying(1048576)")
+ .HasColumnName("job_args");
+
+ b.Property("JobName")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("character varying(128)")
+ .HasColumnName("job_name");
+
+ b.Property("LastTryTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("last_try_time");
+
+ b.Property("NextTryTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("next_try_time");
+
+ b.Property("Priority")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("smallint")
+ .HasDefaultValue((byte)15)
+ .HasColumnName("priority");
+
+ b.Property("TryCount")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("smallint")
+ .HasDefaultValue((short)0)
+ .HasColumnName("try_count");
+
+ b.HasKey("Id")
+ .HasName("pk_abp_background_jobs");
+
+ b.HasIndex("IsAbandoned", "NextTryTime");
+
+ b.ToTable("abp_background_jobs", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.FeatureManagement.FeatureValue", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("character varying(128)")
+ .HasColumnName("name");
+
+ b.Property("ProviderKey")
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)")
+ .HasColumnName("provider_key");
+
+ b.Property("ProviderName")
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)")
+ .HasColumnName("provider_name");
+
+ b.Property("Value")
+ .IsRequired()
+ .HasMaxLength(128)
+ .HasColumnType("character varying(128)")
+ .HasColumnName("value");
+
+ b.HasKey("Id")
+ .HasName("pk_abp_feature_values");
+
+ b.HasIndex("Name", "ProviderName", "ProviderKey")
+ .IsUnique();
+
+ b.ToTable("abp_feature_values", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityClaimType", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("character varying(40)")
+ .HasColumnName("concurrency_stamp");
+
+ b.Property("Description")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)")
+ .HasColumnName("description");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("text")
+ .HasColumnName("extra_properties");
+
+ b.Property("IsStatic")
+ .HasColumnType("boolean")
+ .HasColumnName("is_static");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)")
+ .HasColumnName("name");
+
+ b.Property("Regex")
+ .HasMaxLength(512)
+ .HasColumnType("character varying(512)")
+ .HasColumnName("regex");
+
+ b.Property("RegexDescription")
+ .HasMaxLength(128)
+ .HasColumnType("character varying(128)")
+ .HasColumnName("regex_description");
+
+ b.Property("Required")
+ .HasColumnType("boolean")
+ .HasColumnName("required");
+
+ b.Property("ValueType")
+ .HasColumnType("integer")
+ .HasColumnName("value_type");
+
+ b.HasKey("Id")
+ .HasName("pk_abp_claim_types");
+
+ b.ToTable("abp_claim_types", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityLinkUser", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property("SourceTenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("source_tenant_id");
+
+ b.Property("SourceUserId")
+ .HasColumnType("uuid")
+ .HasColumnName("source_user_id");
+
+ b.Property("TargetTenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("target_tenant_id");
+
+ b.Property("TargetUserId")
+ .HasColumnType("uuid")
+ .HasColumnName("target_user_id");
+
+ b.HasKey("Id")
+ .HasName("pk_abp_link_users");
+
+ b.HasIndex("SourceUserId", "SourceTenantId", "TargetUserId", "TargetTenantId")
+ .IsUnique();
+
+ b.ToTable("abp_link_users", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityRole", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("character varying(40)")
+ .HasColumnName("concurrency_stamp");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("text")
+ .HasColumnName("extra_properties");
+
+ b.Property("IsDefault")
+ .HasColumnType("boolean")
+ .HasColumnName("is_default");
+
+ b.Property("IsPublic")
+ .HasColumnType("boolean")
+ .HasColumnName("is_public");
+
+ b.Property("IsStatic")
+ .HasColumnType("boolean")
+ .HasColumnName("is_static");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)")
+ .HasColumnName("name");
+
+ b.Property("NormalizedName")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)")
+ .HasColumnName("normalized_name");
+
+ b.Property("TenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("tenant_id");
+
+ b.HasKey("Id")
+ .HasName("pk_abp_roles");
+
+ b.HasIndex("NormalizedName");
+
+ b.ToTable("abp_roles", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityRoleClaim", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property("ClaimType")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)")
+ .HasColumnName("claim_type");
+
+ b.Property("ClaimValue")
+ .HasMaxLength(1024)
+ .HasColumnType("character varying(1024)")
+ .HasColumnName("claim_value");
+
+ b.Property("RoleId")
+ .HasColumnType("uuid")
+ .HasColumnName("role_id");
+
+ b.Property("TenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("tenant_id");
+
+ b.HasKey("Id")
+ .HasName("pk_abp_role_claims");
+
+ b.HasIndex("RoleId");
+
+ b.ToTable("abp_role_claims", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentitySecurityLog", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property("Action")
+ .HasMaxLength(96)
+ .HasColumnType("character varying(96)")
+ .HasColumnName("action");
+
+ b.Property("ApplicationName")
+ .HasMaxLength(96)
+ .HasColumnType("character varying(96)")
+ .HasColumnName("application_name");
+
+ b.Property("BrowserInfo")
+ .HasMaxLength(512)
+ .HasColumnType("character varying(512)")
+ .HasColumnName("browser_info");
+
+ b.Property("ClientId")
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)")
+ .HasColumnName("client_id");
+
+ b.Property("ClientIpAddress")
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)")
+ .HasColumnName("client_ip_address");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("character varying(40)")
+ .HasColumnName("concurrency_stamp");
+
+ b.Property("CorrelationId")
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)")
+ .HasColumnName("correlation_id");
+
+ b.Property("CreationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("creation_time");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("text")
+ .HasColumnName("extra_properties");
+
+ b.Property("Identity")
+ .HasMaxLength(96)
+ .HasColumnType("character varying(96)")
+ .HasColumnName("identity");
+
+ b.Property("TenantId")
+ .HasColumnType("uuid")
+ .HasColumnName("tenant_id");
+
+ b.Property("TenantName")
+ .HasMaxLength(64)
+ .HasColumnType("character varying(64)")
+ .HasColumnName("tenant_name");
+
+ b.Property("UserId")
+ .HasColumnType("uuid")
+ .HasColumnName("user_id");
+
+ b.Property("UserName")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)")
+ .HasColumnName("user_name");
+
+ b.HasKey("Id")
+ .HasName("pk_abp_security_logs");
+
+ b.HasIndex("TenantId", "Action");
+
+ b.HasIndex("TenantId", "ApplicationName");
+
+ b.HasIndex("TenantId", "Identity");
+
+ b.HasIndex("TenantId", "UserId");
+
+ b.ToTable("abp_security_logs", (string)null);
+ });
+
+ modelBuilder.Entity("Volo.Abp.Identity.IdentityUser", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid")
+ .HasColumnName("id");
+
+ b.Property("AccessFailedCount")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasDefaultValue(0)
+ .HasColumnName("access_failed_count");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasMaxLength(40)
+ .HasColumnType("character varying(40)")
+ .HasColumnName("concurrency_stamp");
+
+ b.Property("CreationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("creation_time");
+
+ b.Property("CreatorId")
+ .HasColumnType("uuid")
+ .HasColumnName("creator_id");
+
+ b.Property("DeleterId")
+ .HasColumnType("uuid")
+ .HasColumnName("deleter_id");
+
+ b.Property("DeletionTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("deletion_time");
+
+ b.Property("Email")
+ .IsRequired()
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)")
+ .HasColumnName("email");
+
+ b.Property("EmailConfirmed")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("boolean")
+ .HasDefaultValue(false)
+ .HasColumnName("email_confirmed");
+
+ b.Property("ExtraProperties")
+ .HasColumnType("text")
+ .HasColumnName("extra_properties");
+
+ b.Property("IsActive")
+ .HasColumnType("boolean")
+ .HasColumnName("is_active");
+
+ b.Property("IsDeleted")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("boolean")
+ .HasDefaultValue(false)
+ .HasColumnName("is_deleted");
+
+ b.Property("IsExternal")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("boolean")
+ .HasDefaultValue(false)
+ .HasColumnName("is_external");
+
+ b.Property("LastModificationTime")
+ .HasColumnType("timestamp without time zone")
+ .HasColumnName("last_modification_time");
+
+ b.Property("LastModifierId")
+ .HasColumnType("uuid")
+ .HasColumnName("last_modifier_id");
+
+ b.Property("LockoutEnabled")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("boolean")
+ .HasDefaultValue(false)
+ .HasColumnName("lockout_enabled");
+
+ b.Property