新增国家、州省地区的API

This commit is contained in:
2025-12-25 00:59:03 +08:00
parent e396e66959
commit 53b6ceaa69
45 changed files with 669 additions and 87 deletions

View File

@@ -0,0 +1,8 @@
using Atomx.Common.Entities;
namespace Atomx.Admin.Client.Models
{
public class AreaModel:Area
{
}
}

View File

@@ -0,0 +1,9 @@
namespace Atomx.Admin.Client.Models
{
public class AreaSearch : BaseSearch
{
public long CountryId { get; set; }
public long StateProvinceId { get; set; }
public string Name { get; set; } = string.Empty;
}
}

View File

@@ -0,0 +1,8 @@
using Atomx.Common.Entities;
namespace Atomx.Admin.Client.Models
{
public class CountryModel:Country
{
}
}

View File

@@ -0,0 +1,7 @@
namespace Atomx.Admin.Client.Models
{
public class CountrySearch
{
public string Name { get; set; } = string.Empty;
}
}

View File

@@ -0,0 +1,8 @@
using Atomx.Common.Entities;
namespace Atomx.Admin.Client.Models
{
public class StateProvinceModel: StateProvince
{
}
}

View File

@@ -0,0 +1,8 @@
namespace Atomx.Admin.Client.Models
{
public class StateProvinceSearch
{
public long CountryId { get; set; }
public string Name { get; set; } = string.Empty;
}
}

View File

@@ -120,8 +120,6 @@
bool searchExpand { get; set; } = false;
private bool drawerVisible;
SpecificationAttributeOptionModelValidator validator = new();
protected override void OnInitialized()
{
base.OnInitialized();

View File

@@ -1,11 +1,12 @@
using Atomx.Admin.Client.Models;
using FluentValidation;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Client.Validators
{
public class AddressModelValidator : AbstractValidator<AddressModel>
{
public AddressModelValidator()
public AddressModelValidator(IStringLocalizer<AddressModelValidator> localizer)
{
RuleFor(p => p.Name).NotEmpty().WithMessage("请填写收件人信息");
RuleFor(p => p.Email).EmailAddress().When(p => !string.IsNullOrEmpty(p.Email)).WithMessage("请填写你常用的邮箱地址");

View File

@@ -1,11 +1,12 @@
using Atomx.Admin.Client.Models;
using FluentValidation;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Client.Validators
{
public class AdminModelValidator : AbstractValidator<AdminModel>
{
public AdminModelValidator()
public AdminModelValidator(IStringLocalizer<AdminModelValidator> localizer)
{
RuleFor(p => p.Username).NotEmpty().WithMessage("用户名不能为空");
RuleFor(p => p.Username).Length(2, 64).When(p => !string.IsNullOrEmpty(p.Username)).WithMessage("用户名长度必须再2-64个字符之间");

View File

@@ -0,0 +1,14 @@
using Atomx.Admin.Client.Models;
using FluentValidation;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Client.Validators
{
public class AreaModelValidator : AbstractValidator<AreaModel>
{
public AreaModelValidator(IStringLocalizer<AreaModelValidator> localizer)
{
RuleFor(p => p.Name).NotEmpty().WithMessage("请填名称信息");
}
}
}

View File

@@ -1,12 +1,12 @@
using Atomx.Admin.Client.Models;
using Atomx.Common.Enums;
using FluentValidation;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Client.Validators
{
public class CategoryModelValidator : AbstractValidator<CategoryModel>
{
public CategoryModelValidator()
public CategoryModelValidator(IStringLocalizer<CategoryModelValidator> localizer)
{
RuleFor(p => p.Name).NotEmpty().WithMessage("名称不能为空");
RuleFor(p => p.ParentId).Must((p,id)=> ValidateParent(id,p)).WithMessage("不能选择自己做上级分类");

View File

@@ -1,11 +1,12 @@
using Atomx.Admin.Client.Models;
using FluentValidation;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Client.Validators
{
public class CorporationModelValidator : AbstractValidator<CorporationModel>
{
public CorporationModelValidator()
public CorporationModelValidator(IStringLocalizer<CorporationModelValidator> localizer)
{
RuleFor(p => p.Name).NotEmpty().WithMessage("公司名称不能为空");
}

View File

@@ -1,11 +1,12 @@
using Atomx.Admin.Client.Models;
using FluentValidation;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Client.Validators
{
public class CorporationStaffModelValidator : AbstractValidator<CorporationStaffModel>
{
public CorporationStaffModelValidator()
public CorporationStaffModelValidator(IStringLocalizer<CorporationStaffModelValidator> localizer)
{
RuleFor(p => p.Username).NotEmpty().WithMessage("用户名不能为空");
RuleFor(p => p.Username).Length(2, 64).When(p => !string.IsNullOrEmpty(p.Username)).WithMessage("用户名长度必须再2-64个字符之间");

View File

@@ -0,0 +1,14 @@
using Atomx.Admin.Client.Models;
using FluentValidation;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Client.Validators
{
public class CountryModelValidator : AbstractValidator<CountryModel>
{
public CountryModelValidator(IStringLocalizer<CountryModelValidator> localizer)
{
RuleFor(p => p.Name).NotEmpty().WithMessage("请填名称信息");
}
}
}

View File

@@ -1,11 +1,12 @@
using Atomx.Admin.Client.Models;
using FluentValidation;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Client.Validators
{
public class CurrencyModelValidator : AbstractValidator<CurrencyModel>
{
public CurrencyModelValidator()
public CurrencyModelValidator(IStringLocalizer<CurrencyModelValidator> localizer)
{
RuleFor(p => p.Name).NotEmpty().WithMessage("请填写货币名称");
}

View File

@@ -1,11 +1,12 @@
using Atomx.Common.Configuration;
using FluentValidation;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Client.Validators
{
public class GeneralConfigValidator : AbstractValidator<GeneralConfig>
{
public GeneralConfigValidator()
public GeneralConfigValidator(IStringLocalizer<GeneralConfigValidator> localizer)
{
RuleFor(p => p.Name).NotEmpty().WithMessage("网站名称不能为空");
}

View File

@@ -1,11 +1,12 @@
using Atomx.Admin.Client.Models;
using FluentValidation;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Client.Validators
{
public class LanguageModelValidator : AbstractValidator<LanguageModel>
{
public LanguageModelValidator()
public LanguageModelValidator(IStringLocalizer<LanguageModelValidator> localizer)
{
RuleFor(p => p.Title).NotEmpty().WithMessage("请填写语言标题");
RuleFor(p => p.Name).NotEmpty().WithMessage("请填写语言名称");

View File

@@ -1,11 +1,12 @@
using Atomx.Admin.Client.Models;
using FluentValidation;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Client.Validators
{
public class LocaleResourceModelValidator : AbstractValidator<LocaleResourceModel>
{
public LocaleResourceModelValidator()
public LocaleResourceModelValidator(IStringLocalizer<LocaleResourceModelValidator> localizer)
{
RuleFor(p => p.Name).NotEmpty().WithMessage("本地化多语言信息不能为空");
}

View File

@@ -1,11 +1,12 @@
using Atomx.Admin.Client.Models;
using FluentValidation;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Client.Validators
{
public class ManufacturerModelValidator : AbstractValidator<ManufacturerModel>
{
public ManufacturerModelValidator()
public ManufacturerModelValidator(IStringLocalizer<ManufacturerModelValidator> localizer)
{
RuleFor(p => p.Name).NotEmpty().WithMessage("名称不能为空");
}

View File

@@ -1,12 +1,13 @@
using Atomx.Admin.Client.Models;
using Atomx.Common.Models;
using FluentValidation;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Client.Validators
{
public class MenuModelValidator : AbstractValidator<MenuModel>
{
public MenuModelValidator()
public MenuModelValidator(IStringLocalizer<MenuModelValidator> localizer)
{
RuleFor(p => p.Name).NotEmpty().WithMessage("名称不能为空");
}

View File

@@ -1,11 +1,12 @@
using Atomx.Admin.Client.Models;
using FluentValidation;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Client.Validators
{
public class ProductAddStockModelValidator : AbstractValidator<ProductAddStockModel>
{
public ProductAddStockModelValidator()
public ProductAddStockModelValidator(IStringLocalizer<ProductAddStockModelValidator> localizer)
{
//RuleFor(p => p.Username).NotEmpty().WithMessage("用户名不能为空");
//RuleFor(p => p.Username).Length(2, 64).When(p => !string.IsNullOrEmpty(p.Username)).WithMessage("用户名长度必须再2-64个字符之间");

View File

@@ -1,11 +1,12 @@
using Atomx.Admin.Client.Models;
using FluentValidation;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Client.Validators
{
public class ProductAttributeModelValidator : AbstractValidator<ProductAttributeModel>
{
public ProductAttributeModelValidator()
public ProductAttributeModelValidator(IStringLocalizer<ProductAttributeModelValidator> localizer)
{
RuleFor(p => p.Name).NotEmpty().WithMessage("名称不能为空");
RuleFor(p => p.Status).GreaterThan(0).WithMessage("请设置正确的状态");

View File

@@ -1,11 +1,12 @@
using Atomx.Admin.Client.Models;
using FluentValidation;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Client.Validators
{
public class ProductAttributeOptionModelValidator : AbstractValidator<ProductAttributeOptionModel>
{
public ProductAttributeOptionModelValidator()
public ProductAttributeOptionModelValidator(IStringLocalizer<ProductAttributeOptionModelValidator> localizer)
{
RuleFor(p => p.Value).NotEmpty().WithMessage("数值不能为空");
RuleFor(p => p.Status).GreaterThan(0).WithMessage("请设置正确的状态");

View File

@@ -1,11 +1,12 @@
using Atomx.Admin.Client.Models;
using FluentValidation;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Client.Validators
{
public class ProductModelValidator : AbstractValidator<ProductModel>
{
public ProductModelValidator()
public ProductModelValidator(IStringLocalizer<ProductModelValidator> localizer)
{
RuleFor(p => p.Title).NotEmpty().WithMessage("商品标题不能为空");
}

View File

@@ -1,11 +1,12 @@
using Atomx.Admin.Client.Models;
using FluentValidation;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Client.Validators
{
public class RoleModelValidator : AbstractValidator<RoleModel>
{
public RoleModelValidator()
public RoleModelValidator(IStringLocalizer<RoleModelValidator> localizer)
{
RuleFor(p => p.Name).NotEmpty().WithMessage("角色名称不能为空");
}

View File

@@ -1,11 +1,12 @@
using Atomx.Common.Entities;
using FluentValidation;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Client.Validators
{
public class RoleValidator : AbstractValidator<Role>
{
public RoleValidator()
public RoleValidator(IStringLocalizer<RoleValidator> localizer)
{
RuleFor(p => p.Name).NotEmpty().WithMessage("角色名称不能为空");
}

View File

@@ -1,11 +1,12 @@
using Atomx.Admin.Client.Models;
using FluentValidation;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Client.Validators
{
public class SiteAppModelValidator : AbstractValidator<SiteAppModel>
{
public SiteAppModelValidator()
public SiteAppModelValidator(IStringLocalizer<SiteAppModelValidator> localizer)
{
RuleFor(p => p.Name).NotEmpty().WithMessage("请填写网站应用名称");
}

View File

@@ -1,11 +1,12 @@
using Atomx.Admin.Client.Models;
using FluentValidation;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Client.Validators
{
public class SpecificationAttributeModelValidator : AbstractValidator<SpecificationAttributeModel>
{
public SpecificationAttributeModelValidator()
public SpecificationAttributeModelValidator(IStringLocalizer<SpecificationAttributeModelValidator> localizer)
{
RuleFor(p => p.Name).NotEmpty().WithMessage("名称不能为空");
RuleFor(p => p.Status).GreaterThan(0).WithMessage("请设置正确的状态");

View File

@@ -1,11 +1,12 @@
using Atomx.Admin.Client.Models;
using FluentValidation;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Client.Validators
{
public class SpecificationAttributeOptionModelValidator : AbstractValidator<SpecificationAttributeOptionModel>
{
public SpecificationAttributeOptionModelValidator()
public SpecificationAttributeOptionModelValidator(IStringLocalizer<SpecificationAttributeOptionModelValidator> localizer)
{
RuleFor(p => p.Value).NotEmpty().WithMessage("数值不能为空");
RuleFor(p => p.Status).GreaterThan(0).WithMessage("请设置正确的状态");

View File

@@ -0,0 +1,14 @@
using Atomx.Admin.Client.Models;
using FluentValidation;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Client.Validators
{
public class StateProvinceValidator : AbstractValidator<StateProvinceModel>
{
public StateProvinceValidator(IStringLocalizer<StateProvinceValidator> localizer)
{
RuleFor(p => p.Name).NotEmpty().WithMessage("请填名称信息");
}
}
}

View File

@@ -1,11 +1,12 @@
using Atomx.Admin.Client.Models;
using FluentValidation;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Client.Validators
{
public class UploadFileModelValidator : AbstractValidator<UploadFileModel>
{
public UploadFileModelValidator()
public UploadFileModelValidator(IStringLocalizer<UploadFileModelValidator> localizer)
{
RuleFor(p => p.Name).NotEmpty().WithMessage("文件名称不能为空");
}

View File

@@ -1,11 +1,12 @@
using Atomx.Common.Entities;
using FluentValidation;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Client.Validators
{
public class UserValidator : AbstractValidator<User>
{
public UserValidator()
public UserValidator(IStringLocalizer<UserValidator> localizer)
{
RuleFor(p => p.Name).NotEmpty().WithMessage("名称不能为空");
}

View File

@@ -1,11 +1,12 @@
using Atomx.Admin.Client.Models;
using FluentValidation;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Client.Validators
{
public class WarehouseModelValidator : AbstractValidator<WarehouseModel>
{
public WarehouseModelValidator()
public WarehouseModelValidator(IStringLocalizer<WarehouseModelValidator> localizer)
{
RuleFor(p => p.Name).NotEmpty().WithMessage("用户名不能为空");
}

View File

@@ -7,10 +7,12 @@ using Atomx.Common.Models;
using Atomx.Data;
using Atomx.Data.CacheServices;
using Atomx.Data.Services;
using FluentValidation;
using MapsterMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Controllers
{
@@ -25,7 +27,8 @@ namespace Atomx.Admin.Controllers
private readonly IIdentityService _identityService;
private readonly IMapper _mapper;
private readonly ICacheService _cacheService;
readonly IValidator<AddressModel> _validator;
readonly IStringLocalizer<AddressController> _localizer;
/// <summary>
///
@@ -37,7 +40,7 @@ namespace Atomx.Admin.Controllers
/// <param name="mapper"></param>
/// <param name="jwtSettings"></param>
/// <param name="cacheService"></param>
public AddressController(ILogger<AddressController> logger, IIdCreatorService idCreator, IIdentityService identityService, DataContext dbContext, IMapper mapper, ICacheService cacheService)
public AddressController(ILogger<AddressController> logger, IIdCreatorService idCreator, IIdentityService identityService, DataContext dbContext, IMapper mapper, ICacheService cacheService, IValidator<AddressModel> validator, IStringLocalizer<AddressController> localizer)
{
_logger = logger;
_idCreator = idCreator;
@@ -45,6 +48,8 @@ namespace Atomx.Admin.Controllers
_dbContext = dbContext;
_mapper = mapper;
_cacheService = cacheService;
_validator = validator;
_localizer = localizer;
}
/// <summary>
@@ -106,8 +111,7 @@ namespace Atomx.Admin.Controllers
public IActionResult AddressEdit(AddressModel model)
{
var result = new ApiResult<bool>();
var validator = new AddressModelValidator();
var validation = validator.Validate(model);
var validation = _validator.Validate(model);
if (!validation.IsValid)
{
result.Message = ModelState.Values.First().Errors[0].ErrorMessage;

View File

@@ -6,10 +6,12 @@ using Atomx.Common.Models;
using Atomx.Data;
using Atomx.Data.Services;
using Atomx.Utils.Extension;
using FluentValidation;
using MapsterMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Controllers
{
@@ -23,6 +25,8 @@ namespace Atomx.Admin.Controllers
readonly IIdCreatorService _idCreator;
readonly IMapper _mapper;
readonly DataContext _dbContext;
readonly IValidator<AdminModel> _validator;
readonly IStringLocalizer<AdminController> _localizer;
/// <summary>
///
@@ -32,13 +36,15 @@ namespace Atomx.Admin.Controllers
/// <param name="idCreator"></param>
/// <param name="adminService"></param>
/// <param name="mapper"></param>
public AdminController(ILogger<AdminController> logger, IIdentityService identityService, IIdCreatorService idCreator, IMapper mapper, DataContext dataContext)
public AdminController(ILogger<AdminController> logger, IIdentityService identityService, IIdCreatorService idCreator, IMapper mapper, DataContext dataContext, IValidator<AdminModel> validator, IStringLocalizer<AdminController> localizer)
{
_logger = logger;
_identityService = identityService;
_idCreator = idCreator;
_mapper = mapper;
_dbContext = dataContext;
_validator = validator;
_localizer = localizer;
}
/// <summary>
@@ -49,7 +55,7 @@ namespace Atomx.Admin.Controllers
/// <param name="size"></param>
/// <returns></returns>
[HttpPost("search")]
[Authorize(Policy =Permissions.Admin.View)]
[Authorize(Policy = Permissions.Admin.View)]
public IActionResult Search(AdminSearch search, int page, int size = 20)
{
var startTime = search.RangeTime[0];
@@ -158,8 +164,7 @@ namespace Atomx.Admin.Controllers
public IActionResult Add(AdminModel model)
{
var result = new ApiResult<string>();
var validator = new AdminModelValidator();
var validation = validator.Validate(model);
var validation = _validator.Validate(model);
if (!validation.IsValid)
{
var message = validation.Errors.FirstOrDefault()?.ErrorMessage ?? string.Empty;
@@ -211,8 +216,7 @@ namespace Atomx.Admin.Controllers
public IActionResult Edit(AdminModel model)
{
var result = new ApiResult<string>();
var validator = new AdminModelValidator();
var validation = validator.Validate(model);
var validation = _validator.Validate(model);
if (!validation.IsValid)
{
var message = validation.Errors.FirstOrDefault()?.ErrorMessage;

View File

@@ -1,10 +1,17 @@
using Atomx.Admin.Services;
using Atomx.Admin.Client.Models;
using Atomx.Admin.Services;
using Atomx.Common.Constants;
using Atomx.Common.Entities;
using Atomx.Common.Models;
using Atomx.Data;
using Atomx.Data.CacheServices;
using Atomx.Data.Services;
using FluentValidation;
using MapsterMapper;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Controllers
{
@@ -13,6 +20,7 @@ namespace Atomx.Admin.Controllers
/// </summary>
[Route("api/[controller]")]
[ApiController]
[Authorize]
public class AreaController : ControllerBase
{
private readonly ILogger<AreaController> _logger;
@@ -21,7 +29,8 @@ namespace Atomx.Admin.Controllers
private readonly IIdentityService _identityService;
private readonly IMapper _mapper;
private readonly ICacheService _cacheService;
readonly IValidator<AreaModel> _validator;
readonly IStringLocalizer<AreaController> _localizer;
/// <summary>
///
@@ -33,7 +42,7 @@ namespace Atomx.Admin.Controllers
/// <param name="mapper"></param>
/// <param name="jwtSettings"></param>
/// <param name="cacheService"></param>
public AreaController(ILogger<AreaController> logger, IIdCreatorService idCreator, IIdentityService identityService, DataContext dbContext, IMapper mapper, ICacheService cacheService)
public AreaController(ILogger<AreaController> logger, IIdCreatorService idCreator, IIdentityService identityService, DataContext dbContext, IMapper mapper, ICacheService cacheService, IValidator<AreaModel> validator, IStringLocalizer<AreaController> localizer)
{
_logger = logger;
_idCreator = idCreator;
@@ -41,6 +50,125 @@ namespace Atomx.Admin.Controllers
_dbContext = dbContext;
_mapper = mapper;
_cacheService = cacheService;
_validator = validator;
_localizer = localizer;
}
/// <summary>
/// 数据查询
/// </summary>
/// <param name="search"></param>
/// <param name="page"></param>
/// <param name="size"></param>
/// <returns></returns>
[HttpPost("searh")]
[Authorize(Policy = Permissions.User.View)]
public IActionResult AddressList(AreaSearch search, int page, int size = 20)
{
if (page < 1)
{
page = 1;
}
var result = new ApiResult<PagingList<Area>>();
var list = new PagingList<Area>() { Index = page, Size = size };
var query = from p in _dbContext.Areas
select p;
if (!string.IsNullOrEmpty(search.Name))
{
query = from p in query
where p.Name.Contains(search.Name)
select p;
}
if (search.CountryId > 0)
{
query = from p in query
where p.CountryId == search.CountryId
select p;
}
if (search.StateProvinceId > 0)
{
query = from p in query
where p.StateProvinceId == search.StateProvinceId
select p;
}
list.Count = query.Count();
list.Items = query.OrderByDescending(p => p.DisplayOrder).Skip((page - 1) * size).Take(size).ToList();
result = result.IsSuccess(list);
return new JsonResult(result);
}
/// <summary>
/// 新增编辑数据
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
[HttpPost("save")]
public IActionResult AddressEdit(AreaModel model)
{
var result = new ApiResult<bool>();
var validation = _validator.Validate(model);
if (!validation.IsValid)
{
var message = validation.Errors.FirstOrDefault()?.ErrorMessage ?? string.Empty;
return new JsonResult(new ApiResult<string>().IsFail(message, null));
}
var data = _dbContext.Areas.SingleOrDefault(p => p.CountryId == model.CountryId && p.StateProvinceId == model.StateProvinceId && p.Name == model.Name && p.Id != model.Id);
if (data != null)
{
return new JsonResult(new ApiResult<string>().IsFail("当前站点语言下已经存在这个配置,请认真检查", null));
}
if (model.Id > 0)
{
data = _dbContext.Areas.SingleOrDefault(p => p.Id == model.Id);
if (data == null)
{
return new JsonResult(new ApiResult<string>().IsFail("数据不存在", null));
}
data = _mapper.Map(model, data);
_dbContext.SaveChanges();
}
else
{
data = _mapper.Map<Area>(model);
data.Id = _idCreator.CreateId();
_dbContext.Areas.Add(data);
_dbContext.SaveChanges();
}
return new JsonResult(new ApiResult<string>().IsSuccess("操作成功"));
}
/// <summary>
/// 删除数据
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
[HttpPost("delete")]
public async Task<IActionResult> DeleteAsync(long id)
{
var result = new ApiResult<string>();
try
{
Console.WriteLine($"{id} deleted");
var count = _dbContext.Areas.Where(p => p.Id == id).ExecuteDelete();
result = result.IsSuccess(count.ToString());
}
catch (Exception ex)
{
result = result.IsFail(ex.Message);
_logger.LogError(ex.Message);
}
return new JsonResult(result);
}
}

View File

@@ -6,8 +6,10 @@ using Atomx.Common.Models;
using Atomx.Data;
using Atomx.Data.CacheServices;
using Atomx.Data.Services;
using FluentValidation;
using MapsterMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Controllers
{
@@ -22,8 +24,10 @@ namespace Atomx.Admin.Controllers
readonly DataContext _dbContext;
readonly JwtSetting _jwtSetting;
readonly ICacheService _cacheService;
readonly IValidator<CategoryModel> _validator;
readonly IStringLocalizer<CategoryController> _localizer;
public CategoryController(ILogger<CategoryController> logger, IIdentityService identityService, IIdCreatorService idCreator, IMapper mapper, DataContext dbContext, JwtSetting jwtSetting, ICacheService cacheService)
public CategoryController(ILogger<CategoryController> logger, IIdentityService identityService, IIdCreatorService idCreator, IMapper mapper, DataContext dbContext, JwtSetting jwtSetting, ICacheService cacheService, IValidator<CategoryModel> validator, IStringLocalizer<CategoryController> localizer)
{
_logger = logger;
_identityService = identityService;
@@ -32,6 +36,8 @@ namespace Atomx.Admin.Controllers
_dbContext = dbContext;
_jwtSetting = jwtSetting;
_cacheService = cacheService;
_validator = validator;
_localizer = localizer;
}
/// <summary>
@@ -148,8 +154,7 @@ namespace Atomx.Admin.Controllers
public IActionResult Add(CategoryModel model)
{
var result = new ApiResult<string>();
var validator = new CategoryModelValidator();
var validation = validator.Validate(model);
var validation = _validator.Validate(model);
if (!validation.IsValid)
{
var message = validation.Errors.FirstOrDefault()?.ErrorMessage;
@@ -197,8 +202,7 @@ namespace Atomx.Admin.Controllers
public IActionResult Edit(CategoryModel model)
{
var result = new ApiResult<string>();
var validator = new CategoryModelValidator();
var validation = validator.Validate(model);
var validation = _validator.Validate(model);
if (!validation.IsValid)
{
var message = validation.Errors.FirstOrDefault()?.ErrorMessage;

View File

@@ -0,0 +1,161 @@
using Atomx.Admin.Client.Models;
using Atomx.Admin.Services;
using Atomx.Common.Constants;
using Atomx.Common.Entities;
using Atomx.Common.Models;
using Atomx.Data;
using Atomx.Data.CacheServices;
using Atomx.Data.Services;
using FluentValidation;
using MapsterMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Controllers
{
[Route("api/[controller]")]
[ApiController]
[Authorize]
public class CountryController : ControllerBase
{
private readonly ILogger<CountryController> _logger;
private readonly DataContext _dbContext;
private readonly IIdCreatorService _idCreator;
private readonly IIdentityService _identityService;
private readonly IMapper _mapper;
private readonly ICacheService _cacheService;
readonly IValidator<CountryModel> _validator;
readonly IStringLocalizer<CountryController> _localizer;
/// <summary>
///
/// </summary>
/// <param name="logger"></param>
/// <param name="idCreator"></param>
/// <param name="identityService"></param>
/// <param name="dbContext"></param>
/// <param name="mapper"></param>
/// <param name="jwtSettings"></param>
/// <param name="cacheService"></param>
public CountryController(ILogger<CountryController> logger, IIdCreatorService idCreator, IIdentityService identityService, DataContext dbContext, IMapper mapper, ICacheService cacheService, IValidator<CountryModel> validator, IStringLocalizer<CountryController> localizer)
{
_logger = logger;
_idCreator = idCreator;
_identityService = identityService;
_dbContext = dbContext;
_mapper = mapper;
_cacheService = cacheService;
_validator = validator;
_localizer = localizer;
}
/// <summary>
/// 数据查询
/// </summary>
/// <param name="search"></param>
/// <param name="page"></param>
/// <param name="size"></param>
/// <returns></returns>
[HttpPost("searh")]
[Authorize(Policy = Permissions.User.View)]
public IActionResult AddressList(CountrySearch search, int page, int size = 20)
{
if (page < 1)
{
page = 1;
}
var result = new ApiResult<PagingList<Country>>();
var list = new PagingList<Country>() { Index = page, Size = size };
var query = from p in _dbContext.Countries
select p;
if (!string.IsNullOrEmpty(search.Name))
{
query = from p in query
where p.Name.Contains(search.Name)
select p;
}
list.Count = query.Count();
list.Items = query.OrderByDescending(p => p.DisplayOrder).Skip((page - 1) * size).Take(size).ToList();
result = result.IsSuccess(list);
return new JsonResult(result);
}
/// <summary>
/// 新增编辑数据
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
[HttpPost("save")]
public IActionResult AddressEdit(CountryModel model)
{
var result = new ApiResult<bool>();
var validation = _validator.Validate(model);
if (!validation.IsValid)
{
var message = validation.Errors.FirstOrDefault()?.ErrorMessage ?? string.Empty;
return new JsonResult(new ApiResult<string>().IsFail(message, null));
}
var data = _dbContext.Countries.SingleOrDefault(p => p.Name == model.Name && p.Id != model.Id);
if (data != null)
{
return new JsonResult(new ApiResult<string>().IsFail("当前数据名称,请认真检查", null));
}
if (model.Id > 0)
{
data = _dbContext.Countries.SingleOrDefault(p => p.Id == model.Id);
if (data == null)
{
return new JsonResult(new ApiResult<string>().IsFail("数据不存在", null));
}
data = _mapper.Map(model, data);
_dbContext.SaveChanges();
}
else
{
data = _mapper.Map<Country>(model);
data.Id = _idCreator.CreateId();
_dbContext.Countries.Add(data);
_dbContext.SaveChanges();
}
return new JsonResult(new ApiResult<string>().IsSuccess("操作成功"));
}
/// <summary>
/// 删除数据
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
[HttpPost("delete")]
public async Task<IActionResult> DeleteAsync(long id)
{
var result = new ApiResult<string>();
try
{
Console.WriteLine($"{id} deleted");
var count = _dbContext.Countries.Where(p => p.Id == id).ExecuteDelete();
result = result.IsSuccess(count.ToString());
}
catch (Exception ex)
{
result = result.IsFail(ex.Message);
_logger.LogError(ex.Message);
}
return new JsonResult(result);
}
}
}

View File

@@ -6,10 +6,12 @@ using Atomx.Common.Models;
using Atomx.Data;
using Atomx.Data.CacheServices;
using Atomx.Data.Services;
using FluentValidation;
using MapsterMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Controllers
{
@@ -25,8 +27,8 @@ namespace Atomx.Admin.Controllers
private readonly IMapper _mapper;
private readonly JwtSetting _jwtSettings;
private readonly ICacheService _cacheService;
private readonly LocalizationFile _localizationFile;
readonly IValidator<LanguageModel> _validator;
readonly IStringLocalizer<LanguageController> _localizer;
/// <summary>
///
@@ -38,7 +40,8 @@ namespace Atomx.Admin.Controllers
/// <param name="mapper"></param>
/// <param name="jwtSettings"></param>
/// <param name="cacheService"></param>
public LanguageController(ILogger<LanguageController> logger, IIdCreatorService idCreator, IIdentityService identityService, DataContext dbContext, IMapper mapper, JwtSetting jwtSettings, ICacheService cacheService, LocalizationFile localizationFile)
public LanguageController(ILogger<LanguageController> logger, IIdCreatorService idCreator, IIdentityService identityService, DataContext dbContext, IMapper mapper,
JwtSetting jwtSettings, ICacheService cacheService, IValidator<LanguageModel> validator, IStringLocalizer<LanguageController> localizer)
{
_logger = logger;
_idCreator = idCreator;
@@ -47,7 +50,8 @@ namespace Atomx.Admin.Controllers
_mapper = mapper;
_jwtSettings = jwtSettings;
_cacheService = cacheService;
_localizationFile = localizationFile;
_validator = validator;
_localizer = localizer;
}
/// <summary>
@@ -127,8 +131,7 @@ namespace Atomx.Admin.Controllers
public async Task<IActionResult> LanguageEdit(LanguageModel model)
{
var result = new ApiResult<bool>();
var validator = new LanguageModelValidator();
var validation = validator.Validate(model);
var validation = _validator.Validate(model);
if (!validation.IsValid)
{
result = result.IsFail(ModelState.Values.First().Errors[0].ErrorMessage);

View File

@@ -9,9 +9,11 @@ using Atomx.Data.CacheServices;
using Atomx.Data.Services;
using Atomx.Utils.Json;
using Atomx.Utils.Models;
using FluentValidation;
using MapsterMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Controllers
{
@@ -28,6 +30,8 @@ namespace Atomx.Admin.Controllers
private readonly ICacheService _cacheService;
private readonly IBackgroundJobService _backgroundService;
private readonly IWebHostEnvironment _environment;
readonly IValidator<LocaleResourceModel> _validator;
readonly IStringLocalizer<LocaleResourceController> _localizer;
/// <summary>
@@ -40,7 +44,8 @@ namespace Atomx.Admin.Controllers
/// <param name="mapper"></param>
/// <param name="jwtSettings"></param>
/// <param name="cacheService"></param>
public LocaleResourceController(ILogger<LocaleResourceController> logger, IIdCreatorService idCreator, IIdentityService identityService, DataContext dbContext, IMapper mapper, JwtSetting jwtSettings, ICacheService cacheService, IBackgroundJobService backgroundJobService, IWebHostEnvironment environment)
public LocaleResourceController(ILogger<LocaleResourceController> logger, IIdCreatorService idCreator, IIdentityService identityService, DataContext dbContext, IMapper mapper, JwtSetting jwtSettings,
ICacheService cacheService, IBackgroundJobService backgroundJobService, IWebHostEnvironment environment, IValidator<LocaleResourceModel> validator, IStringLocalizer<LocaleResourceController> localizer)
{
_logger = logger;
_idCreator = idCreator;
@@ -51,6 +56,8 @@ namespace Atomx.Admin.Controllers
_cacheService = cacheService;
_backgroundService = backgroundJobService;
_environment = environment;
_validator = validator;
_localizer = localizer;
}
/// <summary>
@@ -165,8 +172,7 @@ namespace Atomx.Admin.Controllers
public async Task<IActionResult> SaveAsync(LocaleResourceModel model)
{
var result = new ApiResult<bool>();
var validator = new LocaleResourceModelValidator();
var validation = validator.Validate(model);
var validation = _validator.Validate(model);
if (!validation.IsValid)
{
result = result.IsFail(ModelState.Values.First().Errors[0].ErrorMessage);

View File

@@ -7,9 +7,11 @@ using Atomx.Common.Models;
using Atomx.Data;
using Atomx.Data.CacheServices;
using Atomx.Data.Services;
using FluentValidation;
using Mapster;
using MapsterMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Controllers
{
@@ -24,8 +26,10 @@ namespace Atomx.Admin.Controllers
readonly DataContext _dbContext;
readonly JwtSetting _jwtSetting;
readonly ICacheService _cacheService;
readonly IValidator<MenuModel> _validator;
readonly IStringLocalizer<MenuController> _localizer;
public MenuController(ILogger<MenuController> logger, IIdentityService identityService, IIdCreatorService idCreator, IMapper mapper, DataContext dbContext, JwtSetting jwtSetting, ICacheService cacheService)
public MenuController(ILogger<MenuController> logger, IIdentityService identityService, IIdCreatorService idCreator, IMapper mapper, DataContext dbContext, JwtSetting jwtSetting, ICacheService cacheService, IValidator<MenuModel> validator, IStringLocalizer<MenuController> localizer)
{
_logger = logger;
_identityService = identityService;
@@ -34,6 +38,8 @@ namespace Atomx.Admin.Controllers
_dbContext = dbContext;
_jwtSetting = jwtSetting;
_cacheService = cacheService;
_validator = validator;
_localizer = localizer;
}
/// <summary>
@@ -137,8 +143,7 @@ namespace Atomx.Admin.Controllers
public IActionResult Add(MenuModel model)
{
var result = new ApiResult<string>();
var validator = new MenuModelValidator();
var validation = validator.Validate(model);
var validation = _validator.Validate(model);
if (!validation.IsValid)
{
@@ -186,8 +191,7 @@ namespace Atomx.Admin.Controllers
public IActionResult Edit(MenuModel model)
{
var result = new ApiResult<string>();
var validator = new MenuModelValidator();
var validation = validator.Validate(model);
var validation = _validator.Validate(model);
if (!validation.IsValid)
{
var message = validation.Errors.FirstOrDefault()?.ErrorMessage;

View File

@@ -1,14 +1,15 @@
using Atomx.Admin.Client.Models;
using Atomx.Admin.Client.Validators;
using Atomx.Admin.Services;
using Atomx.Common.Entities;
using Atomx.Common.Models;
using Atomx.Data;
using Atomx.Data.Services;
using FluentValidation;
using Mapster;
using MapsterMapper;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Controllers
{
@@ -21,6 +22,8 @@ namespace Atomx.Admin.Controllers
readonly IIdCreatorService _idCreator;
readonly IMapper _mapper;
readonly DataContext _dbContext;
readonly IValidator<ProductAttributeModel> _validator;
readonly IStringLocalizer<ProductAttributeController> _localizer;
/// <summary>
///
@@ -30,13 +33,16 @@ namespace Atomx.Admin.Controllers
/// <param name="idCreator"></param>
/// <param name="adminService"></param>
/// <param name="mapper"></param>
public ProductAttributeController(ILogger<ProductAttributeController> logger, IIdentityService identityService, IIdCreatorService idCreator, IMapper mapper, DataContext dataContext)
public ProductAttributeController(ILogger<ProductAttributeController> logger, IIdentityService identityService, IIdCreatorService idCreator, IMapper mapper, DataContext dataContext,
IValidator<ProductAttributeModel> validator, IStringLocalizer<ProductAttributeController> localizer)
{
_logger = logger;
_identityService = identityService;
_idCreator = idCreator;
_mapper = mapper;
_dbContext = dataContext;
_validator = validator;
_localizer = localizer;
}
/// <summary>
@@ -126,8 +132,7 @@ namespace Atomx.Admin.Controllers
public IActionResult Add(ProductAttributeModel model)
{
var result = new ApiResult<string>();
var validator = new ProductAttributeModelValidator();
var validation = validator.Validate(model);
var validation = _validator.Validate(model);
if (!validation.IsValid)
{
var message = validation.Errors.FirstOrDefault()?.ErrorMessage ?? string.Empty;
@@ -170,8 +175,7 @@ namespace Atomx.Admin.Controllers
public IActionResult Edit(ProductAttributeModel model)
{
var result = new ApiResult<string>();
var validator = new ProductAttributeModelValidator();
var validation = validator.Validate(model);
var validation = _validator.Validate(model);
if (!validation.IsValid)
{
var message = validation.Errors.FirstOrDefault()?.ErrorMessage;

View File

@@ -7,10 +7,12 @@ using Atomx.Common.Models;
using Atomx.Data;
using Atomx.Data.CacheServices;
using Atomx.Data.Services;
using FluentValidation;
using MapsterMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Controllers
{
@@ -25,6 +27,8 @@ namespace Atomx.Admin.Controllers
readonly IMapper _mapper;
readonly DataContext _dbContext;
readonly ICacheService _cacheService;
readonly IValidator<RoleModel> _validator;
readonly IStringLocalizer<RoleController> _localizer;
/// <summary>
///
@@ -34,7 +38,7 @@ namespace Atomx.Admin.Controllers
/// <param name="idCreator"></param>
/// <param name="mapper"></param>
/// <param name="userService"></param>
public RoleController(ILogger<RoleController> logger, IIdentityService identityService, IIdCreatorService idCreator, IMapper mapper, DataContext dataContext, ICacheService cacheService)
public RoleController(ILogger<RoleController> logger, IIdentityService identityService, IIdCreatorService idCreator, IMapper mapper, DataContext dataContext, ICacheService cacheService, IValidator<RoleModel> validator, IStringLocalizer<RoleController> localizer)
{
_logger = logger;
_identityService = identityService;
@@ -42,6 +46,8 @@ namespace Atomx.Admin.Controllers
_mapper = mapper;
_dbContext = dataContext;
_cacheService = cacheService;
_validator = validator;
_localizer = localizer;
}
/// <summary>
@@ -111,8 +117,7 @@ namespace Atomx.Admin.Controllers
public async Task<IActionResult> Add(RoleModel model)
{
var result = new ApiResult<string>();
var validator = new RoleModelValidator();
var validation = validator.Validate(model);
var validation = await _validator.ValidateAsync(model);
if (!validation.IsValid)
{
var message = validation.Errors.FirstOrDefault()?.ErrorMessage;
@@ -153,8 +158,7 @@ namespace Atomx.Admin.Controllers
public async Task<IActionResult> EditAsync(RoleModel model)
{
var result = new ApiResult<string>();
var validator = new RoleModelValidator();
var validation = validator.Validate(model);
var validation = await _validator.ValidateAsync(model);
if (!validation.IsValid)
{
var message = validation.Errors.FirstOrDefault()?.ErrorMessage;
@@ -183,7 +187,7 @@ namespace Atomx.Admin.Controllers
{
int count = _dbContext.SaveChanges();
//刷新缓存
await _cacheService.GetRoleById(data.Id,true);
await _cacheService.GetRoleById(data.Id, true);
result = result.IsSuccess(count.ToString());
}
catch (Exception ex)

View File

@@ -0,0 +1,165 @@
using Atomx.Admin.Client.Models;
using Atomx.Admin.Services;
using Atomx.Common.Constants;
using Atomx.Common.Entities;
using Atomx.Common.Models;
using Atomx.Data;
using Atomx.Data.CacheServices;
using Atomx.Data.Services;
using FluentValidation;
using MapsterMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
namespace Atomx.Admin.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class StateProvinceController : ControllerBase
{
private readonly ILogger<StateProvinceController> _logger;
private readonly DataContext _dbContext;
private readonly IIdCreatorService _idCreator;
private readonly IIdentityService _identityService;
private readonly IMapper _mapper;
private readonly ICacheService _cacheService;
readonly IValidator<StateProvinceModel> _validator;
readonly IStringLocalizer<StateProvinceController> _localizer;
/// <summary>
///
/// </summary>
/// <param name="logger"></param>
/// <param name="idCreator"></param>
/// <param name="identityService"></param>
/// <param name="dbContext"></param>
/// <param name="mapper"></param>
/// <param name="jwtSettings"></param>
/// <param name="cacheService"></param>
public StateProvinceController(ILogger<StateProvinceController> logger, IIdCreatorService idCreator, IIdentityService identityService, DataContext dbContext, IMapper mapper, ICacheService cacheService, IValidator<StateProvinceModel> validator, IStringLocalizer<StateProvinceController> localizer)
{
_logger = logger;
_idCreator = idCreator;
_identityService = identityService;
_dbContext = dbContext;
_mapper = mapper;
_cacheService = cacheService;
_validator = validator;
_localizer = localizer;
}
/// <summary>
/// 数据查询
/// </summary>
/// <param name="search"></param>
/// <param name="page"></param>
/// <param name="size"></param>
/// <returns></returns>
[HttpPost("searh")]
[Authorize(Policy = Permissions.User.View)]
public IActionResult AddressList(StateProvinceSearch search, int page, int size = 20)
{
if (page < 1)
{
page = 1;
}
var result = new ApiResult<PagingList<StateProvince>>();
var list = new PagingList<StateProvince>() { Index = page, Size = size };
var query = from p in _dbContext.StateProvinces
select p;
if (!string.IsNullOrEmpty(search.Name))
{
query = from p in query
where p.Name.Contains(search.Name)
select p;
}
if (search.CountryId > 0)
{
query = from p in query
where p.CountryId == search.CountryId
select p;
}
list.Count = query.Count();
list.Items = query.OrderByDescending(p => p.DisplayOrder).Skip((page - 1) * size).Take(size).ToList();
result = result.IsSuccess(list);
return new JsonResult(result);
}
/// <summary>
/// 新增编辑数据
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
[HttpPost("save")]
public IActionResult AddressEdit(StateProvinceModel model)
{
var result = new ApiResult<bool>();
var validation = _validator.Validate(model);
if (!validation.IsValid)
{
var message = validation.Errors.FirstOrDefault()?.ErrorMessage ?? string.Empty;
return new JsonResult(new ApiResult<string>().IsFail(message, null));
}
var data = _dbContext.StateProvinces.SingleOrDefault(p => p.CountryId == model.CountryId && p.Name == model.Name && p.Id != model.Id);
if (data != null)
{
return new JsonResult(new ApiResult<string>().IsFail("当前数据已经存在,请认真检查", null));
}
if (model.Id > 0)
{
data = _dbContext.StateProvinces.SingleOrDefault(p => p.Id == model.Id);
if (data == null)
{
return new JsonResult(new ApiResult<string>().IsFail("数据不存在", null));
}
data = _mapper.Map(model, data);
_dbContext.SaveChanges();
}
else
{
data = _mapper.Map<StateProvince>(model);
data.Id = _idCreator.CreateId();
_dbContext.StateProvinces.Add(data);
_dbContext.SaveChanges();
}
return new JsonResult(new ApiResult<string>().IsSuccess("操作成功"));
}
/// <summary>
/// 删除数据
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
[HttpPost("delete")]
public async Task<IActionResult> DeleteAsync(long id)
{
var result = new ApiResult<string>();
try
{
Console.WriteLine($"{id} deleted");
var count = _dbContext.StateProvinces.Where(p => p.Id == id).ExecuteDelete();
result = result.IsSuccess(count.ToString());
}
catch (Exception ex)
{
result = result.IsFail(ex.Message);
_logger.LogError(ex.Message);
}
return new JsonResult(result);
}
}
}

View File

@@ -1,15 +0,0 @@
namespace Atomx.Common.Models
{
public class LocalizationFile
{
/// <summary>
/// 本地化文件版本
/// </summary>
public string ResourceVersion { get; set; } = string.Empty;
/// <summary>
/// 本地化译文
/// </summary>
public Dictionary<string, string> Translations { get; set; } = new();
}
}