Browse Source

050903

master
wxd 6 months ago
parent
commit
04053d4530
  1. 41
      src/Shentun.ProjectManager.Application.Contracts/MenuInfos/CreateMenuInfoDto.cs
  2. 42
      src/Shentun.ProjectManager.Application.Contracts/MenuInfos/GetMyMenuInfoListDto.cs
  3. 49
      src/Shentun.ProjectManager.Application.Contracts/MenuInfos/MenuInfoDto.cs
  4. 11
      src/Shentun.ProjectManager.Application.Contracts/MenuInfos/MenuInfoIdInputDto.cs
  5. 46
      src/Shentun.ProjectManager.Application.Contracts/MenuInfos/MenuInfoTreeDto.cs
  6. 44
      src/Shentun.ProjectManager.Application.Contracts/MenuInfos/UpdateMenuInfoDto.cs
  7. 24
      src/Shentun.ProjectManager.Application.Contracts/RoleMenuInfos/GetRoleMenuInfoIdsDto.cs
  8. 20
      src/Shentun.ProjectManager.Application.Contracts/RoleMenuInfos/SetUserMenuInfoRequestDto.cs
  9. 358
      src/Shentun.ProjectManager.Application/MenuInfos/MenuInfoAppService.cs
  10. 92
      src/Shentun.ProjectManager.Application/RoleMenuInfos/RoleMenuInfoAppService.cs
  11. 69
      src/Shentun.ProjectManager.Domain/LanguageConverter.cs
  12. 84
      src/Shentun.ProjectManager.Domain/MenuInfos/MenuInfo.cs
  13. 72
      src/Shentun.ProjectManager.Domain/MenuInfos/MenuInfoManager.cs
  14. 30
      src/Shentun.ProjectManager.Domain/RoleMenuInfos/RoleMenuInfo.cs
  15. 2
      src/Shentun.ProjectManager.Domain/Shentun.ProjectManager.Domain.csproj
  16. 29
      src/Shentun.ProjectManager.EntityFrameworkCore/Configures/MenuInfoConfigure.cs
  17. 27
      src/Shentun.ProjectManager.EntityFrameworkCore/Configures/RoleMenuInfoConfigure.cs
  18. 4
      src/Shentun.ProjectManager.EntityFrameworkCore/EntityFrameworkCore/ProjectManagerDbContext.cs
  19. 2290
      src/Shentun.ProjectManager.EntityFrameworkCore/Migrations/20250509085622_insert_menu_info_role_menu_info.Designer.cs
  20. 60
      src/Shentun.ProjectManager.EntityFrameworkCore/Migrations/20250509085622_insert_menu_info_role_menu_info.cs
  21. 228
      src/Shentun.ProjectManager.EntityFrameworkCore/Migrations/ProjectManagerDbContextModelSnapshot.cs

41
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
{
/// <summary>
/// 名称
/// </summary>
public string DisplayName { get; set; }
/// <summary>
/// 路由地址
/// </summary>
public string? RouteUrl { get; set; }
/// <summary>
/// 菜单图标
/// </summary>
public string? IconName { get; set; }
/// <summary>
/// 父id
/// </summary>
public Guid? ParentId { get; set; }
/// <summary>
/// 菜单类型 0 一级菜单 1 带路径的菜单 2 按钮
/// </summary>
public char MenuType { get; set; } = '1';
}
}

42
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; }
/// <summary>
/// 名称
/// </summary>
public string DisplayName { get; set; }
/// <summary>
/// 路由地址
/// </summary>
public string? RouteUrl { get; set; }
/// <summary>
/// 菜单图标
/// </summary>
public string? IconName { get; set; }
/// <summary>
/// 父id
/// </summary>
public Guid? ParentId { get; set; }
public int DisplayOrder { get; set; }
/// <summary>
/// 菜单类型 0 一级菜单 1 带路径的菜单 2 按钮
/// </summary>
public char MenuType { get; set; }
}
}

49
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
{
/// <summary>
/// 名称
/// </summary>
public string DisplayName { get; set; }
/// <summary>
/// 路由地址
/// </summary>
public string? RouteUrl { get; set; }
/// <summary>
/// 菜单图标
/// </summary>
public string? IconName { get; set; }
/// <summary>
/// 自定义简码
/// </summary>
public string SimpleCode { get; set; }
/// <summary>
/// 父id
/// </summary>
public Guid? ParentId { get; set; }
public int DisplayOrder { get; set; }
/// <summary>
/// 是否启用
/// </summary>
public char IsActive { get; set; }
/// <summary>
/// 菜单类型 0 一级菜单 1 带路径的菜单 2 按钮
/// </summary>
public char MenuType { get; set; }
}
}

11
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; }
}
}

46
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; }
/// <summary>
/// 路由地址
/// </summary>
public string RouteUrl { get; set; }
/// <summary>
/// 菜单图标
/// </summary>
public string IconName { get; set; }
//父节点Id
public Guid? ParentId { get; set; }
public int DisplayOrder { get; set; }
public char IsActive { get; set; }
/// <summary>
/// 菜单类型 0 一级菜单 1 带路径的菜单 2 按钮
/// </summary>
public char MenuType { get; set; }
/// <summary>
/// 拼音简码
/// </summary>
public string SimpleCode { get; set; }
public List<MenuInfoTreeDto> TreeChildren { get; set; }
}
}

44
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; }
/// <summary>
/// 名称
/// </summary>
public string DisplayName { get; set; }
/// <summary>
/// 路由地址
/// </summary>
public string? RouteUrl { get; set; }
/// <summary>
/// 菜单图标
/// </summary>
public string? IconName { get; set; }
/// <summary>
/// 是否启用
/// </summary>
public char IsActive { get; set; }
/// <summary>
/// 排序值
/// </summary>
public int? DisplayOrder { get; set; }
/// <summary>
/// 菜单类型 0 一级菜单 1 带路径的菜单 2 按钮
/// </summary>
public char MenuType { get; set; }
}
}

24
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
{
/// <summary>
/// 菜单ID
/// </summary>
public Guid MenuInfoId { get; set; }
/// <summary>
/// 上级ID
/// </summary>
public Guid? ParentId { get; set; }
/// <summary>
/// 菜单名称
/// </summary>
public string DisplayName { get; set; }
}
}

20
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
{
/// <summary>
/// 角色ID
/// </summary>
public Guid RoleId { get; set; }
/// <summary>
/// 对应的菜单ID集合
/// </summary>
public List<Guid> MenuInfoIds { get; set; } = new List<Guid>();
}
}

358
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
{
/// <summary>
/// 后台菜单
/// </summary>
[ApiExplorerSettings(GroupName = "Bus")]
[Authorize]
public class MenuInfoAppService : ApplicationService
{
private readonly IRepository<MenuInfo, Guid> _menuInfoRepository;
private readonly IRepository<RoleMenuInfo> _roleMenuInfoRepository;
private readonly ICurrentUser _currentUser;
private readonly IIdentityUserRepository _userRepository;
private readonly IRepository<IdentityUser, Guid> _identityUserRepository;
private readonly IConfiguration _configuration;
private readonly MenuInfoManager _menuInfoManager;
private readonly CacheService _cacheService;
public MenuInfoAppService(
IRepository<MenuInfo, Guid> menuInfoRepository,
IRepository<RoleMenuInfo> roleMenuInfoRepository,
ICurrentUser currentUser,
MenuInfoManager menuInfoManager,
IIdentityUserRepository userRepository,
IRepository<IdentityUser, Guid> identityUserRepository,
IConfiguration configuration,
CacheService cacheService)
{
_menuInfoRepository = menuInfoRepository;
_menuInfoManager = menuInfoManager;
_roleMenuInfoRepository = roleMenuInfoRepository;
_currentUser = currentUser;
_userRepository = userRepository;
_identityUserRepository = identityUserRepository;
_configuration = configuration;
_cacheService = cacheService;
}
/// <summary>
/// 查询菜单数据 根据ID
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("api/app/MenuInfo/GetMenuInfo")]
public async Task<MenuInfoDto> GetMenuInfoAsync(MenuInfoIdInputDto input)
{
var entity = await _menuInfoRepository.GetAsync(input.MenuInfoId);
var dto = ObjectMapper.Map<MenuInfo, MenuInfoDto>(entity);
dto.CreatorName =await _cacheService.GetNameAsync(dto.CreatorId);
dto.LastModifierName = await _cacheService.GetNameAsync(dto.LastModifierId);
return dto;
}
/// <summary>
/// 创建后台菜单
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("api/app/MenuInfo/CreatetMenuInfo")]
public async Task<MenuInfoDto> CreatetMenuInfoAsync(CreateMenuInfoDto input)
{
var createEntity = ObjectMapper.Map<CreateMenuInfoDto, MenuInfo>(input);
var entity = await _menuInfoManager.CreatetMenuInfoAsync(createEntity);
entity = await _menuInfoRepository.InsertAsync(entity);
var dto = ObjectMapper.Map<MenuInfo, MenuInfoDto>(entity);
return dto;
}
/// <summary>
/// 修改后台菜单
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("api/app/MenuInfo/UpdateMenuInfo")]
public async Task<MenuInfoDto> UpdateMenuInfoAsync( UpdateMenuInfoDto input)
{
var entity = await _menuInfoRepository.GetAsync(input.Id);
var sourceEntity = ObjectMapper.Map<UpdateMenuInfoDto, MenuInfo>(input);
_menuInfoManager.UpdateMenuInfoAsync(sourceEntity, entity);
entity = await _menuInfoRepository.UpdateAsync(entity);
var dto = ObjectMapper.Map<MenuInfo, MenuInfoDto>(entity);
return dto;
}
/// <summary>
/// 删除
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
/// <exception cref="UserFriendlyException"></exception>
[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);
}
/// <summary>
/// 获取当前用户的树型菜单结果
/// </summary>
/// <returns></returns>
[HttpPost("api/app/MenuInfo/GetMyMenuInfoTreeList")]
public async Task<List<MenuInfoTreeDto>> GetMyMenuInfoTreeListAsync()
{
var dataList = await _menuInfoRepository.GetQueryableAsync();
string AdminId = _configuration.GetValue<string>("AdminId");
if (_currentUser.Id.Value != Guid.Parse(AdminId))
{
var userRoles = await _userRepository.GetRolesAsync(_currentUser.Id.Value); //获取当前用户的角色
if (!userRoles.Any())
return new List<MenuInfoTreeDto>();
var userMenuInfoList = await _roleMenuInfoRepository.GetListAsync(m => userRoles.Select(s => s.Id).Contains(m.RoleId)); //当前持有的菜单项
if (!userMenuInfoList.Any())
return new List<MenuInfoTreeDto>();
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);
}
/// <summary>
/// 获取树型菜单结果
/// </summary>
/// <returns></returns>
[HttpPost("api/app/MenuInfo/GetMenuInfoTreeList")]
public async Task<List<MenuInfoTreeDto>> 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);
}
/// <summary>
/// 获取当前用户的菜单列表
/// </summary>
/// <returns></returns>
[HttpPost("api/app/MenuInfo/GetMyMenuInfoList")]
public async Task<List<GetMyMenuInfoListDto>> GetMyMenuInfoListAsync()
{
var query = await _menuInfoRepository.GetQueryableAsync();
query = query.Where(m => m.IsActive == 'Y');
string AdminId = _configuration.GetValue<string>("AdminId");
if (_currentUser.Id.Value != Guid.Parse(AdminId))
{
var userRoles = await _userRepository.GetRolesAsync(_currentUser.Id.Value); //获取当前用户的角色
if (!userRoles.Any())
return new List<GetMyMenuInfoListDto>();
var userMenuInfoList = await _roleMenuInfoRepository.GetListAsync(m => userRoles.Select(s => s.Id).Contains(m.RoleId)); //当前持有的菜单项
if (!userMenuInfoList.Any())
return new List<GetMyMenuInfoListDto>();
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;
}
/// <summary>
/// 获取指定用户的菜单列表
/// </summary>
/// <returns></returns>
[HttpPost("api/app/MenuInfo/GetMyMenuInfoListInUser")]
public async Task<List<MenuInfoDto>> 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<MenuInfoDto>();
var userMenuInfoList = await _roleMenuInfoRepository.GetListAsync(m => userRoles.Select(s => s.Id).Contains(m.RoleId)); //当前持有的菜单项
if (!userMenuInfoList.Any())
return new List<MenuInfoDto>();
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;
}
/// <summary>
/// 获取菜单列表
/// </summary>
/// <returns></returns>
[HttpPost("api/app/MenuInfo/GetMenuInfoList")]
public async Task<List<MenuInfoDto>> 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;
}
/// <summary>
///
/// </summary>
/// <param name="items"></param>
/// <param name="ParentId"></param>
/// <returns></returns>
private List<MenuInfoTreeDto> GetMenuInfoTree(List<MenuInfoTreeDto> 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();
}
}
}

92
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
{
/// <summary>
/// 角色对菜单的权限控制
/// </summary>
[ApiExplorerSettings(GroupName = "Bus")]
[Authorize]
public class RoleMenuInfoAppService : ApplicationService
{
private readonly IRepository<RoleMenuInfo> _roleMenuInfoRepository;
private readonly IRepository<MenuInfo> _menuInfoRepository;
public RoleMenuInfoAppService(
IRepository<RoleMenuInfo> roleMenuInfoRepository,
IRepository<MenuInfo> menuInfoRepository)
{
this._roleMenuInfoRepository = roleMenuInfoRepository;
this._menuInfoRepository = menuInfoRepository;
}
/// <summary>
/// 获取角色对应的菜单选项
/// </summary>
/// <param name="RoleId">角色ID</param>
/// <returns></returns>
[HttpPost("api/app/RoleMenuInfo/GetRoleMenuInfoList")]
public async Task<List<GetRoleMenuInfoIdsDto>> 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;
}
/// <summary>
/// 设置角色的菜单权限
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[HttpPost("api/app/RoleMenuInfo/SetRoleMenuInfo")]
public async Task SetRoleMenuInfoAsync(SetRoleMenuInfoRequestDto input)
{
//删除原有配置
await _roleMenuInfoRepository.DeleteAsync(m => m.RoleId == input.RoleId);
List<RoleMenuInfo> roleMenuInfoList = new List<RoleMenuInfo>();
if (input.MenuInfoIds.Any())
{
//增加新配置
foreach (var item in input.MenuInfoIds)
{
roleMenuInfoList.Add(new RoleMenuInfo
{
RoleId = input.RoleId,
MenuInfoId = item
});
}
await _roleMenuInfoRepository.InsertManyAsync(roleMenuInfoList);
}
}
}
}

69
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 新版
/// <summary>
/// 汉字转首字母
/// </summary>
/// <param name="strChinese"></param>
/// <returns></returns>
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
}
}

84
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
{
/// <summary>
/// 菜单栏目
/// </summary>
public class MenuInfo : AuditedEntity<Guid>, IDisplayOrder, IDisplayName, IHasConcurrencyStamp
{
protected MenuInfo()
{
}
public MenuInfo(Guid id) : base(id)
{
}
/// <summary>
/// 名称
/// </summary>
[StringLength(20)]
public string DisplayName { get; set; }
/// <summary>
/// 路由地址
/// </summary>
[StringLength(100)]
public string? RouteUrl { get; set; }
/// <summary>
/// 菜单图标
/// </summary>
[StringLength(50)]
public string? IconName { get; set; }
/// <summary>
/// 自定义简码
/// </summary>
[StringLength(20)]
public string SimpleCode { get; set; }
/// <summary>
/// 父id
/// </summary>
public Guid? ParentId { get; set; }
public int DisplayOrder { get; set; }
/// <summary>
/// 是否启用
/// </summary>
public char IsActive { get; set; }
/// <summary>
/// 菜单类型 0 一级菜单 1 带路径的菜单 2 按钮
/// </summary>
public char MenuType { get; set; }
public string ConcurrencyStamp { get; set; }
}
}

72
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<MenuInfo, Guid> _menuInfoRepository;
public MenuInfoManager(
IRepository<MenuInfo, Guid> menuInfoRepository
)
{
_menuInfoRepository = menuInfoRepository;
}
/// <summary>
/// 创建
/// </summary>
/// <param name="entity"></param>
/// <returns></returns>
public async Task<MenuInfo> 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;
}
/// <summary>
/// 修改
/// </summary>
/// <param name="sourceEntity">参数实体</param>
/// <param name="targetEntity">待修改的实体</param>
/// <returns></returns>
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;
}
}
}

30
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
{
/// <summary>
/// 角色对应的后台菜单权限
/// </summary>
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 };
}
}
}

2
src/Shentun.ProjectManager.Domain/Shentun.ProjectManager.Domain.csproj

@ -12,6 +12,8 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="NPinyin.Core" Version="3.0.0" />
<PackageReference Include="PinYinConverterCore" Version="1.0.2" />
<PackageReference Include="Volo.Abp.Emailing" Version="6.0.0" />
<PackageReference Include="Volo.Abp.Identity.Domain" Version="6.0.0" />
<PackageReference Include="Volo.Abp.PermissionManagement.Domain.Identity" Version="6.0.0" />

29
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<MenuInfo>
{
public void Configure(EntityTypeBuilder<MenuInfo> 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'");
}
}
}

27
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<RoleMenuInfo>
{
public void Configure(EntityTypeBuilder<RoleMenuInfo> 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();
}
}
}

4
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<ProjectStaffFeedback> projectStaffFeedbacks { get; set; } = null!;
public DbSet<RoleMenuInfo> roleMenuInfos { get; set; } = null!;
public DbSet<MenuInfo> menuInfos { get; set; } = null!;
#endregion

2290
src/Shentun.ProjectManager.EntityFrameworkCore/Migrations/20250509085622_insert_menu_info_role_menu_info.Designer.cs
File diff suppressed because it is too large
View File

60
src/Shentun.ProjectManager.EntityFrameworkCore/Migrations/20250509085622_insert_menu_info_role_menu_info.cs

@ -0,0 +1,60 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Shentun.ProjectManager.Migrations
{
public partial class insert_menu_info_role_menu_info : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "menu_info",
columns: table => new
{
id = table.Column<Guid>(type: "uuid", fixedLength: true, nullable: false),
display_name = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false, comment: "名称"),
route_url = table.Column<string>(type: "character varying(100)", maxLength: 100, nullable: true, comment: "路由地址"),
icon_name = table.Column<string>(type: "character varying(50)", maxLength: 50, nullable: true, comment: "菜单图标"),
simple_code = table.Column<string>(type: "character varying(20)", maxLength: 20, nullable: false, comment: "自定义简码"),
parent_id = table.Column<Guid>(type: "uuid", fixedLength: true, nullable: true, comment: "父id"),
display_order = table.Column<int>(type: "integer", nullable: false, defaultValue: 999999),
is_active = table.Column<char>(type: "character(1)", nullable: false, defaultValueSql: "'Y'", comment: "是否启用"),
menu_type = table.Column<char>(type: "character(1)", nullable: false, defaultValue: '1'),
concurrency_stamp = table.Column<string>(type: "character varying(40)", maxLength: 40, nullable: true),
creation_time = table.Column<DateTime>(type: "timestamp without time zone", nullable: false),
creator_id = table.Column<Guid>(type: "uuid", nullable: true),
last_modification_time = table.Column<DateTime>(type: "timestamp without time zone", nullable: true),
last_modifier_id = table.Column<Guid>(type: "uuid", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("pk_menu_info", x => x.id);
},
comment: "菜单栏目");
migrationBuilder.CreateTable(
name: "role_menu_info",
columns: table => new
{
role_id = table.Column<Guid>(type: "uuid", fixedLength: true, nullable: false),
menu_info_id = table.Column<Guid>(type: "uuid", fixedLength: true, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("pk_role_menuinfo", x => new { x.role_id, x.menu_info_id });
},
comment: "角色对应菜单权限");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "menu_info");
migrationBuilder.DropTable(
name: "role_menu_info");
}
}
}

228
src/Shentun.ProjectManager.EntityFrameworkCore/Migrations/ProjectManagerDbContextModelSnapshot.cs

@ -24,6 +24,94 @@ namespace Shentun.ProjectManager.Migrations
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("Shentun.ProjectManager.Models.MenuInfo", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uuid")
.HasColumnName("id")
.IsFixedLength();
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
.HasColumnType("character varying(40)")
.HasColumnName("concurrency_stamp");
b.Property<DateTime>("CreationTime")
.HasColumnType("timestamp without time zone")
.HasColumnName("creation_time");
b.Property<Guid?>("CreatorId")
.HasColumnType("uuid")
.HasColumnName("creator_id");
b.Property<string>("DisplayName")
.IsRequired()
.HasMaxLength(20)
.HasColumnType("character varying(20)")
.HasColumnName("display_name")
.HasComment("名称");
b.Property<int>("DisplayOrder")
.ValueGeneratedOnAdd()
.HasColumnType("integer")
.HasDefaultValue(999999)
.HasColumnName("display_order");
b.Property<string>("IconName")
.HasMaxLength(50)
.HasColumnType("character varying(50)")
.HasColumnName("icon_name")
.HasComment("菜单图标");
b.Property<char>("IsActive")
.ValueGeneratedOnAdd()
.HasColumnType("character(1)")
.HasColumnName("is_active")
.HasDefaultValueSql("'Y'")
.HasComment("是否启用");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("timestamp without time zone")
.HasColumnName("last_modification_time");
b.Property<Guid?>("LastModifierId")
.HasColumnType("uuid")
.HasColumnName("last_modifier_id");
b.Property<char>("MenuType")
.ValueGeneratedOnAdd()
.HasColumnType("character(1)")
.HasDefaultValue('1')
.HasColumnName("menu_type");
b.Property<Guid?>("ParentId")
.HasColumnType("uuid")
.HasColumnName("parent_id")
.IsFixedLength()
.HasComment("父id");
b.Property<string>("RouteUrl")
.HasMaxLength(100)
.HasColumnType("character varying(100)")
.HasColumnName("route_url")
.HasComment("路由地址");
b.Property<string>("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<Guid>("Id")
@ -251,12 +339,19 @@ namespace Shentun.ProjectManager.Migrations
b.HasComment("项目文件夹表");
});
modelBuilder.Entity("Shentun.ProjectManager.ProjectStaffFeedbacks.ProjectStaffFeedback", b =>
modelBuilder.Entity("Shentun.ProjectManager.Models.ProjectStaff", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uuid")
.HasColumnName("id");
b.Property<short>("CompletionProgress")
.ValueGeneratedOnAdd()
.HasColumnType("smallint")
.HasDefaultValue((short)0)
.HasColumnName("completion_progress")
.HasComment("完成进度 0-100 整数");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
@ -271,25 +366,16 @@ namespace Shentun.ProjectManager.Migrations
.HasColumnType("uuid")
.HasColumnName("creator_id");
b.Property<string>("FeedbackContent")
.IsRequired()
.HasMaxLength(1000)
.HasColumnType("character varying(1000)")
.HasColumnName("feedback_content")
.HasComment("反馈内容");
b.Property<char>("FeedbackFlag")
.ValueGeneratedOnAdd()
.HasMaxLength(1)
.HasColumnType("character(1)")
.HasColumnName("feedback_flag")
.HasDefaultValueSql("'0'")
.HasComment("反馈类型 (0.反馈 1.建议 2.日志)");
b.Property<string>("DemandContent")
.HasMaxLength(2000)
.HasColumnType("character varying(2000)")
.HasColumnName("demand_content")
.HasComment("需求内容");
b.Property<DateTime>("FeedbackTime")
b.Property<DateTime?>("FinishTime")
.HasColumnType("timestamp without time zone")
.HasColumnName("feedback_time")
.HasComment("反馈时间");
.HasColumnName("finish_time")
.HasComment("实际完成时间");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("timestamp without time zone")
@ -299,32 +385,45 @@ namespace Shentun.ProjectManager.Migrations
.HasColumnType("uuid")
.HasColumnName("last_modifier_id");
b.Property<Guid>("ProjectStaffId")
b.Property<DateTime?>("PlanEndTime")
.HasColumnType("timestamp without time zone")
.HasColumnName("plan_end_time")
.HasComment("计划结束时间");
b.Property<DateTime?>("PlanStartTime")
.HasColumnType("timestamp without time zone")
.HasColumnName("plan_start_time")
.HasComment("计划开始时间");
b.Property<Guid>("ProjectId")
.HasColumnType("uuid")
.HasColumnName("project_staff_id")
.HasComment("项目人员id");
.HasColumnName("project_id")
.HasComment("项目id");
b.Property<Guid>("RoleId")
.HasColumnType("uuid")
.HasColumnName("role_id")
.HasComment("角色id");
b.Property<Guid>("UserId")
.HasColumnType("uuid")
.HasColumnName("user_id")
.HasComment("用户id");
b.HasKey("Id")
.HasName("pk_project_staff_feedback");
.HasName("pk_project_staff");
b.ToTable("project_staff_feedback", (string)null);
b.ToTable("project_staff", (string)null);
b.HasComment("人员反馈、建议、日志表");
b.HasComment("项目人员表");
});
modelBuilder.Entity("Shentun.ProjectManager.ProjectStaffs.ProjectStaff", b =>
modelBuilder.Entity("Shentun.ProjectManager.Models.ProjectStaffFeedback", b =>
{
b.Property<Guid>("Id")
.HasColumnType("uuid")
.HasColumnName("id");
b.Property<short>("CompletionProgress")
.ValueGeneratedOnAdd()
.HasColumnType("smallint")
.HasDefaultValue((short)0)
.HasColumnName("completion_progress")
.HasComment("完成进度 0-100 整数");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken()
.HasMaxLength(40)
@ -339,16 +438,25 @@ namespace Shentun.ProjectManager.Migrations
.HasColumnType("uuid")
.HasColumnName("creator_id");
b.Property<string>("DemandContent")
.HasMaxLength(2000)
.HasColumnType("character varying(2000)")
.HasColumnName("demand_content")
.HasComment("需求内容");
b.Property<string>("FeedbackContent")
.IsRequired()
.HasMaxLength(1000)
.HasColumnType("character varying(1000)")
.HasColumnName("feedback_content")
.HasComment("反馈内容");
b.Property<DateTime?>("FinishTime")
b.Property<char>("FeedbackFlag")
.ValueGeneratedOnAdd()
.HasMaxLength(1)
.HasColumnType("character(1)")
.HasColumnName("feedback_flag")
.HasDefaultValueSql("'0'")
.HasComment("反馈类型 (0.反馈 1.建议 2.日志)");
b.Property<DateTime>("FeedbackTime")
.HasColumnType("timestamp without time zone")
.HasColumnName("finish_time")
.HasComment("实际完成时间");
.HasColumnName("feedback_time")
.HasComment("反馈时间");
b.Property<DateTime?>("LastModificationTime")
.HasColumnType("timestamp without time zone")
@ -358,37 +466,37 @@ namespace Shentun.ProjectManager.Migrations
.HasColumnType("uuid")
.HasColumnName("last_modifier_id");
b.Property<DateTime?>("PlanEndTime")
.HasColumnType("timestamp without time zone")
.HasColumnName("plan_end_time")
.HasComment("计划结束时间");
b.Property<Guid>("ProjectStaffId")
.HasColumnType("uuid")
.HasColumnName("project_staff_id")
.HasComment("项目人员id");
b.Property<DateTime?>("PlanStartTime")
.HasColumnType("timestamp without time zone")
.HasColumnName("plan_start_time")
.HasComment("计划开始时间");
b.HasKey("Id")
.HasName("pk_project_staff_feedback");
b.Property<Guid>("ProjectId")
.HasColumnType("uuid")
.HasColumnName("project_id")
.HasComment("项目id");
b.ToTable("project_staff_feedback", (string)null);
b.HasComment("人员反馈、建议、日志表");
});
modelBuilder.Entity("Shentun.ProjectManager.Models.RoleMenuInfo", b =>
{
b.Property<Guid>("RoleId")
.HasColumnType("uuid")
.HasColumnName("role_id")
.HasComment("角色id");
.IsFixedLength();
b.Property<Guid>("UserId")
b.Property<Guid>("MenuInfoId")
.HasColumnType("uuid")
.HasColumnName("user_id")
.HasComment("用户id");
.HasColumnName("menu_info_id")
.IsFixedLength();
b.HasKey("Id")
.HasName("pk_project_staff");
b.HasKey("RoleId", "MenuInfoId")
.HasName("pk_role_menuinfo");
b.ToTable("project_staff", (string)null);
b.ToTable("role_menu_info", (string)null);
b.HasComment("项目人员表");
b.HasComment("角色对应菜单权限");
});
modelBuilder.Entity("Volo.Abp.AuditLogging.AuditLog", b =>

Loading…
Cancel
Save