using System; using System.Collections.Generic; 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.LqTkjlb; using NCC.Extend.Entitys.lq_event; using NCC.Extend.Entitys.lq_eventuser; using NCC.Extend.Entitys.lq_khxx; using NCC.Extend.Entitys.lq_mdxx; using NCC.Extend.Entitys.lq_ryzl; using NCC.Extend.Entitys.lq_tkjlb; using NCC.Extend.Interfaces.LqTkjlb; using NCC.FriendlyException; using NCC.JsonSerialization; using NCC.System.Entitys.Permission; using SqlSugar; using Yitter.IdGenerator; namespace NCC.Extend.LqTkjlb { /// /// 拓客管理服务 /// [ApiDescriptionSettings(Tag = "绿纤拓客管理服务", Name = "LqTkjlb", Order = 200)] [Route("api/Extend/[controller]")] public class LqTkjlbService : ILqTkjlbService, IDynamicApiController, ITransient { private readonly ISqlSugarRepository _lqTkjlbRepository; private readonly SqlSugarScope _db; private readonly IUserManager _userManager; /// /// 初始化一个类型的新实例 /// public LqTkjlbService(ISqlSugarRepository lqTkjlbRepository, IUserManager userManager) { _lqTkjlbRepository = lqTkjlbRepository; _db = _lqTkjlbRepository.Context; _userManager = userManager; } #region 获取拓客管理 /// /// 获取拓客管理 /// /// 参数 /// [HttpGet("{id}")] public async Task GetInfo(string id) { // 使用SqlFunc在查询时直接获取用户名和活动名称 var result = await _db.Queryable() .Where(p => p.Id == id) .Select(p => new LqTkjlbInfoOutput { id = p.Id, expansionTime = p.ExpansionTime, expansionUserId = p.ExpansionUserId, expansionUserName = SqlFunc.Subqueryable().Where(u => u.Id == p.ExpansionUserId).Select(u => u.RealName), customerName = p.CustomerName, customerPhone = p.CustomerPhone, buyNumber = p.BuyNumber, paymentMethod = p.PaymentMethod, isAddWeChat = p.IsAddWeChat, remarks = p.Remarks, storeId = p.StoreId, teamName = p.TeamName, eventId = p.EventId, eventName = SqlFunc.Subqueryable().Where(e => e.Id == p.EventId).Select(e => e.EventName), }) .FirstAsync(); return result; } #endregion #region 获取拓客管理列表 /// /// 获取拓客管理列表 /// /// 请求参数 /// [HttpGet("")] public async Task GetList([FromQuery] LqTkjlbListQueryInput input) { var sidx = input.sidx == null ? "id" : input.sidx; List queryTksj = input.expansionTime != null ? input.expansionTime.Split(',').ToObeject>() : null; DateTime? startTksj = queryTksj != null ? Ext.GetDateTime(queryTksj.First()) : null; DateTime? endTksj = queryTksj != null ? Ext.GetDateTime(queryTksj.Last()) : null; var data = await _db.Queryable() .WhereIF(!string.IsNullOrEmpty(input.id), p => p.Id.Contains(input.id)) .WhereIF(queryTksj != null, p => p.ExpansionTime >= new DateTime(startTksj.ToDate().Year, startTksj.ToDate().Month, startTksj.ToDate().Day, 0, 0, 0)) .WhereIF(queryTksj != null, p => p.ExpansionTime <= new DateTime(endTksj.ToDate().Year, endTksj.ToDate().Month, endTksj.ToDate().Day, 23, 59, 59)) .WhereIF(!string.IsNullOrEmpty(input.expansionUserId), p => p.ExpansionUserId.Equals(input.expansionUserId)) .WhereIF(!string.IsNullOrEmpty(input.customerName), p => p.CustomerName.Contains(input.customerName)) .WhereIF(!string.IsNullOrEmpty(input.customerPhone), p => p.CustomerPhone.Contains(input.customerPhone)) .WhereIF(!string.IsNullOrEmpty(input.buyNumber), p => p.BuyNumber.Equals(input.buyNumber)) .WhereIF(!string.IsNullOrEmpty(input.paymentMethod), p => p.PaymentMethod.Equals(input.paymentMethod)) .WhereIF(!string.IsNullOrEmpty(input.isAddWeChat), p => p.IsAddWeChat.Equals(input.isAddWeChat)) .WhereIF(!string.IsNullOrEmpty(input.remarks), p => p.Remarks.Contains(input.remarks)) .WhereIF(!string.IsNullOrEmpty(input.storeId), p => p.StoreId.Contains(input.storeId)) .WhereIF(!string.IsNullOrEmpty(input.teamName), p => p.TeamName.Contains(input.teamName)) .WhereIF(!string.IsNullOrEmpty(input.eventId), p => p.EventId.Contains(input.eventId)) .Select(it => new LqTkjlbListOutput { id = it.Id, expansionTime = it.ExpansionTime, expansionUserId = it.ExpansionUserId, expansionUserName = SqlFunc.Subqueryable().Where(u => u.MobilePhone == it.ExpansionUserId).Select(u => u.RealName), customerName = it.CustomerName, customerPhone = it.CustomerPhone, buyNumber = it.BuyNumber, paymentMethod = it.PaymentMethod, isAddWeChat = it.IsAddWeChat, remarks = it.Remarks, storeId = it.StoreId, teamName = it.TeamName, eventId = it.EventId, eventName = SqlFunc.Subqueryable().Where(u => u.Id == it.EventId).Select(u => u.EventName), }) .MergeTable() .OrderBy(sidx + " " + input.sort) .ToPagedListAsync(input.currentPage, input.pageSize); return PageResult.SqlSugarPageResult(data); } #endregion #region 新建拓客管理 /// /// 新建拓客管理 /// /// 参数 /// [HttpPost("")] public async Task Create([FromBody] LqTkjlbCrInput input) { var userInfo = await _userManager.GetUserInfo(); //通过input.dhhm去查询用户信息 var user = _db.Queryable().Where(u => u.Sjh == input.customerPhone).Any(); if (user) { return NCCException.Oh("该手机号码已存在于会员或线索池中"); } // 使用事务确保数据一致性 var result = await _db.Ado.UseTranAsync(async () => { //通过input.eventId去查询拓客活动信息 var eventUserInfoList = await _db.Queryable().Where(u => u.EventId == input.eventId && u.UserId == input.expansionUserId).ToListAsync(); if (eventUserInfoList == null || eventUserInfoList.Count == 0) { throw NCCException.Oh("未找到对应的拓客活动用户信息,请确认活动ID和用户ID是否正确"); } var eventUserInfo = eventUserInfoList.First(); // 创建拓客记录 var entity = input.Adapt(); entity.Id = YitIdHelper.NextId().ToString(); entity.TeamName = eventUserInfo.TeamName; entity.StoreId = eventUserInfo.StoreId; entity.DepId = eventUserInfo.DepId; entity.ExpansionTime = DateTime.Now; var isOk = await _db.Insertable(entity).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync(); if (!(isOk > 0)) throw NCCException.Oh("创建拓客记录失败"); // 创建客户信息 LqKhxxEntity MemberInfo = new LqKhxxEntity(); MemberInfo.Id = YitIdHelper.NextId().ToString(); MemberInfo.Khmc = entity.CustomerName; MemberInfo.Sjh = input.customerPhone; // 设置手机号 MemberInfo.Khlx = "线索"; MemberInfo.Dah = "GK" + DateTime.Now.ToString("yyyyMMddHHmmss"); MemberInfo.Gsmd = eventUserInfo.StoreId; var memberResult = await _db.Insertable(MemberInfo).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync(); if (!(memberResult > 0)) { throw NCCException.Oh("创建客户信息失败"); } var storeinfo = await _db.Queryable().Where(u => u.Id == eventUserInfo.StoreId).FirstAsync(); return new { entity = entity, storeinfo = storeinfo }; }); if (!result.IsSuccess) { return NCCException.Oh($"创建拓客记录失败:{result.ErrorMessage}"); } return result.Data; } #endregion #region 获取拓客管理无分页列表 /// /// 获取拓客管理无分页列表 /// /// 请求参数 /// [NonAction] public async Task GetNoPagingList([FromQuery] LqTkjlbListQueryInput input) { var sidx = input.sidx == null ? "id" : input.sidx; List queryExpansionTime = input.expansionTime != null ? input.expansionTime.Split(',').ToObeject>() : null; DateTime? startExpansionTime = queryExpansionTime != null ? Ext.GetDateTime(queryExpansionTime.First()) : null; DateTime? endExpansionTime = queryExpansionTime != null ? Ext.GetDateTime(queryExpansionTime.Last()) : null; var data = await _db.Queryable() .WhereIF(!string.IsNullOrEmpty(input.id), p => p.Id.Contains(input.id)) .WhereIF( queryExpansionTime != null, p => p.ExpansionTime >= new DateTime(startExpansionTime.ToDate().Year, startExpansionTime.ToDate().Month, startExpansionTime.ToDate().Day, 0, 0, 0) ) .WhereIF(queryExpansionTime != null, p => p.ExpansionTime <= new DateTime(endExpansionTime.ToDate().Year, endExpansionTime.ToDate().Month, endExpansionTime.ToDate().Day, 23, 59, 59)) .WhereIF(!string.IsNullOrEmpty(input.expansionUserId), p => p.ExpansionUserId.Equals(input.expansionUserId)) .WhereIF(!string.IsNullOrEmpty(input.customerName), p => p.CustomerName.Contains(input.customerName)) .WhereIF(!string.IsNullOrEmpty(input.customerPhone), p => p.CustomerPhone.Contains(input.customerPhone)) .WhereIF(!string.IsNullOrEmpty(input.buyNumber), p => p.BuyNumber.ToString().Equals(input.buyNumber)) .WhereIF(!string.IsNullOrEmpty(input.paymentMethod), p => p.PaymentMethod.Equals(input.paymentMethod)) .WhereIF(!string.IsNullOrEmpty(input.isAddWeChat), p => p.IsAddWeChat.Equals(input.isAddWeChat)) .WhereIF(!string.IsNullOrEmpty(input.remarks), p => p.Remarks.Contains(input.remarks)) .WhereIF(!string.IsNullOrEmpty(input.storeId), p => p.StoreId.Contains(input.storeId)) .WhereIF(!string.IsNullOrEmpty(input.teamName), p => p.TeamName.Contains(input.teamName)) .WhereIF(!string.IsNullOrEmpty(input.eventId), p => p.EventId.Equals(input.eventId)) .Select(it => new LqTkjlbListOutput { id = it.Id, expansionTime = it.ExpansionTime, expansionUserId = it.ExpansionUserId, expansionUserName = it.ExpansionUserId, // 这里需要根据实际业务逻辑获取用户名 customerName = it.CustomerName, customerPhone = it.CustomerPhone, buyNumber = it.BuyNumber, paymentMethod = it.PaymentMethod, isAddWeChat = it.IsAddWeChat, remarks = it.Remarks, storeId = it.StoreId, teamName = it.TeamName, eventId = it.EventId, eventName = it.EventId, // 这里需要根据实际业务逻辑获取活动名称 }) .MergeTable() .OrderBy(sidx + " " + input.sort) .ToListAsync(); return data; } #endregion #region 导出拓客管理 /// /// 导出拓客管理 /// /// 请求参数 /// [HttpGet("Actions/Export")] public async Task Export([FromQuery] LqTkjlbListQueryInput 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\":\"tkry\"},{\"value\":\"拓客时间\",\"field\":\"tksj\"},{\"value\":\"顾客姓名\",\"field\":\"gkxm\"},{\"value\":\"电话号码\",\"field\":\"dhhm\"},{\"value\":\"购买张数\",\"field\":\"gmzs\"},{\"value\":\"支付方式\",\"field\":\"zffs\"},{\"value\":\"是否加微信\",\"field\":\"sfjwx\"},{\"value\":\"备注\",\"field\":\"bz\"},{\"value\":\"所属门店\",\"field\":\"ssmd\"},{\"value\":\"所属战队\",\"field\":\"sszd\"},]".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] LqTkjlbUpInput 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 获取拓客排行榜 /// /// 获取拓客排行榜 /// /// [HttpGet("Actions/GetRanking")] public async Task GetRanking() { var data = await _db.Queryable() .GroupBy(it => it.TeamName) .Select(it => new LqTkjlbRankingOutput { teamName = it.TeamName, expansionUserCount = SqlFunc.AggregateCount(it.Id) }) .ToListAsync(); // 在内存中排序并添加排名 var sortedData = data.OrderByDescending(it => it.expansionUserCount).ToList(); for (int i = 0; i < sortedData.Count; i++) { sortedData[i].ranking = i + 1; } return sortedData; } #endregion #region 获取战队人员详细报表 /// /// 获取战队人员详细报表 /// /// [HttpGet("Actions/GetTeamDetail")] public async Task GetTeamDetail() { var result = new List(); // 获取所有战队 var teams = await _db.Queryable().GroupBy(it => it.TeamName).Select(it => it.TeamName).ToListAsync(); foreach (var team in teams) { // 获取该战队所有人员的拓客数据 var teamMembers = await _db.Queryable() .Where(it => it.TeamName == team) .GroupBy(it => it.ExpansionUserId) .Select(it => new { // tkry = it.Tkry, tkry = SqlFunc.Subqueryable().Where(u => u.Id == it.ExpansionUserId).Select(u => u.RealName), tkrs = SqlFunc.AggregateCount(it.Id), }) .ToListAsync(); // 按拓客数量排序 var sortedMembers = teamMembers.OrderByDescending(m => m.tkrs).ToList(); // 计算战队总拓客数量 var totalCount = sortedMembers.Sum(m => m.tkrs); // 构建战队详情 var teamDetail = new LqTkjlbTeamDetailOutput { sszd = team, totalCount = totalCount, members = new List(), }; // 添加成员详情 for (int i = 0; i < sortedMembers.Count; i++) { var member = sortedMembers[i]; var percentage = totalCount > 0 ? (int)Math.Round((double)member.tkrs / totalCount * 100) : 0; teamDetail.members.Add( new TeamMemberDetail { tkry = member.tkry, tkrs = member.tkrs, teamRanking = i + 1, percentage = percentage, } ); } result.Add(teamDetail); } // 按战队总拓客数量排序 return result.OrderByDescending(t => t.totalCount).ToList(); } #endregion } }