Initial_commit_SecMPS_v2

This commit is contained in:
2026-05-15 23:22:48 +08:00
commit 23ea4fe05f
13830 changed files with 298675 additions and 0 deletions

View File

@@ -0,0 +1,206 @@
using System;
using System.Collections.Generic;
using System.Linq;
using VolPro.Core.Configuration;
using VolPro.Core.Const;
using VolPro.Core.DBManager;
using VolPro.Core.Enums;
using VolPro.Core.Extensions;
using VolPro.Core.ManageUser;
using VolPro.Core.UserManager;
namespace VolPro.Core.Extensions
{
public static class IdentitySqlCode
{
public static void CreateCode(
Dictionary<string, object> mainData,
string tableName,
List<TableColumnField> tableColumns = null,
string leftQuote = null,
string rightQuote = null)
{
// 1) 读取编码规则
var query = IdentityCode.CodeRules.Where(x =>
!string.IsNullOrEmpty(x.TableName) &&
x.TableName.Equals(tableName, StringComparison.OrdinalIgnoreCase));
if (AppSetting.UseDynamicShareDB)
{
query = query.Where(x => x.DbServiceId == UserContext.CurrentServiceId);
}
else
{
if (AppSetting.TenancyField != null)
{
query = query.Where(x => x.TenancyId == UserContext.CurrentServiceId.ToString());
}
}
var rule = query.OrderByDescending(x => x.CreateDate).FirstOrDefault();
if (rule == null) return;
RuleIncremental ruleIncremental = RuleIncremental.day;
try
{
ruleIncremental = (RuleIncremental)Enum.Parse(typeof(RuleIncremental), rule.RuleIncremental);
}
catch
{
ruleIncremental = RuleIncremental.day;
}
// 2) 映射单据字段rule.Field 可能大小写/别名与实际列名不一致)
string codeFieldName = rule.Field;
if (tableColumns != null && !string.IsNullOrEmpty(codeFieldName))
{
var col = tableColumns.FirstOrDefault(c =>
c.ColumnName.Equals(codeFieldName, StringComparison.OrdinalIgnoreCase));
if (col != null) codeFieldName = col.ColumnName;
}
if (string.IsNullOrEmpty(codeFieldName)) return;
// 3) 找到业务表真实表名与库
var tableInfo = TableColumnContext.TableInfo.FirstOrDefault(x =>
!string.IsNullOrEmpty(x.TableName) &&
x.TableName.Equals(tableName, StringComparison.OrdinalIgnoreCase));
if (tableInfo == null) return;
string dbTableName = string.IsNullOrEmpty(tableInfo.TableTrueName)
? tableInfo.TableName
: tableInfo.TableTrueName;
string dbService = tableInfo.DBServer;
if (string.IsNullOrEmpty(dbService)) return;
// 4) 构造规则前缀与日期起点
string preCode = rule.PrefixCode ?? "";
string concatenationSymbol = rule.ConcatenationSymbol ?? "";
string dateFormat = rule.RuleType;
if (dateFormat == RuleIncremental.none.ToString())
{
dateFormat = null;
}
DateTime? dateNow = null;
switch (ruleIncremental)
{
case RuleIncremental.day:
dateNow = (DateTime)DateTime.Now.ToString("yyyy-MM-dd").GetDateTime();
break;
case RuleIncremental.month:
dateNow = (DateTime)DateTime.Now.ToString("yyyy-MM-01").GetDateTime();
break;
case RuleIncremental.year:
dateNow = (DateTime)DateTime.Now.ToString("yyyy-01-01").GetDateTime();
break;
case RuleIncremental.none:
default:
break;
}
string dateText = dateNow?.ToString("yyyy-MM-dd") ?? "none";
string dateFieldName =
!string.IsNullOrWhiteSpace(rule.OrderFiled)
? rule.OrderFiled
: AppSetting.CreateMember.DateField;
// 5) 共享缓存key与 IdentityCode.CreateList 保持同形态,避免并发重复)
string serviceId = "";
if (AppSetting.UseDynamicShareDB || !string.IsNullOrEmpty(AppSetting.TenancyField))
{
serviceId = $"_{UserContext.CurrentServiceId}";
}
string cacheKey = $"{tableName}_{ruleIncremental}_{dateText}{serviceId}";
// 6) 自增流水号:同一 cacheKey 下,保证并发安全
int number = IdentityCode._counters.AddOrUpdate(
cacheKey,
addValueFactory: (k) =>
{
// 获取库类型决定左右引号MySql: ``, SqlServer: [ ]
string dbType = DbRelativeCache.GetDbType(dbService) ?? DBType.Name;
DbCurrentType dbCurrentType = (DbCurrentType)Enum.Parse(typeof(DbCurrentType), dbType, true);
int last = GetLastIncrementBySql(
dbService,
dbTableName,
codeFieldName,
preCode,
dateFieldName,
dateNow,
rule.ValueLen,
leftQuote,
rightQuote);
return last + 1;
},
updateValueFactory: (k, existingValue) => existingValue + 1);
// 7) 生成最终编码字符串
string ruleText = dateFormat == null
? preCode
: $"{preCode}{concatenationSymbol}{DateTime.Now.ToString(dateFormat)}";
string code = $"{ruleText}{concatenationSymbol}{(number).ToString("D" + rule.ValueLen)}";
mainData[codeFieldName] = code;
}
private static int GetLastIncrementBySql(
string dbService,
string dbTableName,
string codeFieldName,
string preCode,
string dateFieldName,
DateTime? dateNow,
int len,
string leftQuote,
string rightQuote)
{
string table = $"{leftQuote}{dbTableName}{rightQuote}";
string codeField = $"{leftQuote}{codeFieldName}{rightQuote}";
string dateField = string.IsNullOrWhiteSpace(dateFieldName)
? null
: $"{leftQuote}{dateFieldName}{rightQuote}";
string sqlWhere = $"{codeField} LIKE @preCodeLike";
if (dateNow != null && !string.IsNullOrEmpty(dateField))
{
sqlWhere += $" AND {dateField} >= @dateNow";
}
// 取最后一条:按 codeField 倒序取 1 条
// 这里不再通过 leftQuote/rightQuote 推断 DB 类型,所以按 dbService 取一次 DB 类型决定 SQL 语法
string dbType = DbRelativeCache.GetDbType(dbService) ?? DBType.Name;
DbCurrentType dbCurrentType = (DbCurrentType)Enum.Parse(typeof(DbCurrentType), dbType, true);
string sql;
if (dbCurrentType == DbCurrentType.MsSql)
{
sql = $"SELECT TOP 1 {codeField} FROM {table} WHERE {sqlWhere} ORDER BY {codeField} DESC";
}
else if (dbCurrentType == DbCurrentType.Oracle)
{
sql = $"SELECT {codeField} FROM {table} WHERE {sqlWhere} ORDER BY {codeField} DESC FETCH FIRST 1 ROWS ONLY";
}
else
{
sql = $"SELECT {codeField} FROM {table} WHERE {sqlWhere} ORDER BY {codeField} DESC LIMIT 1";
}
var dapper = DbSqlSugar.DbManger.GetConnection(dbService);
string lastCode = dapper.Ado.SqlQuery<string>(sql, new
{
preCodeLike = $"{preCode}%",
dateNow
}).FirstOrDefault();
if (string.IsNullOrEmpty(lastCode)) return 0;
if (lastCode.Length >= len)
{
return int.TryParse(lastCode.Substring(lastCode.Length - len), out var n) ? n : 0;
}
return 0;
}
}
}