Commit 557c9c0ecc8d810a5434478b13771a9a0d4fd4be

Authored by “wangming”
2 parents e9330592 9df65e38

Merge branch 'main' of http://39.98.150.180/wangming/Food-Labeling-Management-Platform

Showing 28 changed files with 1446 additions and 0 deletions
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Common/PagedResultWithPageDto.cs 0 → 100644
  1 +namespace FoodLabeling.Application.Contracts.Dtos.Common;
  2 +
  3 +/// <summary>
  4 +/// 分页返回(包含当前页、总页数)
  5 +/// </summary>
  6 +/// <typeparam name="TItem">列表项类型</typeparam>
  7 +public class PagedResultWithPageDto<TItem>
  8 +{
  9 + /// <summary>
  10 + /// 当前页码(从 1 开始)
  11 + /// </summary>
  12 + public int PageIndex { get; set; }
  13 +
  14 + /// <summary>
  15 + /// 每页条数
  16 + /// </summary>
  17 + public int PageSize { get; set; }
  18 +
  19 + /// <summary>
  20 + /// 总条数
  21 + /// </summary>
  22 + public long TotalCount { get; set; }
  23 +
  24 + /// <summary>
  25 + /// 总页数
  26 + /// </summary>
  27 + public int TotalPages { get; set; }
  28 +
  29 + /// <summary>
  30 + /// 列表数据
  31 + /// </summary>
  32 + public List<TItem> Items { get; set; } = new();
  33 +}
  34 +
... ...
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Location/LocationCreateInputVo.cs 0 → 100644
  1 +namespace FoodLabeling.Application.Contracts.Dtos.Location;
  2 +
  3 +/// <summary>
  4 +/// 新增门店入参
  5 +/// </summary>
  6 +public class LocationCreateInputVo
  7 +{
  8 + public string? Partner { get; set; }
  9 +
  10 + public string? GroupName { get; set; }
  11 +
  12 + /// <summary>
  13 + /// Location ID(业务编码)
  14 + /// </summary>
  15 + public string LocationCode { get; set; } = string.Empty;
  16 +
  17 + public string LocationName { get; set; } = string.Empty;
  18 +
  19 + public string? Street { get; set; }
  20 +
  21 + public string? City { get; set; }
  22 +
  23 + public string? StateCode { get; set; }
  24 +
  25 + public string? Country { get; set; }
  26 +
  27 + public string? ZipCode { get; set; }
  28 +
  29 + public string? Phone { get; set; }
  30 +
  31 + public string? Email { get; set; }
  32 +
  33 + public decimal? Latitude { get; set; }
  34 +
  35 + public decimal? Longitude { get; set; }
  36 +
  37 + public bool State { get; set; } = true;
  38 +}
  39 +
... ...
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Location/LocationGetListInputVo.cs 0 → 100644
  1 +using Volo.Abp.Application.Dtos;
  2 +
  3 +namespace FoodLabeling.Application.Contracts.Dtos.Location;
  4 +
  5 +/// <summary>
  6 +/// 门店分页查询入参
  7 +/// </summary>
  8 +public class LocationGetListInputVo : PagedAndSortedResultRequestDto
  9 +{
  10 + /// <summary>
  11 + /// 模糊搜索(Location ID/Name/Street/City/State/Country/Zip/Phone/Email)
  12 + /// </summary>
  13 + public string? Keyword { get; set; }
  14 +
  15 + /// <summary>
  16 + /// Partner
  17 + /// </summary>
  18 + public string? Partner { get; set; }
  19 +
  20 + /// <summary>
  21 + /// Group
  22 + /// </summary>
  23 + public string? GroupName { get; set; }
  24 +
  25 + /// <summary>
  26 + /// 启用状态
  27 + /// </summary>
  28 + public bool? State { get; set; }
  29 +}
  30 +
... ...
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Location/LocationGetListOutputDto.cs 0 → 100644
  1 +namespace FoodLabeling.Application.Contracts.Dtos.Location;
  2 +
  3 +/// <summary>
  4 +/// 门店列表输出
  5 +/// </summary>
  6 +public class LocationGetListOutputDto
  7 +{
  8 + public Guid Id { get; set; }
  9 +
  10 + public string? Partner { get; set; }
  11 +
  12 + public string? GroupName { get; set; }
  13 +
  14 + public string LocationCode { get; set; } = string.Empty;
  15 +
  16 + public string LocationName { get; set; } = string.Empty;
  17 +
  18 + public string? Street { get; set; }
  19 +
  20 + public string? City { get; set; }
  21 +
  22 + public string? StateCode { get; set; }
  23 +
  24 + public string? Country { get; set; }
  25 +
  26 + public string? ZipCode { get; set; }
  27 +
  28 + public string? Phone { get; set; }
  29 +
  30 + public string? Email { get; set; }
  31 +
  32 + public decimal? Latitude { get; set; }
  33 +
  34 + public decimal? Longitude { get; set; }
  35 +
  36 + public bool State { get; set; }
  37 +}
  38 +
... ...
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/Location/LocationUpdateInputVo.cs 0 → 100644
  1 +namespace FoodLabeling.Application.Contracts.Dtos.Location;
  2 +
  3 +/// <summary>
  4 +/// 编辑门店入参
  5 +/// </summary>
  6 +public class LocationUpdateInputVo
  7 +{
  8 + public string? Partner { get; set; }
  9 +
  10 + public string? GroupName { get; set; }
  11 +
  12 + /// <summary>
  13 + /// Location Name
  14 + /// </summary>
  15 + public string LocationName { get; set; } = string.Empty;
  16 +
  17 + public string? Street { get; set; }
  18 +
  19 + public string? City { get; set; }
  20 +
  21 + public string? StateCode { get; set; }
  22 +
  23 + public string? Country { get; set; }
  24 +
  25 + public string? ZipCode { get; set; }
  26 +
  27 + public string? Phone { get; set; }
  28 +
  29 + public string? Email { get; set; }
  30 +
  31 + public decimal? Latitude { get; set; }
  32 +
  33 + public decimal? Longitude { get; set; }
  34 +
  35 + /// <summary>
  36 + /// 启用状态
  37 + /// </summary>
  38 + public bool State { get; set; } = true;
  39 +}
  40 +
... ...
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacMenu/RbacMenuCreateInputVo.cs 0 → 100644
  1 +namespace FoodLabeling.Application.Contracts.Dtos.RbacMenu;
  2 +
  3 +/// <summary>
  4 +/// 新增权限(Menu)入参(美国版对外)
  5 +/// </summary>
  6 +public class RbacMenuCreateInputVo
  7 +{
  8 + public string MenuName { get; set; } = string.Empty;
  9 +
  10 + public Guid ParentId { get; set; }
  11 +
  12 + public int MenuType { get; set; }
  13 +
  14 + public int MenuSource { get; set; }
  15 +
  16 + public string? PermissionCode { get; set; }
  17 +
  18 + public string? Router { get; set; }
  19 +
  20 + public string? Component { get; set; }
  21 +
  22 + public int OrderNum { get; set; } = 0;
  23 +
  24 + public bool State { get; set; } = true;
  25 +}
  26 +
... ...
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacMenu/RbacMenuGetListInputVo.cs 0 → 100644
  1 +using Volo.Abp.Application.Dtos;
  2 +
  3 +namespace FoodLabeling.Application.Contracts.Dtos.RbacMenu;
  4 +
  5 +/// <summary>
  6 +/// 权限(Menu)分页查询入参(美国版对外)
  7 +/// </summary>
  8 +public class RbacMenuGetListInputVo : PagedAndSortedResultRequestDto
  9 +{
  10 + public string? MenuName { get; set; }
  11 +
  12 + public bool? State { get; set; }
  13 +
  14 + /// <summary>
  15 + /// 菜单来源(与 rbac 的 MenuSource 含义一致,int 存储)
  16 + /// </summary>
  17 + public int? MenuSource { get; set; }
  18 +}
  19 +
... ...
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacMenu/RbacMenuGetListOutputDto.cs 0 → 100644
  1 +namespace FoodLabeling.Application.Contracts.Dtos.RbacMenu;
  2 +
  3 +/// <summary>
  4 +/// 权限(Menu)列表输出(美国版对外)
  5 +/// </summary>
  6 +public class RbacMenuGetListOutputDto
  7 +{
  8 + public Guid Id { get; set; }
  9 +
  10 + public Guid ParentId { get; set; }
  11 +
  12 + public string MenuName { get; set; } = string.Empty;
  13 +
  14 + public string? PermissionCode { get; set; }
  15 +
  16 + public int MenuType { get; set; }
  17 +
  18 + public int MenuSource { get; set; }
  19 +
  20 + public int OrderNum { get; set; }
  21 +
  22 + public bool State { get; set; }
  23 +}
  24 +
... ...
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacMenu/RbacMenuUpdateInputVo.cs 0 → 100644
  1 +namespace FoodLabeling.Application.Contracts.Dtos.RbacMenu;
  2 +
  3 +/// <summary>
  4 +/// 编辑权限(Menu)入参(美国版对外)
  5 +/// </summary>
  6 +public class RbacMenuUpdateInputVo : RbacMenuCreateInputVo
  7 +{
  8 +}
  9 +
... ...
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleCreateInputVo.cs 0 → 100644
  1 +namespace FoodLabeling.Application.Contracts.Dtos.RbacRole;
  2 +
  3 +/// <summary>
  4 +/// 新增角色入参(美国版对外)
  5 +/// </summary>
  6 +public class RbacRoleCreateInputVo
  7 +{
  8 + public string RoleName { get; set; } = string.Empty;
  9 +
  10 + public string RoleCode { get; set; } = string.Empty;
  11 +
  12 + public string? Remark { get; set; }
  13 +
  14 + /// <summary>
  15 + /// 数据范围(与 rbac 的 DataScope 含义一致,int 存储)
  16 + /// </summary>
  17 + public int DataScope { get; set; } = 0;
  18 +
  19 + public bool State { get; set; } = true;
  20 +
  21 + public int OrderNum { get; set; } = 0;
  22 +}
  23 +
... ...
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleGetListInputVo.cs 0 → 100644
  1 +using Volo.Abp.Application.Dtos;
  2 +
  3 +namespace FoodLabeling.Application.Contracts.Dtos.RbacRole;
  4 +
  5 +/// <summary>
  6 +/// 角色分页查询入参(美国版对外)
  7 +/// </summary>
  8 +public class RbacRoleGetListInputVo : PagedAndSortedResultRequestDto
  9 +{
  10 + /// <summary>
  11 + /// 角色名称(模糊)
  12 + /// </summary>
  13 + public string? RoleName { get; set; }
  14 +
  15 + /// <summary>
  16 + /// 角色编码(模糊)
  17 + /// </summary>
  18 + public string? RoleCode { get; set; }
  19 +
  20 + /// <summary>
  21 + /// 启用状态
  22 + /// </summary>
  23 + public bool? State { get; set; }
  24 +}
  25 +
... ...
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleGetListOutputDto.cs 0 → 100644
  1 +namespace FoodLabeling.Application.Contracts.Dtos.RbacRole;
  2 +
  3 +/// <summary>
  4 +/// 角色列表输出(美国版对外)
  5 +/// </summary>
  6 +public class RbacRoleGetListOutputDto
  7 +{
  8 + public Guid Id { get; set; }
  9 +
  10 + public string RoleName { get; set; } = string.Empty;
  11 +
  12 + public string RoleCode { get; set; } = string.Empty;
  13 +
  14 + public string? Remark { get; set; }
  15 +
  16 + public int DataScope { get; set; }
  17 +
  18 + public bool State { get; set; }
  19 +
  20 + public int OrderNum { get; set; }
  21 +}
  22 +
... ...
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleGetOutputDto.cs 0 → 100644
  1 +namespace FoodLabeling.Application.Contracts.Dtos.RbacRole;
  2 +
  3 +/// <summary>
  4 +/// 角色详情输出(美国版对外)
  5 +/// </summary>
  6 +public class RbacRoleGetOutputDto : RbacRoleGetListOutputDto
  7 +{
  8 +}
  9 +
... ...
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRole/RbacRoleUpdateInputVo.cs 0 → 100644
  1 +namespace FoodLabeling.Application.Contracts.Dtos.RbacRole;
  2 +
  3 +/// <summary>
  4 +/// 编辑角色入参(美国版对外)
  5 +/// </summary>
  6 +public class RbacRoleUpdateInputVo : RbacRoleCreateInputVo
  7 +{
  8 +}
  9 +
... ...
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRoleMenu/RbacRoleMenuRemoveInputVo.cs 0 → 100644
  1 +using System.ComponentModel.DataAnnotations;
  2 +
  3 +namespace FoodLabeling.Application.Contracts.Dtos.RbacRoleMenu;
  4 +
  5 +/// <summary>
  6 +/// 角色-权限移除入参
  7 +/// </summary>
  8 +public class RbacRoleMenuRemoveInputVo
  9 +{
  10 + [Required]
  11 + public Guid RoleId { get; set; }
  12 +
  13 + [Required]
  14 + public List<Guid> MenuIds { get; set; } = new();
  15 +}
  16 +
... ...
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/Dtos/RbacRoleMenu/RbacRoleMenuSetInputVo.cs 0 → 100644
  1 +using System.ComponentModel.DataAnnotations;
  2 +
  3 +namespace FoodLabeling.Application.Contracts.Dtos.RbacRoleMenu;
  4 +
  5 +/// <summary>
  6 +/// 角色-权限设置入参(覆盖式)
  7 +/// </summary>
  8 +public class RbacRoleMenuSetInputVo
  9 +{
  10 + /// <summary>
  11 + /// 角色ID
  12 + /// </summary>
  13 + [Required]
  14 + public Guid RoleId { get; set; }
  15 +
  16 + /// <summary>
  17 + /// 菜单ID列表(覆盖式)
  18 + /// </summary>
  19 + [Required]
  20 + public List<Guid> MenuIds { get; set; } = new();
  21 +}
  22 +
... ...
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/FoodLabeling.Application.Contracts.csproj
... ... @@ -4,6 +4,7 @@
4 4 <ItemGroup>
5 5 <ProjectReference Include="..\..\..\framework\Yi.Framework.Ddd.Application.Contracts\Yi.Framework.Ddd.Application.Contracts.csproj" />
6 6 <ProjectReference Include="..\FoodLabeling.Domain.Shared\FoodLabeling.Domain.Shared.csproj" />
  7 + <ProjectReference Include="..\..\rbac\Yi.Framework.Rbac.Domain.Shared\Yi.Framework.Rbac.Domain.Shared.csproj" />
7 8 </ItemGroup>
8 9  
9 10 <ItemGroup>
... ...
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/IServices/ILocationAppService.cs 0 → 100644
  1 +using FoodLabeling.Application.Contracts.Dtos.Location;
  2 +using FoodLabeling.Application.Contracts.Dtos.Common;
  3 +using Volo.Abp.Application.Dtos;
  4 +using Volo.Abp.Application.Services;
  5 +
  6 +namespace FoodLabeling.Application.Contracts.IServices;
  7 +
  8 +/// <summary>
  9 +/// 门店管理接口(美国版)
  10 +/// </summary>
  11 +public interface ILocationAppService : IApplicationService
  12 +{
  13 + /// <summary>
  14 + /// 门店分页列表
  15 + /// </summary>
  16 + /// <param name="input">查询条件</param>
  17 + Task<PagedResultWithPageDto<LocationGetListOutputDto>> GetListAsync(LocationGetListInputVo input);
  18 +
  19 + /// <summary>
  20 + /// 新增门店
  21 + /// </summary>
  22 + /// <param name="input">门店信息</param>
  23 + Task<LocationGetListOutputDto> CreateAsync(LocationCreateInputVo input);
  24 +
  25 + /// <summary>
  26 + /// 编辑门店
  27 + /// </summary>
  28 + /// <param name="id">门店Id</param>
  29 + /// <param name="input">门店信息</param>
  30 + Task<LocationGetListOutputDto> UpdateAsync(Guid id, LocationUpdateInputVo input);
  31 +
  32 + /// <summary>
  33 + /// 删除门店(逻辑删除)
  34 + /// </summary>
  35 + /// <param name="id">门店Id</param>
  36 + Task DeleteAsync(Guid id);
  37 +}
  38 +
... ...
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/IServices/IRbacMenuAppService.cs 0 → 100644
  1 +using FoodLabeling.Application.Contracts.Dtos.RbacMenu;
  2 +using FoodLabeling.Application.Contracts.Dtos.Common;
  3 +using Volo.Abp.Application.Dtos;
  4 +using Volo.Abp.Application.Services;
  5 +
  6 +namespace FoodLabeling.Application.Contracts.IServices;
  7 +
  8 +/// <summary>
  9 +/// 权限(Menu)管理接口(仅用于食品标签-美国版对外)
  10 +/// </summary>
  11 +public interface IRbacMenuAppService : IApplicationService
  12 +{
  13 + /// <summary>
  14 + /// 权限分页列表
  15 + /// </summary>
  16 + Task<PagedResultWithPageDto<RbacMenuGetListOutputDto>> GetListAsync(RbacMenuGetListInputVo input);
  17 +
  18 + /// <summary>
  19 + /// 权限详情
  20 + /// </summary>
  21 + Task<RbacMenuGetListOutputDto> GetAsync(Guid id);
  22 +
  23 + /// <summary>
  24 + /// 新增权限
  25 + /// </summary>
  26 + Task<RbacMenuGetListOutputDto> CreateAsync(RbacMenuCreateInputVo input);
  27 +
  28 + /// <summary>
  29 + /// 编辑权限
  30 + /// </summary>
  31 + Task<RbacMenuGetListOutputDto> UpdateAsync(Guid id, RbacMenuUpdateInputVo input);
  32 +
  33 + /// <summary>
  34 + /// 删除权限(逻辑删除)
  35 + /// </summary>
  36 + Task DeleteAsync(List<Guid> ids);
  37 +}
  38 +
... ...
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/IServices/IRbacRoleAppService.cs 0 → 100644
  1 +using FoodLabeling.Application.Contracts.Dtos.RbacRole;
  2 +using FoodLabeling.Application.Contracts.Dtos.Common;
  3 +using Volo.Abp.Application.Dtos;
  4 +using Volo.Abp.Application.Services;
  5 +
  6 +namespace FoodLabeling.Application.Contracts.IServices;
  7 +
  8 +/// <summary>
  9 +/// 角色管理接口(仅用于食品标签-美国版对外)
  10 +/// </summary>
  11 +public interface IRbacRoleAppService : IApplicationService
  12 +{
  13 + /// <summary>
  14 + /// 角色分页列表
  15 + /// </summary>
  16 + Task<PagedResultWithPageDto<RbacRoleGetListOutputDto>> GetListAsync(RbacRoleGetListInputVo input);
  17 +
  18 + /// <summary>
  19 + /// 角色详情
  20 + /// </summary>
  21 + Task<RbacRoleGetOutputDto> GetAsync(Guid id);
  22 +
  23 + /// <summary>
  24 + /// 新增角色
  25 + /// </summary>
  26 + Task<RbacRoleGetOutputDto> CreateAsync(RbacRoleCreateInputVo input);
  27 +
  28 + /// <summary>
  29 + /// 编辑角色
  30 + /// </summary>
  31 + Task<RbacRoleGetOutputDto> UpdateAsync(Guid id, RbacRoleUpdateInputVo input);
  32 +
  33 + /// <summary>
  34 + /// 删除角色(逻辑删除)
  35 + /// </summary>
  36 + Task DeleteAsync(List<Guid> ids);
  37 +}
  38 +
... ...
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application.Contracts/IServices/IRbacRoleMenuAppService.cs 0 → 100644
  1 +using FoodLabeling.Application.Contracts.Dtos.RbacRoleMenu;
  2 +using Volo.Abp.Application.Services;
  3 +
  4 +namespace FoodLabeling.Application.Contracts.IServices;
  5 +
  6 +/// <summary>
  7 +/// 角色-权限关联接口(仅用于食品标签-美国版对外)
  8 +/// </summary>
  9 +public interface IRbacRoleMenuAppService : IApplicationService
  10 +{
  11 + /// <summary>
  12 + /// 覆盖式设置角色的菜单权限
  13 + /// </summary>
  14 + Task SetAsync(RbacRoleMenuSetInputVo input);
  15 +
  16 + /// <summary>
  17 + /// 获取角色已分配的菜单ID列表
  18 + /// </summary>
  19 + Task<List<Guid>> GetMenuIdsAsync(Guid roleId);
  20 +
  21 + /// <summary>
  22 + /// 移除角色的指定菜单权限
  23 + /// </summary>
  24 + Task RemoveAsync(RbacRoleMenuRemoveInputVo input);
  25 +}
  26 +
... ...
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/FoodLabeling.Application.csproj
... ... @@ -5,6 +5,7 @@
5 5 <ProjectReference Include="..\..\..\framework\Yi.Framework.Ddd.Application\Yi.Framework.Ddd.Application.csproj" />
6 6 <ProjectReference Include="..\FoodLabeling.Application.Contracts\FoodLabeling.Application.Contracts.csproj" />
7 7 <ProjectReference Include="..\FoodLabeling.Domain\FoodLabeling.Domain.csproj" />
  8 + <ProjectReference Include="..\..\rbac\Yi.Framework.Rbac.Domain\Yi.Framework.Rbac.Domain.csproj" />
8 9 </ItemGroup>
9 10  
10 11 <ItemGroup>
... ...
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/LocationAppService.cs 0 → 100644
  1 +using FoodLabeling.Application.Contracts.Dtos.Location;
  2 +using FoodLabeling.Application.Contracts.IServices;
  3 +using FoodLabeling.Domain.Entities;
  4 +using FoodLabeling.Application.Contracts.Dtos.Common;
  5 +using Microsoft.AspNetCore.Mvc;
  6 +using SqlSugar;
  7 +using Volo.Abp;
  8 +using Volo.Abp.Application.Dtos;
  9 +using Volo.Abp.Application.Services;
  10 +using Yi.Framework.SqlSugarCore.Abstractions;
  11 +
  12 +namespace FoodLabeling.Application.Services;
  13 +
  14 +/// <summary>
  15 +/// 门店管理服务(美国版)
  16 +/// </summary>
  17 +public class LocationAppService : ApplicationService, ILocationAppService
  18 +{
  19 + private readonly ISqlSugarRepository<LocationAggregateRoot, Guid> _locationRepository;
  20 +
  21 + public LocationAppService(ISqlSugarRepository<LocationAggregateRoot, Guid> locationRepository)
  22 + {
  23 + _locationRepository = locationRepository;
  24 + }
  25 +
  26 + /// <inheritdoc />
  27 + public async Task<PagedResultWithPageDto<LocationGetListOutputDto>> GetListAsync([FromQuery] LocationGetListInputVo input)
  28 + {
  29 + RefAsync<int> total = 0;
  30 +
  31 + var keyword = input.Keyword?.Trim();
  32 + var partner = input.Partner?.Trim();
  33 + var groupName = input.GroupName?.Trim();
  34 +
  35 + var query = _locationRepository._DbQueryable
  36 + .Where(x => x.IsDeleted == false)
  37 + .WhereIF(!string.IsNullOrEmpty(partner), x => x.Partner == partner)
  38 + .WhereIF(!string.IsNullOrEmpty(groupName), x => x.GroupName == groupName)
  39 + .WhereIF(input.State is not null, x => x.State == input.State)
  40 + .WhereIF(!string.IsNullOrEmpty(keyword),
  41 + x =>
  42 + x.LocationCode.Contains(keyword!) ||
  43 + x.LocationName.Contains(keyword!) ||
  44 + (x.Street != null && x.Street.Contains(keyword!)) ||
  45 + (x.City != null && x.City.Contains(keyword!)) ||
  46 + (x.StateCode != null && x.StateCode.Contains(keyword!)) ||
  47 + (x.Country != null && x.Country.Contains(keyword!)) ||
  48 + (x.ZipCode != null && x.ZipCode.Contains(keyword!)) ||
  49 + (x.Phone != null && x.Phone.Contains(keyword!)) ||
  50 + (x.Email != null && x.Email.Contains(keyword!))
  51 + );
  52 +
  53 + // 先按排序字段走(如前端传入),否则默认按创建时间倒序
  54 + if (!string.IsNullOrWhiteSpace(input.Sorting))
  55 + {
  56 + query = query.OrderBy(input.Sorting);
  57 + }
  58 + else
  59 + {
  60 + query = query.OrderBy(x => x.CreationTime, OrderByType.Desc);
  61 + }
  62 +
  63 + var entities = await query.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
  64 +
  65 + var items = entities.Select(x => new LocationGetListOutputDto
  66 + {
  67 + Id = x.Id,
  68 + Partner = x.Partner,
  69 + GroupName = x.GroupName,
  70 + LocationCode = x.LocationCode,
  71 + LocationName = x.LocationName,
  72 + Street = x.Street,
  73 + City = x.City,
  74 + StateCode = x.StateCode,
  75 + Country = x.Country,
  76 + ZipCode = x.ZipCode,
  77 + Phone = x.Phone,
  78 + Email = x.Email,
  79 + Latitude = x.Latitude,
  80 + Longitude = x.Longitude,
  81 + State = x.State
  82 + }).ToList();
  83 +
  84 + var pageSize = input.MaxResultCount <= 0 ? items.Count : input.MaxResultCount;
  85 + var pageIndex = pageSize <= 0 ? 1 : (input.SkipCount / pageSize) + 1;
  86 + var totalPages = pageSize <= 0 ? 0 : (int)Math.Ceiling(total / (double)pageSize);
  87 +
  88 + return new PagedResultWithPageDto<LocationGetListOutputDto>
  89 + {
  90 + PageIndex = pageIndex,
  91 + PageSize = pageSize,
  92 + TotalCount = total,
  93 + TotalPages = totalPages,
  94 + Items = items
  95 + };
  96 + }
  97 +
  98 + /// <inheritdoc />
  99 + public async Task<LocationGetListOutputDto> CreateAsync([FromBody] LocationCreateInputVo input)
  100 + {
  101 + var locationCode = input.LocationCode?.Trim();
  102 + if (string.IsNullOrWhiteSpace(locationCode))
  103 + {
  104 + throw new UserFriendlyException("Location ID不能为空");
  105 + }
  106 +
  107 + var locationName = input.LocationName?.Trim();
  108 + if (string.IsNullOrWhiteSpace(locationName))
  109 + {
  110 + throw new UserFriendlyException("Location Name不能为空");
  111 + }
  112 +
  113 + var isExist = await _locationRepository.IsAnyAsync(x => x.LocationCode == locationCode);
  114 + if (isExist)
  115 + {
  116 + throw new UserFriendlyException("Location ID已存在");
  117 + }
  118 +
  119 + var entity = new LocationAggregateRoot(GuidGenerator.Create())
  120 + {
  121 + Partner = input.Partner?.Trim(),
  122 + GroupName = input.GroupName?.Trim(),
  123 + LocationCode = locationCode,
  124 + LocationName = locationName,
  125 + Street = input.Street?.Trim(),
  126 + City = input.City?.Trim(),
  127 + StateCode = input.StateCode?.Trim(),
  128 + Country = input.Country?.Trim(),
  129 + ZipCode = input.ZipCode?.Trim(),
  130 + Phone = input.Phone?.Trim(),
  131 + Email = input.Email?.Trim(),
  132 + Latitude = input.Latitude,
  133 + Longitude = input.Longitude,
  134 + State = input.State
  135 + };
  136 +
  137 + await _locationRepository.InsertAsync(entity);
  138 +
  139 + return new LocationGetListOutputDto
  140 + {
  141 + Id = entity.Id,
  142 + Partner = entity.Partner,
  143 + GroupName = entity.GroupName,
  144 + LocationCode = entity.LocationCode,
  145 + LocationName = entity.LocationName,
  146 + Street = entity.Street,
  147 + City = entity.City,
  148 + StateCode = entity.StateCode,
  149 + Country = entity.Country,
  150 + ZipCode = entity.ZipCode,
  151 + Phone = entity.Phone,
  152 + Email = entity.Email,
  153 + Latitude = entity.Latitude,
  154 + Longitude = entity.Longitude,
  155 + State = entity.State
  156 + };
  157 + }
  158 +
  159 + /// <inheritdoc />
  160 + public async Task<LocationGetListOutputDto> UpdateAsync(Guid id, [FromBody] LocationUpdateInputVo input)
  161 + {
  162 + var entity = await _locationRepository.GetSingleAsync(x => x.Id == id && x.IsDeleted == false);
  163 + if (entity is null)
  164 + {
  165 + throw new UserFriendlyException("门店不存在");
  166 + }
  167 +
  168 + var locationName = input.LocationName?.Trim();
  169 + if (string.IsNullOrWhiteSpace(locationName))
  170 + {
  171 + throw new UserFriendlyException("Location Name不能为空");
  172 + }
  173 +
  174 + // LocationCode 默认不允许修改:业务编码需要保持唯一且稳定(如需变更,应走“新建+迁移”方案)
  175 + entity.Partner = input.Partner?.Trim();
  176 + entity.GroupName = input.GroupName?.Trim();
  177 + entity.LocationName = locationName;
  178 + entity.Street = input.Street?.Trim();
  179 + entity.City = input.City?.Trim();
  180 + entity.StateCode = input.StateCode?.Trim();
  181 + entity.Country = input.Country?.Trim();
  182 + entity.ZipCode = input.ZipCode?.Trim();
  183 + entity.Phone = input.Phone?.Trim();
  184 + entity.Email = input.Email?.Trim();
  185 + entity.Latitude = input.Latitude;
  186 + entity.Longitude = input.Longitude;
  187 + entity.State = input.State;
  188 +
  189 + await _locationRepository.UpdateAsync(entity);
  190 +
  191 + return new LocationGetListOutputDto
  192 + {
  193 + Id = entity.Id,
  194 + Partner = entity.Partner,
  195 + GroupName = entity.GroupName,
  196 + LocationCode = entity.LocationCode,
  197 + LocationName = entity.LocationName,
  198 + Street = entity.Street,
  199 + City = entity.City,
  200 + StateCode = entity.StateCode,
  201 + Country = entity.Country,
  202 + ZipCode = entity.ZipCode,
  203 + Phone = entity.Phone,
  204 + Email = entity.Email,
  205 + Latitude = entity.Latitude,
  206 + Longitude = entity.Longitude,
  207 + State = entity.State
  208 + };
  209 + }
  210 +
  211 + /// <inheritdoc />
  212 + public async Task DeleteAsync(Guid id)
  213 + {
  214 + var entity = await _locationRepository.GetSingleAsync(x => x.Id == id && x.IsDeleted == false);
  215 + if (entity is null)
  216 + {
  217 + throw new UserFriendlyException("门店不存在");
  218 + }
  219 +
  220 + entity.IsDeleted = true;
  221 + await _locationRepository.UpdateAsync(entity);
  222 + }
  223 +}
  224 +
... ...
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/RbacMenuAppService.cs 0 → 100644
  1 +using FoodLabeling.Application.Contracts.Dtos.RbacMenu;
  2 +using FoodLabeling.Application.Contracts.Dtos.Common;
  3 +using FoodLabeling.Application.Contracts.IServices;
  4 +using Microsoft.AspNetCore.Mvc;
  5 +using SqlSugar;
  6 +using Volo.Abp;
  7 +using Volo.Abp.Application.Services;
  8 +using Volo.Abp.Domain.Entities;
  9 +using Yi.Framework.Rbac.Domain.Entities;
  10 +using Yi.Framework.SqlSugarCore.Abstractions;
  11 +
  12 +namespace FoodLabeling.Application.Services;
  13 +
  14 +/// <summary>
  15 +/// 权限(Menu)管理(食品标签-美国版对外)
  16 +/// </summary>
  17 +public class RbacMenuAppService : ApplicationService, IRbacMenuAppService
  18 +{
  19 + private readonly ISqlSugarRepository<MenuAggregateRoot, Guid> _menuRepository;
  20 +
  21 + public RbacMenuAppService(ISqlSugarRepository<MenuAggregateRoot, Guid> menuRepository)
  22 + {
  23 + _menuRepository = menuRepository;
  24 + }
  25 +
  26 + /// <inheritdoc />
  27 + public async Task<PagedResultWithPageDto<RbacMenuGetListOutputDto>> GetListAsync([FromQuery] RbacMenuGetListInputVo input)
  28 + {
  29 + RefAsync<int> total = 0;
  30 +
  31 + var query = _menuRepository._DbQueryable
  32 + .Where(x => x.IsDeleted == false)
  33 + .WhereIF(!string.IsNullOrWhiteSpace(input.MenuName), x => x.MenuName.Contains(input.MenuName!.Trim()))
  34 + .WhereIF(input.State is not null, x => x.State == input.State)
  35 + .WhereIF(input.MenuSource is not null, x => x.MenuSource == (Yi.Framework.Rbac.Domain.Shared.Enums.MenuSourceEnum)input.MenuSource!.Value)
  36 + .OrderBy(x => x.OrderNum, OrderByType.Desc);
  37 +
  38 + var entities = await query.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
  39 +
  40 + var items = entities.Select(x => new RbacMenuGetListOutputDto
  41 + {
  42 + Id = x.Id,
  43 + ParentId = x.ParentId,
  44 + MenuName = x.MenuName ?? string.Empty,
  45 + PermissionCode = x.PermissionCode,
  46 + MenuType = (int)x.MenuType,
  47 + MenuSource = (int)x.MenuSource,
  48 + OrderNum = x.OrderNum,
  49 + State = x.State
  50 + }).ToList();
  51 +
  52 + var pageSize = input.MaxResultCount <= 0 ? items.Count : input.MaxResultCount;
  53 + var pageIndex = pageSize <= 0 ? 1 : (input.SkipCount / pageSize) + 1;
  54 + var totalPages = pageSize <= 0 ? 0 : (int)Math.Ceiling(total / (double)pageSize);
  55 +
  56 + return new PagedResultWithPageDto<RbacMenuGetListOutputDto>
  57 + {
  58 + PageIndex = pageIndex,
  59 + PageSize = pageSize,
  60 + TotalCount = total,
  61 + TotalPages = totalPages,
  62 + Items = items
  63 + };
  64 + }
  65 +
  66 + /// <inheritdoc />
  67 + public async Task<RbacMenuGetListOutputDto> GetAsync(Guid id)
  68 + {
  69 + var entity = await _menuRepository.GetSingleAsync(x => x.Id == id && x.IsDeleted == false);
  70 + if (entity is null)
  71 + {
  72 + throw new UserFriendlyException("权限不存在");
  73 + }
  74 +
  75 + return new RbacMenuGetListOutputDto
  76 + {
  77 + Id = entity.Id,
  78 + ParentId = entity.ParentId,
  79 + MenuName = entity.MenuName ?? string.Empty,
  80 + PermissionCode = entity.PermissionCode,
  81 + MenuType = (int)entity.MenuType,
  82 + MenuSource = (int)entity.MenuSource,
  83 + OrderNum = entity.OrderNum,
  84 + State = entity.State
  85 + };
  86 + }
  87 +
  88 + /// <inheritdoc />
  89 + public async Task<RbacMenuGetListOutputDto> CreateAsync([FromBody] RbacMenuCreateInputVo input)
  90 + {
  91 + var name = input.MenuName?.Trim();
  92 + if (string.IsNullOrWhiteSpace(name))
  93 + {
  94 + throw new UserFriendlyException("权限名称不能为空");
  95 + }
  96 +
  97 + var entity = new MenuAggregateRoot
  98 + {
  99 + MenuName = name,
  100 + ParentId = input.ParentId,
  101 + MenuType = (Yi.Framework.Rbac.Domain.Shared.Enums.MenuTypeEnum)input.MenuType,
  102 + MenuSource = (Yi.Framework.Rbac.Domain.Shared.Enums.MenuSourceEnum)input.MenuSource,
  103 + PermissionCode = input.PermissionCode?.Trim(),
  104 + Router = input.Router?.Trim(),
  105 + Component = input.Component?.Trim(),
  106 + OrderNum = input.OrderNum,
  107 + State = input.State
  108 + };
  109 + EntityHelper.TrySetId(entity, () => GuidGenerator.Create());
  110 +
  111 + await _menuRepository.InsertAsync(entity);
  112 + return await GetAsync(entity.Id);
  113 + }
  114 +
  115 + /// <inheritdoc />
  116 + public async Task<RbacMenuGetListOutputDto> UpdateAsync(Guid id, [FromBody] RbacMenuUpdateInputVo input)
  117 + {
  118 + var entity = await _menuRepository.GetSingleAsync(x => x.Id == id && x.IsDeleted == false);
  119 + if (entity is null)
  120 + {
  121 + throw new UserFriendlyException("权限不存在");
  122 + }
  123 +
  124 + var name = input.MenuName?.Trim();
  125 + if (string.IsNullOrWhiteSpace(name))
  126 + {
  127 + throw new UserFriendlyException("权限名称不能为空");
  128 + }
  129 +
  130 + entity.MenuName = name;
  131 + entity.ParentId = input.ParentId;
  132 + entity.MenuType = (Yi.Framework.Rbac.Domain.Shared.Enums.MenuTypeEnum)input.MenuType;
  133 + entity.MenuSource = (Yi.Framework.Rbac.Domain.Shared.Enums.MenuSourceEnum)input.MenuSource;
  134 + entity.PermissionCode = input.PermissionCode?.Trim();
  135 + entity.Router = input.Router?.Trim();
  136 + entity.Component = input.Component?.Trim();
  137 + entity.OrderNum = input.OrderNum;
  138 + entity.State = input.State;
  139 +
  140 + await _menuRepository.UpdateAsync(entity);
  141 + return await GetAsync(entity.Id);
  142 + }
  143 +
  144 + /// <inheritdoc />
  145 + public async Task DeleteAsync([FromBody] List<Guid> ids)
  146 + {
  147 + var idList = ids?.Distinct().ToList() ?? new List<Guid>();
  148 + if (idList.Count == 0)
  149 + {
  150 + return;
  151 + }
  152 +
  153 + // 权限表为软删(ISoftDelete)
  154 + await _menuRepository.DeleteAsync(x => idList.Contains(x.Id));
  155 + }
  156 +}
  157 +
... ...
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/RbacRoleAppService.cs 0 → 100644
  1 +using FoodLabeling.Application.Contracts.Dtos.RbacRole;
  2 +using FoodLabeling.Application.Contracts.Dtos.Common;
  3 +using FoodLabeling.Application.Contracts.IServices;
  4 +using Microsoft.AspNetCore.Mvc;
  5 +using SqlSugar;
  6 +using Volo.Abp;
  7 +using Volo.Abp.Application.Services;
  8 +using Volo.Abp.Domain.Entities;
  9 +using Volo.Abp.Uow;
  10 +using Yi.Framework.Rbac.Domain.Entities;
  11 +using Yi.Framework.SqlSugarCore.Abstractions;
  12 +
  13 +namespace FoodLabeling.Application.Services;
  14 +
  15 +/// <summary>
  16 +/// 角色管理(食品标签-美国版对外)
  17 +/// </summary>
  18 +public class RbacRoleAppService : ApplicationService, IRbacRoleAppService
  19 +{
  20 + private readonly ISqlSugarRepository<RoleAggregateRoot, Guid> _roleRepository;
  21 + private readonly ISqlSugarRepository<RoleMenuEntity> _roleMenuRepository;
  22 + private readonly ISqlSugarRepository<RoleDeptEntity> _roleDeptRepository;
  23 + private readonly ISqlSugarRepository<UserRoleEntity> _userRoleRepository;
  24 +
  25 + public RbacRoleAppService(
  26 + ISqlSugarRepository<RoleAggregateRoot, Guid> roleRepository,
  27 + ISqlSugarRepository<RoleMenuEntity> roleMenuRepository,
  28 + ISqlSugarRepository<RoleDeptEntity> roleDeptRepository,
  29 + ISqlSugarRepository<UserRoleEntity> userRoleRepository)
  30 + {
  31 + _roleRepository = roleRepository;
  32 + _roleMenuRepository = roleMenuRepository;
  33 + _roleDeptRepository = roleDeptRepository;
  34 + _userRoleRepository = userRoleRepository;
  35 + }
  36 +
  37 + /// <inheritdoc />
  38 + public async Task<PagedResultWithPageDto<RbacRoleGetListOutputDto>> GetListAsync([FromQuery] RbacRoleGetListInputVo input)
  39 + {
  40 + RefAsync<int> total = 0;
  41 +
  42 + var query = _roleRepository._DbQueryable
  43 + .Where(x => x.IsDeleted == false)
  44 + .WhereIF(!string.IsNullOrWhiteSpace(input.RoleCode), x => x.RoleCode.Contains(input.RoleCode!.Trim()))
  45 + .WhereIF(!string.IsNullOrWhiteSpace(input.RoleName), x => x.RoleName.Contains(input.RoleName!.Trim()))
  46 + .WhereIF(input.State is not null, x => x.State == input.State);
  47 +
  48 + if (!string.IsNullOrWhiteSpace(input.Sorting))
  49 + {
  50 + query = query.OrderBy(input.Sorting);
  51 + }
  52 + else
  53 + {
  54 + query = query.OrderBy(x => x.OrderNum, OrderByType.Desc);
  55 + }
  56 +
  57 + var entities = await query.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);
  58 +
  59 + var items = entities.Select(x => new RbacRoleGetListOutputDto
  60 + {
  61 + Id = x.Id,
  62 + RoleName = x.RoleName ?? string.Empty,
  63 + RoleCode = x.RoleCode ?? string.Empty,
  64 + Remark = x.Remark,
  65 + DataScope = (int)x.DataScope,
  66 + State = x.State,
  67 + OrderNum = x.OrderNum
  68 + }).ToList();
  69 +
  70 + var pageSize = input.MaxResultCount <= 0 ? items.Count : input.MaxResultCount;
  71 + var pageIndex = pageSize <= 0 ? 1 : (input.SkipCount / pageSize) + 1;
  72 + var totalPages = pageSize <= 0 ? 0 : (int)Math.Ceiling(total / (double)pageSize);
  73 +
  74 + return new PagedResultWithPageDto<RbacRoleGetListOutputDto>
  75 + {
  76 + PageIndex = pageIndex,
  77 + PageSize = pageSize,
  78 + TotalCount = total,
  79 + TotalPages = totalPages,
  80 + Items = items
  81 + };
  82 + }
  83 +
  84 + /// <inheritdoc />
  85 + public async Task<RbacRoleGetOutputDto> GetAsync(Guid id)
  86 + {
  87 + var entity = await _roleRepository.GetSingleAsync(x => x.Id == id && x.IsDeleted == false);
  88 + if (entity is null)
  89 + {
  90 + throw new UserFriendlyException("角色不存在");
  91 + }
  92 +
  93 + return new RbacRoleGetOutputDto
  94 + {
  95 + Id = entity.Id,
  96 + RoleName = entity.RoleName ?? string.Empty,
  97 + RoleCode = entity.RoleCode ?? string.Empty,
  98 + Remark = entity.Remark,
  99 + DataScope = (int)entity.DataScope,
  100 + State = entity.State,
  101 + OrderNum = entity.OrderNum
  102 + };
  103 + }
  104 +
  105 + /// <inheritdoc />
  106 + public async Task<RbacRoleGetOutputDto> CreateAsync([FromBody] RbacRoleCreateInputVo input)
  107 + {
  108 + var roleName = input.RoleName?.Trim();
  109 + var roleCode = input.RoleCode?.Trim();
  110 + if (string.IsNullOrWhiteSpace(roleName))
  111 + {
  112 + throw new UserFriendlyException("角色名称不能为空");
  113 + }
  114 +
  115 + if (string.IsNullOrWhiteSpace(roleCode))
  116 + {
  117 + throw new UserFriendlyException("角色编码不能为空");
  118 + }
  119 +
  120 + var isExist = await _roleRepository.IsAnyAsync(x => x.RoleCode == roleCode || x.RoleName == roleName);
  121 + if (isExist)
  122 + {
  123 + throw new UserFriendlyException("角色名称或编码已存在");
  124 + }
  125 +
  126 + var entity = new RoleAggregateRoot
  127 + {
  128 + RoleName = roleName,
  129 + RoleCode = roleCode,
  130 + Remark = input.Remark?.Trim(),
  131 + DataScope = (Yi.Framework.Rbac.Domain.Shared.Enums.DataScopeEnum)input.DataScope,
  132 + State = input.State,
  133 + OrderNum = input.OrderNum
  134 + };
  135 + EntityHelper.TrySetId(entity, () => GuidGenerator.Create());
  136 +
  137 + await _roleRepository.InsertAsync(entity);
  138 +
  139 + return await GetAsync(entity.Id);
  140 + }
  141 +
  142 + /// <inheritdoc />
  143 + public async Task<RbacRoleGetOutputDto> UpdateAsync(Guid id, [FromBody] RbacRoleUpdateInputVo input)
  144 + {
  145 + var entity = await _roleRepository.GetSingleAsync(x => x.Id == id && x.IsDeleted == false);
  146 + if (entity is null)
  147 + {
  148 + throw new UserFriendlyException("角色不存在");
  149 + }
  150 +
  151 + var roleName = input.RoleName?.Trim();
  152 + var roleCode = input.RoleCode?.Trim();
  153 + if (string.IsNullOrWhiteSpace(roleName))
  154 + {
  155 + throw new UserFriendlyException("角色名称不能为空");
  156 + }
  157 +
  158 + if (string.IsNullOrWhiteSpace(roleCode))
  159 + {
  160 + throw new UserFriendlyException("角色编码不能为空");
  161 + }
  162 +
  163 + var isExist = await _roleRepository._DbQueryable
  164 + .Where(x => x.Id != entity.Id && x.IsDeleted == false)
  165 + .AnyAsync(x => x.RoleCode == roleCode || x.RoleName == roleName);
  166 + if (isExist)
  167 + {
  168 + throw new UserFriendlyException("角色名称或编码已存在");
  169 + }
  170 +
  171 + entity.RoleName = roleName;
  172 + entity.RoleCode = roleCode;
  173 + entity.Remark = input.Remark?.Trim();
  174 + entity.DataScope = (Yi.Framework.Rbac.Domain.Shared.Enums.DataScopeEnum)input.DataScope;
  175 + entity.State = input.State;
  176 + entity.OrderNum = input.OrderNum;
  177 +
  178 + await _roleRepository.UpdateAsync(entity);
  179 +
  180 + return await GetAsync(entity.Id);
  181 + }
  182 +
  183 + /// <inheritdoc />
  184 + [UnitOfWork]
  185 + public async Task DeleteAsync([FromBody] List<Guid> ids)
  186 + {
  187 + var idList = ids?.Distinct().ToList() ?? new List<Guid>();
  188 + if (idList.Count == 0)
  189 + {
  190 + return;
  191 + }
  192 +
  193 + await _roleMenuRepository.DeleteAsync(x => idList.Contains(x.RoleId));
  194 + await _roleDeptRepository.DeleteAsync(x => idList.Contains(x.RoleId));
  195 + await _userRoleRepository.DeleteAsync(x => idList.Contains(x.RoleId));
  196 +
  197 + // 角色表为软删(ISoftDelete)
  198 + await _roleRepository.DeleteAsync(x => idList.Contains(x.Id));
  199 + }
  200 +}
  201 +
... ...
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Application/Services/RbacRoleMenuAppService.cs 0 → 100644
  1 +using FoodLabeling.Application.Contracts.Dtos.RbacRoleMenu;
  2 +using FoodLabeling.Application.Contracts.IServices;
  3 +using Microsoft.AspNetCore.Mvc;
  4 +using SqlSugar;
  5 +using Volo.Abp;
  6 +using Volo.Abp.Application.Services;
  7 +using Volo.Abp.Uow;
  8 +using Yi.Framework.Rbac.Domain.Entities;
  9 +using Yi.Framework.SqlSugarCore.Abstractions;
  10 +
  11 +namespace FoodLabeling.Application.Services;
  12 +
  13 +/// <summary>
  14 +/// 角色-权限关联(食品标签-美国版对外)
  15 +/// </summary>
  16 +public class RbacRoleMenuAppService : ApplicationService, IRbacRoleMenuAppService
  17 +{
  18 + private readonly ISqlSugarRepository<RoleAggregateRoot, Guid> _roleRepository;
  19 + private readonly ISqlSugarRepository<MenuAggregateRoot, Guid> _menuRepository;
  20 + private readonly ISqlSugarRepository<RoleMenuEntity> _roleMenuRepository;
  21 +
  22 + public RbacRoleMenuAppService(
  23 + ISqlSugarRepository<RoleAggregateRoot, Guid> roleRepository,
  24 + ISqlSugarRepository<MenuAggregateRoot, Guid> menuRepository,
  25 + ISqlSugarRepository<RoleMenuEntity> roleMenuRepository)
  26 + {
  27 + _roleRepository = roleRepository;
  28 + _menuRepository = menuRepository;
  29 + _roleMenuRepository = roleMenuRepository;
  30 + }
  31 +
  32 + /// <inheritdoc />
  33 + [UnitOfWork]
  34 + public async Task SetAsync([FromBody] RbacRoleMenuSetInputVo input)
  35 + {
  36 + var role = await _roleRepository.GetSingleAsync(x => x.Id == input.RoleId && x.IsDeleted == false);
  37 + if (role is null)
  38 + {
  39 + throw new UserFriendlyException("角色不存在");
  40 + }
  41 +
  42 + var menuIds = input.MenuIds?.Distinct().ToList() ?? new List<Guid>();
  43 + if (menuIds.Count == 0)
  44 + {
  45 + // 覆盖式:传空表示清空
  46 + await _roleMenuRepository.DeleteAsync(x => x.RoleId == input.RoleId);
  47 + return;
  48 + }
  49 +
  50 + // 只允许分配未删除的菜单
  51 + var existMenuIds = await _menuRepository._DbQueryable
  52 + .Where(x => x.IsDeleted == false)
  53 + .Where(x => menuIds.Contains(x.Id))
  54 + .Select(x => x.Id)
  55 + .ToListAsync();
  56 +
  57 + await _roleMenuRepository.DeleteAsync(x => x.RoleId == input.RoleId);
  58 +
  59 + var entities = existMenuIds.Select(menuId => new RoleMenuEntity
  60 + {
  61 + RoleId = input.RoleId,
  62 + MenuId = menuId
  63 + }).ToList();
  64 +
  65 + if (entities.Count > 0)
  66 + {
  67 + await _roleMenuRepository.InsertRangeAsync(entities);
  68 + }
  69 + }
  70 +
  71 + /// <inheritdoc />
  72 + public async Task<List<Guid>> GetMenuIdsAsync([FromQuery] Guid roleId)
  73 + {
  74 + return await _roleMenuRepository._DbQueryable
  75 + .Where(x => x.RoleId == roleId)
  76 + .Select(x => x.MenuId)
  77 + .ToListAsync();
  78 + }
  79 +
  80 + /// <inheritdoc />
  81 + [UnitOfWork]
  82 + public async Task RemoveAsync([FromBody] RbacRoleMenuRemoveInputVo input)
  83 + {
  84 + var role = await _roleRepository.GetSingleAsync(x => x.Id == input.RoleId && x.IsDeleted == false);
  85 + if (role is null)
  86 + {
  87 + throw new UserFriendlyException("角色不存在");
  88 + }
  89 +
  90 + var menuIds = input.MenuIds?.Distinct().ToList() ?? new List<Guid>();
  91 + if (menuIds.Count == 0)
  92 + {
  93 + return;
  94 + }
  95 +
  96 + await _roleMenuRepository._Db.Deleteable<RoleMenuEntity>()
  97 + .Where(x => x.RoleId == input.RoleId)
  98 + .WhereIF(menuIds.Count > 0, x => menuIds.Contains(x.MenuId))
  99 + .ExecuteCommandAsync();
  100 + }
  101 +}
  102 +
... ...
美国版/Food Labeling Management Code/Yi.Abp.Net8/module/food-labeling-us/FoodLabeling.Domain/Entities/LocationAggregateRoot.cs 0 → 100644
  1 +using SqlSugar;
  2 +using Volo.Abp.Auditing;
  3 +using Volo.Abp.Domain.Entities;
  4 +using Yi.Framework.Core.Data;
  5 +
  6 +namespace FoodLabeling.Domain.Entities;
  7 +
  8 +/// <summary>
  9 +/// 门店/位置
  10 +/// </summary>
  11 +[SugarTable("location")]
  12 +public class LocationAggregateRoot : AggregateRoot<Guid>, ISoftDelete, IAuditedObject, IOrderNum, IState
  13 +{
  14 + public LocationAggregateRoot()
  15 + {
  16 + }
  17 +
  18 + public LocationAggregateRoot(Guid id)
  19 + {
  20 + Id = id;
  21 + }
  22 +
  23 + /// <summary>
  24 + /// 主键
  25 + /// </summary>
  26 + [SugarColumn(IsPrimaryKey = true)]
  27 + public override Guid Id { get; protected set; }
  28 +
  29 + /// <summary>
  30 + /// 逻辑删除
  31 + /// </summary>
  32 + public bool IsDeleted { get; set; }
  33 +
  34 + /// <summary>
  35 + /// 创建时间
  36 + /// </summary>
  37 + public DateTime CreationTime { get; set; } = DateTime.Now;
  38 +
  39 + /// <summary>
  40 + /// 创建者
  41 + /// </summary>
  42 + public Guid? CreatorId { get; set; }
  43 +
  44 + /// <summary>
  45 + /// 最后修改者
  46 + /// </summary>
  47 + public Guid? LastModifierId { get; set; }
  48 +
  49 + /// <summary>
  50 + /// 最后修改时间
  51 + /// </summary>
  52 + public DateTime? LastModificationTime { get; set; }
  53 +
  54 + /// <summary>
  55 + /// 排序
  56 + /// </summary>
  57 + public int OrderNum { get; set; } = 0;
  58 +
  59 + /// <summary>
  60 + /// 启用状态
  61 + /// </summary>
  62 + public bool State { get; set; } = true;
  63 +
  64 + /// <summary>
  65 + /// Partner(原型中的 Partner 下拉)
  66 + /// </summary>
  67 + public string? Partner { get; set; }
  68 +
  69 + /// <summary>
  70 + /// Group(原型中的 Group 下拉)
  71 + /// </summary>
  72 + [SugarColumn(ColumnName = "GroupName")]
  73 + public string? GroupName { get; set; }
  74 +
  75 + /// <summary>
  76 + /// Location ID(业务编码)
  77 + /// </summary>
  78 + [SugarColumn(ColumnName = "LocationCode")]
  79 + public string LocationCode { get; set; } = string.Empty;
  80 +
  81 + /// <summary>
  82 + /// Location Name
  83 + /// </summary>
  84 + [SugarColumn(ColumnName = "LocationName")]
  85 + public string LocationName { get; set; } = string.Empty;
  86 +
  87 + /// <summary>
  88 + /// Street
  89 + /// </summary>
  90 + public string? Street { get; set; }
  91 +
  92 + /// <summary>
  93 + /// City
  94 + /// </summary>
  95 + public string? City { get; set; }
  96 +
  97 + /// <summary>
  98 + /// State(如 NY)
  99 + /// </summary>
  100 + [SugarColumn(ColumnName = "StateCode")]
  101 + public string? StateCode { get; set; }
  102 +
  103 + /// <summary>
  104 + /// Country
  105 + /// </summary>
  106 + public string? Country { get; set; }
  107 +
  108 + /// <summary>
  109 + /// Zip Code
  110 + /// </summary>
  111 + [SugarColumn(ColumnName = "ZipCode")]
  112 + public string? ZipCode { get; set; }
  113 +
  114 + /// <summary>
  115 + /// Phone
  116 + /// </summary>
  117 + public string? Phone { get; set; }
  118 +
  119 + /// <summary>
  120 + /// Email
  121 + /// </summary>
  122 + public string? Email { get; set; }
  123 +
  124 + /// <summary>
  125 + /// Latitude
  126 + /// </summary>
  127 + public decimal? Latitude { get; set; }
  128 +
  129 + /// <summary>
  130 + /// Longitude
  131 + /// </summary>
  132 + public decimal? Longitude { get; set; }
  133 +}
  134 +
... ...
项目相关文档/门店(Location)接口对接说明.md 0 → 100644
  1 +## 概述
  2 +
  3 +美国版后端采用 ABP 动态接口(ConventionalControllers),宿主统一前缀为 `api/app`,Swagger 地址为:
  4 +
  5 +- `http://localhost:19001/swagger`
  6 +
  7 +门店模块的服务类为 `LocationAppService`(模块:`food-labeling-us`)。
  8 +
  9 +> 说明:接口的最终 URL 以 Swagger 展示为准(在 Swagger 里搜索 `Location` 或 `LocationAppService` 即可)。
  10 +
  11 +---
  12 +
  13 +## 数据库表
  14 +
  15 +表名:`location`
  16 +
  17 +核心字段(与原型一致):
  18 +
  19 +- Partner:`Partner`
  20 +- Group:`GroupName`
  21 +- Location ID:`LocationCode`
  22 +- Location Name:`LocationName`
  23 +- Street/City/State/Country/Zip:`Street`/`City`/`StateCode`/`Country`/`ZipCode`
  24 +- Phone/Email:`Phone`/`Email`
  25 +- GPS:`Latitude`/`Longitude`
  26 +- Active Location:`State`(1=启用,0=停用)
  27 +
  28 +---
  29 +
  30 +## 接口 1:门店分页列表
  31 +
  32 +### 方法签名
  33 +
  34 +`Task<PagedResultDto<LocationGetListOutputDto>> GetListAsync(LocationGetListInputVo input)`
  35 +
  36 +### 入参(LocationGetListInputVo)
  37 +
  38 +- `SkipCount`:跳过条数(分页用)
  39 +- `MaxResultCount`:每页条数(分页用)
  40 +- `Sorting`:排序字段(可选;不传默认按 CreationTime 倒序)
  41 +- `Keyword`:关键字模糊搜索(会匹配 LocationCode/LocationName/Street/City/StateCode/Country/ZipCode/Phone/Email)
  42 +- `Partner`:Partner 精确过滤(可选)
  43 +- `GroupName`:Group 精确过滤(可选)
  44 +- `State`:启用状态过滤(可选,true/false)
  45 +
  46 +### 出参(PagedResultDto<LocationGetListOutputDto>)
  47 +
  48 +- `TotalCount`:总数
  49 +- `Items`:列表
  50 +
  51 +`LocationGetListOutputDto` 字段:
  52 +
  53 +- `Id`
  54 +- `Partner`
  55 +- `GroupName`
  56 +- `LocationCode`
  57 +- `LocationName`
  58 +- `Street`
  59 +- `City`
  60 +- `StateCode`
  61 +- `Country`
  62 +- `ZipCode`
  63 +- `Phone`
  64 +- `Email`
  65 +- `Latitude`
  66 +- `Longitude`
  67 +- `State`
  68 +
  69 +---
  70 +
  71 +## 接口 2:新增门店
  72 +
  73 +### 方法签名
  74 +
  75 +`Task<LocationGetListOutputDto> CreateAsync(LocationCreateInputVo input)`
  76 +
  77 +### 入参(LocationCreateInputVo)
  78 +
  79 +- `Partner`:可选
  80 +- `GroupName`:可选
  81 +- `LocationCode`:必填(唯一,重复会报错)
  82 +- `LocationName`:必填
  83 +- `Street/City/StateCode/Country/ZipCode`:可选
  84 +- `Phone/Email`:可选
  85 +- `Latitude/Longitude`:可选(decimal)
  86 +- `State`:是否启用(默认 true)
  87 +
  88 +### 校验规则
  89 +
  90 +- `LocationCode` 不能为空,且唯一
  91 +- `LocationName` 不能为空
  92 +
  93 +---
  94 +
  95 +## Swagger 中如何找到
  96 +
  97 +1. 启动后端宿主(`Yi.Abp.Web`),确保端口为 `19001`
  98 +2. 打开 `http://localhost:19001/swagger`
  99 +3. 在接口分组里找到 **“食品标签-美国版接口”** 或直接搜索 `Location`
  100 +4. 查看 `LocationAppService` 的 `GetListAsync` 与 `CreateAsync`
  101 +
... ...