using System.ComponentModel.DataAnnotations; using MAX.Framework.Commons; using MAX.Framework.Validation; using Store.Shops.Dtos; using Store.Shops.Entities; using Store.Shops.Mappers; namespace Store.Shops.Services; public sealed partial class ShopService { /// 保存当前账号的店铺售后地址;同账号同店铺更新原记录。 public async Task SaveDefaultAddress(AddressRequest request, CancellationToken ct) { RequestValidator.Validate(request); var actor = await Actor(); using var work = db.CreateUnitOfWork(); work.IsolationLevel = System.Data.IsolationLevel.Serializable; work.GetOrBeginTransaction(); var orm = work.Orm; await RequireShop(orm, actor, request.ShopId, ct); var row = await orm.Select() .Where(a => a.UserId == actor.UserName && a.ShopId == request.ShopId).ForUpdate().FirstAsync(ct); if (row == null) await orm.Insert(new DefaultAddressEntity { UserId = actor.UserName, ShopId = request.ShopId, ProvinceName = request.ProvinceName, CityName = request.CityName, CountyName = request.CountyName, DetailInfo = request.DetailInfo, Receiver = request.Receiver, TelNumber = request.TelNumber, AddTime = DateTime.Now, MdyTime = DateTime.Now }).ExecuteAffrowsAsync(ct); else await orm.Update().Where(a => a.Id == row.Id) .Set(a => a.ProvinceName, request.ProvinceName).Set(a => a.CityName, request.CityName) .Set(a => a.CountyName, request.CountyName).Set(a => a.DetailInfo, request.DetailInfo) .Set(a => a.Receiver, request.Receiver).Set(a => a.TelNumber, request.TelNumber) .Set(a => a.MdyTime, DateTime.Now).ExecuteAffrowsAsync(ct); ct.ThrowIfCancellationRequested(); work.Commit(); } /// 按当前账号和可见店铺范围查询默认地址。 public async Task> DefaultAddresses(AddressSearchRequest request, CancellationToken ct) { RequestValidator.Validate(request); Page(request.Page, request.PageSize); var actor = await Actor(); var ids = await VisibleIds(actor, ct); var query = db.Select().Where(a => a.UserId == actor.UserName && ids.Contains(a.ShopId)) .WhereIf(request.ShopIds != null, a => request.ShopIds!.Contains(a.ShopId)); var count = request.NotCount ? -1 : await query.CountAsync(ct); var rows = await query.OrderByDescending(a => a.Id).Page(request.Page, request.PageSize).ToListAsync(ct); return new(rows.Select(new ShopDetailsMapper().Map).ToList(), count); } /// 删除本人指定店铺的默认地址,不影响其他账号保存的地址。 public async Task DeleteDefaultAddresses(ShopIdsRequest request, CancellationToken ct) { RequestValidator.Validate(request); Ids(request.ShopIds); var actor = await Actor(); var ids = await VisibleIds(actor, ct); if (request.ShopIds.Except(ids).Any()) throw new AppException("包含无权访问的店铺"); await db.Delete().Where(a => a.UserId == actor.UserName && request.ShopIds.Contains(a.ShopId)).ExecuteAffrowsAsync(ct); } /// 以店铺及订单为键保存解密地址,禁止跨店覆盖。 public async Task SaveOrderAddress(OrderAddressRequest request, CancellationToken ct) { RequestValidator.Validate(request); var actor = await Actor(); using var work = db.CreateUnitOfWork(); work.IsolationLevel = System.Data.IsolationLevel.Serializable; work.GetOrBeginTransaction(); var orm = work.Orm; await RequireShop(orm, actor, request.ShopId, ct); var row = await orm.Select().Where(a => a.ShopId == request.ShopId && a.OrderId == request.OrderId).ForUpdate().FirstAsync(ct); if (row == null) await orm.Insert(new OrderAddressEntity { ShopId = request.ShopId, OrderId = request.OrderId, OrderAddress = request.OrderAddress, AddTime = DateTime.Now, MdyTime = DateTime.Now }).ExecuteAffrowsAsync(ct); else await orm.Update().Where(a => a.Id == row.Id).Set(a => a.OrderAddress, request.OrderAddress) .Set(a => a.MdyTime, DateTime.Now).ExecuteAffrowsAsync(ct); ct.ThrowIfCancellationRequested(); work.Commit(); } /// 查询订单解密地址,先限制当前用户可见店铺,再按订单过滤。 public async Task> OrderAddresses(OrderSearchRequest request, CancellationToken ct) { RequestValidator.Validate(request); Page(request.Page, request.PageSize); if (request.OrderIds == null) throw new ValidationException("订单编号不能为空"); Ids(request.OrderIds); var actor = await Actor(); var ids = await VisibleIds(actor, ct); var query = db.Select().Where(a => ids.Contains(a.ShopId) && request.OrderIds.Contains(a.OrderId)); var count = request.NotCount ? -1 : await query.CountAsync(ct); var rows = await query.OrderByDescending(a => a.Id).Page(request.Page, request.PageSize).ToListAsync(ct); return new(rows.Select(new ShopDetailsMapper().Map).ToList(), count); } /// 采购备注按可信主账号归属保存,直属子账号共享主账号的备注。 public async Task SaveBuyNote(NoteRequest request, CancellationToken ct) { RequestValidator.Validate(request); var owner = MainName(await Actor()); if (request.MainUserName != null && request.MainUserName != owner) throw new AppException("无权修改其他主账号备注"); using var work = db.CreateUnitOfWork(); work.IsolationLevel = System.Data.IsolationLevel.Serializable; work.GetOrBeginTransaction(); var orm = work.Orm; var row = await orm.Select().Where(n => n.UserName == owner && n.SpuCode == request.SpuCode).ForUpdate().FirstAsync(ct); if (row == null) await orm.Insert(new BuyUrlNoteEntity { UserName = owner, SpuCode = request.SpuCode, BuyUrlNotes = request.BuyUrlNotes, AddTime = DateTime.Now, MdyTime = DateTime.Now }).ExecuteAffrowsAsync(ct); else await orm.Update().Where(n => n.Id == row.Id).Set(n => n.BuyUrlNotes, request.BuyUrlNotes) .Set(n => n.MdyTime, DateTime.Now).ExecuteAffrowsAsync(ct); ct.ThrowIfCancellationRequested(); work.Commit(); } /// 分页查询当前主账号的采购备注。 public async Task> BuyNotes(NoteSearchRequest request, CancellationToken ct) { RequestValidator.Validate(request); Page(request.Page, request.PageSize); Ids(request.SpuCodes); var owner = MainName(await Actor()); if (request.MainUserName != null && request.MainUserName != owner) throw new AppException("无权查询其他主账号备注"); var query = db.Select().Where(n => n.UserName == owner && request.SpuCodes.Contains(n.SpuCode)); var count = request.NotCount ? -1 : await query.CountAsync(ct); var rows = await query.OrderByDescending(n => n.Id).Page(request.Page, request.PageSize).ToListAsync(ct); return new(rows.Select(new ShopDetailsMapper().Map).ToList(), count); } }