LocationAppService.cs 8.12 KB
using FoodLabeling.Application.Helpers;
using FoodLabeling.Application.Contracts.Dtos.Location;
using FoodLabeling.Application.Contracts.IServices;
using FoodLabeling.Domain.Entities;
using FoodLabeling.Application.Contracts.Dtos.Common;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Yi.Framework.SqlSugarCore.Abstractions;

namespace FoodLabeling.Application.Services;

/// <summary>
/// 门店管理服务(美国版)
/// </summary>
public class LocationAppService : ApplicationService, ILocationAppService
{
    private readonly ISqlSugarRepository<LocationAggregateRoot, Guid> _locationRepository;

    public LocationAppService(ISqlSugarRepository<LocationAggregateRoot, Guid> locationRepository)
    {
        _locationRepository = locationRepository;
    }

    /// <inheritdoc />
    public async Task<PagedResultWithPageDto<LocationGetListOutputDto>> GetListAsync([FromQuery] LocationGetListInputVo input)
    {
        RefAsync<int> total = 0;

        var keyword = input.Keyword?.Trim();
        var partner = input.Partner?.Trim();
        var groupName = input.GroupName?.Trim();

        var query = _locationRepository._DbQueryable
            .Where(x => x.IsDeleted == false)
            .WhereIF(!string.IsNullOrEmpty(partner), x => x.Partner == partner)
            .WhereIF(!string.IsNullOrEmpty(groupName), x => x.GroupName == groupName)
            .WhereIF(input.State is not null, x => x.State == input.State)
            .WhereIF(!string.IsNullOrEmpty(keyword),
                x =>
                    x.LocationCode.Contains(keyword!) ||
                    x.LocationName.Contains(keyword!) ||
                    (x.Street != null && x.Street.Contains(keyword!)) ||
                    (x.City != null && x.City.Contains(keyword!)) ||
                    (x.StateCode != null && x.StateCode.Contains(keyword!)) ||
                    (x.Country != null && x.Country.Contains(keyword!)) ||
                    (x.ZipCode != null && x.ZipCode.Contains(keyword!)) ||
                    (x.Phone != null && x.Phone.Contains(keyword!)) ||
                    (x.Email != null && x.Email.Contains(keyword!))
            );

        // 先按排序字段走(如前端传入),否则默认按创建时间倒序
        if (!string.IsNullOrWhiteSpace(input.Sorting))
        {
            query = query.OrderBy(input.Sorting);
        }
        else
        {
            query = query.OrderBy(x => x.CreationTime, OrderByType.Desc);
        }

        var entities = await query.ToPageListAsync(input.SkipCount, input.MaxResultCount, total);

        var items = entities.Select(x => new LocationGetListOutputDto
        {
            Id = x.Id,
            Partner = x.Partner,
            GroupName = x.GroupName,
            LocationCode = x.LocationCode,
            LocationName = x.LocationName,
            Street = x.Street,
            City = x.City,
            StateCode = x.StateCode,
            Country = x.Country,
            ZipCode = x.ZipCode,
            Phone = x.Phone,
            Email = x.Email,
            Latitude = x.Latitude,
            Longitude = x.Longitude,
            State = x.State
        }).ToList();

        var pageSize = input.MaxResultCount <= 0 ? items.Count : input.MaxResultCount;
        var pageIndex = pageSize <= 0 ? 1 : PagedQueryConvention.PageIndexFromSkipCount(input.SkipCount);
        var totalPages = pageSize <= 0 ? 0 : (int)Math.Ceiling(total / (double)pageSize);

        return new PagedResultWithPageDto<LocationGetListOutputDto>
        {
            PageIndex = pageIndex,
            PageSize = pageSize,
            TotalCount = total,
            TotalPages = totalPages,
            Items = items
        };
    }

    /// <inheritdoc />
    public async Task<LocationGetListOutputDto> CreateAsync([FromBody] LocationCreateInputVo input)
    {
        var locationCode = input.LocationCode?.Trim();
        if (string.IsNullOrWhiteSpace(locationCode))
        {
            throw new UserFriendlyException("Location ID不能为空");
        }

        var locationName = input.LocationName?.Trim();
        if (string.IsNullOrWhiteSpace(locationName))
        {
            throw new UserFriendlyException("Location Name不能为空");
        }

        var isExist = await _locationRepository.IsAnyAsync(x => x.LocationCode == locationCode);
        if (isExist)
        {
            throw new UserFriendlyException("Location ID已存在");
        }

        var entity = new LocationAggregateRoot(GuidGenerator.Create())
        {
            Partner = input.Partner?.Trim(),
            GroupName = input.GroupName?.Trim(),
            LocationCode = locationCode,
            LocationName = locationName,
            Street = input.Street?.Trim(),
            City = input.City?.Trim(),
            StateCode = input.StateCode?.Trim(),
            Country = input.Country?.Trim(),
            ZipCode = input.ZipCode?.Trim(),
            Phone = input.Phone?.Trim(),
            Email = input.Email?.Trim(),
            Latitude = input.Latitude,
            Longitude = input.Longitude,
            State = input.State
        };

        await _locationRepository.InsertAsync(entity);

        return new LocationGetListOutputDto
        {
            Id = entity.Id,
            Partner = entity.Partner,
            GroupName = entity.GroupName,
            LocationCode = entity.LocationCode,
            LocationName = entity.LocationName,
            Street = entity.Street,
            City = entity.City,
            StateCode = entity.StateCode,
            Country = entity.Country,
            ZipCode = entity.ZipCode,
            Phone = entity.Phone,
            Email = entity.Email,
            Latitude = entity.Latitude,
            Longitude = entity.Longitude,
            State = entity.State
        };
    }

    /// <inheritdoc />
    public async Task<LocationGetListOutputDto> UpdateAsync(Guid id, [FromBody] LocationUpdateInputVo input)
    {
        var entity = await _locationRepository.GetSingleAsync(x => x.Id == id && x.IsDeleted == false);
        if (entity is null)
        {
            throw new UserFriendlyException("门店不存在");
        }

        var locationName = input.LocationName?.Trim();
        if (string.IsNullOrWhiteSpace(locationName))
        {
            throw new UserFriendlyException("Location Name不能为空");
        }

        // LocationCode 默认不允许修改:业务编码需要保持唯一且稳定(如需变更,应走“新建+迁移”方案)
        entity.Partner = input.Partner?.Trim();
        entity.GroupName = input.GroupName?.Trim();
        entity.LocationName = locationName;
        entity.Street = input.Street?.Trim();
        entity.City = input.City?.Trim();
        entity.StateCode = input.StateCode?.Trim();
        entity.Country = input.Country?.Trim();
        entity.ZipCode = input.ZipCode?.Trim();
        entity.Phone = input.Phone?.Trim();
        entity.Email = input.Email?.Trim();
        entity.Latitude = input.Latitude;
        entity.Longitude = input.Longitude;
        entity.State = input.State;

        await _locationRepository.UpdateAsync(entity);

        return new LocationGetListOutputDto
        {
            Id = entity.Id,
            Partner = entity.Partner,
            GroupName = entity.GroupName,
            LocationCode = entity.LocationCode,
            LocationName = entity.LocationName,
            Street = entity.Street,
            City = entity.City,
            StateCode = entity.StateCode,
            Country = entity.Country,
            ZipCode = entity.ZipCode,
            Phone = entity.Phone,
            Email = entity.Email,
            Latitude = entity.Latitude,
            Longitude = entity.Longitude,
            State = entity.State
        };
    }

    /// <inheritdoc />
    public async Task DeleteAsync(Guid id)
    {
        var entity = await _locationRepository.GetSingleAsync(x => x.Id == id && x.IsDeleted == false);
        if (entity is null)
        {
            throw new UserFriendlyException("门店不存在");
        }

        entity.IsDeleted = true;
        await _locationRepository.UpdateAsync(entity);
    }
}