using System;
using System.Linq;
using System.Threading.Tasks;
using System.Collections.Generic;
using HT.Cloud.Code;
using SqlSugar;
using HT.Cloud.DataBase;
using HT.Cloud.Domain.SystemManage;
using HT.Cloud.Code.Model;
using System.Globalization;
//using NetTaste;
namespace HT.Cloud.Service.SystemManage
{
///
/// 创 建:超级管理员
/// 日 期:2022-10-06 11:25
/// 描 述:条码规则服务类
///
public class CoderuleService : BaseService, IDenpendency
{
public CoderuleService(ISqlSugarClient context) : base(context)
{
}
#region 获取数据
public async Task> GetList(string keyword = "")
{
var data = GetQuery();
if (!string.IsNullOrEmpty(keyword))
{
data = data.Where(a => a.F_RuleName.Contains(keyword));
}
return await data.OrderBy(a => a.F_Id , OrderByType.Desc).ToListAsync();
}
public async Task> GetLookList(string keyword = "")
{
var query = GetQuery();
if (!string.IsNullOrEmpty(keyword))
{
//此处需修改
query = query.Where(a => a.F_RuleName.Contains(keyword));
}
//权限过滤
query = GetDataPrivilege("a", query: query);
return await query.OrderBy(a => a.F_Id , OrderByType.Desc).ToListAsync();
}
public async Task> GetLookList(SoulPage pagination,string keyword = "",string id="")
{
//反格式化显示只能用"等于",其他不支持
Dictionary> dic = new Dictionary>();
Dictionary enabledTemp = new Dictionary();
enabledTemp.Add("1", "有效");
enabledTemp.Add("0", "无效");
dic.Add("F_EnabledMark", enabledTemp);
var setList = await GlobalContext.GetService().GetItemList("RuleReset");
Dictionary resetTemp = new Dictionary();
foreach (var item in setList)
{
resetTemp.Add(item.F_ItemCode, item.F_ItemName);
}
dic.Add("F_Reset", resetTemp);
var printList = await GlobalContext.GetService().GetItemList("PrintType");
Dictionary printTemp = new Dictionary();
foreach (var item in printList)
{
printTemp.Add(item.F_ItemCode, item.F_ItemName);
}
dic.Add("F_PrintType", printTemp);
pagination = ChangeSoulData(dic, pagination);
var query = GetQuery();
if (!string.IsNullOrEmpty(keyword))
{
query = query.Where(a => a.F_RuleName.Contains(keyword));
}
if(!string.IsNullOrEmpty(id))
{
query = query.Where(a => a.F_Id == id);
}
//权限过滤
query = GetDataPrivilege("a", query: query);
return await query.ToPageListAsync(pagination);
}
public async Task GetForm(string keyValue)
{
var data = await GetQuery().FirstAsync(a => a.F_Id == keyValue);
return data;
}
private ISugarQueryable GetQuery()
{
var query = repository.IQueryable()
.InnerJoin((a,b)=>a.F_TemplateId == b.F_Id)
.Select((a, b) => new CoderuleEntity
{
F_Id=a.F_Id.SelectAll(),
F_TemplateName = b.F_TemplateName,
F_PrintType = b.F_PrintType,
F_Batch=b.F_Batch
}).MergeTable().Where(a => a.F_DeleteMark == false);
return query;
}
public async Task GetLookForm(string keyValue)
{
var data = await GetQuery().FirstAsync(a => a.F_Id == keyValue);
return GetFieldsFilterData(data);
}
#endregion
#region 提交数据
public async Task SubmitForm(CoderuleEntity entity, string keyValue)
{
if(string.IsNullOrEmpty(keyValue))
{
entity.F_DeleteMark = false;
entity.Create();
await repository.Insert(entity);
}
else
{
entity.Modify(keyValue);
await repository.Update(entity);
}
}
public async Task DeleteForm(string keyValue)
{
var ids = keyValue.Split(',');
await repository.Delete(a => ids.Contains(a.F_Id.ToString()));
}
///
/// 计算编码规则生成流水号注意:此编码规则只支持单个流水号
///
/// 规则名称
/// 生成数量
/// 是否预览,预览不新增条码不操作Redis zincr
/// 通配符替换列表
///
public async Task> GetBillNumber(
string ruleName,
int count,
bool preview = false,
List replaceList = null)
{
var now = DateTime.Now;
var rule = await repository.Db.Queryable().FirstAsync(a => a.F_RuleName == ruleName);
var resetRule = "NoReset";
switch (rule.F_Reset)
{
//By 年 月 日
case "yyyy":
case "yyyy-MM":
case "yyyy-MM-dd":
resetRule = DateTime.Now.ToString(rule.F_Reset); break;
//By 周
case "yyyy-MM-WW":
var gc = new GregorianCalendar();
var thisWeek = gc.GetWeekOfYear(now, CalendarWeekRule.FirstDay, DayOfWeek.Sunday);
resetRule = DateTime.Now.ToString("yyyy") + "W" + thisWeek; break;
default:
break;
}
var codeRuleFormatList = rule.F_RuleJson.ToObject>();
//格式化
var format = string.Empty;
var reset = string.Empty;
//流水号长度
int flowNumberLength = 5;
//流水号初始值
int initVal = 0;
//流水号最大值
int? maxVal = null;
//默认10进制
int toBase = 10;
//步长
decimal increment = 1;
string diyCode = string.Empty;
char replaceChar = '*';
List list = new List();
codeRuleFormatList.ForEach(item =>
{
//编码前缀类型 1 - 固定参数 2 - 日期 3 - 年 4 - 月 5 - 日 6 - 周别 7 - 周几 8 - 小时 9 - 上午下午 10 - 班别 11 - 流水号 12 - 自定义
switch (item.FormatType)
{
//固定参数
case 1:
format += item.FormatString;
break;
//日期
case 2:
format += now.ToString(item.FormatString);
break;
//年
case 3:
var ye = now.ToString("yyyy");
//判断是否有自定义
if (!string.IsNullOrEmpty(item.FormatString))
{
var yl = item.FormatString.Length;//yyyy 还是yy 还是y
if (yl <= 4)
ye = ye.Substring(4 - yl, yl);
}
format += ye;
break;
//月
case 4:
var m = item.DiyDate[now.Month - 1];
format += m;
break;
//日
case 5:
var d = item.DiyDate[now.Day - 1];
format += d;
break;
//周别 (本年的第几周)
case 6:
var gc = new GregorianCalendar();
var thisWeek = gc.GetWeekOfYear(now, CalendarWeekRule.FirstDay,DayOfWeek.Sunday);
var y = item.DiyDate[thisWeek - 1];
format += y;
break;
//周几 (按照周一是第一天算)
case 7:
var wk = now.DayOfWeek.ToInt();
if (wk == 0)
wk = 6;
else
wk -= 1;
var w = item.DiyDate[wk];
format += w;
break;
case 8:
var h = now.ToString(item.FormatString);
format += h;
break;
case 9:
var ch = now.Hour;
format += ch < 12? item.DiyDate[0] : item.DiyDate[1];
break;
//班别
case 10:
string csstr = "";
foreach (var cs in item.DiyDate)
{
var strs = cs.Split(".");
var times = strs[1].Split("-");
if (int.Parse(times[0].Split(":")[0]) < int.Parse(times[1].Split(":")[0]))
{
//开始时间
var startTime = DateTime.Parse($"{now:yyyy/MM/dd} {times[0]}");
//结束时间
var endTime = DateTime.Parse($"{now:yyyy/MM/dd} {times[1]}");
if (DateTime.Now>=startTime && DateTime.Now < endTime)
{
csstr = strs[0];
break;
}
}
else
{
//开始时间
var startTime = DateTime.Parse($"{now:yyyy/MM/dd} {times[0]}");
//结束时间
var endTime = DateTime.Parse($"{now:yyyy/MM/dd} {times[1]}").AddDays(1);
if (DateTime.Now >= startTime && DateTime.Now < endTime)
{
csstr = strs[0];
break;
}
}
}
format += csstr;
break;
//流水
case 11:
initVal = item.InitValue.Value;
maxVal = item.MaxValue;
flowNumberLength = item.FormatString.Length;
toBase = item.ToBase;
format += "^_^";
increment = item.Increment.Value;
break;
//自定义方法
case 12:
//反射执行方法获取参数
var udf =((Task)this.GetType().GetMethod(item.FormatString, new Type[] { }).Invoke(this, new object[] { ruleName })).GetAwaiter().GetResult();
format += udf;
break;
//通配符
case 13:
//如果作为检查流水号的长度的条件,则最后一个通配符是00,2位,那么流水号是4位,就会有问题 2 != 4
replaceChar = item.FormatString.FirstOrDefault();
var tempstr = "".PadLeft(item.FormatString.Length, replaceChar);
format += tempstr;
break;
default:
break;
}
});
//判断编码格式是否有效
if (!string.IsNullOrEmpty(format))
{
for (int i = 0; i < count; i++)
{
var score = 0M;
var scoreString = string.Empty;
//预览
if (!preview)
{
if (GlobalContext.SystemConfig.CacheProvider == Define.CACHEPROVIDER_REDIS)
{
score = await BaseHelper.ZIncrByAsync(GlobalContext.SystemConfig.ProjectPrefix + $"_BillNumber:{ruleName}", resetRule, increment);
}
else
{
var rulelog = await repository.Db.Queryable().FirstAsync(a => a.F_Key == GlobalContext.SystemConfig.ProjectPrefix + $"_BillNumber:{ruleName}" && a.F_Value == resetRule);
if (rulelog == null)
{
rulelog = new CoderulelogEntity();
rulelog.F_Id = Utils.GetGuid();
rulelog.F_Key = GlobalContext.SystemConfig.ProjectPrefix + $"_BillNumber:{ruleName}";
rulelog.F_Value = resetRule;
rulelog.F_Score = (int)increment;
rulelog.F_RuleId = rule.F_Id;
await repository.Db.Insertable(rulelog).ExecuteCommandAsync();
}
else
{
await repository.Db.Updateable(a => new CoderulelogEntity
{
F_Score = a.F_Score + (int)increment
}).Where(a => a.F_Id == rulelog.F_Id).ExecuteCommandAsync();
}
}
}
else
{
if (GlobalContext.SystemConfig.CacheProvider == Define.CACHEPROVIDER_REDIS)
{
score = await BaseHelper.ZScoreAsync(GlobalContext.SystemConfig.ProjectPrefix + $"_BillNumber:{ruleName}", resetRule)??0;
score += increment;
}
else
{
var rulelog = await repository.Db.Queryable().FirstAsync(a => a.F_Key == GlobalContext.SystemConfig.ProjectPrefix + $"_BillNumber:{ruleName}" && a.F_Value == resetRule);
if (rulelog == null)
{
score += increment;
}
else
{
score = (rulelog.F_Score??0) + increment;
}
}
}
//10进制流水号
var flowNumber = score + initVal;
//判断流水号是否超过流水号设定的最大值
if (maxVal > 0 && flowNumber > maxVal)
throw new Exception($"Morethan the flownumber settinged max value:{maxVal} and now value:{flowNumber}");
//默认10进制
scoreString = flowNumber.ToString();
if (toBase != 10)
scoreString = scoreString.ToLong().ToBase(toBase);
//^_^是代表可以任意位置流水号
var flow = scoreString.PadLeft(flowNumberLength, '0');
if (flow.Length != flowNumberLength)
{
throw new Exception($"bill encode ({ruleName})settinged error,FlowLength,current:[{flow.Length}],setting:[{flowNumberLength}]");
}
var v = format.Replace("^_^", flow);
if (replaceList!=null&&replaceList.Count>0)
foreach (var item in replaceList)
{
var temp = "".PadLeft(item.Length, replaceChar);
v = v.ReplaceFrist(temp, item);
}
list.Add(v);
}
}
return list;
}
public async Task> GetPrintJson(string code,string templateId)
{
var template = await repository.Db.Queryable().FirstAsync(a => a.F_Id == templateId);
List list = new List();
list.Add(new SugarParameter("rulecode", code));
if (!string.IsNullOrEmpty(template.F_TemplateSqlParm))
{
var dic = template.F_TemplateSqlParm.ToObject>();
foreach (var item in dic)
{
list.Add(new SugarParameter(item.Key, item.Value));
}
}
var printResult = string.IsNullOrEmpty(template.F_TemplateSql) ? null : await repository.Db.Ado.SqlQueryAsync(template.F_TemplateSql, list);
if (printResult!=null && printResult.Count>0)
{
var printData = (printResult[0] as IDictionary)?.ToDictionary(k => k.Key.ToLower(), v => v.Value?.ToString());
printData.Add("rulecode", code);
return printData;
}
else
{
var printData = new Dictionary();
printData.Add("rulecode", code);
return printData;
}
}
public async Task> CreateForm(string keyValue, int count = 1, bool needPrint = false)
{
var list = new List();
var rule = await repository.Db.Queryable().FirstAsync(a => a.F_Id == keyValue);
var template = await repository.Db.Queryable().FirstAsync(a => a.F_Id == rule.F_TemplateId);
var logs = new List();
var codes = await GetBillNumber(rule.F_RuleName, count);
if (template.F_Batch == true)
{
PrintEntity entity = new PrintEntity();
entity.data = new PrintDetail();
entity.data.printIniInfo = new PrintInitInfo();
entity.data.printIniInfo.printType = template.F_PrintType;
entity.data.printIniInfo.isBatch = template.F_Batch;
entity.data.printIniInfo.realName = template.F_TemplateName;
entity.data.printIniInfo.filePath = (GlobalContext.HttpContext.Request.IsHttps ? "https://" : "http://") + GlobalContext.HttpContext.Request.Host + template.F_TemplateFile;
entity.requestId = Utils.GetGuid();
var listJson = new List>();
for (int i = 0; i < count; i++)
{
var log = new CodegeneratelogEntity();
log.Create();
log.F_Code = codes[i];
log.F_PrintCount = needPrint ? 1 : 0;
log.F_RuleId = rule.F_Id;
log.F_RuleName = rule.F_RuleName;
log.F_EnabledMark = true;
log.F_DeleteMark = false;
var printJson = await GetPrintJson(log.F_Code, template.F_Id);
log.F_PrintJson = printJson.ToJson();
logs.Add(log);
listJson.Add(printJson);
}
entity.data.data = listJson;
list.Add(entity);
}
else
{
for (int i = 0; i < count; i++)
{
var log = new CodegeneratelogEntity();
log.Create();
log.F_Code = codes[i];
log.F_PrintCount = needPrint ? 1 : 0;
log.F_RuleId = rule.F_Id;
log.F_RuleName = rule.F_RuleName;
log.F_EnabledMark = true;
log.F_DeleteMark = false;
var printJson = await GetPrintJson(log.F_Code, template.F_Id);
log.F_PrintJson = printJson.ToJson();
logs.Add(log);
PrintEntity entity = new PrintEntity();
entity.data = new PrintDetail();
entity.data.printIniInfo = new PrintInitInfo();
entity.data.printIniInfo.printType = template.F_PrintType;
entity.data.printIniInfo.isBatch = template.F_Batch;
entity.data.printIniInfo.realName = template.F_TemplateName;
entity.data.printIniInfo.filePath = (GlobalContext.HttpContext.Request.IsHttps ? "https://" : "http://") + GlobalContext.HttpContext.Request.Host + template.F_TemplateFile;
entity.requestId = Utils.GetGuid();
entity.data.data = printJson;
list.Add(entity);
}
}
//新增log
await repository.Db.Insertable(logs).ExecuteCommandAsync();
return list;
}
#endregion
}
}