MapRepository.cs 7.37 KB
using Microsoft.EntityFrameworkCore;
using Rcs.Domain.Entities;
using Rcs.Domain.Repositories;
using Rcs.Infrastructure.DB.MsSql;

namespace Rcs.Infrastructure.DB.Repositories
{
    /// <summary>
    /// 地图仓储实现
    /// </summary>
    public class MapRepository : Repository<Map>, IMapRepository
    {
        public MapRepository(AppDbContext context) : base(context)
        {
        }

        /// <summary>
        /// 根据地图编码获取地图
        /// </summary>
        public async Task<Map?> GetByMapCodeAsync(
            string mapCode,
            CancellationToken cancellationToken = default)
        {
            return await _dbSet
                .FirstOrDefaultAsync(m => m.MapCode == mapCode, cancellationToken);
        }

        /// <summary>
        /// 获取所有激活的地图
        /// </summary>
        public async Task<IEnumerable<Map>> GetActiveAsync(
            CancellationToken cancellationToken = default)
        {
            return await _dbSet
                .Where(m => m.Active)
                .OrderBy(m => m.MapCode)
                .ToListAsync(cancellationToken);
        }

        /// <summary>
        /// 获取包含所有关联数据的地图(Nodes、Edges、Resources、StorageLocations、StorageAreas)
        /// @author zzy
        /// </summary>
        public async Task<Map?> GetWithFullDetailsAsync(
            Guid mapId,
            CancellationToken cancellationToken = default)
        {
            return await _dbSet
                .Include(m => m.MapNodes)
                    .ThenInclude(n => n.StorageLocations)
                        .ThenInclude(sl => sl.StorageArea)
                .Include(m => m.MapEdges)
                .Include(m => m.MapResources)
                .FirstOrDefaultAsync(m => m.MapId == mapId, cancellationToken);
        }

        /// <summary>
        /// 根据地图编码获取包含所有关联数据的地图
        /// </summary>
        public async Task<Map?> GetWithFullDetailsByCodeAsync(
            string mapCode,
            CancellationToken cancellationToken = default)
        {
            return await _dbSet
                .Include(m => m.MapNodes)
                .Include(m => m.MapEdges)
                .Include(m => m.MapResources)
                .FirstOrDefaultAsync(m => m.MapCode == mapCode, cancellationToken);
        }

        /// <summary>
        /// 根据查询参数筛选地图
        /// </summary>
        public async Task<IEnumerable<Map>> GetByFilterAsync(
            string? mapCode = null,
            string? mapName = null,
            bool? active = null,
            CancellationToken cancellationToken = default)
        {
            var queryable = _dbSet.AsQueryable();

            // 按地图编码筛选
            if (!string.IsNullOrWhiteSpace(mapCode))
            {
                queryable = queryable.Where(m => m.MapCode.Contains(mapCode));
            }

            // 按地图名称筛选
            if (!string.IsNullOrWhiteSpace(mapName))
            {
                queryable = queryable.Where(m => m.MapName.Contains(mapName));
            }

            // 按是否启用筛选
            if (active.HasValue)
            {
                queryable = queryable.Where(m => m.Active == active.Value);
            }

            return await queryable
                .OrderBy(m => m.MapCode)
                .ToListAsync(cancellationToken);
        }

        /// <summary>
        /// 根据查询参数筛选地图(带分页)
        /// </summary>
        public async Task<(IEnumerable<Map> Maps, int TotalCount)> GetByFilterWithPaginationAsync(
            string? mapCode = null,
            string? mapName = null,
            bool? active = null,
            DateTime? createdAtFrom = null,
            DateTime? createdAtTo = null,
            int pageNumber = 1,
            int pageSize = 10,
            CancellationToken cancellationToken = default)
        {
            var queryable = _dbSet.AsQueryable();

            // 按地图编码筛选
            if (!string.IsNullOrWhiteSpace(mapCode))
            {
                queryable = queryable.Where(m => m.MapCode.Contains(mapCode));
            }

            // 按地图名称筛选
            if (!string.IsNullOrWhiteSpace(mapName))
            {
                queryable = queryable.Where(m => m.MapName.Contains(mapName));
            }

            // 按是否启用筛选
            if (active.HasValue)
            {
                queryable = queryable.Where(m => m.Active == active.Value);
            }

            // 按创建时间范围筛选
            if (createdAtFrom.HasValue)
            {
                queryable = queryable.Where(m => m.CreatedAt.HasValue && m.CreatedAt.Value >= createdAtFrom.Value);
            }

            if (createdAtTo.HasValue)
            {
                queryable = queryable.Where(m => m.CreatedAt.HasValue && m.CreatedAt.Value <= createdAtTo.Value);
            }

            // 获取总记录数
            var totalCount = await queryable.CountAsync(cancellationToken);

            // 应用分页
            var maps = await queryable
                .OrderBy(m => m.MapCode)
                .Skip((pageNumber - 1) * pageSize)
                .Take(pageSize)
                .ToListAsync(cancellationToken);

            return (maps, totalCount);
        }

        /// <summary>
        /// 根据地图ID删除地图及其所有关联数据(Nodes、Edges、Resources)
        /// </summary>
        public async Task<bool> DeleteWithNavigationDataAsync(
            Guid mapId,
            CancellationToken cancellationToken = default)
        {
            try
            {
                // 开始事务以确保数据一致性
                using var transaction = await _context.Database.BeginTransactionAsync(cancellationToken);

                // 1. 首先检查地图是否存在
                var map = await _dbSet
                    .Include(m => m.MapNodes)
                    .Include(m => m.MapEdges)
                    .Include(m => m.MapResources)
                    .FirstOrDefaultAsync(m => m.MapId == mapId, cancellationToken);

                if (map == null)
                {
                    await transaction.RollbackAsync(cancellationToken);
                    return false;
                }
                
                // 2. 删除关联的 MapResources
                if (map.MapResources.Any())
                {
                    _context.MapResources.RemoveRange(map.MapResources);
                }

                // 3. 删除关联的 MapEdges(需要先删除相关的外键约束)
                if (map.MapEdges.Any())
                {
                    _context.MapEdges.RemoveRange(map.MapEdges);
                }

                // 4. 删除关联的 MapNodes
                if (map.MapNodes.Any())
                {
                    _context.MapNodes.RemoveRange(map.MapNodes);
                }

                // 5. 删除地图本身
                _dbSet.Remove(map);

                // 6. 保存所有更改
                await _context.SaveChangesAsync(cancellationToken);

                // 7. 提交事务
                await transaction.CommitAsync(cancellationToken);

                return true;
            }
            catch (Exception)
            {
                // 如果出现异常,事务会自动回滚
                return false;
            }
        }
    }
}