using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Globalization; using System.Linq; using System.Threading.Tasks; using Mapster; using Microsoft.AspNetCore.Mvc; using NCC.ClayObject; using NCC.Common.Configuration; using NCC.Common.Core.Manager; using NCC.Common.Enum; using NCC.Common.Extension; using NCC.Common.Filter; using NCC.Common.Helper; using NCC.Common.Model.NPOI; using NCC.DataEncryption; using NCC.Dependency; using NCC.DynamicApiController; using NCC.Extend.Entitys.Dto.LqYcsdJsj; using NCC.Extend.Entitys.Dto.LqJinsanjiaoUser; using NCC.Extend.Entitys.lq_jinsanjiao_user; using NCC.Extend.Entitys.lq_kd_jksyj; using NCC.Extend.Entitys.lq_mdxx; using NCC.Extend.Entitys.lq_ycsd_jsj; using NCC.Extend.Interfaces.LqYcsdJsj; using NCC.System.Entitys.Permission; using NCC.FriendlyException; using NCC.JsonSerialization; using SqlSugar; using Yitter.IdGenerator; namespace NCC.Extend.LqYcsdJsj { /// /// 金三角设定服务 /// [ApiDescriptionSettings(Tag = "绿纤金三角服务", Name = "LqYcsdJsj", Order = 200)] [Route("api/Extend/[controller]")] public class LqYcsdJsjService : ILqYcsdJsjService, IDynamicApiController, ITransient { private readonly ISqlSugarRepository _lqYcsdJsjRepository; private readonly SqlSugarScope _db; private readonly IUserManager _userManager; /// /// 初始化一个类型的新实例 /// public LqYcsdJsjService(ISqlSugarRepository lqYcsdJsjRepository, IUserManager userManager) { _lqYcsdJsjRepository = lqYcsdJsjRepository; _db = _lqYcsdJsjRepository.Context; _userManager = userManager; } #region 获取金三角设定 /// /// 获取金三角设定 /// /// 参数 /// [HttpGet("{id}")] public async Task GetInfo(string id) { var entity = await _db.Queryable().FirstAsync(p => p.Id == id); var output = entity.Adapt(); return output; } #endregion #region 获取金三角设定详情 /// /// 获取金三角设定详情(包含成员信息) /// /// 金三角ID /// [HttpGet("{id}/detail")] public async Task GetDetail(string id) { var entity = await _db.Queryable().FirstAsync(p => p.Id == id); if (entity == null) throw NCCException.Oh(ErrorCode.COM1005); var output = entity.Adapt(); // 获取成员信息 var members = await _db.Queryable() .Where(x => x.JsjId == id && x.Status == "ACTIVE" && x.DeleteMark == 0) .OrderBy(x => x.SortOrder) .Select(x => new { id = x.Id, userId = x.UserId, userName = x.UserName, isLeader = x.IsLeader, sortOrder = x.SortOrder, status = x.Status, }) .ToListAsync(); return new { jsj = output, members = members }; } #endregion #region 获取金三角设定列表 /// /// 获取金三角设定列表 /// /// 请求参数 /// [HttpGet("")] public async Task GetList([FromQuery] LqYcsdJsjListQueryInput input) { var sidx = input.sidx == null ? "id" : input.sidx; var data = await _db.Queryable() .WhereIF(!string.IsNullOrEmpty(input.id), p => p.Id.Contains(input.id)) .WhereIF(!string.IsNullOrEmpty(input.yf), p => p.Yf.Contains(input.yf)) .WhereIF(!string.IsNullOrEmpty(input.md), p => p.Md.Contains(input.md)) .WhereIF(!string.IsNullOrEmpty(input.jsj), p => p.Jsj.Contains(input.jsj)) .Select(it => new LqYcsdJsjListOutput { id = it.Id, yf = it.Yf, md = it.Md, jsj = it.Jsj, }) .MergeTable() .OrderBy(sidx + " " + input.sort) .ToPagedListAsync(input.currentPage, input.pageSize); return PageResult.SqlSugarPageResult(data); } #endregion #region 获取本月金三角列表 /// /// 获取本月金三角列表 /// /// 本月金三角列表 [HttpGet("Actions/GetThisMonthList")] public async Task GetThisMonthList() { var data = await _db.Queryable() .Where(x => x.Yf == DateTime.Now.ToString("yyyyMM")) .Select(it => new LqYcsdJsjListOutput { id = it.Id, yf = it.Yf, md = it.Md, jsj = it.Jsj, }) .MergeTable() .ToListAsync(); return data; } #endregion #region 获取用户本月金三角信息 /// /// 获取某个用户本月所在的金三角信息 /// /// 用户ID /// 用户本月所在的金三角信息 [HttpGet("Actions/GetThisMonthJsjInfo")] public async Task GetThisMonthJsjInfo([FromQuery] string userId) { if (string.IsNullOrEmpty(userId)) { throw NCCException.Oh(ErrorCode.COM1001, "用户ID不能为空"); } var currentMonth = DateTime.Now.ToString("yyyyMM"); // 先查询用户的金三角关联信息 var jsjUser = await _db.Queryable().Where(x => x.UserId == userId && x.DeleteMark == 0).FirstAsync(); if (jsjUser == null) { return null; } // 查询金三角信息 var jsj = await _db.Queryable().Where(x => x.Id == jsjUser.JsjId && x.Yf == currentMonth).FirstAsync(); if (jsj == null) { return null; } // 查询门店信息 var store = await _db.Queryable().Where(x => x.Id == jsj.Md).FirstAsync(); return new LqYcsdJsjByUserMonthOutput { jsjId = jsj.Id, jsjName = jsj.Jsj, month = jsj.Yf, storeId = jsj.Md, storeName = store?.Dm, userId = jsjUser.UserId, userName = jsjUser.UserName, isLeader = jsjUser.IsLeader, status = jsjUser.Status, sortOrder = jsjUser.SortOrder, }; } #endregion #region 根据用户和月份获取金三角信息 /// /// 根据用户和时间获取金三角信息 /// /// /// 根据指定的用户ID和时间,从时间中提取月份,查询该用户在该月份的金三角信息。 /// /// 示例请求: /// GET /api/Extend/LqYcsdJsj/GetJsjInfoByUserMonth?userId=123456&dateTime=2024-12-15%2014:30:00 /// /// 参数说明: /// - userId: 用户ID,必填 /// - dateTime: 时间,格式为yyyy-MM-dd HH:mm:ss,必填 /// /// 返回信息包括: /// - 金三角基本信息(ID、名称、月份) /// - 门店信息(ID、名称) /// - 用户信息(ID、姓名、是否顾问、状态、排序) /// /// 查询参数 /// 金三角信息 /// 查询成功 /// 参数错误 /// 未找到相关数据 [HttpGet("GetJsjInfoByUserMonth")] public async Task GetJsjInfoByUserMonth([FromQuery] LqYcsdJsjByUserMonthInput input) { if (string.IsNullOrEmpty(input.UserId)) { throw NCCException.Oh(ErrorCode.COM1001, "用户ID不能为空"); } if (input.DateTime == default(DateTime)) { throw NCCException.Oh(ErrorCode.COM1001, "时间不能为空"); } // 从时间中提取月份(格式:yyyyMM) var month = input.DateTime.ToString("yyyyMM"); // 先查询用户的金三角关联信息 var jsjUser = await _db.Queryable().Where(x => x.UserId == input.UserId && x.DeleteMark == 0 && x.Month == month).FirstAsync(); if (jsjUser == null) { return null; } // 查询金三角信息 var jsj = await _db.Queryable().Where(x => x.Id == jsjUser.JsjId && x.Yf == month).FirstAsync(); if (jsj == null) { return null; } // 查询门店信息 var store = await _db.Queryable().Where(x => x.Id == jsj.Md).FirstAsync(); return new LqYcsdJsjByUserMonthOutput { jsjId = jsj.Id, jsjName = jsj.Jsj, month = jsj.Yf, storeId = jsj.Md, storeName = store?.Dm, userId = jsjUser.UserId, userName = jsjUser.UserName, isLeader = jsjUser.IsLeader, status = jsjUser.Status, sortOrder = jsjUser.SortOrder, }; } #endregion #region 标记删除用户金三角关联信息 /// /// 标记删除用户金三角关联信息 /// /// /// 根据金三角用户关系ID,将绑定关系的删除标记设置为已删除 /// /// 示例请求: /// ```json /// { /// "id": "关系ID" /// } /// ``` /// /// 参数 /// /// 成功删除 /// 参数错误 /// 服务器错误 [HttpPost("Actions/DeleteJsjUserRelation")] public async Task DeleteJsjUserRelation([FromBody] LqJinsanjiaoUserDeleteInput input) { if (string.IsNullOrEmpty(input.Id)) throw NCCException.Oh(ErrorCode.COM1000, "ID不能为空"); var isOk = await _db.Updateable() .SetColumns(x => new LqJinsanjiaoUserEntity { DeleteMark = 1, Status = "INACTIVE" }) .Where(x => x.Id == input.Id && x.DeleteMark == 0) .ExecuteCommandAsync(); if (!(isOk > 0)) throw NCCException.Oh(ErrorCode.COM1000, "未找到要删除的记录"); } #endregion #region 新建金三角 /// /// 新建金三角 /// /// 参数 /// [HttpPost("")] public async Task Create([FromBody] LqYcsdJsjCrInput input) { var userInfo = await _userManager.GetUserInfo(); // 参数验证 if (string.IsNullOrEmpty(input.yf)) throw NCCException.Oh(ErrorCode.COM1000, "月份不能为空"); if (string.IsNullOrEmpty(input.md)) throw NCCException.Oh(ErrorCode.COM1000, "门店不能为空"); if (string.IsNullOrEmpty(input.jsj)) throw NCCException.Oh(ErrorCode.COM1000, "金三角名称不能为空"); // 验证月份格式 if (!DateTime.TryParseExact(input.yf, "yyyyMM", null, DateTimeStyles.None, out _)) { throw NCCException.Oh(ErrorCode.COM1000, "月份格式必须为yyyyMM"); } // 验证多人战队必须有顾问 if (input.members != null && input.members.Count >= 2) { var hasLeader = input.members.Any(m => m.isLeader == 1); if (!hasLeader) { throw NCCException.Oh(ErrorCode.COM1000, "两人或两人以上的战队必须有一个顾问"); } } // 验证成员 UserID 不能为空 if (input.members != null && input.members.Count > 0) { foreach (var member in input.members) { if (string.IsNullOrEmpty(member.userId)) { throw NCCException.Oh(ErrorCode.COM1000, $"成员【{member.userName}】的 UserID 不能为空"); } } } // 验证金三角名称是否已存在 var existingJsj = await _db.Queryable().Where(x => x.Yf == input.yf && x.Md == input.md && x.Jsj == input.jsj).FirstAsync(); if (existingJsj != null) { throw NCCException.Oh(ErrorCode.COM1000, "该门店该月份已存在同名金三角"); } try { // 开启事务 _db.BeginTran(); // 1. 创建金三角基础信息 var entity = input.Adapt(); entity.Id = YitIdHelper.NextId().ToString(); var isOk = await _db.Insertable(entity).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync(); if (!(isOk > 0)) throw NCCException.Oh(ErrorCode.COM1000); // 2 创建金三角成员绑定关系 if (input.members != null && input.members.Count > 0) { await CreateJsjMembers(entity.Id, input.members, userInfo.userId, input.yf); } // 3. 创建站点战队T区(如果金三角不是T区且不是单人),暂时不用创建金三角的T区,等待业务部门确认逻辑后进行 // if (!input.jsj.EndsWith("T区") && input.members != null && input.members.Count > 1) // { // await CreateOrUpdateTeamTArea(input.yf, input.jsj, input.md, userInfo.userId); // } // 提交事务 _db.CommitTran(); } catch (Exception ex) { // 回滚事务 _db.RollbackTran(); throw NCCException.Oh(ErrorCode.COM1000, ex.Message); } } #endregion #region 给金三角添加用户绑定关系 /// /// 给金三角添加用户绑定关系 /// /// /// 将用户添加到指定的金三角中,建立绑定关系。 /// /// 示例请求: /// ```json /// { /// "jsjId": "金三角ID", /// "userId": "用户ID", /// "userName": "用户姓名", /// "isLeader": 0, /// "status": "ACTIVE", /// "sortOrder": 1 /// } /// ``` /// /// 参数说明: /// - jsjId: 金三角ID,必填 /// - userId: 用户ID,必填 /// - userName: 用户姓名,必填 /// - isLeader: 是否顾问(0-否,1-是),默认0 /// - status: 状态(ACTIVE-活跃,INACTIVE-非活跃),默认ACTIVE /// - sortOrder: 排序号,如果不填则自动设置为最大排序号+1 /// /// 业务规则: /// 1. 金三角必须存在 /// 2. 用户必须存在 /// 3. 用户不能在同一个月份的其他金三角中(如果已存在绑定关系,需要先解除) /// 4. 用户不能重复添加到当前金三角 /// 5. 如果多人战队(2人及以上),必须至少有一个顾问 /// /// 添加用户绑定关系的参数 /// 绑定关系ID /// 添加成功 /// 参数错误或业务规则验证失败 /// 金三角或用户不存在 /// 服务器错误 [HttpPost("Actions/AddUserToJsj")] public async Task AddUserToJsj([FromBody] LqJinsanjiaoUserCrInput input) { var userInfo = await _userManager.GetUserInfo(); // 1. 参数验证 if (string.IsNullOrEmpty(input.jsjId)) throw NCCException.Oh("金三角ID不能为空"); if (string.IsNullOrEmpty(input.userId)) throw NCCException.Oh("用户ID不能为空(请确保选择了有效的系统用户)"); if (string.IsNullOrEmpty(input.userName)) throw NCCException.Oh("用户姓名不能为空"); // 2. 验证金三角是否存在 var jsj = await _db.Queryable().Where(x => x.Id == input.jsjId).FirstAsync(); if (jsj == null) throw NCCException.Oh("金三角不存在"); // 4. 验证用户是否已经在同一个月份的其他金三角中 var existingRelation = await _db.Queryable() .Where(x => x.UserId == input.userId && x.JsjId != input.jsjId && x.Month == jsj.Yf && x.DeleteMark == 0).FirstAsync(); if (existingRelation != null) { var existingJsj = await _db.Queryable().Where(x => x.Id == existingRelation.JsjId).FirstAsync(); throw NCCException.Oh($"该用户已在{existingJsj?.Jsj ?? "其他"}金三角中,请先解除绑定关系"); } // 5. 验证用户是否已经在当前金三角中 var currentRelation = await _db.Queryable().Where(x => x.UserId == input.userId && x.JsjId == input.jsjId && x.DeleteMark == 0).FirstAsync(); if (currentRelation != null) { // 如果已存在但已删除或非活跃,则恢复;否则提示已存在 if (currentRelation.DeleteMark == 0 && currentRelation.Status == "ACTIVE") { throw NCCException.Oh(ErrorCode.COM1000, "该用户已在该金三角中"); } else { // 恢复已删除或非活跃的关系 currentRelation.Status = input.status ?? "ACTIVE"; currentRelation.IsLeader = input.isLeader; currentRelation.UserName = input.userName; currentRelation.DeleteMark = 0; currentRelation.LastModifyTime = DateTime.Now; currentRelation.LastModifyUserId = userInfo.userId; // 如果指定了排序号,更新排序号 if (input.sortOrder > 0) { currentRelation.SortOrder = input.sortOrder; } await _db.Updateable(currentRelation).ExecuteCommandAsync(); return new { id = currentRelation.Id, message = "已恢复用户绑定关系" }; } } // 6. 获取当前金三角的成员数量(用于验证多人战队必须有顾问) var memberCount = await _db.Queryable() .Where(x => x.JsjId == input.jsjId && x.DeleteMark == 0 && x.Status == "ACTIVE") .CountAsync(); // 如果添加后成员数量>=2,且当前用户不是顾问,则需要验证是否已有顾问 if (memberCount + 1 >= 2 && input.isLeader == 0) { var hasLeader = await _db.Queryable().Where(x => x.JsjId == input.jsjId && x.DeleteMark == 0 && x.Status == "ACTIVE" && x.IsLeader == 1).CountAsync() > 0; if (!hasLeader) { throw NCCException.Oh("两人或两人以上的战队必须有一个顾问"); } } // 7. 自动计算排序号(如果没有指定) int sortOrder = input.sortOrder; if (sortOrder <= 0) { var maxSortOrder = await _db.Queryable().Where(x => x.JsjId == input.jsjId && x.DeleteMark == 0).MaxAsync(x => (int?)x.SortOrder); sortOrder = maxSortOrder.HasValue ? maxSortOrder.Value + 1 : 1; } try { // 开启事务 _db.BeginTran(); // 8. 创建用户绑定关系 var memberEntity = new LqJinsanjiaoUserEntity { Id = YitIdHelper.NextId().ToString(), JsjId = input.jsjId, UserId = input.userId, UserName = input.userName, IsLeader = input.isLeader, Status = input.status ?? "ACTIVE", SortOrder = sortOrder, CreatorTime = DateTime.Now, CreatorUserId = userInfo.userId, DeleteMark = 0, Month = jsj.Yf, // 使用金三角的月份 }; var isOk = await _db.Insertable(memberEntity).ExecuteCommandAsync(); if (!(isOk > 0)) throw NCCException.Oh("添加用户绑定关系失败"); // 提交事务 _db.CommitTran(); return new { id = memberEntity.Id, message = "添加成功" }; } catch (Exception ex) { // 回滚事务 _db.RollbackTran(); throw NCCException.Oh(ErrorCode.COM1000, ex.Message); } } #endregion #region 获取金三角设定无分页列表 /// /// 获取金三角设定无分页列表 /// /// 请求参数 /// [NonAction] public async Task GetNoPagingList([FromQuery] LqYcsdJsjListQueryInput input) { var sidx = input.sidx == null ? "id" : input.sidx; var data = await _db.Queryable() .WhereIF(!string.IsNullOrEmpty(input.id), p => p.Id.Contains(input.id)) .WhereIF(!string.IsNullOrEmpty(input.yf), p => p.Yf.Contains(input.yf)) .WhereIF(!string.IsNullOrEmpty(input.md), p => p.Md.Contains(input.md)) .WhereIF(!string.IsNullOrEmpty(input.jsj), p => p.Jsj.Contains(input.jsj)) .Select(it => new LqYcsdJsjListOutput { id = it.Id, yf = it.Yf, md = it.Md, jsj = it.Jsj, }) .MergeTable() .OrderBy(sidx + " " + input.sort) .ToListAsync(); return data; } #endregion #region 导出金三角设定 /// /// 导出金三角设定 /// /// 请求参数 /// [HttpGet("Actions/Export")] public async Task Export([FromQuery] LqYcsdJsjListQueryInput input) { var userInfo = await _userManager.GetUserInfo(); var exportData = new List(); if (input.dataType == 0) { var data = Clay.Object(await this.GetList(input)); exportData = data.Solidify>().list; } else { exportData = await this.GetNoPagingList(input); } List paramList = "[{\"value\":\"主键\",\"field\":\"id\"},{\"value\":\"月份\",\"field\":\"yf\"},{\"value\":\"门店\",\"field\":\"md\"},{\"value\":\"金三角\",\"field\":\"jsj\"}]".ToList(); ExcelConfig excelconfig = new ExcelConfig(); excelconfig.FileName = "金三角设定.xls"; excelconfig.HeadFont = "微软雅黑"; excelconfig.HeadPoint = 10; excelconfig.IsAllSizeColumn = true; excelconfig.ColumnModel = new List(); List selectKeyList = input.selectKey.Split(',').ToList(); foreach (var item in selectKeyList) { var isExist = paramList.Find(p => p.field == item); if (isExist != null) { excelconfig.ColumnModel.Add(new ExcelColumnModel() { Column = isExist.field, ExcelColumn = isExist.value }); } } var addPath = FileVariable.TemporaryFilePath + excelconfig.FileName; ExcelExportHelper.Export(exportData, excelconfig, addPath); var fileName = _userManager.UserId + "|" + addPath + "|xls"; var output = new { name = excelconfig.FileName, url = "/api/File/Download?encryption=" + DESCEncryption.Encrypt(fileName, "NCC") }; return output; } #endregion #region 批量删除金三角设定 /// /// 批量删除金三角设定 /// /// 主键数组 /// [HttpPost("batchRemove")] public async Task BatchRemove([FromBody] List ids) { var entitys = await _db.Queryable().In(it => it.Id, ids).ToListAsync(); if (entitys.Count > 0) { try { //开启事务 _db.BeginTran(); //批量删除金三角设定 await _db.Deleteable().In(d => d.Id, ids).ExecuteCommandAsync(); //关闭事务 _db.CommitTran(); } catch (Exception) { //回滚事务 _db.RollbackTran(); throw NCCException.Oh(ErrorCode.COM1002); } } } #endregion #region 更新金三角设定 /// /// 更新金三角设定 /// /// 主键 /// 参数 /// [HttpPut("{id}")] public async Task Update(string id, [FromBody] LqYcsdJsjUpInput input) { var entity = input.Adapt(); var isOk = await _db.Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync(); if (!(isOk > 0)) throw NCCException.Oh(ErrorCode.COM1001); } #endregion #region 删除金三角设定 /// /// 删除金三角设定 /// /// [HttpDelete("{id}")] public async Task Delete(string id) { var entity = await _db.Queryable().FirstAsync(p => p.Id == id); _ = entity ?? throw NCCException.Oh(ErrorCode.COM1005); var isOk = await _db.Deleteable().Where(d => d.Id == id).ExecuteCommandAsync(); if (!(isOk > 0)) throw NCCException.Oh(ErrorCode.COM1002); } #endregion #region 金三角月度业绩统计 /// /// 获取金三角月度业绩统计 /// /// 月份(格式:yyyyMM),为空则查询所有月份 /// 金三角ID,为空则查询所有金三角 /// 门店ID,为空则查询所有门店 /// 金三角月度业绩统计列表 [HttpGet("Actions/GetMonthlyPerformance")] public async Task GetMonthlyPerformance([FromQuery] string month = null, [FromQuery] string jsjId = null, [FromQuery] string storeId = null) { var query = _db.Queryable() .LeftJoin((jsj, jksyj) => jsj.Id == jksyj.Jsj_id) .LeftJoin((jsj, jksyj, md) => jsj.Md == md.Id) .Where((jsj, jksyj, md) => jsj.Yf != null) .Where((jsj, jksyj, md) => jksyj.Yjsj != null) .Where((jsj, jksyj, md) => jksyj.Jksyj != null && jksyj.Jksyj != "" && jksyj.Jksyj != "0") .WhereIF(!string.IsNullOrEmpty(month), (jsj, jksyj, md) => jsj.Yf == month) .WhereIF(!string.IsNullOrEmpty(jsjId), (jsj, jksyj, md) => jsj.Id == jsjId) .WhereIF(!string.IsNullOrEmpty(storeId), (jsj, jksyj, md) => jsj.Md == storeId) .GroupBy( (jsj, jksyj, md) => new { jsj.Id, jsj.Jsj, jsj.Yf, jsj.Md, md.Dm, } ) .Select( (jsj, jksyj, md) => new { jsjId = jsj.Id, jsjName = jsj.Jsj, month = jsj.Yf, storeId = jsj.Md, storeName = md.Dm, totalPerformance = SqlFunc.AggregateSum(SqlFunc.ToDecimal(jksyj.Jksyj)), orderCount = SqlFunc.AggregateCount(jksyj.Id), avgPerformance = SqlFunc.AggregateAvg(SqlFunc.ToDecimal(jksyj.Jksyj)), lastOrderDate = SqlFunc.AggregateMax(jksyj.Yjsj), firstOrderDate = SqlFunc.AggregateMin(jksyj.Yjsj), } ) .OrderBy(jsj => jsj.month, OrderByType.Desc) .OrderBy(jsj => jsj.totalPerformance, OrderByType.Desc); var result = await query.ToListAsync(); return result; } /// /// 获取金三角月度业绩排名 /// /// 月份(格式:yyyyMM) /// 排名数量,默认10 /// 金三角月度业绩排名列表 [HttpGet("Actions/GetMonthlyPerformanceRanking")] public async Task GetMonthlyPerformanceRanking([FromQuery] string month, [FromQuery] int topCount = 10) { if (string.IsNullOrEmpty(month)) { throw NCCException.Oh(ErrorCode.COM1001, "月份参数不能为空"); } var query = _db.Queryable() .LeftJoin((jsj, jksyj) => jsj.Id == jksyj.Jsj_id) .LeftJoin((jsj, jksyj, md) => jsj.Md == md.Id) .Where((jsj, jksyj, md) => jsj.Yf == month) .Where((jsj, jksyj, md) => jksyj.Yjsj != null) .Where((jsj, jksyj, md) => jksyj.Jksyj != null && jksyj.Jksyj != "" && jksyj.Jksyj != "0") .GroupBy( (jsj, jksyj, md) => new { jsj.Id, jsj.Jsj, jsj.Yf, jsj.Md, md.Dm, } ) .Select( (jsj, jksyj, md) => new { jsjId = jsj.Id, jsjName = jsj.Jsj, month = jsj.Yf, storeId = jsj.Md, storeName = md.Dm, totalPerformance = SqlFunc.AggregateSum(SqlFunc.ToDecimal(jksyj.Jksyj)), orderCount = SqlFunc.AggregateCount(jksyj.Id), ranking = 0, // 排名将在后续计算 } ) .OrderBy(jsj => jsj.totalPerformance, OrderByType.Desc) .Take(topCount); var result = await query.ToListAsync(); // 创建包含排名的结果 var rankedResult = result .Select( (item, index) => new { item.jsjId, item.jsjName, item.month, item.storeId, item.storeName, item.totalPerformance, item.orderCount, ranking = index + 1, } ) .ToList(); return rankedResult; } #endregion #region 私有辅助方法 /// /// 创建或更新门店T区 /// /// 月份 /// 门店ID /// 创建人ID /// private async Task CreateOrUpdateStoreTArea(string yf, string mdId, string creatorUserId) { // 获取门店名称 var storeName = await GetStoreNameById(mdId); var tAreaName = $"{storeName}T区"; // 检查该门店该月份是否已有T区 var existingTArea = await _db.Queryable().Where(x => x.Yf == yf && x.Md == mdId && x.Jsj == tAreaName).FirstAsync(); if (existingTArea == null) { // 创建门店T区 var tAreaEntity = new LqYcsdJsjEntity { Id = YitIdHelper.NextId().ToString(), Yf = yf, Md = mdId, Jsj = tAreaName, }; await _db.Insertable(tAreaEntity).ExecuteCommandAsync(); } } /// /// 创建或更新战队T区 /// /// 月份 /// 战队名称 /// 门店ID /// 创建人ID /// private async Task CreateOrUpdateTeamTArea(string yf, string teamName, string mdId, string creatorUserId) { var tAreaName = $"{teamName}T区"; // 检查该战队该月份是否已有T区 var existingTArea = await _db.Queryable().Where(x => x.Yf == yf && x.Md == mdId && x.Jsj == tAreaName).FirstAsync(); if (existingTArea == null) { // 创建战队T区 var tAreaEntity = new LqYcsdJsjEntity { Id = YitIdHelper.NextId().ToString(), Yf = yf, Md = mdId, Jsj = tAreaName, }; await _db.Insertable(tAreaEntity).ExecuteCommandAsync(); } } /// /// 创建金三角成员绑定关系 /// /// 金三角ID /// 成员列表 /// 创建人ID /// 月份(格式:yyyyMM) /// private async Task CreateJsjMembers(string jsjId, List members, string creatorUserId, string yf) { var memberEntities = new List(); for (int i = 0; i < members.Count; i++) { var member = members[i]; var memberEntity = new NCC.Extend.Entitys.lq_jinsanjiao_user.LqJinsanjiaoUserEntity { Id = YitIdHelper.NextId().ToString(), JsjId = jsjId, UserId = member.userId, UserName = member.userName, IsLeader = member.isLeader, Status = "ACTIVE", SortOrder = member.sortOrder > 0 ? member.sortOrder : i + 1, CreatorTime = DateTime.Now, CreatorUserId = creatorUserId, DeleteMark = 0, Month = yf, }; memberEntities.Add(memberEntity); } if (memberEntities.Count > 0) { await _db.Insertable(memberEntities).ExecuteCommandAsync(); } } /// /// 根据门店ID获取门店名称 /// /// 门店ID /// private async Task GetStoreNameById(string mdId) { try { var storeName = await _db.Queryable().Where(x => x.Id == mdId).Select(x => x.Dm).FirstAsync(); return string.IsNullOrEmpty(storeName) ? "未知门店" : storeName; } catch { return "未知门店"; } } #endregion } }