mirror of
https://gitee.com/dotnetchina/OpenAuth.Net.git
synced 2025-08-23 13:06:48 +08:00
parent
f7088c9d29
commit
9c2d044d12
11
Infrastructure/Snowflake/IIdGenerator.cs
Normal file
11
Infrastructure/Snowflake/IIdGenerator.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Yitter.IdGenerator
|
||||||
|
{
|
||||||
|
public interface IIdGenerator
|
||||||
|
{
|
||||||
|
Action<OverCostActionArg> GenIdActionAsync { get; set; }
|
||||||
|
|
||||||
|
long NewLong();
|
||||||
|
}
|
||||||
|
}
|
13
Infrastructure/Snowflake/ISnowWorker.cs
Normal file
13
Infrastructure/Snowflake/ISnowWorker.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Yitter.IdGenerator
|
||||||
|
{
|
||||||
|
internal interface ISnowWorker
|
||||||
|
{
|
||||||
|
Action<OverCostActionArg> GenAction { get; set; }
|
||||||
|
|
||||||
|
long NextId();
|
||||||
|
}
|
||||||
|
}
|
65
Infrastructure/Snowflake/IdGeneratorOptions.cs
Normal file
65
Infrastructure/Snowflake/IdGeneratorOptions.cs
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Yitter.IdGenerator
|
||||||
|
{
|
||||||
|
public class IdGeneratorOptions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 雪花计算方法
|
||||||
|
/// (1|2)
|
||||||
|
/// </summary>
|
||||||
|
public short Method { get; set; } = 1;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 开始时间(UTC格式)
|
||||||
|
/// 不能超过当前系统时间
|
||||||
|
/// </summary>
|
||||||
|
public DateTime StartTime { get; set; } = DateTime.MinValue;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 机器码
|
||||||
|
/// 与 WorkerIdBitLength 有关系
|
||||||
|
/// </summary>
|
||||||
|
public ushort WorkerId { get; set; } = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 机器码位长
|
||||||
|
/// 范围:2-21(要求:序列数位长+机器码位长不超过22)。
|
||||||
|
/// 建议范围:6-12。
|
||||||
|
/// </summary>
|
||||||
|
public byte WorkerIdBitLength { get; set; } = 6;//10;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 序列数位长
|
||||||
|
/// 范围:2-21(要求:序列数位长+机器码位长不超过22)。
|
||||||
|
/// 建议范围:6-14。
|
||||||
|
/// </summary>
|
||||||
|
public byte SeqBitLength { get; set; } = 6;//10;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最大序列数(含)
|
||||||
|
/// (由SeqBitLength计算的最大值)
|
||||||
|
/// </summary>
|
||||||
|
public int MaxSeqNumber { get; set; } = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最小序列数(含)
|
||||||
|
/// 默认11,不小于5,不大于MaxSeqNumber-2
|
||||||
|
/// </summary>
|
||||||
|
public ushort MinSeqNumber { get; set; } = 11;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最大漂移次数(含),
|
||||||
|
/// 默认2000,推荐范围500-10000(与计算能力有关)
|
||||||
|
/// </summary>
|
||||||
|
public int TopOverCostCount { get; set; } = 2000;
|
||||||
|
|
||||||
|
|
||||||
|
public IdGeneratorOptions()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
26
Infrastructure/Snowflake/OverCostActionArg.cs
Normal file
26
Infrastructure/Snowflake/OverCostActionArg.cs
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Yitter.IdGenerator
|
||||||
|
{
|
||||||
|
public class OverCostActionArg
|
||||||
|
{
|
||||||
|
public int ActionType { get; set; }
|
||||||
|
public long TimeTick { get; set; }
|
||||||
|
public ushort WorkerId { get; set; }
|
||||||
|
public int OverCostCountInOneTerm { get; set; }
|
||||||
|
public int GenCountInOneTerm { get; set; }
|
||||||
|
public int TermIndex { get; set; }
|
||||||
|
|
||||||
|
public OverCostActionArg(ushort workerId, long timeTick, int actionType = 0, int overCostCountInOneTerm = 0, int genCountWhenOverCost = 0,int index=0)
|
||||||
|
{
|
||||||
|
ActionType = actionType;
|
||||||
|
TimeTick = timeTick;
|
||||||
|
WorkerId = workerId;
|
||||||
|
OverCostCountInOneTerm = overCostCountInOneTerm;
|
||||||
|
GenCountInOneTerm = genCountWhenOverCost;
|
||||||
|
TermIndex = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
296
Infrastructure/Snowflake/SnowWorkerM1.cs
Normal file
296
Infrastructure/Snowflake/SnowWorkerM1.cs
Normal file
@ -0,0 +1,296 @@
|
|||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Yitter.IdGenerator
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 雪花漂移算法
|
||||||
|
/// </summary>
|
||||||
|
internal class SnowWorkerM1 : ISnowWorker
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 基础时间
|
||||||
|
/// </summary>
|
||||||
|
protected readonly DateTime StartTimeUtc = new DateTime(2020, 2, 20, 2, 20, 2, 20, DateTimeKind.Utc);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 机器码
|
||||||
|
/// </summary>
|
||||||
|
protected readonly ushort WorkerId = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 机器码位长
|
||||||
|
/// (机器码+序列数<=22位)
|
||||||
|
/// </summary>
|
||||||
|
protected readonly byte WorkerIdBitLength = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 自增序列数位长
|
||||||
|
/// (机器码+序列数<=22位)
|
||||||
|
/// </summary>
|
||||||
|
protected readonly byte SeqBitLength = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最大序列数(含此值)
|
||||||
|
/// 超过最大值,就会从MinSeqNumber开始
|
||||||
|
/// </summary>
|
||||||
|
protected readonly int MaxSeqNumber = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最小序列数(含此值)
|
||||||
|
/// </summary>
|
||||||
|
protected readonly ushort MinSeqNumber = 0;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 最大漂移次数
|
||||||
|
/// </summary>
|
||||||
|
protected readonly int TopOverCostCount = 0;
|
||||||
|
|
||||||
|
protected readonly byte _TimestampShift = 0;
|
||||||
|
protected static object _SyncLock = new object();
|
||||||
|
|
||||||
|
protected ushort _CurrentSeqNumber;
|
||||||
|
protected long _LastTimeTick = -1L;
|
||||||
|
protected long _TurnBackTimeTick = -1L;
|
||||||
|
|
||||||
|
protected bool _IsOverCost = false;
|
||||||
|
protected int _OverCostCountInOneTerm = 0;
|
||||||
|
protected int _GenCountInOneTerm = 0;
|
||||||
|
protected int _TermIndex = 0;
|
||||||
|
public Action<OverCostActionArg> GenAction { get; set; }
|
||||||
|
|
||||||
|
public SnowWorkerM1(IdGeneratorOptions options)
|
||||||
|
{
|
||||||
|
WorkerId = options.WorkerId;
|
||||||
|
WorkerIdBitLength = options.WorkerIdBitLength;
|
||||||
|
SeqBitLength = options.SeqBitLength;
|
||||||
|
MaxSeqNumber = options.MaxSeqNumber;
|
||||||
|
MinSeqNumber = options.MinSeqNumber;
|
||||||
|
_CurrentSeqNumber = options.MinSeqNumber;
|
||||||
|
TopOverCostCount = options.TopOverCostCount;
|
||||||
|
|
||||||
|
if (options.StartTime != DateTime.MinValue)
|
||||||
|
{
|
||||||
|
StartTimeUtc = options.StartTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WorkerId < 1)
|
||||||
|
{
|
||||||
|
WorkerId = (ushort)DateTime.Now.Millisecond;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SeqBitLength == 0)
|
||||||
|
{
|
||||||
|
SeqBitLength = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WorkerIdBitLength == 0)
|
||||||
|
{
|
||||||
|
WorkerIdBitLength = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MaxSeqNumber == 0)
|
||||||
|
{
|
||||||
|
MaxSeqNumber = (int)Math.Pow(2, SeqBitLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
_TimestampShift = (byte)(WorkerIdBitLength + SeqBitLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void DoGenIdAction(OverCostActionArg arg)
|
||||||
|
{
|
||||||
|
Task.Run(() =>
|
||||||
|
{
|
||||||
|
GenAction(arg);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BeginOverCostCallBack(in long useTimeTick)
|
||||||
|
{
|
||||||
|
if (GenAction == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DoGenIdAction(new OverCostActionArg(
|
||||||
|
WorkerId,
|
||||||
|
useTimeTick,
|
||||||
|
1,
|
||||||
|
_OverCostCountInOneTerm,
|
||||||
|
_GenCountInOneTerm,
|
||||||
|
_TermIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void EndOverCostCallBack(in long useTimeTick)
|
||||||
|
{
|
||||||
|
if (_TermIndex > 10000)
|
||||||
|
{
|
||||||
|
_TermIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GenAction == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DoGenIdAction(new OverCostActionArg(
|
||||||
|
WorkerId,
|
||||||
|
useTimeTick,
|
||||||
|
2,
|
||||||
|
_OverCostCountInOneTerm,
|
||||||
|
_GenCountInOneTerm,
|
||||||
|
_TermIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TurnBackCallBack(in long useTimeTick)
|
||||||
|
{
|
||||||
|
if (GenAction == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DoGenIdAction(new OverCostActionArg(
|
||||||
|
WorkerId,
|
||||||
|
useTimeTick,
|
||||||
|
8,
|
||||||
|
_OverCostCountInOneTerm,
|
||||||
|
_GenCountInOneTerm,
|
||||||
|
_TermIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
private long NextOverCostId()
|
||||||
|
{
|
||||||
|
long currentTimeTick = GetCurrentTimeTick();
|
||||||
|
|
||||||
|
if (currentTimeTick > _LastTimeTick)
|
||||||
|
{
|
||||||
|
EndOverCostCallBack(currentTimeTick);
|
||||||
|
|
||||||
|
_LastTimeTick = currentTimeTick;
|
||||||
|
_CurrentSeqNumber = MinSeqNumber;
|
||||||
|
_IsOverCost = false;
|
||||||
|
_OverCostCountInOneTerm = 0;
|
||||||
|
_GenCountInOneTerm = 0;
|
||||||
|
|
||||||
|
return CalcId(_LastTimeTick);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_OverCostCountInOneTerm >= TopOverCostCount)
|
||||||
|
{
|
||||||
|
EndOverCostCallBack(currentTimeTick);
|
||||||
|
|
||||||
|
_LastTimeTick = GetNextTimeTick();
|
||||||
|
_CurrentSeqNumber = MinSeqNumber;
|
||||||
|
_IsOverCost = false;
|
||||||
|
_OverCostCountInOneTerm = 0;
|
||||||
|
_GenCountInOneTerm = 0;
|
||||||
|
|
||||||
|
return CalcId(_LastTimeTick);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_CurrentSeqNumber > MaxSeqNumber)
|
||||||
|
{
|
||||||
|
_LastTimeTick++;
|
||||||
|
_CurrentSeqNumber = MinSeqNumber;
|
||||||
|
_IsOverCost = true;
|
||||||
|
_OverCostCountInOneTerm++;
|
||||||
|
_GenCountInOneTerm++;
|
||||||
|
|
||||||
|
return CalcId(_LastTimeTick);
|
||||||
|
}
|
||||||
|
|
||||||
|
_GenCountInOneTerm++;
|
||||||
|
return CalcId(_LastTimeTick);
|
||||||
|
}
|
||||||
|
|
||||||
|
private long NextNormalId()
|
||||||
|
{
|
||||||
|
long currentTimeTick = GetCurrentTimeTick();
|
||||||
|
|
||||||
|
if (currentTimeTick > _LastTimeTick)
|
||||||
|
{
|
||||||
|
_LastTimeTick = currentTimeTick;
|
||||||
|
_CurrentSeqNumber = MinSeqNumber;
|
||||||
|
|
||||||
|
return CalcId(_LastTimeTick);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_CurrentSeqNumber > MaxSeqNumber)
|
||||||
|
{
|
||||||
|
BeginOverCostCallBack(currentTimeTick);
|
||||||
|
|
||||||
|
_TermIndex++;
|
||||||
|
_LastTimeTick++;
|
||||||
|
_CurrentSeqNumber = MinSeqNumber;
|
||||||
|
_IsOverCost = true;
|
||||||
|
_OverCostCountInOneTerm++;
|
||||||
|
_GenCountInOneTerm = 1;
|
||||||
|
|
||||||
|
return CalcId(_LastTimeTick);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentTimeTick < _LastTimeTick)
|
||||||
|
{
|
||||||
|
if (_TurnBackTimeTick < 1)
|
||||||
|
{
|
||||||
|
_TurnBackTimeTick = _LastTimeTick - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Thread.Sleep(10);
|
||||||
|
TurnBackCallBack(_TurnBackTimeTick);
|
||||||
|
|
||||||
|
return CalcTurnBackId(_TurnBackTimeTick);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return CalcId(_LastTimeTick);
|
||||||
|
}
|
||||||
|
|
||||||
|
private long CalcId(in long useTimeTick)
|
||||||
|
{
|
||||||
|
var result = ((useTimeTick << _TimestampShift) +
|
||||||
|
((long)WorkerId << SeqBitLength) +
|
||||||
|
(uint)_CurrentSeqNumber);
|
||||||
|
|
||||||
|
_CurrentSeqNumber++;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private long CalcTurnBackId(in long useTimeTick)
|
||||||
|
{
|
||||||
|
var result = ((useTimeTick << _TimestampShift) +
|
||||||
|
((long)WorkerId << SeqBitLength) + 0);
|
||||||
|
|
||||||
|
_TurnBackTimeTick--;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual long GetCurrentTimeTick()
|
||||||
|
{
|
||||||
|
return (long)(DateTime.UtcNow - StartTimeUtc).TotalMilliseconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual long GetNextTimeTick()
|
||||||
|
{
|
||||||
|
long tempTimeTicker = GetCurrentTimeTick();
|
||||||
|
|
||||||
|
while (tempTimeTicker <= _LastTimeTick)
|
||||||
|
{
|
||||||
|
tempTimeTicker = GetCurrentTimeTick();
|
||||||
|
}
|
||||||
|
|
||||||
|
return tempTimeTicker;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public virtual long NextId()
|
||||||
|
{
|
||||||
|
lock (_SyncLock)
|
||||||
|
{
|
||||||
|
return _IsOverCost ? NextOverCostId() : NextNormalId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
49
Infrastructure/Snowflake/SnowWorkerM2.cs
Normal file
49
Infrastructure/Snowflake/SnowWorkerM2.cs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Yitter.IdGenerator
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 常规雪花算法
|
||||||
|
/// </summary>
|
||||||
|
internal class SnowWorkerM2 : SnowWorkerM1
|
||||||
|
{
|
||||||
|
public SnowWorkerM2(IdGeneratorOptions options) : base(options)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public override long NextId()
|
||||||
|
{
|
||||||
|
lock (_SyncLock)
|
||||||
|
{
|
||||||
|
long currentTimeTick = GetCurrentTimeTick();
|
||||||
|
|
||||||
|
if (_LastTimeTick == currentTimeTick)
|
||||||
|
{
|
||||||
|
if (_CurrentSeqNumber++ > MaxSeqNumber)
|
||||||
|
{
|
||||||
|
_CurrentSeqNumber = MinSeqNumber;
|
||||||
|
currentTimeTick = GetNextTimeTick();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_CurrentSeqNumber = MinSeqNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentTimeTick < _LastTimeTick)
|
||||||
|
{
|
||||||
|
throw new Exception(string.Format("Time error for {0} milliseconds", _LastTimeTick - currentTimeTick));
|
||||||
|
}
|
||||||
|
|
||||||
|
_LastTimeTick = currentTimeTick;
|
||||||
|
var result = ((currentTimeTick << _TimestampShift) + ((long)WorkerId << SeqBitLength) + (uint)_CurrentSeqNumber);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
83
Infrastructure/Snowflake/YitIdGenerator.cs
Normal file
83
Infrastructure/Snowflake/YitIdGenerator.cs
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace Yitter.IdGenerator
|
||||||
|
{
|
||||||
|
public class YitIdGenerator : IIdGenerator
|
||||||
|
{
|
||||||
|
private ISnowWorker _SnowWorker { get; set; }
|
||||||
|
|
||||||
|
public Action<OverCostActionArg> GenIdActionAsync
|
||||||
|
{
|
||||||
|
get => _SnowWorker.GenAction;
|
||||||
|
set => _SnowWorker.GenAction = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public YitIdGenerator(IdGeneratorOptions options)
|
||||||
|
{
|
||||||
|
if (options == null)
|
||||||
|
{
|
||||||
|
throw new ApplicationException("options error.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.StartTime > DateTime.Now)
|
||||||
|
{
|
||||||
|
throw new ApplicationException("StartTime error.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.SeqBitLength + options.WorkerIdBitLength > 22)
|
||||||
|
{
|
||||||
|
throw new ApplicationException("error:WorkerIdBitLength + SeqBitLength <= 22");
|
||||||
|
}
|
||||||
|
|
||||||
|
var maxWorkerIdNumber = Math.Pow(2, options.WorkerIdBitLength) - 1;
|
||||||
|
if (options.WorkerId < 1 || options.WorkerId > maxWorkerIdNumber)
|
||||||
|
{
|
||||||
|
throw new ApplicationException("WorkerId is error. (range:[1, " + maxWorkerIdNumber + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.SeqBitLength < 2 || options.SeqBitLength > 21)
|
||||||
|
{
|
||||||
|
throw new ApplicationException("SeqBitLength is error. (range:[2, 21])");
|
||||||
|
}
|
||||||
|
|
||||||
|
var maxSeqNumber = Math.Pow(2, options.SeqBitLength) - 1;
|
||||||
|
if (options.MaxSeqNumber < 0 || options.MaxSeqNumber > maxSeqNumber)
|
||||||
|
{
|
||||||
|
throw new ApplicationException("MaxSeqNumber is error. (range:[1, " + maxSeqNumber + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
var maxValue = maxSeqNumber - 2;
|
||||||
|
if (options.MinSeqNumber < 5 || options.MinSeqNumber > maxValue)
|
||||||
|
{
|
||||||
|
throw new ApplicationException("MinSeqNumber is error. (range:[5, " + maxValue + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (options.Method)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
_SnowWorker = new SnowWorkerM1(options);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
_SnowWorker = new SnowWorkerM2(options);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
_SnowWorker = new SnowWorkerM1(options);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.Method == 1)
|
||||||
|
{
|
||||||
|
Thread.Sleep(500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public long NewLong()
|
||||||
|
{
|
||||||
|
return _SnowWorker.NextId();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
27
Infrastructure/Test/TestSnowflake.cs
Normal file
27
Infrastructure/Test/TestSnowflake.cs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using Yitter.IdGenerator;
|
||||||
|
|
||||||
|
namespace Infrastructure.Test
|
||||||
|
{
|
||||||
|
class TestSnowflake
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void Generate()
|
||||||
|
{
|
||||||
|
// 全局初始化设置WorkerId,默认最大2^16-1。(初始化过程全局只需一次,且必须最先设置)
|
||||||
|
var options = new IdGeneratorOptions(){ WorkerId = 1};
|
||||||
|
IIdGenerator IdHelper = new YitIdGenerator(options);
|
||||||
|
|
||||||
|
// 初始化以后,就可以在需要的地方调用方法生成ID。
|
||||||
|
long val =IdHelper.NewLong();
|
||||||
|
int val2 = (int)val;
|
||||||
|
|
||||||
|
Console.WriteLine($"val:{val}/int:{val2}");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -1,127 +1,127 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Infrastructure;
|
using Infrastructure;
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using OpenAuth.App.Interface;
|
using OpenAuth.App.Interface;
|
||||||
using OpenAuth.Repository.Core;
|
using OpenAuth.Repository.Core;
|
||||||
using OpenAuth.Repository.Domain;
|
using OpenAuth.Repository.Domain;
|
||||||
using OpenAuth.Repository.Interface;
|
using OpenAuth.Repository.Interface;
|
||||||
|
|
||||||
namespace OpenAuth.App
|
namespace OpenAuth.App
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 业务层基类,UnitWork用于事务操作,Repository用于普通的数据库操作
|
/// 业务层基类,UnitWork用于事务操作,Repository用于普通的数据库操作
|
||||||
/// <para>如用户管理:Class UserManagerApp:BaseApp<User></para>
|
/// <para>如用户管理:Class UserManagerApp:BaseApp<User></para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
public class BaseApp<T, TDbContext> where T : Entity where TDbContext: DbContext
|
public class BaseApp<T, TDbContext> where T : StringEntity where TDbContext: DbContext
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 用于普通的数据库操作
|
/// 用于普通的数据库操作
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected IRepository<T, TDbContext> Repository;
|
protected IRepository<T, TDbContext> Repository;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 用于事务操作
|
/// 用于事务操作
|
||||||
/// <para>使用详见:http://doc.openauth.me/core/unitwork.html</para>
|
/// <para>使用详见:http://doc.openauth.me/core/unitwork.html</para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected IUnitWork<TDbContext> UnitWork;
|
protected IUnitWork<TDbContext> UnitWork;
|
||||||
|
|
||||||
protected IAuth _auth;
|
protected IAuth _auth;
|
||||||
|
|
||||||
public BaseApp(IUnitWork<TDbContext> unitWork, IRepository<T,TDbContext> repository, IAuth auth)
|
public BaseApp(IUnitWork<TDbContext> unitWork, IRepository<T,TDbContext> repository, IAuth auth)
|
||||||
{
|
{
|
||||||
UnitWork = unitWork;
|
UnitWork = unitWork;
|
||||||
Repository = repository;
|
Repository = repository;
|
||||||
_auth = auth;
|
_auth = auth;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取当前登录用户的数据访问权限
|
/// 获取当前登录用户的数据访问权限
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name=""parameterName>linq表达式参数的名称,如u=>u.name中的"u"</param>
|
/// <param name=""parameterName>linq表达式参数的名称,如u=>u.name中的"u"</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
protected IQueryable<T> GetDataPrivilege(string parametername)
|
protected IQueryable<T> GetDataPrivilege(string parametername)
|
||||||
{
|
{
|
||||||
var loginUser = _auth.GetCurrentUser();
|
var loginUser = _auth.GetCurrentUser();
|
||||||
if (loginUser.User.Account == Define.SYSTEM_USERNAME) return UnitWork.Find<T>(null); //超级管理员特权
|
if (loginUser.User.Account == Define.SYSTEM_USERNAME) return UnitWork.Find<T>(null); //超级管理员特权
|
||||||
|
|
||||||
var moduleName = typeof(T).Name;
|
var moduleName = typeof(T).Name;
|
||||||
var rule = UnitWork.FirstOrDefault<DataPrivilegeRule>(u => u.SourceCode == moduleName);
|
var rule = UnitWork.FirstOrDefault<DataPrivilegeRule>(u => u.SourceCode == moduleName);
|
||||||
if (rule == null) return UnitWork.Find<T>(null); //没有设置数据规则,那么视为该资源允许被任何主体查看
|
if (rule == null) return UnitWork.Find<T>(null); //没有设置数据规则,那么视为该资源允许被任何主体查看
|
||||||
if (rule.PrivilegeRules.Contains(Define.DATAPRIVILEGE_LOGINUSER) ||
|
if (rule.PrivilegeRules.Contains(Define.DATAPRIVILEGE_LOGINUSER) ||
|
||||||
rule.PrivilegeRules.Contains(Define.DATAPRIVILEGE_LOGINROLE)||
|
rule.PrivilegeRules.Contains(Define.DATAPRIVILEGE_LOGINROLE)||
|
||||||
rule.PrivilegeRules.Contains(Define.DATAPRIVILEGE_LOGINORG))
|
rule.PrivilegeRules.Contains(Define.DATAPRIVILEGE_LOGINORG))
|
||||||
{
|
{
|
||||||
|
|
||||||
//即把{loginUser} =='xxxxxxx'换为 loginUser.User.Id =='xxxxxxx',从而把当前登录的用户名与当时设计规则时选定的用户id对比
|
//即把{loginUser} =='xxxxxxx'换为 loginUser.User.Id =='xxxxxxx',从而把当前登录的用户名与当时设计规则时选定的用户id对比
|
||||||
rule.PrivilegeRules = rule.PrivilegeRules.Replace(Define.DATAPRIVILEGE_LOGINUSER, loginUser.User.Id);
|
rule.PrivilegeRules = rule.PrivilegeRules.Replace(Define.DATAPRIVILEGE_LOGINUSER, loginUser.User.Id);
|
||||||
|
|
||||||
var roles = loginUser.Roles.Select(u => u.Id).ToList();
|
var roles = loginUser.Roles.Select(u => u.Id).ToList();
|
||||||
roles.Sort(); //按字母排序,这样可以进行like操作
|
roles.Sort(); //按字母排序,这样可以进行like操作
|
||||||
rule.PrivilegeRules = rule.PrivilegeRules.Replace(Define.DATAPRIVILEGE_LOGINROLE,
|
rule.PrivilegeRules = rule.PrivilegeRules.Replace(Define.DATAPRIVILEGE_LOGINROLE,
|
||||||
string.Join(',',roles));
|
string.Join(',',roles));
|
||||||
|
|
||||||
var orgs = loginUser.Orgs.Select(u => u.Id).ToList();
|
var orgs = loginUser.Orgs.Select(u => u.Id).ToList();
|
||||||
orgs.Sort();
|
orgs.Sort();
|
||||||
rule.PrivilegeRules = rule.PrivilegeRules.Replace(Define.DATAPRIVILEGE_LOGINORG,
|
rule.PrivilegeRules = rule.PrivilegeRules.Replace(Define.DATAPRIVILEGE_LOGINORG,
|
||||||
string.Join(',',orgs));
|
string.Join(',',orgs));
|
||||||
}
|
}
|
||||||
return UnitWork.Find<T>(null).GenerateFilter(parametername,
|
return UnitWork.Find<T>(null).GenerateFilter(parametername,
|
||||||
JsonHelper.Instance.Deserialize<FilterGroup>(rule.PrivilegeRules));
|
JsonHelper.Instance.Deserialize<FilterGroup>(rule.PrivilegeRules));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 按id批量删除
|
/// 按id批量删除
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ids"></param>
|
/// <param name="ids"></param>
|
||||||
public virtual void Delete(string[] ids)
|
public virtual void Delete(string[] ids)
|
||||||
{
|
{
|
||||||
Repository.Delete(u => ids.Contains(u.Id));
|
Repository.Delete(u => ids.Contains(u.Id));
|
||||||
}
|
}
|
||||||
|
|
||||||
public T Get(string id)
|
public T Get(string id)
|
||||||
{
|
{
|
||||||
return Repository.FirstOrDefault(u => u.Id == id);
|
return Repository.FirstOrDefault(u => u.Id == id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 计算实体更新的层级信息
|
/// 计算实体更新的层级信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="U">U必须是一个继承TreeEntity的结构</typeparam>
|
/// <typeparam name="U">U必须是一个继承TreeEntity的结构</typeparam>
|
||||||
/// <param name="entity"></param>
|
/// <param name="entity"></param>
|
||||||
public void CaculateCascade<U>(U entity) where U : TreeEntity
|
public void CaculateCascade<U>(U entity) where U : TreeEntity
|
||||||
{
|
{
|
||||||
if (entity.ParentId == "") entity.ParentId = null;
|
if (entity.ParentId == "") entity.ParentId = null;
|
||||||
string cascadeId;
|
string cascadeId;
|
||||||
int currentCascadeId = 1; //当前结点的级联节点最后一位
|
int currentCascadeId = 1; //当前结点的级联节点最后一位
|
||||||
var sameLevels = UnitWork.Find<U>(o => o.ParentId == entity.ParentId && o.Id != entity.Id);
|
var sameLevels = UnitWork.Find<U>(o => o.ParentId == entity.ParentId && o.Id != entity.Id);
|
||||||
foreach (var obj in sameLevels)
|
foreach (var obj in sameLevels)
|
||||||
{
|
{
|
||||||
int objCascadeId = int.Parse(obj.CascadeId.TrimEnd('.').Split('.').Last());
|
int objCascadeId = int.Parse(obj.CascadeId.TrimEnd('.').Split('.').Last());
|
||||||
if (currentCascadeId <= objCascadeId) currentCascadeId = objCascadeId + 1;
|
if (currentCascadeId <= objCascadeId) currentCascadeId = objCascadeId + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(entity.ParentId))
|
if (!string.IsNullOrEmpty(entity.ParentId))
|
||||||
{
|
{
|
||||||
var parentOrg = UnitWork.FirstOrDefault<U>(o => o.Id == entity.ParentId);
|
var parentOrg = UnitWork.FirstOrDefault<U>(o => o.Id == entity.ParentId);
|
||||||
if (parentOrg != null)
|
if (parentOrg != null)
|
||||||
{
|
{
|
||||||
cascadeId = parentOrg.CascadeId + currentCascadeId + ".";
|
cascadeId = parentOrg.CascadeId + currentCascadeId + ".";
|
||||||
entity.ParentName = parentOrg.Name;
|
entity.ParentName = parentOrg.Name;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw new Exception("未能找到该组织的父节点信息");
|
throw new Exception("未能找到该组织的父节点信息");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cascadeId = ".0." + currentCascadeId + ".";
|
cascadeId = ".0." + currentCascadeId + ".";
|
||||||
entity.ParentName = "根节点";
|
entity.ParentName = "根节点";
|
||||||
}
|
}
|
||||||
|
|
||||||
entity.CascadeId = cascadeId;
|
entity.CascadeId = cascadeId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
128
OpenAuth.App/Base/BaseLongApp.cs
Normal file
128
OpenAuth.App/Base/BaseLongApp.cs
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using Infrastructure;
|
||||||
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using OpenAuth.App.Interface;
|
||||||
|
using OpenAuth.Repository.Core;
|
||||||
|
using OpenAuth.Repository.Domain;
|
||||||
|
using OpenAuth.Repository.Interface;
|
||||||
|
|
||||||
|
namespace OpenAuth.App
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// ⭐⭐数据库Id为numberic类型的数据表相关业务使用该基类⭐⭐
|
||||||
|
/// 业务层基类,UnitWork用于事务操作,Repository用于普通的数据库操作
|
||||||
|
/// <para>如用户管理:Class UserManagerApp:BaseApp<User></para>
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T"></typeparam>
|
||||||
|
public class BaseLongApp<T, TDbContext> where T : LongEntity where TDbContext: DbContext
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 用于普通的数据库操作
|
||||||
|
/// </summary>
|
||||||
|
protected IRepository<T, TDbContext> Repository;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 用于事务操作
|
||||||
|
/// <para>使用详见:http://doc.openauth.me/core/unitwork.html</para>
|
||||||
|
/// </summary>
|
||||||
|
protected IUnitWork<TDbContext> UnitWork;
|
||||||
|
|
||||||
|
protected IAuth _auth;
|
||||||
|
|
||||||
|
public BaseLongApp(IUnitWork<TDbContext> unitWork, IRepository<T,TDbContext> repository, IAuth auth)
|
||||||
|
{
|
||||||
|
UnitWork = unitWork;
|
||||||
|
Repository = repository;
|
||||||
|
_auth = auth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前登录用户的数据访问权限
|
||||||
|
/// </summary>
|
||||||
|
/// <param name=""parameterName>linq表达式参数的名称,如u=>u.name中的"u"</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
protected IQueryable<T> GetDataPrivilege(string parametername)
|
||||||
|
{
|
||||||
|
var loginUser = _auth.GetCurrentUser();
|
||||||
|
if (loginUser.User.Account == Define.SYSTEM_USERNAME) return UnitWork.Find<T>(null); //超级管理员特权
|
||||||
|
|
||||||
|
var moduleName = typeof(T).Name;
|
||||||
|
var rule = UnitWork.FirstOrDefault<DataPrivilegeRule>(u => u.SourceCode == moduleName);
|
||||||
|
if (rule == null) return UnitWork.Find<T>(null); //没有设置数据规则,那么视为该资源允许被任何主体查看
|
||||||
|
if (rule.PrivilegeRules.Contains(Define.DATAPRIVILEGE_LOGINUSER) ||
|
||||||
|
rule.PrivilegeRules.Contains(Define.DATAPRIVILEGE_LOGINROLE)||
|
||||||
|
rule.PrivilegeRules.Contains(Define.DATAPRIVILEGE_LOGINORG))
|
||||||
|
{
|
||||||
|
|
||||||
|
//即把{loginUser} =='xxxxxxx'换为 loginUser.User.Id =='xxxxxxx',从而把当前登录的用户名与当时设计规则时选定的用户id对比
|
||||||
|
rule.PrivilegeRules = rule.PrivilegeRules.Replace(Define.DATAPRIVILEGE_LOGINUSER, loginUser.User.Id);
|
||||||
|
|
||||||
|
var roles = loginUser.Roles.Select(u => u.Id).ToList();
|
||||||
|
roles.Sort(); //按字母排序,这样可以进行like操作
|
||||||
|
rule.PrivilegeRules = rule.PrivilegeRules.Replace(Define.DATAPRIVILEGE_LOGINROLE,
|
||||||
|
string.Join(',',roles));
|
||||||
|
|
||||||
|
var orgs = loginUser.Orgs.Select(u => u.Id).ToList();
|
||||||
|
orgs.Sort();
|
||||||
|
rule.PrivilegeRules = rule.PrivilegeRules.Replace(Define.DATAPRIVILEGE_LOGINORG,
|
||||||
|
string.Join(',',orgs));
|
||||||
|
}
|
||||||
|
return UnitWork.Find<T>(null).GenerateFilter(parametername,
|
||||||
|
JsonHelper.Instance.Deserialize<FilterGroup>(rule.PrivilegeRules));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 按id批量删除
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="ids"></param>
|
||||||
|
public virtual void Delete(long[] ids)
|
||||||
|
{
|
||||||
|
Repository.Delete(u => ids.Contains(u.Id));
|
||||||
|
}
|
||||||
|
|
||||||
|
public T Get(long id)
|
||||||
|
{
|
||||||
|
return Repository.FirstOrDefault(u => u.Id == id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 计算实体更新的层级信息
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="U">U必须是一个继承TreeEntity的结构</typeparam>
|
||||||
|
/// <param name="entity"></param>
|
||||||
|
public void CaculateCascade<U>(U entity) where U : TreeEntity
|
||||||
|
{
|
||||||
|
if (entity.ParentId == "") entity.ParentId = null;
|
||||||
|
string cascadeId;
|
||||||
|
int currentCascadeId = 1; //当前结点的级联节点最后一位
|
||||||
|
var sameLevels = UnitWork.Find<U>(o => o.ParentId == entity.ParentId && o.Id != entity.Id);
|
||||||
|
foreach (var obj in sameLevels)
|
||||||
|
{
|
||||||
|
int objCascadeId = int.Parse(obj.CascadeId.TrimEnd('.').Split('.').Last());
|
||||||
|
if (currentCascadeId <= objCascadeId) currentCascadeId = objCascadeId + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(entity.ParentId))
|
||||||
|
{
|
||||||
|
var parentOrg = UnitWork.FirstOrDefault<U>(o => o.Id == entity.ParentId);
|
||||||
|
if (parentOrg != null)
|
||||||
|
{
|
||||||
|
cascadeId = parentOrg.CascadeId + currentCascadeId + ".";
|
||||||
|
entity.ParentName = parentOrg.Name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new Exception("未能找到该组织的父节点信息");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cascadeId = ".0." + currentCascadeId + ".";
|
||||||
|
entity.ParentName = "根节点";
|
||||||
|
}
|
||||||
|
|
||||||
|
entity.CascadeId = cascadeId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -487,7 +487,7 @@ namespace OpenAuth.App
|
|||||||
var types = AssemblyLoadContext.Default
|
var types = AssemblyLoadContext.Default
|
||||||
.LoadFromAssemblyName(new AssemblyName(compilation.Name))
|
.LoadFromAssemblyName(new AssemblyName(compilation.Name))
|
||||||
.GetTypes().Where(x => x.GetTypeInfo().BaseType != null
|
.GetTypes().Where(x => x.GetTypeInfo().BaseType != null
|
||||||
&& x.BaseType == typeof(Entity));
|
&& x.BaseType == typeof(StringEntity));
|
||||||
foreach (var entity in types)
|
foreach (var entity in types)
|
||||||
{
|
{
|
||||||
if (entity.Name == moduleCode )
|
if (entity.Name == moduleCode )
|
||||||
|
32
OpenAuth.Repository/Core/LongEntity.cs
Normal file
32
OpenAuth.Repository/Core/LongEntity.cs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using Yitter.IdGenerator;
|
||||||
|
|
||||||
|
namespace OpenAuth.Repository.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 数据库Id为numberic类型的数据实体使用该基类,用法同Entity
|
||||||
|
/// 数据库Id字段为numberic(16,0)或以上长度的整型,采用雪花算法生成Id。
|
||||||
|
/// </summary>
|
||||||
|
public class LongEntity :BaseEntity
|
||||||
|
{
|
||||||
|
[Browsable(false)]
|
||||||
|
public long Id { get; set; }
|
||||||
|
public override bool KeyIsNull()
|
||||||
|
{
|
||||||
|
return Id == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 采用雪花算法计算Id
|
||||||
|
/// </summary>
|
||||||
|
public override void GenerateDefaultKeyVal()
|
||||||
|
{
|
||||||
|
// 全局初始化设置WorkerId,默认最大2^16-1。(初始化过程全局只需一次,且必须最先设置)
|
||||||
|
var options = new IdGeneratorOptions(){ WorkerId = 1};
|
||||||
|
IIdGenerator IdHelper = new YitIdGenerator(options);
|
||||||
|
|
||||||
|
// 初始化以后,就可以在需要的地方调用方法生成ID。
|
||||||
|
Id = IdHelper.NewLong();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
31
OpenAuth.Repository/Core/StringEntity.cs
Normal file
31
OpenAuth.Repository/Core/StringEntity.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
|
||||||
|
namespace OpenAuth.Repository.Core
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 主键为字符串的实体基类,为系统默认的实体类型
|
||||||
|
/// </summary>
|
||||||
|
public class StringEntity : BaseEntity
|
||||||
|
{
|
||||||
|
[Browsable(false)]
|
||||||
|
public string Id { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 判断主键是否为空,常用做判定操作是【添加】还是【编辑】
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public override bool KeyIsNull()
|
||||||
|
{
|
||||||
|
return string.IsNullOrEmpty(Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 创建默认的主键值
|
||||||
|
/// </summary>
|
||||||
|
public override void GenerateDefaultKeyVal()
|
||||||
|
{
|
||||||
|
Id = Guid.NewGuid().ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,7 @@ namespace OpenAuth.Repository.Core
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 树状结构实体
|
/// 树状结构实体
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class TreeEntity: Entity
|
public abstract class TreeEntity: StringEntity
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 节点语义ID
|
/// 节点语义ID
|
||||||
|
@ -18,7 +18,7 @@ namespace OpenAuth.Repository.Domain
|
|||||||
/// 应用
|
/// 应用
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Table("Application")]
|
[Table("Application")]
|
||||||
public partial class Application : Entity
|
public partial class Application : StringEntity
|
||||||
{
|
{
|
||||||
public Application()
|
public Application()
|
||||||
{
|
{
|
||||||
|
@ -20,7 +20,7 @@ namespace OpenAuth.Repository.Domain
|
|||||||
/// 代码生成器的表信息
|
/// 代码生成器的表信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Table("BuilderTable")]
|
[Table("BuilderTable")]
|
||||||
public partial class BuilderTable : Entity
|
public partial class BuilderTable : StringEntity
|
||||||
{
|
{
|
||||||
public BuilderTable()
|
public BuilderTable()
|
||||||
{
|
{
|
||||||
|
@ -20,7 +20,7 @@ namespace OpenAuth.Repository.Domain
|
|||||||
/// 代码生成器的字段信息
|
/// 代码生成器的字段信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Table("BuilderTableColumn")]
|
[Table("BuilderTableColumn")]
|
||||||
public partial class BuilderTableColumn : Entity
|
public partial class BuilderTableColumn : StringEntity
|
||||||
{
|
{
|
||||||
public BuilderTableColumn()
|
public BuilderTableColumn()
|
||||||
{
|
{
|
||||||
|
@ -18,7 +18,7 @@ namespace OpenAuth.Repository.Domain
|
|||||||
/// 分类表,也可用作数据字典。表示一个全集,比如:男、女、未知。关联的分类类型表示按什么进行的分类,如:按照性别对人类对象集
|
/// 分类表,也可用作数据字典。表示一个全集,比如:男、女、未知。关联的分类类型表示按什么进行的分类,如:按照性别对人类对象集
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Table("Category")]
|
[Table("Category")]
|
||||||
public partial class Category : Entity
|
public partial class Category : StringEntity
|
||||||
{
|
{
|
||||||
public Category()
|
public Category()
|
||||||
{
|
{
|
||||||
|
@ -18,7 +18,7 @@ namespace OpenAuth.Repository.Domain
|
|||||||
/// 分类类型
|
/// 分类类型
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Table("CategoryType")]
|
[Table("CategoryType")]
|
||||||
public partial class CategoryType : Entity
|
public partial class CategoryType : StringEntity
|
||||||
{
|
{
|
||||||
public CategoryType()
|
public CategoryType()
|
||||||
{
|
{
|
||||||
|
@ -18,7 +18,7 @@ namespace OpenAuth.Repository.Domain
|
|||||||
/// 系统授权规制表
|
/// 系统授权规制表
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Table("DataPrivilegeRule")]
|
[Table("DataPrivilegeRule")]
|
||||||
public partial class DataPrivilegeRule : Entity
|
public partial class DataPrivilegeRule : StringEntity
|
||||||
{
|
{
|
||||||
public DataPrivilegeRule()
|
public DataPrivilegeRule()
|
||||||
{
|
{
|
||||||
|
@ -19,7 +19,7 @@ namespace OpenAuth.Repository.Domain
|
|||||||
/// 工作流流程实例表
|
/// 工作流流程实例表
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Table("FlowInstance")]
|
[Table("FlowInstance")]
|
||||||
public partial class FlowInstance : Entity
|
public partial class FlowInstance : StringEntity
|
||||||
{
|
{
|
||||||
public FlowInstance()
|
public FlowInstance()
|
||||||
{
|
{
|
||||||
|
@ -18,7 +18,7 @@ namespace OpenAuth.Repository.Domain
|
|||||||
/// 工作流实例操作记录
|
/// 工作流实例操作记录
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Table("FlowInstanceOperationHistory")]
|
[Table("FlowInstanceOperationHistory")]
|
||||||
public partial class FlowInstanceOperationHistory : Entity
|
public partial class FlowInstanceOperationHistory : StringEntity
|
||||||
{
|
{
|
||||||
public FlowInstanceOperationHistory()
|
public FlowInstanceOperationHistory()
|
||||||
{
|
{
|
||||||
|
@ -18,7 +18,7 @@ namespace OpenAuth.Repository.Domain
|
|||||||
/// 工作流实例流转历史记录
|
/// 工作流实例流转历史记录
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Table("FlowInstanceTransitionHistory")]
|
[Table("FlowInstanceTransitionHistory")]
|
||||||
public partial class FlowInstanceTransitionHistory : Entity
|
public partial class FlowInstanceTransitionHistory : StringEntity
|
||||||
{
|
{
|
||||||
public FlowInstanceTransitionHistory()
|
public FlowInstanceTransitionHistory()
|
||||||
{
|
{
|
||||||
|
@ -19,7 +19,7 @@ namespace OpenAuth.Repository.Domain
|
|||||||
/// 工作流模板信息表
|
/// 工作流模板信息表
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Table("FlowScheme")]
|
[Table("FlowScheme")]
|
||||||
public partial class FlowScheme : Entity
|
public partial class FlowScheme : StringEntity
|
||||||
{
|
{
|
||||||
public FlowScheme()
|
public FlowScheme()
|
||||||
{
|
{
|
||||||
|
@ -18,7 +18,7 @@ namespace OpenAuth.Repository.Domain
|
|||||||
/// 表单模板表
|
/// 表单模板表
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Table("Form")]
|
[Table("Form")]
|
||||||
public partial class Form : Entity
|
public partial class Form : StringEntity
|
||||||
{
|
{
|
||||||
public Form()
|
public Form()
|
||||||
{
|
{
|
||||||
|
@ -18,7 +18,7 @@ namespace OpenAuth.Repository.Domain
|
|||||||
/// 模拟一个自定页面的表单,该数据会关联到流程实例FrmData,可用于复杂页面的设计及后期的数据分析
|
/// 模拟一个自定页面的表单,该数据会关联到流程实例FrmData,可用于复杂页面的设计及后期的数据分析
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Table("FrmLeaveReq")]
|
[Table("FrmLeaveReq")]
|
||||||
public partial class FrmLeaveReq : Entity
|
public partial class FrmLeaveReq : StringEntity
|
||||||
{
|
{
|
||||||
public FrmLeaveReq()
|
public FrmLeaveReq()
|
||||||
{
|
{
|
||||||
|
@ -18,7 +18,7 @@ namespace OpenAuth.Repository.Domain
|
|||||||
/// 模块元素表(需要权限控制的按钮)
|
/// 模块元素表(需要权限控制的按钮)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Table("ModuleElement")]
|
[Table("ModuleElement")]
|
||||||
public partial class ModuleElement : Entity
|
public partial class ModuleElement : StringEntity
|
||||||
{
|
{
|
||||||
public ModuleElement()
|
public ModuleElement()
|
||||||
{
|
{
|
||||||
|
@ -20,7 +20,7 @@ namespace OpenAuth.Repository.Domain
|
|||||||
/// 定时任务
|
/// 定时任务
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Table("OpenJob")]
|
[Table("OpenJob")]
|
||||||
public partial class OpenJob : Entity
|
public partial class OpenJob : StringEntity
|
||||||
{
|
{
|
||||||
public OpenJob()
|
public OpenJob()
|
||||||
{
|
{
|
||||||
|
@ -18,7 +18,7 @@ namespace OpenAuth.Repository.Domain
|
|||||||
/// 多对多关系集中映射
|
/// 多对多关系集中映射
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Table("Relevance")]
|
[Table("Relevance")]
|
||||||
public partial class Relevance : Entity
|
public partial class Relevance : StringEntity
|
||||||
{
|
{
|
||||||
public Relevance()
|
public Relevance()
|
||||||
{
|
{
|
||||||
|
@ -18,7 +18,7 @@ namespace OpenAuth.Repository.Domain
|
|||||||
/// 角色表
|
/// 角色表
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Table("Role")]
|
[Table("Role")]
|
||||||
public partial class Role : Entity
|
public partial class Role : StringEntity
|
||||||
{
|
{
|
||||||
public Role()
|
public Role()
|
||||||
{
|
{
|
||||||
|
@ -18,7 +18,7 @@ namespace OpenAuth.Repository.Domain
|
|||||||
/// 系统日志
|
/// 系统日志
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Table("SysLog")]
|
[Table("SysLog")]
|
||||||
public partial class SysLog : Entity
|
public partial class SysLog : StringEntity
|
||||||
{
|
{
|
||||||
public SysLog()
|
public SysLog()
|
||||||
{
|
{
|
||||||
|
@ -18,7 +18,7 @@ namespace OpenAuth.Repository.Domain
|
|||||||
/// 系统消息表
|
/// 系统消息表
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Table("SysMessage")]
|
[Table("SysMessage")]
|
||||||
public partial class SysMessage : Entity
|
public partial class SysMessage : StringEntity
|
||||||
{
|
{
|
||||||
public SysMessage()
|
public SysMessage()
|
||||||
{
|
{
|
||||||
|
@ -15,7 +15,7 @@ namespace OpenAuth.Repository.Domain
|
|||||||
/// 文件
|
/// 文件
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Table("UploadFile")]
|
[Table("UploadFile")]
|
||||||
public partial class UploadFile : Entity
|
public partial class UploadFile : StringEntity
|
||||||
{
|
{
|
||||||
public UploadFile()
|
public UploadFile()
|
||||||
{
|
{
|
||||||
|
@ -18,7 +18,7 @@ namespace OpenAuth.Repository.Domain
|
|||||||
/// 用户基本信息表
|
/// 用户基本信息表
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Table("User")]
|
[Table("User")]
|
||||||
public partial class User : Entity
|
public partial class User : StringEntity
|
||||||
{
|
{
|
||||||
public User()
|
public User()
|
||||||
{
|
{
|
||||||
|
@ -18,7 +18,7 @@ namespace OpenAuth.Repository.Domain
|
|||||||
/// 入库通知单明细
|
/// 入库通知单明细
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Table("WmsInboundOrderDtbl")]
|
[Table("WmsInboundOrderDtbl")]
|
||||||
public partial class WmsInboundOrderDtbl : Entity
|
public partial class WmsInboundOrderDtbl : StringEntity
|
||||||
{
|
{
|
||||||
public WmsInboundOrderDtbl()
|
public WmsInboundOrderDtbl()
|
||||||
{
|
{
|
||||||
|
@ -18,7 +18,7 @@ namespace OpenAuth.Repository.Domain
|
|||||||
/// 入库通知单(入库订单)
|
/// 入库通知单(入库订单)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Table("WmsInboundOrderTbl")]
|
[Table("WmsInboundOrderTbl")]
|
||||||
public partial class WmsInboundOrderTbl : Entity
|
public partial class WmsInboundOrderTbl : StringEntity
|
||||||
{
|
{
|
||||||
public WmsInboundOrderTbl()
|
public WmsInboundOrderTbl()
|
||||||
{
|
{
|
||||||
|
@ -113,7 +113,6 @@ namespace OpenAuth.Repository
|
|||||||
public virtual DbSet<OpenJob> OpenJobs { get; set; }
|
public virtual DbSet<OpenJob> OpenJobs { get; set; }
|
||||||
public virtual DbSet<BuilderTable> BuilderTables { get; set; }
|
public virtual DbSet<BuilderTable> BuilderTables { get; set; }
|
||||||
public virtual DbSet<BuilderTableColumn> BuilderTableColumns { get; set; }
|
public virtual DbSet<BuilderTableColumn> BuilderTableColumns { get; set; }
|
||||||
|
|
||||||
//非数据库表格
|
//非数据库表格
|
||||||
public virtual DbQuery<SysTableColumn> SysTableColumns { get; set; }
|
public virtual DbQuery<SysTableColumn> SysTableColumns { get; set; }
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user