LqMdRoomService.cs 8.21 KB
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using NCC.Common.Extension;
using NCC.Common.Core.Manager;
using NCC.Dependency;
using NCC.DynamicApiController;
using NCC.Extend.Entitys.Dto.Common;
using NCC.Extend.Entitys.Dto.LqMdRoom;
using NCC.Extend.Entitys.Enum;
using NCC.Extend.Entitys.lq_md_room;
using NCC.Extend.Entitys.lq_mdxx;
using NCC.Extend.Interfaces.LqMdRoom;
using NCC.FriendlyException;
using SqlSugar;
using Yitter.IdGenerator;

namespace NCC.Extend.LqMdRoom
{
    /// <summary>
    /// 门店房间维护(供预约等按门店选择房间)
    /// </summary>
    [ApiDescriptionSettings(Tag = "绿纤门店房间", Name = "LqMdRoom", Order = 201)]
    [Route("api/Extend/[controller]")]
    public class LqMdRoomService : ILqMdRoomService, IDynamicApiController, ITransient
    {
        private readonly ISqlSugarRepository<LqMdRoomEntity> _roomRepository;
        private readonly SqlSugarScope _db;
        private readonly IUserManager _userManager;

        /// <summary>
        /// 初始化
        /// </summary>
        public LqMdRoomService(ISqlSugarRepository<LqMdRoomEntity> roomRepository, IUserManager userManager)
        {
            _roomRepository = roomRepository;
            _db = _roomRepository.Context;
            _userManager = userManager;
        }

        /// <summary>
        /// 房间类型下拉
        /// </summary>
        [HttpGet("Selector/RoomType")]
        public List<EnumOutput> GetRoomTypeSelector()
        {
            return Enum.GetValues<LqStoreRoomTypeEnum>().Select(e => new EnumOutput
            {
                Value = (int)e,
                Name = e.ToString(),
                Description = e.GetDescription()
            }).ToList();
        }

        /// <summary>
        /// 按门店查询房间列表(不分页,按排序号、名称)
        /// </summary>
        /// <param name="storeId">门店ID</param>
        [HttpGet("GetByStoreId")]
        public async Task<dynamic> GetByStoreId([FromQuery] string storeId)
        {
            if (string.IsNullOrWhiteSpace(storeId))
            {
                throw NCCException.Oh("门店ID不能为空");
            }

            var storeOk = await _db.Queryable<LqMdxxEntity>().AnyAsync(x => x.Id == storeId);
            if (!storeOk)
            {
                throw NCCException.Oh("门店不存在");
            }

            // 先查实体再映射:避免 SqlSugar 直接 Select 到 DTO 时映射/SQL 异常导致列表为空
            var entities = await _db.Queryable<LqMdRoomEntity>()
                .Where(x => x.StoreId == storeId)
                .OrderBy(x => x.SortNo)
                .OrderBy(x => x.RoomName)
                .ToListAsync();

            var list = entities.Select(x => new LqMdRoomListOutput
            {
                id = x.Id,
                storeId = x.StoreId,
                roomName = x.RoomName,
                sortNo = x.SortNo,
                enabled = x.Enabled,
                roomType = x.RoomType,
                capacity = x.Capacity,
                remark = x.Remark,
                createTime = x.CreateTime,
                lastModifyTime = x.LastModifyTime
            }).ToList();

            return new { list };
        }

        /// <summary>
        /// 按门店保存房间列表(增量:提交中未包含的已有记录将删除;无 id 行为新增)
        /// </summary>
        [HttpPost("SaveByStore")]
        public async Task SaveByStore([FromBody] LqMdRoomSaveInput input)
        {
            _ = await _userManager.GetUserInfo();
            if (input == null || string.IsNullOrWhiteSpace(input.storeId))
            {
                throw NCCException.Oh("门店ID不能为空");
            }

            var storeOk = await _db.Queryable<LqMdxxEntity>().AnyAsync(x => x.Id == input.storeId);
            if (!storeOk)
            {
                throw NCCException.Oh("门店不存在");
            }

            var rawRows = input.rooms ?? new List<LqMdRoomItemInput>();
            var rows = rawRows
                .Where(r => r != null && !string.IsNullOrWhiteSpace(r.roomName))
                .Select(r => new LqMdRoomItemInput
                {
                    id = string.IsNullOrWhiteSpace(r.id) ? null : r.id.Trim(),
                    roomName = r.roomName.Trim(),
                    sortNo = r.sortNo,
                    enabled = r.enabled,
                    roomType = r.roomType,
                    capacity = r.capacity,
                    remark = string.IsNullOrWhiteSpace(r.remark) ? null : r.remark.Trim()
                })
                .ToList();

            if (rows.Count > 200)
            {
                throw NCCException.Oh("单个门店房间数量不能超过200条");
            }

            foreach (var r in rows)
            {
                if (r.roomName.Length > 64)
                {
                    throw NCCException.Oh("房间名称长度不能超过64个字符");
                }

                var rt = r.roomType ?? (int)LqStoreRoomTypeEnum.其他;
                if (!Enum.IsDefined(typeof(LqStoreRoomTypeEnum), rt))
                {
                    throw NCCException.Oh("房间类型不合法");
                }

                if (r.remark != null && r.remark.Length > 500)
                {
                    throw NCCException.Oh("备注长度不能超过500个字符");
                }

                if (r.capacity != null && (r.capacity < 0 || r.capacity > 999))
                {
                    throw NCCException.Oh("可容纳人数应在0~999之间");
                }
            }

            var now = DateTime.Now;
            var incomingIds = rows.Where(x => !string.IsNullOrEmpty(x.id)).Select(x => x.id).ToList();
            var existing = await _db.Queryable<LqMdRoomEntity>()
                .Where(x => x.StoreId == input.storeId)
                .ToListAsync();

            try
            {
                _db.BeginTran();

                var idsToDelete = existing.Select(x => x.Id).Except(incomingIds).ToList();
                if (idsToDelete.Count > 0)
                {
                    await _db.Deleteable<LqMdRoomEntity>().In(x => x.Id, idsToDelete).ExecuteCommandAsync();
                }

                foreach (var item in rows)
                {
                    var en = (item.enabled ?? 1) == 0 ? 0 : 1;
                    var sort = item.sortNo ?? 0;
                    var rt = item.roomType ?? (int)LqStoreRoomTypeEnum.其他;

                    if (!string.IsNullOrEmpty(item.id))
                    {
                        var old = existing.FirstOrDefault(x => x.Id == item.id);
                        if (old == null || old.StoreId != input.storeId)
                        {
                            throw NCCException.Oh($"房间不存在或不属于当前门店:{item.id}");
                        }

                        old.RoomName = item.roomName;
                        old.SortNo = sort;
                        old.Enabled = en;
                        old.RoomType = rt;
                        old.Capacity = item.capacity;
                        old.Remark = item.remark;
                        old.LastModifyTime = now;
                        await _db.Updateable(old).ExecuteCommandAsync();
                    }
                    else
                    {
                        var entity = new LqMdRoomEntity
                        {
                            Id = YitIdHelper.NextId().ToString(),
                            StoreId = input.storeId,
                            RoomName = item.roomName,
                            SortNo = sort,
                            Enabled = en,
                            RoomType = rt,
                            Capacity = item.capacity,
                            Remark = item.remark,
                            CreateTime = now,
                            LastModifyTime = now
                        };
                        await _db.Insertable(entity).ExecuteCommandAsync();
                    }
                }

                _db.CommitTran();
            }
            catch
            {
                _db.RollbackTran();
                throw;
            }
        }
    }
}