using System.Text;
using JNPF.Common.Const;
using JNPF.Common.Core.Manager;
using JNPF.Common.Core.Manager.Files;
using JNPF.Common.Enums;
using JNPF.Common.Filter;
using JNPF.Common.Manager;
using JNPF.Common.Security;
using JNPF.DependencyInjection;
using JNPF.DynamicApiController;
using JNPF.FriendlyException;
using JNPF.LinqBuilder;
using JNPF.Logging.Attributes;
using JNPF.Systems.Entitys.Dto.BillRule;
using JNPF.Systems.Entitys.Dto.System.BillRule;
using JNPF.Systems.Entitys.Permission;
using JNPF.Systems.Entitys.System;
using JNPF.Systems.Interfaces.System;
using Mapster;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
namespace JNPF.Systems;
///
/// 单据规则.
///
[ApiDescriptionSettings(Tag = "System", Name = "BillRule", Order = 200)]
[Route("api/system/[controller]")]
public class BillRuleService : IBillRullService, IDynamicApiController, ITransient
{
///
/// 服务基础仓储.
///
private readonly ISqlSugarRepository _repository;
///
/// 文件服务.
///
private readonly IFileManager _fileManager;
///
/// 缓存管理器.
///
private readonly ICacheManager _cacheManager;
///
/// 用户管理.
///
private readonly IUserManager _userManager;
///
/// 初始化一个类型的新实例.
///
public BillRuleService(
ISqlSugarRepository repository,
ICacheManager cacheManager,
IUserManager userManager,
IFileManager fileManager)
{
_repository = repository;
_cacheManager = cacheManager;
_userManager = userManager;
_fileManager = fileManager;
}
#region Get
///
/// 列表.
///
///
[HttpGet("Selector")]
public async Task GetSelector([FromQuery] BillRuleListQueryInput input)
{
var list = await _repository.AsSugarClient().Queryable((a, b) => new JoinQueryInfos(JoinType.Left, b.Id == a.CreatorUserId))
.Where(a => a.DeleteMark == null && a.EnabledMark == 1)
.WhereIF(!string.IsNullOrEmpty(input.categoryId), a => a.Category == input.categoryId)
.WhereIF(!string.IsNullOrEmpty(input.keyword), a => a.FullName.Contains(input.keyword) || a.EnCode.Contains(input.keyword))
.OrderBy(a => a.SortCode).OrderBy(a => a.CreatorTime, OrderByType.Desc)
.Select((a, b) => new BillRuleListOutput
{
id = a.Id,
lastModifyTime = a.LastModifyTime,
enabledMark = a.EnabledMark,
creatorUser = SqlFunc.MergeString(b.RealName, "/", b.Account),
fullName = a.FullName,
enCode = a.EnCode,
outputNumber = a.OutputNumber,
digit = a.Digit,
startNumber = a.StartNumber,
sortCode = a.SortCode,
creatorTime = a.CreatorTime
}).ToPagedListAsync(input.currentPage, input.pageSize);
return PageResult.SqlSugarPageResult(list);
}
///
/// 获取单据规则列表(带分页).
///
/// 请求参数.
///
[HttpGet("")]
[OperateLog("单据规则", "查询")]
public async Task GetList([FromQuery] BillRuleListQueryInput input)
{
var list = await _repository.AsSugarClient().Queryable((a, b, c) => new JoinQueryInfos(JoinType.Left, a.CreatorUserId == b.Id, JoinType.Left, a.Category == c.Id))
.Where(a => a.DeleteMark == null)
.WhereIF(!string.IsNullOrEmpty(input.categoryId), a => a.Category == input.categoryId)
.WhereIF(!string.IsNullOrEmpty(input.keyword), a => a.FullName.Contains(input.keyword) || a.EnCode.Contains(input.keyword))
.Select((a, b, c) => new BillRuleListOutput
{
id = a.Id,
lastModifyTime = a.LastModifyTime,
enabledMark = a.EnabledMark,
creatorUser = SqlFunc.MergeString(b.RealName, "/", b.Account),
fullName = a.FullName,
enCode = a.EnCode,
outputNumber = a.OutputNumber,
digit = a.Digit,
startNumber = a.StartNumber,
sortCode = a.SortCode,
creatorTime = a.CreatorTime,
category = c.FullName
}).MergeTable()
.OrderBy(a => a.sortCode).OrderBy(a => a.creatorTime, OrderByType.Desc)
.OrderByIF(!string.IsNullOrEmpty(input.keyword), a => a.lastModifyTime, OrderByType.Desc).ToPagedListAsync(input.currentPage, input.pageSize);
return PageResult.SqlSugarPageResult(list);
}
///
/// 获取单据流水号(工作流程调用).
///
/// 编码.
///
[HttpGet("BillNumber/{enCode}")]
public async Task GetBillNumber(string enCode)
{
return await GetBillNumber(enCode, true);
}
///
/// 信息.
///
/// 主键.
///
[HttpGet("{id}")]
public async Task GetInfo(string id)
{
return (await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null)).Adapt();
}
///
/// 导出.
///
/// 主键.
///
[HttpGet("{id}/Action/Export")]
public async Task ActionsExport(string id)
{
var data = await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null);
var jsonStr = data.ToJsonString();
return await _fileManager.Export(jsonStr, data.FullName, ExportFileType.bb);
}
#endregion
#region Post
///
/// 新建.
///
/// 实体对象.
///
[HttpPost("")]
[OperateLog("单据规则", "新增")]
public async Task Create([FromBody] BillRuleCrInput input)
{
if (await _repository.IsAnyAsync(x => (x.EnCode == input.enCode || x.FullName == input.fullName) && x.DeleteMark == null))
throw Oops.Oh(ErrorCode.COM1004);
var entity = input.Adapt();
var isOk = await _repository.AsInsertable(entity).IgnoreColumns(ignoreNullColumn: true).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
if (isOk < 1)
throw Oops.Oh(ErrorCode.COM1000);
}
///
/// 修改.
///
/// 主键值.
/// 实体对象.
///
[HttpPut("{id}")]
[OperateLog("单据规则", "修改")]
public async Task Update(string id, [FromBody] BillRuleUpInput input)
{
if (await _repository.IsAnyAsync(x => x.Id != id && (x.EnCode == input.enCode || x.FullName == input.fullName) && x.DeleteMark == null))
throw Oops.Oh(ErrorCode.COM1004);
var entity = input.Adapt();
var isOk = await _repository.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandHasChangeAsync();
if (!isOk)
throw Oops.Oh(ErrorCode.COM1001);
}
///
/// 删除.
///
/// 主键.
///
[HttpDelete("{id}")]
[OperateLog("单据规则", "删除")]
public async Task Delete(string id)
{
var entity = await _repository.GetFirstAsync(x => x.Id == id && x.DeleteMark == null);
if (entity == null)
throw Oops.Oh(ErrorCode.COM1005);
if (!string.IsNullOrEmpty(entity.OutputNumber))
throw Oops.Oh(ErrorCode.BR0001);
var isOk = await _repository.AsUpdateable(entity).CallEntityMethod(m => m.Delete()).UpdateColumns(it => new { it.DeleteMark, it.DeleteTime, it.DeleteUserId }).ExecuteCommandHasChangeAsync();
if (!isOk)
throw Oops.Oh(ErrorCode.COM1002);
}
///
/// 修改单据规则状态.
///
/// 主键值.
///
[HttpPut("{id}/Actions/State")]
public async Task ActionsState(string id)
{
var isOk = await _repository.AsUpdateable().SetColumns(it => new BillRuleEntity()
{
EnabledMark = SqlFunc.IIF(it.EnabledMark == 1, 0, 1),
LastModifyUserId = _userManager.UserId,
LastModifyTime = SqlFunc.GetDate()
}).Where(it => it.Id.Equals(id)).ExecuteCommandHasChangeAsync();
if (!isOk)
throw Oops.Oh(ErrorCode.COM1003);
}
///
/// 导入.
///
///
///
[HttpPost("Action/Import")]
public async Task ActionsImport(IFormFile file)
{
var fileType = Path.GetExtension(file.FileName).Replace(".", string.Empty);
if (!fileType.ToLower().Equals(ExportFileType.bb.ToString()))
throw Oops.Oh(ErrorCode.D3006);
var josn = _fileManager.Import(file);
var data = josn.ToObject();
if (data == null || data.Prefix.IsNullOrEmpty())
throw Oops.Oh(ErrorCode.D3006);
var isOk = await _repository.AsSugarClient().Storageable(data).ExecuteCommandAsync();
if (isOk < 1)
throw Oops.Oh(ErrorCode.D3008);
}
#endregion
#region PublicMethod
///
/// 获取流水号.
///
/// 流水编码.
/// 是否缓存:每个用户会自动占用一个流水号,这个刷新页面也不会跳号.
///
[NonAction]
public async Task GetBillNumber(string enCode, bool isCache = false)
{
string cacheKey = string.Format("{0}{1}_{2}", CommonConst.CACHEKEYBILLRULE, _userManager.TenantId, _userManager.UserId + enCode);
string strNumber = string.Empty;
if (isCache)
{
if (!_cacheManager.Exists(cacheKey))
{
strNumber = await GetNumber(enCode);
await _cacheManager.SetAsync(cacheKey, strNumber, new TimeSpan(0, 3, 0));
}
else
{
strNumber = await _cacheManager.GetAsync(cacheKey);
}
}
else
{
strNumber = await GetNumber(enCode);
_cacheManager.Set(cacheKey, strNumber, new TimeSpan(0, 3, 0));
}
return strNumber;
}
#endregion
#region PrivateMethod
///
/// 获取流水号.
///
///
///
private async Task GetNumber(string enCode)
{
StringBuilder strNumber = new StringBuilder();
var entity = await _repository.GetFirstAsync(m => m.EnCode == enCode && m.DeleteMark == null);
if (entity != null)
{
// 处理隔天流水号归0
if (entity.OutputNumber != null)
{
var serialDate = entity.OutputNumber.Remove(entity.OutputNumber.Length - (int)entity.Digit).Replace(entity.Prefix, string.Empty);
var thisDate = entity.DateFormat == "no" ? string.Empty : DateTime.Now.ToString(entity.DateFormat);
if (serialDate != thisDate)
{
entity.ThisNumber = 0;
}
else
{
entity.ThisNumber++;
}
}
else
{
entity.ThisNumber = 0;
}
// 拼接单据编码
// 前缀
strNumber.Append(entity.Prefix);
if (entity.DateFormat != "no")
strNumber.Append(DateTime.Now.ToString(entity.DateFormat)); // 日期格式
var number = int.Parse(entity.StartNumber) + entity.ThisNumber;
strNumber.Append(number.ToString().PadLeft((int)entity.Digit, '0')); // 流水号
entity.OutputNumber = strNumber.ToString();
var str = strNumber.ToString();
// 更新流水号
await _repository.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandHasChangeAsync();
}
else
{
strNumber.Append("单据规则不存在");
}
return strNumber.ToString();
}
#endregion
}