using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using NCC.Common.Core.Manager;
using NCC.Common.Enum;
using NCC.Common.Filter;
using NCC.Dependency;
using NCC.DynamicApiController;
using NCC.Extend.Entitys.Dto.LqMdTarget;
using NCC.Extend.Entitys.Enum;
using NCC.Extend.Entitys.lq_md_target;
using NCC.Extend.Entitys.lq_mdxx;
using NCC.Extend.Interfaces.LqMdTarget;
using NCC.FriendlyException;
using SqlSugar;
using Yitter.IdGenerator;
namespace NCC.Extend.LqMdTarget
{
///
/// 门店目标服务
///
[ApiDescriptionSettings(Tag = "绿纤门店目标服务", Name = "LqMdTarget", Order = 200)]
[Route("api/Extend/[controller]")]
public class LqMdTargetService : ILqMdTargetService, IDynamicApiController, ITransient
{
private readonly ISqlSugarRepository _lqMdTargetRepository;
private readonly SqlSugarScope _db;
private readonly IUserManager _userManager;
///
/// 初始化一个类型的新实例
///
public LqMdTargetService(ISqlSugarRepository lqMdTargetRepository, IUserManager userManager)
{
_lqMdTargetRepository = lqMdTargetRepository;
_db = _lqMdTargetRepository.Context;
_userManager = userManager;
}
#region 获取门店目标信息
///
/// 获取门店目标信息
///
/// 主键ID
///
[HttpGet("{id}")]
public async Task GetInfo(string id)
{
var entity = await _db.Queryable().FirstAsync(p => p.Id == id);
_ = entity ?? throw NCCException.Oh(ErrorCode.COM1005);
var output = entity.Adapt();
return output;
}
#endregion
#region 获取门店目标列表
///
/// 获取门店目标列表
///
/// 请求参数
///
[HttpGet("")]
public async Task GetList([FromQuery] LqMdTargetListQueryInput input)
{
var sidx = input.sidx == null ? "F_Id" : input.sidx;
var data = await _db.Queryable()
.WhereIF(!string.IsNullOrEmpty(input.storeId), p => p.StoreId.Contains(input.storeId))
.WhereIF(!string.IsNullOrEmpty(input.month), p => p.Month == input.month)
.WhereIF(!string.IsNullOrEmpty(input.businessUnit), p => p.BusinessUnit.Contains(input.businessUnit))
.WhereIF(!string.IsNullOrEmpty(input.techDepartment), p => p.TechDepartment.Contains(input.techDepartment))
.WhereIF(!string.IsNullOrEmpty(input.educationDepartment), p => p.EducationDepartment.Contains(input.educationDepartment))
.WhereIF(!string.IsNullOrEmpty(input.majorProjectDepartment), p => p.MajorProjectDepartment.Contains(input.majorProjectDepartment))
.Select(it => new LqMdTargetListOutput
{
id = it.Id,
storeId = it.StoreId,
month = it.Month,
businessUnit = it.BusinessUnit,
techDepartment = it.TechDepartment,
educationDepartment = it.EducationDepartment,
majorProjectDepartment = it.MajorProjectDepartment,
businessUnitTarget = it.BusinessUnitTarget,
techDepartmentTarget = it.TechDepartmentTarget,
educationDepartmentTarget = it.EducationDepartmentTarget,
businessUnitGeneralManager = it.BusinessUnitGeneralManager,
businessUnitManager = it.BusinessUnitManager,
storeTarget = it.StoreTarget,
storeLifeline = it.StoreLifeline,
storeConsumeTarget = it.StoreConsumeTarget,
storeProjectTarget = it.StoreProjectTarget,
storeHeadcountTarget = it.StoreHeadcountTarget,
assistantHeadcountTargetStage1 = it.AssistantHeadcountTargetStage1,
assistantHeadcountTargetStage2 = it.AssistantHeadcountTargetStage2,
createTime = it.CreateTime,
createUser = it.CreateUser,
updateTime = it.UpdateTime,
updateUser = it.UpdateUser,
})
.MergeTable()
.OrderBy(sidx + " " + input.sort)
.ToPagedListAsync(input.currentPage, input.pageSize);
return PageResult.SqlSugarPageResult(data);
}
#endregion
#region 新建门店目标
///
/// 新建门店目标
///
/// 参数
///
[HttpPost("")]
public async Task Create([FromBody] LqMdTargetCrInput input)
{
var userInfo = await _userManager.GetUserInfo();
// 验证门店ID和月份的唯一性
var exists = await _db.Queryable().Where(p => p.StoreId == input.storeId && p.Month == input.month).AnyAsync();
if (exists)
{
throw NCCException.Oh(ErrorCode.COM1000, "该门店在该月份已存在目标记录");
}
// 验证月份格式
if (input.month.Length != 6 || !Regex.IsMatch(input.month, @"^\d{6}$"))
{
throw NCCException.Oh(ErrorCode.COM1000, "月份格式必须为YYYYMM(如:202501)");
}
var entity = input.Adapt();
entity.Id = YitIdHelper.NextId().ToString();
entity.CreateTime = DateTime.Now;
entity.CreateUser = userInfo.userId;
var isOk = await _db.Insertable(entity).IgnoreColumns(ignoreNullColumn: true).ExecuteCommandAsync();
if (!(isOk > 0))
throw NCCException.Oh(ErrorCode.COM1000);
}
#endregion
#region 根据门店批量创建数据
///
/// 根据门店批量创建数据
/// 会删除设置月份的所有门店数据(谨用!!!)
///
/// 月份(YYYYMM格式)
///
[HttpPost("BatchCreateByStores")]
public async Task BatchCreateByStores([FromQuery] string month)
{
var userInfo = await _userManager.GetUserInfo();
// 验证月份格式
if (string.IsNullOrEmpty(month) || month.Length != 6 || !Regex.IsMatch(month, @"^\d{6}$"))
{
throw NCCException.Oh(ErrorCode.COM1000, "月份格式必须为YYYYMM(如:202501)");
}
//查询门店列表
var storeList = await _db.Queryable().Where(p => p.Status == StatusEnum.有效.GetHashCode()).Select(p => p.Id).ToListAsync();
// 删除设置月份的所有门店数据
await _db.Deleteable().Where(p => p.Month == month).ExecuteCommandAsync();
// 批量创建
var entities = storeList.Select(storeId => new LqMdTargetEntity
{
Id = YitIdHelper.NextId().ToString(),
StoreId = storeId,
Month = month,
BusinessUnit = "",
TechDepartment = "",
EducationDepartment = "",
MajorProjectDepartment = "",
BusinessUnitTarget = 0,
TechDepartmentTarget = 0,
EducationDepartmentTarget = 0,
BusinessUnitGeneralManager = "",
BusinessUnitManager = "",
StoreTarget = 0,
StoreLifeline = 0,
StoreConsumeTarget = 0,
StoreProjectTarget = 0,
StoreHeadcountTarget = 0,
AssistantHeadcountTargetStage1 = 0,
AssistantHeadcountTargetStage2 = 0,
CreateTime = DateTime.Now,
CreateUser = userInfo.userId,
}).ToList();
var isOk = await _db.Insertable(entities).ExecuteCommandAsync();
if (!(isOk > 0))
throw NCCException.Oh(ErrorCode.COM1000);
return new { success = true, message = $"成功创建{isOk}条记录", createdCount = isOk };
}
#endregion
#region 更新门店目标
///
/// 更新门店目标
///
/// 主键ID
/// 参数
///
[HttpPut("{id}")]
public async Task Update(string id, [FromBody] LqMdTargetUpInput input)
{
var userInfo = await _userManager.GetUserInfo();
// 验证记录是否存在
var entity = await _db.Queryable().FirstAsync(p => p.Id == id);
_ = entity ?? throw NCCException.Oh(ErrorCode.COM1005);
// 验证月份格式
if (input.month.Length != 6 || !Regex.IsMatch(input.month, @"^\d{6}$"))
{
throw NCCException.Oh("月份格式必须为YYYYMM(如:202501)");
}
// 如果门店ID或月份发生变化,需要验证唯一性
if (entity.StoreId != input.storeId || entity.Month != input.month)
{
var exists = await _db.Queryable().Where(p => p.StoreId == input.storeId && p.Month == input.month && p.Id != id).AnyAsync();
if (exists)
{
throw NCCException.Oh("该门店在该月份已存在目标记录");
}
}
var updateEntity = input.Adapt();
updateEntity.Id = id;
updateEntity.UpdateTime = DateTime.Now;
updateEntity.UpdateUser = userInfo.userId;
var isOk = await _db.Updateable(updateEntity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
if (!(isOk > 0))
throw NCCException.Oh(ErrorCode.COM1001);
}
#endregion
#region 删除门店目标
///
/// 删除门店目标
///
/// 主键ID
///
[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格式),如果为空则同步到当前月份
///
[HttpPost("SyncLastMonthData")]
public async Task SyncLastMonthData([FromQuery] string targetMonth = null)
{
var userInfo = await _userManager.GetUserInfo();
// 确定目标月份
string targetMonthStr;
if (string.IsNullOrEmpty(targetMonth))
{
// 如果未指定,使用当前月份
var now = DateTime.Now;
targetMonthStr = now.ToString("yyyyMM");
}
else
{
// 验证月份格式
if (targetMonth.Length != 6 || !Regex.IsMatch(targetMonth, @"^\d{6}$"))
{
throw NCCException.Oh(ErrorCode.COM1000, "月份格式必须为YYYYMM(如:202501)");
}
targetMonthStr = targetMonth;
}
// 计算上个月份
var targetDate = DateTime.ParseExact(targetMonthStr, "yyyyMM", null);
var lastMonthDate = targetDate.AddMonths(-1);
var lastMonthStr = lastMonthDate.ToString("yyyyMM");
// 查询上个月的所有门店目标数据
var lastMonthData = await _db.Queryable()
.Where(p => p.Month == lastMonthStr)
.ToListAsync();
if (lastMonthData == null || lastMonthData.Count == 0)
{
return new
{
success = true,
message = $"上个月({lastMonthStr})没有数据可同步",
syncedCount = 0,
skippedCount = 0
};
}
// 查询目标月份已存在的记录
var existingStoreIds = await _db.Queryable()
.Where(p => p.Month == targetMonthStr)
.Select(p => p.StoreId)
.ToListAsync();
// 过滤掉已存在的门店,只同步新门店
var newEntities = lastMonthData
.Where(p => !existingStoreIds.Contains(p.StoreId))
.Select(p => new LqMdTargetEntity
{
Id = YitIdHelper.NextId().ToString(),
StoreId = p.StoreId,
Month = targetMonthStr,
BusinessUnit = p.BusinessUnit,
TechDepartment = p.TechDepartment,
EducationDepartment = p.EducationDepartment,
MajorProjectDepartment = p.MajorProjectDepartment,
BusinessUnitTarget = p.BusinessUnitTarget,
TechDepartmentTarget = p.TechDepartmentTarget,
EducationDepartmentTarget = p.EducationDepartmentTarget,
BusinessUnitGeneralManager = p.BusinessUnitGeneralManager,
BusinessUnitManager = p.BusinessUnitManager,
StoreTarget = p.StoreTarget,
StoreLifeline = p.StoreLifeline,
StoreConsumeTarget = p.StoreConsumeTarget,
StoreProjectTarget = p.StoreProjectTarget,
StoreHeadcountTarget = p.StoreHeadcountTarget,
AssistantHeadcountTargetStage1 = p.AssistantHeadcountTargetStage1,
AssistantHeadcountTargetStage2 = p.AssistantHeadcountTargetStage2,
CreateTime = DateTime.Now,
CreateUser = userInfo.userId,
})
.ToList();
int syncedCount = 0;
int skippedCount = lastMonthData.Count - newEntities.Count;
if (newEntities.Count > 0)
{
syncedCount = await _db.Insertable(newEntities).ExecuteCommandAsync();
}
return new
{
success = true,
message = $"同步完成:成功同步{syncedCount}条记录,跳过{skippedCount}条已存在的记录",
syncedCount = syncedCount,
skippedCount = skippedCount,
lastMonth = lastMonthStr,
targetMonth = targetMonthStr
};
}
#endregion
}
}