feat: 框架代码同步 (#342)

Co-authored-by: tk <fiyne1a@dingtalk.com>
This commit is contained in:
2025-07-29 10:11:54 +08:00
committed by GitHub
parent e99cb2aff9
commit 1650b8a127
230 changed files with 2488 additions and 1438 deletions

View File

@ -41,6 +41,7 @@ USDT
响应体
响应状态码
唯一编码
处理中
备注
外国人居留证
外部错误
@ -58,13 +59,14 @@ USDT
已冻结
已发送
已婚
已完成
已校验
已经冻结
已解冻
已读
并且
归属角色
归属部门
待执行
微信支付
成功
或者
@ -99,10 +101,12 @@ USDT
最后登录时间
未处理异常
未婚
未结算
未读
本人数据
本科
本部门和下级部门数据
本部门和下级部门数据
本部门和所有子部门数据
本部门数据
框架
比较数据库结构
@ -112,6 +116,7 @@ USDT
消息类型
港澳台通行证
用户代理
用户取消
用户名
用户导出
用户邀请导出
@ -128,13 +133,12 @@ USDT
等于
等待发送
等待支付
管理员充值
管理员扣费
管理员赠送
管理模块
系统模块
绑定手机号码
结果非预期
结算解冻
群众
自助充值
自定义
@ -149,8 +153,9 @@ USDT
请求方式
请求日志导出
调试
超时解冻
身份证
转账支出
转账收入
运行
追踪
追踪标识

View File

@ -2,6 +2,7 @@
6位数字
8位以上数字字母组合
XML注释文件不存在
不能设置自己为上级
中文姓名
事务已回滚
事务已提交
@ -32,6 +33,7 @@ XML注释文件不存在
性别不正确
手机号码不正确
手机号码不能为空
指定的上级为该账号的下级用户
接口编码不存在
支付宝账号
支付方式不正确
@ -59,9 +61,6 @@ XML注释文件不存在
未指定部门
未获取到待执行任务
档案可见性不正确
模块名称不能为空
模块类型不能为空
模块说明不能为空
此节点已下线
民族不正确
消息主题不能为空
@ -72,13 +71,11 @@ XML注释文件不存在
用户名不能为空
用户名不能是手机号码
用户名或密码错误
用户名长度4位以上
用户头像不能为空
用户编号不存在
登录用户
目标设备不能为空
短信验证请求不能为空
种子数据插入完成
站内信不存在
站内信状态不正确
站内信类型不正确
@ -119,6 +116,7 @@ XML注释文件不存在
随机延时结束时间不正确
随机延时起始时间不正确
非JSON字符串
此操作不被允许
验证数据不能为空
验证码不正确
验证码不能为空

View File

@ -1,5 +1,5 @@
[
// ------------------------------ 主控面板 ------------------------------
// ------------------------------ 主控面板 /home ------------------------------
{
"Component": "home",
"Icon": "el-icon-house",
@ -8,9 +8,9 @@
"Path": "/home",
"Sort": 999,
"Title": "主控面板",
"Type": 1
"Type": 1,
},
// ------------------------------ 权限管理 ------------------------------
// ------------------------------ 权限管理 /power ------------------------------
{
"Icon": "el-icon-setting",
"Id": 373837917724677,
@ -18,96 +18,96 @@
"Path": "/power",
"Sort": 100,
"Title": "权限管理",
"Type": 1
"Type": 1,
},
{
"Component": "sys/user",
"Component": "sys/power/user",
"Icon": "el-icon-user",
"Id": 373837957840901,
"Name": "sys/user",
"Name": "sys/power/user",
"ParentId": 373837917724677,
"Path": "/power/user",
"Sort": 100,
"Title": "用户管理",
"Type": 1
"Type": 1,
},
{
"Component": "sys/role",
"Component": "sys/power/role",
"Icon": "sc-icon-role",
"Id": 373838018527237,
"Name": "sys/role",
"Name": "sys/power/role",
"ParentId": 373837917724677,
"Path": "/power/role",
"Sort": 99,
"Title": "角色管理",
"Type": 1
"Type": 1,
},
{
"Component": "sys/dept",
"Component": "sys/power/dept",
"Icon": "sc-icon-dept",
"Id": 373838045605893,
"Name": "sys/dept",
"Name": "sys/power/dept",
"ParentId": 373837917724677,
"Path": "/power/dept",
"Sort": 98,
"Title": "部门管理",
"Type": 1
"Type": 1,
},
{
"Component": "sys/menu",
"Component": "sys/power/menu",
"Icon": "el-icon-fold",
"Id": 373838070898693,
"Name": "sys/menu",
"Name": "sys/power/menu",
"ParentId": 373837917724677,
"Path": "/power/menu",
"Sort": 97,
"Title": "菜单管理",
"Type": 1
"Type": 1,
},
// ------------------------------ 财务管理 ------------------------------
// ------------------------------ 财务管理 /finance ------------------------------
{
"Icon": "el-icon-money",
"Id": 690906994118665,
"Name": "finance",
"Name": "sys/finance",
"Path": "/finance",
"Sort": 99,
"Title": "财务管理",
"Type": 1
"Type": 1,
},
{
"Component": "sys/wallet",
"Component": "sys/finance/wallet",
"Icon": "el-icon-wallet",
"Id": 690907673255942,
"Name": "sys/wallet",
"Name": "sys/finance/wallet",
"ParentId": 690906994118665,
"Path": "/finance/wallet",
"Sort": 100,
"Title": "钱包管理",
"Type": 1
"Type": 1,
},
{
"Component": "sys/trade",
"Component": "sys/finance/trade",
"Icon": "el-icon-calendar",
"Id": 690907673255943,
"Name": "sys/trade",
"Name": "sys/finance/trade",
"ParentId": 690906994118665,
"Path": "/finance/trade",
"Sort": 99,
"Title": "交易流水",
"Type": 1
"Type": 1,
},
{
"Component": "sys/order",
"Component": "sys/finance/order",
"Icon": "el-icon-shopping-cart",
"Id": 690907673255944,
"Name": "sys/order",
"Name": "sys/finance/order",
"ParentId": 690906994118665,
"Path": "/finance/order",
"Sort": 98,
"Title": "充值订单",
"Type": 1
"Title": "自助充值",
"Type": 1,
},
// ------------------------------ 营销管理 ------------------------------
// ------------------------------ 营销管理 /market ------------------------------
{
"Icon": "el-icon-share",
"Id": 692575802241032,
@ -115,67 +115,67 @@
"Path": "/market",
"Sort": 98,
"Title": "营销管理",
"Type": 1
"Type": 1,
},
{
"Component": "sys/invite",
"Component": "sys/market/invite",
"Icon": "el-icon-connection",
"Id": 692575802245126,
"Name": "sys/invite",
"Name": "sys/market/invite",
"ParentId": 692575802241032,
"Path": "/market/invite",
"Sort": 100,
"Title": "邀请管理",
"Type": 1
"Title": "粉丝管理",
"Type": 1,
},
// ------------------------------ 系统管理 ------------------------------
// ------------------------------ 系统管理 /system ------------------------------
{
"Icon": "sc-icon-app",
"Id": 485278637670422,
"Name": "sys",
"Path": "/sys",
"Name": "system",
"Path": "/system",
"Sort": 98,
"Title": "系统管理",
"Type": 1
"Type": 1,
},
{
"Component": "sys/config",
"Component": "sys/system/config",
"Icon": "el-icon-set-up",
"Id": 380415005847557,
"Name": "sys/config",
"Name": "sys/system/config",
"ParentId": 485278637670422,
"Path": "/system/config",
"Sort": 100,
"Title": "系统设置",
"Type": 1
"Type": 1,
},
{
"Component": "sys/job",
"Component": "sys/system/job",
"Icon": "sc-icon-scheduled-job",
"Id": 510067557638158,
"Name": "sys/job",
"Name": "sys/system/job",
"ParentId": 485278637670422,
"Path": "/system/job",
"Sort": 99,
"Title": "计划作业",
"Type": 1
"Type": 1,
},
{
"Component": "sys/dic",
"Component": "sys/system/dic",
"Icon": "sc-icon-dic",
"Id": 375315654221829,
"Name": "sys/dic",
"Name": "sys/system/dic",
"ParentId": 485278637670422,
"Path": "/system/dic",
"Sort": 98,
"Title": "字典管理",
"Type": 1
"Type": 1,
},
{
"Component": "sys/msg",
"Component": "sys/system/msg",
"Icon": "el-icon-message",
"Id": 482779610341392,
"Name": "sys/msg",
"Name": "sys/system/msg",
"ParentId": 485278637670422,
"Path": "/system/msg",
"Sort": 97,
@ -183,28 +183,28 @@
"Type": 1,
},
{
"Component": "sys/api",
"Component": "sys/system/api",
"Icon": "sc-icon-api",
"Id": 397880678895621,
"Name": "sys/api",
"Name": "sys/system/api",
"ParentId": 485278637670422,
"Path": "/system/api",
"Sort": 96,
"Title": "接口管理",
"Type": 1
"Type": 1,
},
{
"Component": "sys/cache",
"Component": "sys/system/cache",
"Icon": "sc-icon-memory",
"Id": 374911555702789,
"Name": "sys/cache",
"Name": "sys/system/cache",
"ParentId": 485278637670422,
"Path": "/system/cache",
"Sort": 95,
"Title": "缓存管理",
"Type": 1
"Type": 1,
},
// ------------------------------ 档案管理 ------------------------------
// ------------------------------ 档案管理 /archive ------------------------------
{
"Icon": "sc-icon-archive",
"Id": 616214756757512,
@ -212,20 +212,20 @@
"Path": "/archive",
"Sort": 97,
"Title": "档案管理",
"Type": 1
"Type": 1,
},
{
"Component": "sys/doc",
"Component": "sys/archive/doc",
"Icon": "el-icon-document",
"Id": 616214756757516,
"Name": "archive/doc",
"Name": "sys/archive/doc",
"ParentId": 616214756757512,
"Path": "/archive/doc",
"Sort": 100,
"Title": "文档管理",
"Type": 1
"Type": 1,
},
// ------------------------------ 日志管理 ------------------------------
// ------------------------------ 日志管理 /log ------------------------------
{
"Icon": "el-icon-tickets",
"Id": 374792687640581,
@ -233,7 +233,7 @@
"Path": "/log",
"Sort": 96,
"Title": "日志管理",
"Type": 1
"Type": 1,
},
{
"Component": "sys/log/operation",
@ -257,7 +257,7 @@
"Title": "登录日志",
"Type": 1,
},
// ------------------------------ 开发管理 ------------------------------
// ------------------------------ 开发管理 /dev ------------------------------
{
"Icon": "sc-icon-code",
"Id": 373838105399301,
@ -265,29 +265,29 @@
"Path": "/dev",
"Sort": 95,
"Title": "开发管理",
"Type": 1
"Type": 1,
},
{
"Component": "dev/code",
"Component": "sys/dev/code",
"Icon": "sc-icon-code2",
"Id": 373838147022853,
"Name": "dev/code",
"Name": "sys/dev/code",
"ParentId": 373838105399301,
"Path": "/dev/code",
"Sort": 100,
"Title": "代码生成",
"Type": 1
"Type": 1,
},
{
"Component": "sys/template",
"Component": "sys/dev/template",
"Icon": "sc-icon-template",
"Id": 694076641718288,
"Name": "dev/template",
"Name": "sys/dev/template",
"ParentId": 373838105399301,
"Path": "/dev/template",
"Sort": 99,
"Title": "页面模板",
"Type": 1
"Type": 1,
},
{
"Id": 482777529417739,

View File

@ -19,11 +19,11 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Roslynator.Analyzers" Version="4.13.1">
<PackageReference Include="Roslynator.Analyzers" Version="4.14.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="SonarAnalyzer.CSharp" Version="10.14.0.120626">
<PackageReference Include="SonarAnalyzer.CSharp" Version="10.15.0.120848">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@ -16,7 +16,7 @@ public static class ISelectExtensions
{
if (req.IgnoreOwner) {
me = me.DisableGlobalFilter(Chars.FLG_FREE_SQL_GLOBAL_FILTER_SELF, Chars.FLG_FREE_SQL_GLOBAL_FILTER_DEPT
, Chars.FLG_FREE_SQL_GLOBAL_FILTER_DEPT_WITH_CHILD);
, Chars.FLG_FREE_SQL_GLOBAL_FILTER_DEPT_WITH_CHILDREN, Chars.FLG_FREE_SQL_GLOBAL_FILTER_DEPT_WITH_SON);
}
return me;

View File

@ -69,4 +69,9 @@ public interface ICrudModule<in TCreateReq, TCreateRsp, in TEditReq, TQueryReq,
/// 查询实体
/// </summary>
Task<IEnumerable<TQueryRsp>> QueryAsync(QueryReq<TQueryReq> req);
/// <summary>
/// 实体求和
/// </summary>
Task<decimal> SumAsync(QueryReq<TQueryReq> req);
}

View File

@ -103,7 +103,7 @@ public abstract class RepositoryService<TEntity, TPrimary, TLogger>(BasicReposit
var update = BuildUpdate(newValue, includeFields, excludeFields, ignoreVersion).Where(whereExp).Where(whereSql);
if (disableGlobalDataFilter) {
update = update.DisableGlobalFilter(Chars.FLG_FREE_SQL_GLOBAL_FILTER_SELF, Chars.FLG_FREE_SQL_GLOBAL_FILTER_DEPT
, Chars.FLG_FREE_SQL_GLOBAL_FILTER_DEPT_WITH_CHILD);
, Chars.FLG_FREE_SQL_GLOBAL_FILTER_DEPT_WITH_CHILDREN, Chars.FLG_FREE_SQL_GLOBAL_FILTER_DEPT_WITH_SON);
}
return update.ExecuteEffectsAsync();

View File

@ -8,5 +8,5 @@ public interface IFieldSummary
/// <summary>
/// 备注
/// </summary>
string Summary { get; init; }
string Summary { get; set; }
}

View File

@ -79,5 +79,5 @@ public record Sys_Api : ImmutableEntity<string>, IFieldSummary
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_63)]
[CsvIgnore]
[JsonIgnore]
public virtual string Summary { get; init; }
public virtual string Summary { get; set; }
}

View File

@ -85,5 +85,5 @@ public record Sys_CodeTemplate : VersionEntity, IFieldSort, IFieldSummary, IFiel
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
[CsvIgnore]
[JsonIgnore]
public virtual string Summary { get; init; }
public virtual string Summary { get; set; }
}

View File

@ -68,5 +68,5 @@ public record Sys_Dept : VersionEntity, IFieldEnabled, IFieldSummary, IFieldSort
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
[CsvIgnore]
[JsonIgnore]
public virtual string Summary { get; init; }
public virtual string Summary { get; set; }
}

View File

@ -45,7 +45,7 @@ public record Sys_DicContent : VersionEntity, IFieldEnabled, IFieldSummary
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
[CsvIgnore]
[JsonIgnore]
public virtual string Summary { get; init; }
public virtual string Summary { get; set; }
/// <summary>
/// 键值

View File

@ -134,7 +134,7 @@ public record Sys_Job : VersionEntity, IFieldEnabled, IFieldSummary
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
[CsvIgnore]
[JsonIgnore]
public virtual string Summary { get; init; }
public virtual string Summary { get; set; }
/// <summary>
/// 执行用户

View File

@ -104,7 +104,7 @@ public record Sys_Role : VersionEntity, IFieldSort, IFieldEnabled, IFieldSummary
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
[CsvIgnore]
[JsonIgnore]
public virtual string Summary { get; init; }
public virtual string Summary { get; set; }
/// <summary>
/// 此角色下的用户集合

View File

@ -62,7 +62,7 @@ public record Sys_SiteMsg : VersionEntity, IRegister, IFieldSummary
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
[CsvIgnore]
[JsonIgnore]
public virtual string Summary { get; init; }
public virtual string Summary { get; set; }
/// <summary>
/// 消息主题

View File

@ -121,7 +121,7 @@ public record Sys_User : VersionEntity, IFieldSummary, IFieldEnabled, IRegister
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
[CsvIgnore]
[JsonIgnore]
public virtual string Summary { get; init; }
public virtual string Summary { get; set; }
/// <summary>
/// 授权验证Token全局唯一可以随时重置强制下线

View File

@ -46,6 +46,14 @@ public record Sys_UserInvite : VersionEntity, IFieldOwner
[JsonIgnore]
public virtual long? OwnerId { get; init; }
/// <summary>
/// 允许自助充值
/// </summary>
[Column]
[CsvIgnore]
[JsonIgnore]
public virtual bool SelfRechargeAllowed { get; init; }
/// <summary>
/// 用户
/// </summary>

View File

@ -87,7 +87,7 @@ public record Sys_WalletFrozen : LiteVersionEntity, IFieldOwner, IFieldSummary
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
[CsvIgnore]
[JsonIgnore]
public virtual string Summary { get; init; }
public virtual string Summary { get; set; }
/// <summary>
/// 钱包

View File

@ -12,7 +12,7 @@ public record Sys_WalletTrade : ImmutableEntity, IFieldOwner, IFieldSummary
[Column]
[CsvIgnore]
[JsonIgnore]
public virtual long Amount { get; init; }
public virtual long Amount { get; set; }
/// <summary>
/// 交易前余额
@ -60,7 +60,7 @@ public record Sys_WalletTrade : ImmutableEntity, IFieldOwner, IFieldSummary
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
[CsvIgnore]
[JsonIgnore]
public virtual string Summary { get; init; }
public virtual string Summary { get; set; }
/// <summary>
/// 交易方向

View File

@ -48,6 +48,23 @@ public record QueryReq<T> : DataAbstraction
/// </summary>
public string[] RequiredFields { get; init; }
/// <summary>
/// 求和表达式
/// </summary>
public Expression<Func<TEntity, long>> GetSumExp<TEntity>()
{
if (RequiredFields.NullOrEmpty()) {
return null;
}
var field = RequiredFields[0];
var leftParameter = Expression.Parameter(typeof(TEntity), "a");
var prop = typeof(TEntity).GetRecursiveProperty(field);
return prop == null || prop.GetCustomAttribute<DangerFieldAttribute>() != null
? null
: Expression.Lambda<Func<TEntity, long>>(CreatePropertyExpression(leftParameter, field), leftParameter);
}
/// <summary>
/// 列表表达式
/// </summary>
@ -79,4 +96,9 @@ public record QueryReq<T> : DataAbstraction
, bindings.SelectMany(x => x.Item1.PropertyType == x.Item2.Type ? [Expression.Bind(x.Item1, x.Item2)] : x.Item2.Bindings.ToArray()));
return Expression.Lambda<Func<TEntity, TEntity>>(expBody, expParameter);
}
private static Expression CreatePropertyExpression(ParameterExpression param, string propertyPath)
{
return propertyPath.Split('.').Aggregate<string, Expression>(param, Expression.PropertyOrField);
}
}

View File

@ -31,5 +31,5 @@ public sealed record ExportApiRsp : QueryApiRsp
[CsvIndex(3)]
[CsvIgnore(false)]
[CsvName(nameof(Ln.接口描述))]
public override string Summary { get; init; }
public override string Summary { get; set; }
}

View File

@ -33,5 +33,5 @@ public record QueryApiRsp : Sys_Api
/// <inheritdoc cref="IFieldSummary.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Summary { get; init; }
public override string Summary { get; set; }
}

View File

@ -26,5 +26,5 @@ public record CreateCodeTemplateReq : Sys_CodeTemplate
/// <inheritdoc cref="IFieldSummary.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Summary { get; init; }
public override string Summary { get; set; }
}

View File

@ -64,7 +64,7 @@ public record QueryCodeTemplateRsp : Sys_CodeTemplate
/// <inheritdoc cref="IFieldSummary.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Summary { get; init; }
public override string Summary { get; set; }
/// <inheritdoc cref="IFieldVersion.Version" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]

View File

@ -13,7 +13,7 @@ public record CreateDepositOrderReq : Sys_DepositOrder
/// <inheritdoc cref="Sys_DepositOrder.DepositPoint" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
[Range(100, long.MaxValue)]
[Range(100, int.MaxValue)]
public override long DepositPoint { get; init; }
/// <inheritdoc cref="Sys_DepositOrder.PaymentMode" />

View File

@ -23,5 +23,5 @@ public record CreateDeptReq : Sys_Dept
/// <inheritdoc cref="IFieldSummary.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Summary { get; init; }
public override string Summary { get; set; }
}

View File

@ -43,5 +43,5 @@ public sealed record ExportDeptRsp : QueryDeptRsp
[CsvIndex(3)]
[CsvIgnore(false)]
[CsvName(nameof(Ln.备注))]
public override string Summary { get; init; }
public override string Summary { get; set; }
}

View File

@ -34,7 +34,7 @@ public record QueryDeptRsp : Sys_Dept
/// <inheritdoc cref="IFieldSummary.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Summary { get; init; }
public override string Summary { get; set; }
/// <inheritdoc cref="IFieldVersion.Version" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]

View File

@ -38,7 +38,7 @@ public sealed record FieldItemInfo : DataAbstraction
/// <summary>
/// 备注
/// </summary>
public string Summary { get; init; }
public string Summary { get; set; }
/// <summary>
/// 类型

View File

@ -33,5 +33,5 @@ public sealed record GenerateCsCodeReq : DataAbstraction
/// <summary>
/// 描述
/// </summary>
public string Summary { get; init; }
public string Summary { get; set; }
}

View File

@ -21,7 +21,7 @@ public record CreateDicContentReq : Sys_DicContent
/// <inheritdoc cref="Sys_DicContent.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Summary { get; init; }
public override string Summary { get; set; }
/// <inheritdoc cref="Sys_DicContent.Value" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]

View File

@ -27,7 +27,7 @@ public sealed record ExportDicContentRsp : QueryDicContentRsp
[CsvIndex(4)]
[CsvIgnore(false)]
[CsvName(nameof(Ln.备注))]
public override string Summary { get; init; }
public override string Summary { get; set; }
/// <inheritdoc />
[CsvIndex(1)]

View File

@ -23,7 +23,7 @@ public record QueryDicContentRsp : Sys_DicContent
/// <inheritdoc cref="Sys_DicContent.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Summary { get; init; }
public override string Summary { get; set; }
/// <inheritdoc cref="Sys_DicContent.Value" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]

View File

@ -58,7 +58,7 @@ public record CreateJobReq : Sys_Job
/// <inheritdoc cref="IFieldSummary.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Summary { get; init; }
public override string Summary { get; set; }
/// <inheritdoc cref="Sys_Job.UserId" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]

View File

@ -112,7 +112,7 @@ public record QueryJobRsp : Sys_Job
/// <inheritdoc cref="IFieldSummary.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Summary { get; init; }
public override string Summary { get; set; }
/// <inheritdoc cref="Sys_Job.User" />
public new virtual QueryUserRsp User { get; init; }

View File

@ -55,7 +55,7 @@ public record CreateRoleReq : Sys_Role
/// <inheritdoc cref="IFieldSummary.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Summary { get; init; }
public override string Summary { get; set; }
/// <inheritdoc />
protected override IEnumerable<ValidationResult> ValidateInternal(ValidationContext validationContext)

View File

@ -63,7 +63,7 @@ public record QueryRoleRsp : Sys_Role
/// <inheritdoc cref="IFieldSummary.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Summary { get; init; }
public override string Summary { get; set; }
/// <inheritdoc cref="IFieldVersion.Version" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]

View File

@ -46,7 +46,7 @@ public sealed record ExportSiteMsgRsp : QuerySiteMsgRsp
[CsvIndex(4)]
[CsvIgnore(false)]
[CsvName(nameof(Ln.消息摘要))]
public override string Summary { get; init; }
public override string Summary { get; set; }
/// <inheritdoc />
[CsvIndex(3)]

View File

@ -53,7 +53,7 @@ public record QuerySiteMsgRsp : Sys_SiteMsg
/// <inheritdoc cref="Sys_SiteMsg.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Summary { get; init; }
public override string Summary { get; set; }
/// <inheritdoc cref="Sys_SiteMsg.Title" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]

View File

@ -44,7 +44,7 @@ public abstract record CreateEditUserReq : Sys_User
/// <inheritdoc cref="Sys_User.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Summary { get; init; }
public override string Summary { get; set; }
/// <inheritdoc cref="Sys_User.UserName" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]

View File

@ -6,7 +6,7 @@ namespace NetAdmin.Domain.Dto.Sys.User;
/// <summary>
/// 请求:创建用户
/// </summary>
public sealed record CreateUserReq : CreateEditUserReq
public record CreateUserReq : CreateEditUserReq
{
/// <inheritdoc />
public override bool Enabled { get; init; } = true;

View File

@ -1,5 +1,6 @@
using NetAdmin.Domain.Dto.Sys.Dept;
using NetAdmin.Domain.Dto.Sys.Role;
using NetAdmin.Domain.Dto.Sys.UserInvite;
namespace NetAdmin.Domain.Dto.Sys.User;
@ -30,7 +31,7 @@ public record QueryUserRsp : Sys_User
/// <summary>
/// 本部门以及子部门编号
/// </summary>
public List<long?> DeptIds { get; init; }
public IReadOnlyCollection<long?> DeptIds { get; init; }
/// <inheritdoc cref="Sys_User.Email" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
@ -44,6 +45,9 @@ public record QueryUserRsp : Sys_User
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override long Id { get; init; }
/// <inheritdoc cref="Sys_User.Invite" />
public new virtual QueryUserInviteRsp Invite { get; init; }
/// <inheritdoc cref="Sys_User.InviteCode" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string InviteCode { get; init; }
@ -61,7 +65,7 @@ public record QueryUserRsp : Sys_User
/// <inheritdoc cref="Sys_User.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Summary { get; init; }
public override string Summary { get; set; }
/// <inheritdoc cref="Sys_User.UserName" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]

View File

@ -0,0 +1,8 @@
using NetAdmin.Domain.Dto.Sys.User;
namespace NetAdmin.Domain.Dto.Sys.UserInvite;
/// <summary>
/// 请求:创建粉丝账号
/// </summary>
public record CreateFansAccountReq : CreateUserReq;

View File

@ -8,4 +8,7 @@ public record CreateUserInviteReq : Sys_UserInvite
/// <inheritdoc cref="Sys_UserInvite.CommissionRatio" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override int CommissionRatio { get; init; }
/// <inheritdoc />
public override bool SelfRechargeAllowed { get; init; } = true;
}

View File

@ -54,6 +54,10 @@ public record QueryUserInviteRsp : Sys_UserInvite
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override long? OwnerId { get; init; }
/// <inheritdoc cref="Sys_UserInvite.SelfRechargeAllowed" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override bool SelfRechargeAllowed { get; init; }
/// <inheritdoc cref="Sys_UserInvite.User" />
[CsvIgnore]
public new virtual QueryUserRsp User { get; init; }

View File

@ -0,0 +1,15 @@
namespace NetAdmin.Domain.Dto.Sys.UserInvite;
/// <summary>
/// 请求:修改粉丝角色
/// </summary>
public record SetFansRoleReq : Sys_UserInvite
{
/// <inheritdoc />
public override long Id { get; init; }
/// <summary>
/// 角色编号
/// </summary>
public long RoleId { get; init; }
}

View File

@ -0,0 +1,30 @@
namespace NetAdmin.Domain.Dto.Sys.UserInvite;
/// <summary>
/// 请求:设置上级
/// </summary>
public record SetInviterReq : Sys_UserInvite
{
/// <inheritdoc cref="EntityBase{T}.Id" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override long Id { get; init; }
/// <inheritdoc />
[Required]
[Range(1, long.MaxValue)]
public override long? OwnerId { get; init; }
/// <inheritdoc cref="IFieldVersion.Version" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override long Version { get; init; }
/// <inheritdoc />
protected override IEnumerable<ValidationResult> ValidateInternal(ValidationContext validationContext)
{
if (OwnerId == Id) {
yield return new ValidationResult(Ln., [nameof(OwnerId)]);
}
yield return ValidationResult.Success;
}
}

View File

@ -0,0 +1,19 @@
namespace NetAdmin.Domain.Dto.Sys.UserInvite;
/// <summary>
/// 请求:设置允许自助充值
/// </summary>
public record SetSelfRechargeAllowedReq : Sys_UserInvite
{
/// <inheritdoc cref="EntityBase{T}.Id" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override long Id { get; init; }
/// <inheritdoc cref="Sys_UserInvite.SelfRechargeAllowed" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override bool SelfRechargeAllowed { get; init; }
/// <inheritdoc cref="IFieldVersion.Version" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override long Version { get; init; }
}

View File

@ -25,7 +25,7 @@ public record CreateWalletFrozenReq : Sys_WalletFrozen
/// <inheritdoc cref="IFieldSummary.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Summary { get; init; }
public override string Summary { get; set; }
/// <inheritdoc cref="IFieldVersion.Version" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]

View File

@ -49,7 +49,7 @@ public record QueryWalletFrozenRsp : Sys_WalletFrozen
/// <inheritdoc cref="IFieldSummary.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Summary { get; init; }
public override string Summary { get; set; }
/// <inheritdoc cref="IFieldVersion.Version" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]

View File

@ -7,7 +7,7 @@ public record CreateWalletTradeReq : Sys_WalletTrade
{
/// <inheritdoc cref="Sys_WalletTrade.Amount" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override long Amount { get; init; }
public override long Amount { get; set; }
/// <inheritdoc cref="Sys_WalletTrade.BusinessOrderNumber" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
@ -22,7 +22,7 @@ public record CreateWalletTradeReq : Sys_WalletTrade
/// <inheritdoc cref="IFieldSummary.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Summary { get; init; }
public override string Summary { get; set; }
/// <inheritdoc cref="Sys_WalletTrade.TradeDirection" />
public override TradeDirections TradeDirection { get; init; }
@ -42,9 +42,12 @@ public record CreateWalletTradeReq : Sys_WalletTrade
protected override IEnumerable<ValidationResult> ValidateInternal(ValidationContext validationContext)
{
var tradeDirection = TradeType.Attr<TradeAttribute>().Direction;
if (Amount == 0 || (tradeDirection == TradeDirections.Income && Amount < 0) || (tradeDirection == TradeDirections.Expense && Amount > 0)) {
if (Amount == 0) {
yield return new ValidationResult(Ln., [nameof(Amount)]);
}
else if ((tradeDirection == TradeDirections.Income && Amount < 0) || (tradeDirection == TradeDirections.Expense && Amount > 0)) {
Amount = -Amount;
}
yield return ValidationResult.Success;
}

View File

@ -9,7 +9,7 @@ public record QueryWalletTradeRsp : Sys_WalletTrade
{
/// <inheritdoc cref="Sys_WalletTrade.Amount" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override long Amount { get; init; }
public override long Amount { get; set; }
/// <inheritdoc cref="Sys_WalletTrade.BalanceBefore" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
@ -49,7 +49,7 @@ public record QueryWalletTradeRsp : Sys_WalletTrade
/// <inheritdoc cref="IFieldSummary.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Summary { get; init; }
public override string Summary { get; set; }
/// <inheritdoc cref="Sys_WalletTrade.TradeDirection" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]

View File

@ -0,0 +1,28 @@
namespace NetAdmin.Domain.Dto.Sys.WalletTrade;
/// <summary>
/// 请求:转账
/// </summary>
public record TransferReq : Sys_WalletTrade
{
/// <inheritdoc cref="Sys_WalletTrade.Amount" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override long Amount { get; set; }
/// <inheritdoc cref="IFieldOwner.OwnerId" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[Required]
[UserId]
[Range(1, long.MaxValue)]
public override long? OwnerId { get; init; }
/// <inheritdoc cref="IFieldSummary.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Summary { get; set; }
/// <inheritdoc />
protected override IEnumerable<ValidationResult> ValidateInternal(ValidationContext validationContext)
{
yield return Amount <= 0 ? new ValidationResult(Ln., [nameof(Amount)]) : ValidationResult.Success;
}
}

View File

@ -15,10 +15,10 @@ public enum DataScopes
,
/// <summary>
/// 本部门和下级部门数据
/// 本部门和所有子部门数据
/// </summary>
[ResourceDescription<Ln>(nameof(Ln.本部门和下级部门数据))]
DeptWithChild = 2
[ResourceDescription<Ln>(nameof(Ln.本部门和所有子部门数据))]
DeptWithChildren = 2
,
@ -43,4 +43,12 @@ public enum DataScopes
/// </summary>
[ResourceDescription<Ln>(nameof(Ln.指定部门数据))]
SpecificDept = 5
,
/// <summary>
/// 本部门和下一级部门数据
/// </summary>
[ResourceDescription<Ln>(nameof(Ln.本部门和下一级部门数据))]
DeptWithSon = 6
}

View File

@ -0,0 +1,13 @@
using NetAdmin.Domain.Dto.Sys.User;
namespace NetAdmin.Domain.Events.Sys;
/// <summary>
/// 用户注册事件
/// </summary>
public sealed record UserRegisteredEvent : EventData<UserInfoRsp>
{
/// <inheritdoc />
public UserRegisteredEvent(UserInfoRsp payLoad) //
: base(payLoad) { }
}

View File

@ -46,11 +46,13 @@ public static class Chars
public const string FLG_DB_FIELD_TYPE_VARCHAR_7 = "varchar(7)";
public const string FLG_DB_INDEX_PREFIX = "idx_{tablename}_";
public const string FLG_DB_TABLE_NAME_PREFIX = "";
public const string FLG_FREE_SQL_GLOBAL_FILTER_SELF = nameof(FLG_FREE_SQL_GLOBAL_FILTER_SELF);
public const string FLG_FREE_SQL_GLOBAL_FILTER_DEPT_WITH_CHILD = nameof(FLG_FREE_SQL_GLOBAL_FILTER_DEPT_WITH_CHILD);
public const string FLG_FREE_SQL_GLOBAL_FILTER_DEPT = nameof(FLG_FREE_SQL_GLOBAL_FILTER_DEPT);
public const string FLG_DIC_CATALOG_NEW_USER_ROLE_CONFIG = "new-user-role-config";
public const string FLG_FREE_SQL_GLOBAL_FILTER_DELETE = nameof(FLG_FREE_SQL_GLOBAL_FILTER_DELETE);
public const string FLG_FREE_SQL_GLOBAL_FILTER_DEPT = nameof(FLG_FREE_SQL_GLOBAL_FILTER_DEPT);
public const string FLG_FREE_SQL_GLOBAL_FILTER_DEPT_WITH_CHILDREN = nameof(FLG_FREE_SQL_GLOBAL_FILTER_DEPT_WITH_CHILDREN);
public const string FLG_FREE_SQL_GLOBAL_FILTER_DEPT_WITH_SON = nameof(FLG_FREE_SQL_GLOBAL_FILTER_DEPT_WITH_SON);
public const string FLG_FREE_SQL_GLOBAL_FILTER_MEMBER = nameof(FLG_FREE_SQL_GLOBAL_FILTER_MEMBER);
public const string FLG_FREE_SQL_GLOBAL_FILTER_SELF = nameof(FLG_FREE_SQL_GLOBAL_FILTER_SELF);
public const string FLG_FREE_SQL_GLOBAL_FILTER_TENANT = nameof(FLG_FREE_SQL_GLOBAL_FILTER_TENANT);
public const string FLG_FRONT_APP_SET_HOME_GRID = "APP_SET_HOME_GRID";
public const string FLG_HTTP_HEADER_KEY_ACCESS_TOKEN = "ACCESS-TOKEN";

View File

@ -0,0 +1,24 @@
namespace NetAdmin.Infrastructure.Enums;
/// <summary>
/// 管理员交易类型
/// </summary>
[Export]
public enum AdminTradeTypes
{
/// <summary>
/// 管理员赠送
/// </summary>
[ResourceDescription<Ln>(nameof(Ln.管理员赠送))]
[Trade(Direction = TradeDirections.Income)]
AdminDeposit = 1
,
/// <summary>
/// 管理员扣费
/// </summary>
[ResourceDescription<Ln>(nameof(Ln.管理员扣费))]
[Trade(Direction = TradeDirections.Expense)]
AdminDeduct = 2
}

View File

@ -7,9 +7,9 @@ namespace NetAdmin.Infrastructure.Enums;
public enum TradeTypes
{
/// <summary>
/// 管理员充值
/// 管理员赠送
/// </summary>
[ResourceDescription<Ln>(nameof(Ln.管理员充值))]
[ResourceDescription<Ln>(nameof(Ln.管理员赠送))]
[Trade(Direction = TradeDirections.Income)]
AdminDeposit = 1
@ -30,4 +30,22 @@ public enum TradeTypes
[ResourceDescription<Ln>(nameof(Ln.自助充值))]
[Trade(Direction = TradeDirections.Income)]
SelfDeposit = 3
,
/// <summary>
/// 转账支出
/// </summary>
[ResourceDescription<Ln>(nameof(Ln.转账支出))]
[Trade(Direction = TradeDirections.Expense)]
TransferExpense = 4
,
/// <summary>
/// 转账收入
/// </summary>
[ResourceDescription<Ln>(nameof(Ln.转账收入))]
[Trade(Direction = TradeDirections.Income)]
TransferIncome = 5
}

View File

@ -1,3 +1,5 @@
using NetAdmin.Domain.Dto.Sys.Dic.Content;
using NetAdmin.Domain.Dto.Sys.User;
using NetAdmin.Domain.Dto.Sys.UserInvite;
namespace NetAdmin.SysComponent.Application.Modules.Sys;
@ -11,8 +13,38 @@ public interface IUserInviteModule : ICrudModule<CreateUserInviteReq, QueryUserI
, DelReq // 删除类型
>
{
/// <summary>
/// 创建粉丝账号
/// </summary>
Task<QueryUserRsp> CreateFansAccountAsync(CreateFansAccountReq req);
/// <summary>
/// 获取自己是否允许自助充值
/// </summary>
Task<bool> GetSelfRechargeAllowedAsync();
/// <summary>
/// 查询可分配的角色
/// </summary>
Task<IEnumerable<QueryDicContentRsp>> QueryRolesAllowApplyAsync();
/// <summary>
/// 设置返佣比率
/// </summary>
Task<int> SetCommissionRatioAsync(SetCommissionRatioReq req);
/// <summary>
/// 修改粉丝角色
/// </summary>
Task<int> SetFansRoleAsync(SetFansRoleReq req);
/// <summary>
/// 设置上级
/// </summary>
Task<int> SetInviterAsync(SetInviterReq req);
/// <summary>
/// 设置允许自助充值
/// </summary>
Task<int> SetSelfRechargeAllowedAsync(SetSelfRechargeAllowedReq req);
}

View File

@ -9,4 +9,15 @@ public interface IWalletTradeModule : ICrudModule<CreateWalletTradeReq, QueryWal
, EditWalletTradeReq // 编辑类型
, QueryWalletTradeReq, QueryWalletTradeRsp // 查询类型
, DelReq // 删除类型
>;
>
{
/// <summary>
/// 从他人账户转账给自己
/// </summary>
Task<int> TransferFromAnotherAccountAsync(TransferReq req);
/// <summary>
/// 转账到他人账户
/// </summary>
Task<int> TransferToAnotherAccountAsync(TransferReq req);
}

View File

@ -36,7 +36,7 @@ public sealed class ApiService(
.ToDictionaryAsync(a => a.Count())
.ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary(y => y, y => typeof(Sys_Api).GetProperty(y)!.GetValue(x.Key)!.ToString())
req.RequiredFields.ToImmutableDictionary(y => y, y => typeof(Sys_Api).GetProperty(y)!.GetValue(x.Key)?.ToString())
, x.Value))
.OrderByDescending(x => x.Value);
}
@ -140,6 +140,13 @@ public sealed class ApiService(
}
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryApiReq> req)
{
req.ThrowIfInvalid();
return QueryInternal(req with { Order = Orders.None }).WithNoLockNoWait().SumAsync(req.GetSumExp<Sys_Api>());
}
/// <inheritdoc />
public async Task SyncAsync()
{

View File

@ -44,8 +44,9 @@ public sealed class CodeTemplateService(BasicRepository<Sys_CodeTemplate, long>
y => y
, y => y.Contains('.')
? typeof(Sys_CodeTemplate).GetRecursiveProperty(y)!.GetValue(
x.Key.GetType().GetRecursiveProperty(y[..y.LastIndexOf('.')]).GetValue(x.Key))!.ToString()
: typeof(Sys_CodeTemplate).GetProperty(y)!.GetValue(x.Key)!.ToString()), x.Value))
x.Key.GetType().GetRecursiveProperty(y[..y.LastIndexOf('.')]).GetValue(x.Key))
?.ToString()
: typeof(Sys_CodeTemplate).GetProperty(y)!.GetValue(x.Key)?.ToString()), x.Value))
.OrderByDescending(x => x.Value);
}
@ -114,6 +115,13 @@ public sealed class CodeTemplateService(BasicRepository<Sys_CodeTemplate, long>
return ret.Adapt<IEnumerable<QueryCodeTemplateRsp>>();
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryCodeTemplateReq> req)
{
req.ThrowIfInvalid();
return QueryInternal(req with { Order = Orders.None }).WithNoLockNoWait().SumAsync(req.GetSumExp<Sys_CodeTemplate>());
}
private ISelect<Sys_CodeTemplate> QueryInternal(QueryReq<QueryCodeTemplateReq> req)
{
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter);

View File

@ -40,7 +40,7 @@ public sealed class ConfigService(BasicRepository<Sys_Config, long> rpo) //
.ToDictionaryAsync(a => a.Count())
.ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary(y => y, y => typeof(Sys_Config).GetProperty(y)!.GetValue(x.Key)!.ToString())
req.RequiredFields.ToImmutableDictionary(y => y, y => typeof(Sys_Config).GetProperty(y)!.GetValue(x.Key)?.ToString())
, x.Value))
.OrderByDescending(x => x.Value);
}
@ -132,6 +132,13 @@ public sealed class ConfigService(BasicRepository<Sys_Config, long> rpo) //
return UpdateAsync(req, [nameof(req.Enabled)]);
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryConfigReq> req)
{
req.ThrowIfInvalid();
return QueryInternal(req with { Order = Orders.None }).WithNoLockNoWait().SumAsync(req.GetSumExp<Sys_Config>());
}
private ISelect<Sys_Config> QueryInternal(QueryReq<QueryConfigReq> req)
{
var ret = Rpo.Select.Include(a => a.UserRegisterDept)

View File

@ -8,5 +8,5 @@ public interface IUserInviteService : IService, IUserInviteModule
/// <summary>
/// 获取关联用户Id
/// </summary>
Task<List<long>> GetAssociatedUserIdAsync(long userId);
Task<List<long>> GetAssociatedUserIdAsync(long userId, bool up = true);
}

View File

@ -213,6 +213,13 @@ public sealed class DepositOrderService(BasicRepository<Sys_DepositOrder, long>
return ret;
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryDepositOrderReq> req)
{
req.ThrowIfInvalid();
return QueryInternal(req with { Order = Orders.None }).WithNoLockNoWait().SumAsync(req.GetSumExp<Sys_DepositOrder>());
}
private ISelect<Sys_DepositOrder> QueryInternal(QueryReq<QueryDepositOrderReq> req)
{
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter);

View File

@ -40,7 +40,7 @@ public sealed class DeptService(BasicRepository<Sys_Dept, long> rpo) //
.ToDictionaryAsync(a => a.Count())
.ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary(y => y, y => typeof(Sys_Dept).GetProperty(y)!.GetValue(x.Key)!.ToString())
req.RequiredFields.ToImmutableDictionary(y => y, y => typeof(Sys_Dept).GetProperty(y)!.GetValue(x.Key)?.ToString())
, x.Value))
.OrderByDescending(x => x.Value);
}
@ -131,6 +131,13 @@ public sealed class DeptService(BasicRepository<Sys_Dept, long> rpo) //
return UpdateAsync(req, [nameof(req.Enabled)]);
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryDeptReq> req)
{
req.ThrowIfInvalid();
return QueryInternal(req with { Order = Orders.None }).WithNoLockNoWait().SumAsync(req.GetSumExp<Sys_Dept>());
}
private ISelect<Sys_Dept> QueryInternal(QueryReq<QueryDeptReq> req)
{
return QueryInternal(req, false);

View File

@ -352,7 +352,7 @@ public sealed class DevService(IApiService apiService) : ServiceBase<DevService>
/// <inheritdoc cref="IFieldSummary.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Summary { get; init; }
public override string Summary { get; set; }
""");
}
@ -661,7 +661,7 @@ public sealed class DevService(IApiService apiService) : ServiceBase<DevService>
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
[CsvIgnore]
[JsonIgnore]
public virtual string Summary { get; init; }
public virtual string Summary { get; set; }
""");
}
@ -904,7 +904,7 @@ public sealed class DevService(IApiService apiService) : ServiceBase<DevService>
/// <inheritdoc cref="IFieldSummary.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Summary { get; init; }
public override string Summary { get; set; }
""");
}

View File

@ -41,7 +41,7 @@ public sealed class DicCatalogService(BasicRepository<Sys_DicCatalog, long> rpo)
.ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary(
y => y, y => typeof(Sys_DicCatalog).GetProperty(y)!.GetValue(x.Key)!.ToString()), x.Value))
y => y, y => typeof(Sys_DicCatalog).GetProperty(y)!.GetValue(x.Key)?.ToString()), x.Value))
.OrderByDescending(x => x.Value);
}
@ -120,6 +120,13 @@ public sealed class DicCatalogService(BasicRepository<Sys_DicCatalog, long> rpo)
return ret.Adapt<IEnumerable<QueryDicCatalogRsp>>();
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryDicCatalogReq> req)
{
req.ThrowIfInvalid();
return QueryInternal(req with { Order = Orders.None }).WithNoLockNoWait().SumAsync(req.GetSumExp<Sys_DicCatalog>());
}
private ISelect<Sys_DicCatalog> QueryInternal(QueryReq<QueryDicCatalogReq> req)
{
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter)

View File

@ -41,7 +41,7 @@ public sealed class DicContentService(BasicRepository<Sys_DicContent, long> rpo)
.ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary(
y => y, y => typeof(Sys_DicContent).GetProperty(y)!.GetValue(x.Key)!.ToString()), x.Value))
y => y, y => typeof(Sys_DicContent).GetProperty(y)!.GetValue(x.Key)?.ToString()), x.Value))
.OrderByDescending(x => x.Value);
}
@ -138,6 +138,13 @@ public sealed class DicContentService(BasicRepository<Sys_DicContent, long> rpo)
return UpdateAsync(req, [nameof(Sys_DicContent.Enabled)]);
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryDicContentReq> req)
{
req.ThrowIfInvalid();
return QueryInternal(req with { Order = Orders.None }).WithNoLockNoWait().SumAsync(req.GetSumExp<Sys_DicContent>());
}
private ISelect<Sys_DicContent> QueryInternal(QueryReq<QueryDicContentReq> req)
{
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter)

View File

@ -41,7 +41,7 @@ public sealed class DocCatalogService(BasicRepository<Sys_DocCatalog, long> rpo)
.ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary(
y => y, y => typeof(Sys_DocCatalog).GetProperty(y)!.GetValue(x.Key)!.ToString()), x.Value))
y => y, y => typeof(Sys_DocCatalog).GetProperty(y)!.GetValue(x.Key)?.ToString()), x.Value))
.OrderByDescending(x => x.Value);
}
@ -121,6 +121,13 @@ public sealed class DocCatalogService(BasicRepository<Sys_DocCatalog, long> rpo)
return ret.Adapt<IEnumerable<QueryDocCatalogRsp>>();
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryDocCatalogReq> req)
{
req.ThrowIfInvalid();
return QueryInternal(req with { Order = Orders.None }).WithNoLockNoWait().SumAsync(req.GetSumExp<Sys_DocCatalog>());
}
private ISelect<Sys_DocCatalog> QueryInternal(QueryReq<QueryDocCatalogReq> req)
{
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter);

View File

@ -45,7 +45,7 @@ public sealed class DocContentService(BasicRepository<Sys_DocContent, long> rpo)
.ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary(
y => y, y => typeof(Sys_DocContent).GetProperty(y)!.GetValue(x.Key)!.ToString()), x.Value))
y => y, y => typeof(Sys_DocContent).GetProperty(y)!.GetValue(x.Key)?.ToString()), x.Value))
.OrderByDescending(x => x.Value);
}
@ -131,6 +131,13 @@ public sealed class DocContentService(BasicRepository<Sys_DocContent, long> rpo)
return UpdateAsync(req, [nameof(Sys_DocContent.Enabled)]);
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryDocContentReq> req)
{
req.ThrowIfInvalid();
return QueryInternal(req with { Order = Orders.None }).WithNoLockNoWait().SumAsync(req.GetSumExp<Sys_DocContent>());
}
/// <inheritdoc />
public async Task<QueryDocContentRsp> ViewAsync(QueryDocContentReq req)
{

View File

@ -41,7 +41,7 @@ public sealed class JobRecordService(BasicRepository<Sys_JobRecord, long> rpo) /
.ToDictionaryAsync(a => a.Count())
.ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary(y => y, y => typeof(Sys_JobRecord).GetProperty(y)!.GetValue(x.Key)!.ToString())
req.RequiredFields.ToImmutableDictionary(y => y, y => typeof(Sys_JobRecord).GetProperty(y)!.GetValue(x.Key)?.ToString())
, x.Value))
.OrderByDescending(x => x.Value);
}
@ -150,6 +150,13 @@ public sealed class JobRecordService(BasicRepository<Sys_JobRecord, long> rpo) /
return ret.Adapt<IEnumerable<QueryJobRecordRsp>>();
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryJobRecordReq> req)
{
req.ThrowIfInvalid();
return QueryInternal(req with { Order = Orders.None }).WithNoLockNoWait().SumAsync(req.GetSumExp<Sys_JobRecord>());
}
private ISelect<Sys_JobRecord> QueryInternal(QueryReq<QueryJobRecordReq> req)
{
var ret = Rpo.Select.Include(a => a.Job)

View File

@ -45,7 +45,7 @@ public sealed class JobService(BasicRepository<Sys_Job, long> rpo, IJobRecordSer
.ToDictionaryAsync(a => a.Count())
.ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary(y => y, y => typeof(Sys_Job).GetProperty(y)!.GetValue(x.Key)!.ToString())
req.RequiredFields.ToImmutableDictionary(y => y, y => typeof(Sys_Job).GetProperty(y)!.GetValue(x.Key)?.ToString())
, x.Value))
.OrderByDescending(x => x.Value);
}
@ -317,6 +317,13 @@ public sealed class JobService(BasicRepository<Sys_Job, long> rpo, IJobRecordSer
return UpdateAsync(req, [nameof(Sys_Job.Enabled)]);
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryJobReq> req)
{
req.ThrowIfInvalid();
return QueryInternal(req with { Order = Orders.None }).WithNoLockNoWait().SumAsync(req.GetSumExp<Sys_Job>());
}
private static DateTime? GetNextExecTime(string cron)
{
return CronExpression.Parse(cron, CronFormat.IncludeSeconds).GetNextOccurrence(DateTime.UtcNow, TimeZoneInfo.Local)?.ToLocalTime();

View File

@ -40,7 +40,7 @@ public sealed class LoginLogService(BasicRepository<Sys_LoginLog, long> rpo) //
.ToDictionaryAsync(a => a.Count())
.ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary(y => y, y => typeof(Sys_LoginLog).GetProperty(y)!.GetValue(x.Key)!.ToString())
req.RequiredFields.ToImmutableDictionary(y => y, y => typeof(Sys_LoginLog).GetProperty(y)!.GetValue(x.Key)?.ToString())
, x.Value))
.OrderByDescending(x => x.Value);
}
@ -117,6 +117,13 @@ public sealed class LoginLogService(BasicRepository<Sys_LoginLog, long> rpo) //
return ret.Adapt<IEnumerable<QueryLoginLogRsp>>();
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryLoginLogReq> req)
{
req.ThrowIfInvalid();
return QueryInternal(req with { Order = Orders.None }).WithNoLockNoWait().SumAsync(req.GetSumExp<Sys_LoginLog>());
}
private ISelect<Sys_LoginLog> QueryInternal(QueryReq<QueryLoginLogReq> req)
{
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter);

View File

@ -40,7 +40,7 @@ public sealed class MenuService(BasicRepository<Sys_Menu, long> rpo, IUserServic
.ToDictionaryAsync(a => a.Count())
.ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary(y => y, y => typeof(Sys_Menu).GetProperty(y)!.GetValue(x.Key)!.ToString())
req.RequiredFields.ToImmutableDictionary(y => y, y => typeof(Sys_Menu).GetProperty(y)!.GetValue(x.Key)?.ToString())
, x.Value))
.OrderByDescending(x => x.Value);
}
@ -103,6 +103,13 @@ public sealed class MenuService(BasicRepository<Sys_Menu, long> rpo, IUserServic
return ret.Adapt<IEnumerable<QueryMenuRsp>>();
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryMenuReq> req)
{
req.ThrowIfInvalid();
return QueryInternal(req with { Order = Orders.None }).WithNoLockNoWait().SumAsync(req.GetSumExp<Sys_Menu>());
}
/// <inheritdoc />
public async Task<IEnumerable<QueryMenuRsp>> UserMenusAsync()
{

View File

@ -42,7 +42,7 @@ public sealed class RequestLogDetailService(BasicRepository<Sys_RequestLogDetail
.ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary(
y => y, y => typeof(Sys_RequestLogDetail).GetProperty(y)!.GetValue(x.Key)!.ToString()), x.Value))
y => y, y => typeof(Sys_RequestLogDetail).GetProperty(y)!.GetValue(x.Key)?.ToString()), x.Value))
.OrderByDescending(x => x.Value);
}
@ -107,6 +107,13 @@ public sealed class RequestLogDetailService(BasicRepository<Sys_RequestLogDetail
return ret.Adapt<IEnumerable<QueryRequestLogDetailRsp>>();
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryRequestLogDetailReq> req)
{
req.ThrowIfInvalid();
return QueryInternal(req with { Order = Orders.None }).WithNoLockNoWait().SumAsync(req.GetSumExp<Sys_RequestLogDetail>());
}
private ISelect<Sys_RequestLogDetail> QueryInternal(QueryReq<QueryRequestLogDetailReq> req)
{
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter);

View File

@ -43,7 +43,7 @@ public sealed class RequestLogService(BasicRepository<Sys_RequestLog, long> rpo,
.ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary(
y => y, y => typeof(Sys_RequestLog).GetProperty(y)!.GetValue(x.Key)!.ToString()), x.Value))
y => y, y => typeof(Sys_RequestLog).GetProperty(y)!.GetValue(x.Key)?.ToString()), x.Value))
.OrderByDescending(x => x.Value);
}
@ -190,6 +190,13 @@ public sealed class RequestLogService(BasicRepository<Sys_RequestLog, long> rpo,
return ret.Adapt<IEnumerable<QueryRequestLogRsp>>();
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryRequestLogReq> req)
{
req.ThrowIfInvalid();
return QueryInternal(req with { Order = Orders.None }).WithNoLockNoWait().SumAsync(req.GetSumExp<Sys_RequestLog>());
}
private ISelect<Sys_RequestLog> QueryInternal(QueryReq<QueryRequestLogReq> req)
{
return QueryInternal(req, true);

View File

@ -41,7 +41,7 @@ public sealed class RoleService(BasicRepository<Sys_Role, long> rpo, IUserRoleSe
.ToDictionaryAsync(a => a.Count())
.ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary(y => y, y => typeof(Sys_Role).GetProperty(y)!.GetValue(x.Key)!.ToString())
req.RequiredFields.ToImmutableDictionary(y => y, y => typeof(Sys_Role).GetProperty(y)!.GetValue(x.Key)?.ToString())
, x.Value))
.OrderByDescending(x => x.Value);
}
@ -142,6 +142,13 @@ public sealed class RoleService(BasicRepository<Sys_Role, long> rpo, IUserRoleSe
return UpdateAsync(req, [nameof(req.IgnorePermissionControl)]);
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryRoleReq> req)
{
req.ThrowIfInvalid();
return QueryInternal(req with { Order = Orders.None }).WithNoLockNoWait().SumAsync(req.GetSumExp<Sys_Role>());
}
/// <inheritdoc />
public Task<IOrderedEnumerable<KeyValuePair<IImmutableDictionary<string, string>, int>>> UserCountByAsync(QueryReq<QueryUserRoleReq> req)
{

View File

@ -41,7 +41,7 @@ public sealed class SiteMsgDeptService(BasicRepository<Sys_SiteMsgDept, long> rp
.ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary(
y => y, y => typeof(Sys_SiteMsgDept).GetProperty(y)!.GetValue(x.Key)!.ToString()), x.Value))
y => y, y => typeof(Sys_SiteMsgDept).GetProperty(y)!.GetValue(x.Key)?.ToString()), x.Value))
.OrderByDescending(x => x.Value);
}
@ -104,6 +104,13 @@ public sealed class SiteMsgDeptService(BasicRepository<Sys_SiteMsgDept, long> rp
return ret.Adapt<IEnumerable<QuerySiteMsgDeptRsp>>();
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QuerySiteMsgDeptReq> req)
{
req.ThrowIfInvalid();
return QueryInternal(req with { Order = Orders.None }).WithNoLockNoWait().SumAsync(req.GetSumExp<Sys_SiteMsgDept>());
}
private ISelect<Sys_SiteMsgDept> QueryInternal(QueryReq<QuerySiteMsgDeptReq> req)
{
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter);

View File

@ -41,7 +41,7 @@ public sealed class SiteMsgFlagService(BasicRepository<Sys_SiteMsgFlag, long> rp
.ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary(
y => y, y => typeof(Sys_SiteMsgFlag).GetProperty(y)!.GetValue(x.Key)!.ToString()), x.Value))
y => y, y => typeof(Sys_SiteMsgFlag).GetProperty(y)!.GetValue(x.Key)?.ToString()), x.Value))
.OrderByDescending(x => x.Value);
}
@ -111,6 +111,13 @@ public sealed class SiteMsgFlagService(BasicRepository<Sys_SiteMsgFlag, long> rp
return UpdateAsync(req, [nameof(req.UserSiteMsgStatus)], null, a => a.UserId == req.UserId && a.SiteMsgId == req.SiteMsgId);
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QuerySiteMsgFlagReq> req)
{
req.ThrowIfInvalid();
return QueryInternal(req with { Order = Orders.None }).WithNoLockNoWait().SumAsync(req.GetSumExp<Sys_SiteMsgFlag>());
}
private ISelect<Sys_SiteMsgFlag> QueryInternal(QueryReq<QuerySiteMsgFlagReq> req)
{
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter);

View File

@ -41,7 +41,7 @@ public sealed class SiteMsgRoleService(BasicRepository<Sys_SiteMsgRole, long> rp
.ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary(
y => y, y => typeof(Sys_SiteMsgRole).GetProperty(y)!.GetValue(x.Key)!.ToString()), x.Value))
y => y, y => typeof(Sys_SiteMsgRole).GetProperty(y)!.GetValue(x.Key)?.ToString()), x.Value))
.OrderByDescending(x => x.Value);
}
@ -104,6 +104,13 @@ public sealed class SiteMsgRoleService(BasicRepository<Sys_SiteMsgRole, long> rp
return ret.Adapt<IEnumerable<QuerySiteMsgRoleRsp>>();
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QuerySiteMsgRoleReq> req)
{
req.ThrowIfInvalid();
return QueryInternal(req with { Order = Orders.None }).WithNoLockNoWait().SumAsync(req.GetSumExp<Sys_SiteMsgRole>());
}
private ISelect<Sys_SiteMsgRole> QueryInternal(QueryReq<QuerySiteMsgRoleReq> req)
{
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter);

View File

@ -44,7 +44,7 @@ public sealed class SiteMsgService(BasicRepository<Sys_SiteMsg, long> rpo, Conte
.ToDictionaryAsync(a => a.Count())
.ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary(y => y, y => typeof(Sys_SiteMsg).GetProperty(y)!.GetValue(x.Key)!.ToString())
req.RequiredFields.ToImmutableDictionary(y => y, y => typeof(Sys_SiteMsg).GetProperty(y)!.GetValue(x.Key)?.ToString())
, x.Value))
.OrderByDescending(x => x.Value);
}
@ -195,6 +195,13 @@ public sealed class SiteMsgService(BasicRepository<Sys_SiteMsg, long> rpo, Conte
}
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QuerySiteMsgReq> req)
{
req.ThrowIfInvalid();
return QueryInternal(req with { Order = Orders.None }).WithNoLockNoWait().SumAsync(req.GetSumExp<Sys_SiteMsg>());
}
/// <inheritdoc />
public async Task<long> UnreadCountAsync()
{

View File

@ -41,7 +41,7 @@ public sealed class SiteMsgUserService(BasicRepository<Sys_SiteMsgUser, long> rp
.ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary(
y => y, y => typeof(Sys_SiteMsgUser).GetProperty(y)!.GetValue(x.Key)!.ToString()), x.Value))
y => y, y => typeof(Sys_SiteMsgUser).GetProperty(y)!.GetValue(x.Key)?.ToString()), x.Value))
.OrderByDescending(x => x.Value);
}
@ -104,6 +104,13 @@ public sealed class SiteMsgUserService(BasicRepository<Sys_SiteMsgUser, long> rp
return ret.Adapt<IEnumerable<QuerySiteMsgUserRsp>>();
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QuerySiteMsgUserReq> req)
{
req.ThrowIfInvalid();
return QueryInternal(req with { Order = Orders.None }).WithNoLockNoWait().SumAsync(req.GetSumExp<Sys_SiteMsgUser>());
}
private ISelect<Sys_SiteMsgUser> QueryInternal(QueryReq<QuerySiteMsgUserReq> req)
{
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter);

View File

@ -1,6 +1,12 @@
using NetAdmin.Application.Extensions;
using NetAdmin.Domain.Contexts;
using NetAdmin.Domain.DbMaps.Sys;
using NetAdmin.Domain.Dto.Sys.Dept;
using NetAdmin.Domain.Dto.Sys.Dic.Catalog;
using NetAdmin.Domain.Dto.Sys.Dic.Content;
using NetAdmin.Domain.Dto.Sys.User;
using NetAdmin.Domain.Dto.Sys.UserInvite;
using NetAdmin.Domain.Dto.Sys.UserRole;
using NetAdmin.Domain.Extensions;
namespace NetAdmin.SysComponent.Application.Services.Sys;
@ -54,6 +60,19 @@ public sealed class UserInviteService(BasicRepository<Sys_UserInvite, long> rpo)
return ret.Adapt<QueryUserInviteRsp>();
}
/// <inheritdoc />
public async Task<QueryUserRsp> CreateFansAccountAsync(CreateFansAccountReq req)
{
req.ThrowIfInvalid();
var rolesAllowApply = (await QueryRolesAllowApplyAsync().ConfigureAwait(false)).Select(x => x.Value);
return !req.RoleIds.All(x => rolesAllowApply.Contains(x.ToInvString()))
? throw new NetAdminInvalidOperationException(Ln.)
: await S<IUserService>()
.CreateAsync(req with { Invite = new CreateUserInviteReq { OwnerId = UserToken.Id, OwnerDeptId = UserToken.DeptId } })
.ConfigureAwait(false);
}
/// <inheritdoc />
public Task<int> DeleteAsync(DelReq req)
{
@ -80,17 +99,18 @@ public sealed class UserInviteService(BasicRepository<Sys_UserInvite, long> rpo)
}
/// <inheritdoc />
public Task<List<long>> GetAssociatedUserIdAsync(long userId)
public Task<List<long>> GetAssociatedUserIdAsync(long userId, bool up = true)
{
return Rpo.Orm.Select<Sys_UserInvite>()
.DisableGlobalFilter(Chars.FLG_FREE_SQL_GLOBAL_FILTER_SELF, Chars.FLG_FREE_SQL_GLOBAL_FILTER_DEPT
, Chars.FLG_FREE_SQL_GLOBAL_FILTER_DEPT_WITH_CHILD)
, Chars.FLG_FREE_SQL_GLOBAL_FILTER_DEPT_WITH_CHILDREN, Chars.FLG_FREE_SQL_GLOBAL_FILTER_DEPT_WITH_SON)
.Where(a => a.Id == userId)
.AsTreeCte( //
up: true
up: up
, disableGlobalFilters: [
Chars.FLG_FREE_SQL_GLOBAL_FILTER_SELF, Chars.FLG_FREE_SQL_GLOBAL_FILTER_DEPT
, Chars.FLG_FREE_SQL_GLOBAL_FILTER_DEPT_WITH_CHILD
, Chars.FLG_FREE_SQL_GLOBAL_FILTER_DEPT_WITH_CHILDREN
, Chars.FLG_FREE_SQL_GLOBAL_FILTER_DEPT_WITH_SON
])
.ToListAsync(a => a.Id);
}
@ -103,6 +123,15 @@ public sealed class UserInviteService(BasicRepository<Sys_UserInvite, long> rpo)
return ret.Adapt<QueryUserInviteRsp>();
}
/// <inheritdoc />
public Task<bool> GetSelfRechargeAllowedAsync()
{
return QueryInternal(new QueryReq<QueryUserInviteReq> { Filter = new QueryUserInviteReq { Id = UserToken.Id } })
.DisableGlobalFilter(Chars.FLG_FREE_SQL_GLOBAL_FILTER_SELF, Chars.FLG_FREE_SQL_GLOBAL_FILTER_DEPT
, Chars.FLG_FREE_SQL_GLOBAL_FILTER_DEPT_WITH_CHILDREN, Chars.FLG_FREE_SQL_GLOBAL_FILTER_DEPT_WITH_SON)
.ToOneAsync(a => a.SelfRechargeAllowed);
}
/// <inheritdoc />
public async Task<PagedQueryRsp<QueryUserInviteRsp>> PagedQueryAsync(PagedQueryReq<QueryUserInviteReq> req)
{
@ -121,7 +150,7 @@ public sealed class UserInviteService(BasicRepository<Sys_UserInvite, long> rpo)
public async Task<IEnumerable<QueryUserInviteRsp>> QueryAsync(QueryReq<QueryUserInviteReq> req)
{
req.ThrowIfInvalid();
var query = QueryInternal(req).Include(a => a.Owner).Include(a => a.User).WithNoLockNoWait();
var query = QueryInternal(req).Include(a => a.Owner).IncludeMany(a => a.User.Roles).WithNoLockNoWait();
var ret = req.Filter?.IsPlainQuery == true
? await query.ToListAsync().ConfigureAwait(false)
: await query.ToTreeListAsync().ConfigureAwait(false);
@ -129,6 +158,34 @@ public sealed class UserInviteService(BasicRepository<Sys_UserInvite, long> rpo)
return ret.Adapt<IEnumerable<QueryUserInviteRsp>>();
}
/// <inheritdoc />
public async Task<IEnumerable<QueryDicContentRsp>> QueryRolesAllowApplyAsync()
{
var dicService = S<IDicService>();
var catalogIds = (await dicService.QueryCatalogAsync(new QueryReq<QueryDicCatalogReq> {
DynamicFilter = new DynamicFilterInfo {
Field = nameof(QueryDicCatalogReq.Code)
, Operator = DynamicFilterOperators.Any
, Value = S<ContextUserInfo>()
.Roles
.Select(x =>
$"{Chars.FLG_DIC_CATALOG_NEW_USER_ROLE_CONFIG}>{x.Id}")
}
})
.ConfigureAwait(false)).Select(x => x.Id);
return !catalogIds.Any()
? null
: await dicService
.QueryContentAsync(new QueryReq<QueryDicContentReq> {
DynamicFilter = new DynamicFilterInfo {
Field = nameof(QueryDicContentReq.CatalogId)
, Operator = DynamicFilterOperators.Any
, Value = catalogIds
}
})
.ConfigureAwait(false);
}
/// <inheritdoc />
public Task<int> SetCommissionRatioAsync(SetCommissionRatioReq req)
{
@ -136,6 +193,62 @@ public sealed class UserInviteService(BasicRepository<Sys_UserInvite, long> rpo)
return UpdateAsync(req with { CommissionRatio = req.CommissionRatio }, [nameof(req.CommissionRatio)], null, a => a.Id == req.Id, null, true);
}
/// <inheritdoc />
public async Task<int> SetFansRoleAsync(SetFansRoleReq req)
{
req.ThrowIfInvalid();
var rolesAllowApply = (await QueryRolesAllowApplyAsync().ConfigureAwait(false)).Select(x => x.Value).ToList();
if (!rolesAllowApply.Contains(req.RoleId.ToInvString())) {
throw new NetAdminInvalidOperationException(Ln.);
}
var userRoleService = App.GetService<IUserRoleService>();
_ = await userRoleService.BulkDeleteByUserIdAsync(req.Id).ConfigureAwait(false);
_ = await userRoleService.CreateAsync(new CreateUserRoleReq { RoleId = req.RoleId, UserId = req.Id }).ConfigureAwait(false);
return 1;
}
/// <inheritdoc />
public async Task<int> SetInviterAsync(SetInviterReq req)
{
req.ThrowIfInvalid();
var userService = S<IUserService>();
var child = await userService.GetAsync(new QueryUserReq { Id = req.Id }).ConfigureAwait(false);
var parent = await userService.GetAsync(new QueryUserReq { Id = req.OwnerId!.Value }).ConfigureAwait(false);
// 不能将上级设置为自己的下级避免死循环
if ((await GetAssociatedUserIdAsync(req.Id, false).ConfigureAwait(false)).Contains(req.OwnerId!.Value)) {
throw new NetAdminInvalidOperationException(Ln.);
}
// 修改部门层级关系
var dept = await S<IDeptService>().GetAsync(new QueryDeptReq { Id = child.DeptId }).ConfigureAwait(false);
if (dept.Id == req.Id && dept.Id != parent.DeptId) {
_ = await S<IDeptService>().EditAsync(dept.Adapt<EditDeptReq>() with { ParentId = parent.DeptId }).ConfigureAwait(false);
}
return await UpdateAsync( //
new Sys_UserInvite { Id = req.Id, Version = req.Version, OwnerId = req.OwnerId!.Value, OwnerDeptId = parent.DeptId }
, [nameof(req.OwnerDeptId), nameof(req.OwnerId)])
.ConfigureAwait(false);
}
/// <inheritdoc />
public Task<int> SetSelfRechargeAllowedAsync(SetSelfRechargeAllowedReq req)
{
req.ThrowIfInvalid();
return UpdateAsync(req, [nameof(req.SelfRechargeAllowed)]);
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryUserInviteReq> req)
{
req.ThrowIfInvalid();
return QueryInternal(req with { Order = Orders.None }).WithNoLockNoWait().SumAsync(req.GetSumExp<Sys_UserInvite>());
}
private ISelect<Sys_UserInvite> QueryInternal(QueryReq<QueryUserInviteReq> req)
{
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter)

View File

@ -60,7 +60,7 @@ public sealed class UserProfileService(BasicRepository<Sys_UserProfile, long> rp
.ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary(
y => y, y => typeof(Sys_UserProfile).GetProperty(y)!.GetValue(x.Key)!.ToString()), x.Value))
y => y, y => typeof(Sys_UserProfile).GetProperty(y)!.GetValue(x.Key)?.ToString()), x.Value))
.OrderByDescending(x => x.Value);
}
@ -182,6 +182,13 @@ public sealed class UserProfileService(BasicRepository<Sys_UserProfile, long> rp
return UpdateAsync(req, [nameof(req.AppConfig)], null, a => a.Id == UserToken.Id, null, true);
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryUserProfileReq> req)
{
req.ThrowIfInvalid();
return QueryInternal(req with { Order = Orders.None }).WithNoLockNoWait().SumAsync(req.GetSumExp<Sys_UserProfile>());
}
private ISelect<Sys_UserProfile> QueryInternal(QueryReq<QueryUserProfileReq> req)
{
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter);

View File

@ -46,7 +46,7 @@ public sealed class UserRoleService(BasicRepository<Sys_UserRole, long> rpo) //
.ToDictionaryAsync(a => a.Count())
.ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary(y => y, y => typeof(Sys_UserRole).GetProperty(y)!.GetValue(x.Key)!.ToString())
req.RequiredFields.ToImmutableDictionary(y => y, y => typeof(Sys_UserRole).GetProperty(y)!.GetValue(x.Key)?.ToString())
, x.Value))
.OrderByDescending(x => x.Value);
}
@ -110,6 +110,13 @@ public sealed class UserRoleService(BasicRepository<Sys_UserRole, long> rpo) //
return ret.Adapt<IEnumerable<QueryUserRoleRsp>>();
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryUserRoleReq> req)
{
req.ThrowIfInvalid();
return QueryInternal(req with { Order = Orders.None }).WithNoLockNoWait().SumAsync(req.GetSumExp<Sys_UserRole>());
}
private ISelect<Sys_UserRole> QueryInternal(QueryReq<QueryUserRoleReq> req)
{
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter);

View File

@ -24,7 +24,8 @@ public sealed class UserService(
, IEventPublisher eventPublisher) //
: RepositoryService<Sys_User, long, IUserService>(rpo), IUserService
{
private readonly Expression<Func<Sys_User, Sys_User>> _listUserExp = a => new Sys_User {
private readonly Expression<Func<Sys_User, Sys_User>> _listUserExp = a => //
new Sys_User {
Id = a.Id
, Avatar = a.Avatar
, Email = a.Email
@ -35,12 +36,11 @@ public sealed class UserService(
, Version = a.Version
, CreatedTime = a.CreatedTime
, LastLoginTime = a.LastLoginTime
, Dept = new Sys_Dept {
Id = a.Dept.Id, Name = a.Dept.Name
}
, Dept = new Sys_Dept { Id = a.Dept.Id, Name = a.Dept.Name }
, Roles = a.Roles
, CreatedUserId = a.CreatedUserId
, CreatedUserName = a.CreatedUserName
, Invite = new Sys_UserInvite { Owner = new Sys_User { Id = a.Invite.Owner.Id, UserName = a.Invite.Owner.UserName } }
};
/// <inheritdoc />
@ -99,7 +99,7 @@ public sealed class UserService(
.ToDictionaryAsync(a => a.Count())
.ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary(y => y, y => typeof(Sys_User).GetProperty(y)!.GetValue(x.Key)!.ToString())
req.RequiredFields.ToImmutableDictionary(y => y, y => typeof(Sys_User).GetProperty(y)!.GetValue(x.Key)?.ToString())
, x.Value))
.OrderByDescending(x => x.Value);
}
@ -110,10 +110,10 @@ public sealed class UserService(
req.ThrowIfInvalid();
var roles = await CreateEditCheckAsync(req).ConfigureAwait(false);
var newDeptId = YitIdHelper.NextId();
var userId = YitIdHelper.NextId();
// 主表
var entity = req.Adapt<Sys_User>() with { DeptId = newDeptId };
var entity = req.Adapt<Sys_User>() with { DeptId = userId, Id = userId };
var dbUser = await Rpo.InsertAsync(entity).ConfigureAwait(false);
// 分表
@ -139,7 +139,9 @@ public sealed class UserService(
_ = await userInviteService.CreateAsync((req.Invite ?? new CreateUserInviteReq()) with { Id = dbUser.Id }).ConfigureAwait(false);
// 创建一个用户自己的部门
_ = S<IDeptService>().CreateAsync(new CreateDeptReq { Id = newDeptId, Name = $"{req.UserName}的部门", ParentId = req.Invite?.OwnerDeptId ?? 0 });
_ = await S<IDeptService>()
.CreateAsync(new CreateDeptReq { Id = userId, Name = $"{req.UserName}", ParentId = req.Invite?.OwnerDeptId ?? 0 })
.ConfigureAwait(false);
// 发布用户创建事件
var ret = userList.First();
@ -275,7 +277,8 @@ public sealed class UserService(
var listUserExp = req.GetToListExp<Sys_User>() ?? _listUserExp;
var includeRoles = listUserExp == _listUserExp;
var select = await QueryInternalAsync(req, includeRoles).ConfigureAwait(false);
IEnumerable<Sys_User> list = await select.Page(req.Page, req.PageSize)
IEnumerable<Sys_User> list = await select.Include(a => a.Invite.Owner)
.Page(req.Page, req.PageSize)
.WithNoLockNoWait()
.Count(out var total)
.ToListAsync(listUserExp)
@ -338,8 +341,10 @@ public sealed class UserService(
Profile = new CreateUserProfileReq()
, Invite = new CreateUserInviteReq { OwnerId = inviterId, OwnerDeptId = inviterDeptId }
};
return (await CreateAsync(createReq with { Mobile = config.RegisterMobileRequired ? createReq.Mobile : null }).ConfigureAwait(false))
var ret = (await CreateAsync(createReq with { Mobile = config.RegisterMobileRequired ? createReq.Mobile : null }).ConfigureAwait(false))
.Adapt<UserInfoRsp>();
await eventPublisher.PublishAsync(new UserRegisteredEvent(ret)).ConfigureAwait(false);
return ret;
}
/// <inheritdoc />
@ -475,6 +480,13 @@ public sealed class UserService(
return userProfileService.SetSessionUserAppConfigAsync(req);
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryUserReq> req)
{
req.ThrowIfInvalid();
return QueryInternal(req with { Order = Orders.None }).WithNoLockNoWait().SumAsync(req.GetSumExp<Sys_User>());
}
/// <inheritdoc />
public async Task<UserInfoRsp> UserInfoAsync()
{
@ -506,14 +518,7 @@ public sealed class UserService(
.Where(a => req.RoleIds.Contains(a.Id))
.ToDictionaryAsync(a => a.Id, a => a.DashboardLayout)
.ConfigureAwait(false);
if (roles.Count != req.RoleIds.Count) {
throw new NetAdminInvalidOperationException(Ln.);
}
// 检查部门是否存在
var dept = await Rpo.Orm.Select<Sys_Dept>().WithNoLockNoWait().Where(a => req.DeptId == a.Id).ToListAsync(a => a.Id).ConfigureAwait(false);
return dept.Count != 1 ? throw new NetAdminInvalidOperationException(Ln.) : roles;
return roles.Count != req.RoleIds.Count ? throw new NetAdminInvalidOperationException(Ln.) : roles;
}
private async Task<LoginRsp> LoginInternalAsync(Sys_User dbUser)
@ -552,7 +557,8 @@ public sealed class UserService(
req.Filter?.RoleId > 0, a => Enumerable.Any(a.Roles, b => b.Id == req.Filter.RoleId))
.WhereIf( //
req.Keywords?.Length > 0
, a => a.Id == req.Keywords.Int64Try(0) || a.UserName == req.Keywords || a.Mobile == req.Keywords || a.Email == req.Keywords ||
, a => a.Id == req.Keywords.Int64Try(0) || a.UserName.Contains(req.Keywords) || a.Mobile == req.Keywords ||
a.Email == req.Keywords ||
a.Summary.Contains(req.Keywords));
// ReSharper restore InvokeAsExtensionMethod

View File

@ -84,7 +84,10 @@ public sealed class UserWalletService(BasicRepository<Sys_UserWallet, long> rpo)
public async Task<QueryUserWalletRsp> GetAsync(QueryUserWalletReq req)
{
req.ThrowIfInvalid();
var ret = await QueryInternal(new QueryReq<QueryUserWalletReq> { Filter = req, Order = Orders.None }).ToOneAsync().ConfigureAwait(false);
var ret = await QueryInternal(new QueryReq<QueryUserWalletReq> { Filter = req, Order = Orders.None })
.Include(a => a.Owner)
.ToOneAsync()
.ConfigureAwait(false);
return ret.Adapt<QueryUserWalletRsp>();
}
@ -93,7 +96,8 @@ public sealed class UserWalletService(BasicRepository<Sys_UserWallet, long> rpo)
{
req.ThrowIfInvalid();
var list = await QueryInternal(req)
.Include(a => a.Owner)
.IncludeMany(a => a.Owner.Roles)
.Include(a => a.Owner.Invite.Owner)
.Page(req.Page, req.PageSize)
.WithNoLockNoWait()
.Count(out var total)
@ -111,6 +115,13 @@ public sealed class UserWalletService(BasicRepository<Sys_UserWallet, long> rpo)
return ret.Adapt<IEnumerable<QueryUserWalletRsp>>();
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryUserWalletReq> req)
{
req.ThrowIfInvalid();
return QueryInternal(req with { Order = Orders.None }).WithNoLockNoWait().SumAsync(req.GetSumExp<Sys_UserWallet>());
}
private ISelect<Sys_UserWallet> QueryInternal(QueryReq<QueryUserWalletReq> req)
{
IEnumerable<long> deptIds = null;

View File

@ -45,7 +45,7 @@ public sealed class VerifyCodeService(BasicRepository<Sys_VerifyCode, long> rpo,
.ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary(
y => y, y => typeof(Sys_VerifyCode).GetProperty(y)!.GetValue(x.Key)!.ToString()), x.Value))
y => y, y => typeof(Sys_VerifyCode).GetProperty(y)!.GetValue(x.Key)?.ToString()), x.Value))
.OrderByDescending(x => x.Value);
}
@ -123,6 +123,7 @@ public sealed class VerifyCodeService(BasicRepository<Sys_VerifyCode, long> rpo,
QueryVerifyCodeRsp ret;
#if !DEBUG
// 有发送记录且小于1分钟不允许
if (lastSent != null && (DateTime.Now - lastSent.CreatedTime).TotalMinutes < 1) {
throw new NetAdminInvalidOperationException(Ln._1分钟内只能发送1次);
@ -147,6 +148,13 @@ public sealed class VerifyCodeService(BasicRepository<Sys_VerifyCode, long> rpo,
return UpdateAsync(req, [nameof(req.Status)]);
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryVerifyCodeReq> req)
{
req.ThrowIfInvalid();
return QueryInternal(req with { Order = Orders.None }).WithNoLockNoWait().SumAsync(req.GetSumExp<Sys_VerifyCode>());
}
/// <inheritdoc />
public async Task<bool> VerifyAsync(VerifyCodeReq req)
{

View File

@ -47,8 +47,9 @@ public sealed class WalletFrozenService(BasicRepository<Sys_WalletFrozen, long>
y => y
, y => y.Contains('.')
? typeof(Sys_WalletFrozen).GetRecursiveProperty(y)!.GetValue(
x.Key.GetType().GetRecursiveProperty(y[..y.LastIndexOf('.')]).GetValue(x.Key))!.ToString()
: typeof(Sys_WalletFrozen).GetProperty(y)!.GetValue(x.Key)!.ToString()), x.Value))
x.Key.GetType().GetRecursiveProperty(y[..y.LastIndexOf('.')]).GetValue(x.Key))
?.ToString()
: typeof(Sys_WalletFrozen).GetProperty(y)!.GetValue(x.Key)?.ToString()), x.Value))
.OrderByDescending(x => x.Value);
}
@ -173,6 +174,13 @@ public sealed class WalletFrozenService(BasicRepository<Sys_WalletFrozen, long>
return 1;
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryWalletFrozenReq> req)
{
req.ThrowIfInvalid();
return QueryInternal(req with { Order = Orders.None }).WithNoLockNoWait().SumAsync(req.GetSumExp<Sys_WalletFrozen>());
}
private ISelect<Sys_WalletFrozen> QueryInternal(QueryReq<QueryWalletFrozenReq> req)
{
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter);

View File

@ -1,5 +1,7 @@
using NetAdmin.Application.Extensions;
using NetAdmin.Domain.DbMaps.Sys;
using NetAdmin.Domain.Dto.Sys.User;
using NetAdmin.Domain.Dto.Sys.UserInvite;
using NetAdmin.Domain.Dto.Sys.UserWallet;
using NetAdmin.Domain.Dto.Sys.WalletTrade;
using NetAdmin.Domain.Extensions;
@ -103,7 +105,7 @@ public sealed class WalletTradeService(BasicRepository<Sys_WalletTrade, long> rp
{
req.ThrowIfInvalid();
var list = await QueryInternal(req)
.Include(a => a.Owner)
.Include(a => a.Owner.Invite.Owner)
.Page(req.Page, req.PageSize)
.WithNoLockNoWait()
.Count(out var total)
@ -121,9 +123,95 @@ public sealed class WalletTradeService(BasicRepository<Sys_WalletTrade, long> rp
return ret.Adapt<IEnumerable<QueryWalletTradeRsp>>();
}
/// <inheritdoc />
public async Task<decimal> SumAsync(QueryReq<QueryWalletTradeReq> req)
{
req.ThrowIfInvalid();
return req.RequiredFields[0].Equals(nameof(QueryWalletTradeReq.Amount), StringComparison.OrdinalIgnoreCase)
? await QueryInternal(req with { Order = Orders.None })
.WithNoLockNoWait()
.SumAsync(a => SqlExt.Case().When(a.Amount < 0, -a.Amount).Else(a.Amount).End())
.ConfigureAwait(false)
: await QueryInternal(req with { Order = Orders.None })
.WithNoLockNoWait()
.SumAsync(req.GetSumExp<Sys_WalletTrade>())
.ConfigureAwait(false);
}
/// <inheritdoc />
public async Task<int> TransferFromAnotherAccountAsync(TransferReq req)
{
// 检查源账户是不是自己的下级
var fromAccount = await S<IUserInviteService>().GetAsync(new QueryUserInviteReq { Id = req.OwnerId!.Value }).ConfigureAwait(false);
if (fromAccount == null || fromAccount.OwnerId != UserToken.Id) {
throw new NetAdminInvalidOperationException(Ln.);
}
var fromUser = await S<IUserService>().GetAsync(new QueryUserReq { Id = fromAccount.Id }).ConfigureAwait(false);
// 源账户扣钱
_ = await CreateAsync(new CreateWalletTradeReq {
OwnerDeptId = fromUser.DeptId
, Amount = -req.Amount
, OwnerId = fromUser.Id
, Summary = req.Summary
, TradeDirection = TradeDirections.Expense
, TradeType = TradeTypes.TransferExpense
})
.ConfigureAwait(false);
// 自己账户加钱
_ = await CreateAsync(new CreateWalletTradeReq {
Amount = req.Amount
, Summary = req.Summary
, TradeDirection = TradeDirections.Income
, TradeType = TradeTypes.TransferIncome
, OwnerId = UserToken.Id
, OwnerDeptId = UserToken.DeptId
})
.ConfigureAwait(false);
return 1;
}
/// <inheritdoc />
public async Task<int> TransferToAnotherAccountAsync(TransferReq req)
{
var toUser = await S<IUserService>().GetAsync(new QueryUserReq { Id = req.OwnerId!.Value }).ConfigureAwait(false);
// 自己账户扣钱
_ = await CreateAsync(new CreateWalletTradeReq {
Amount = -req.Amount
, Summary = req.Summary
, TradeDirection = TradeDirections.Expense
, TradeType = TradeTypes.TransferExpense
, OwnerId = UserToken.Id
, OwnerDeptId = UserToken.DeptId
})
.ConfigureAwait(false);
// 他人账户加钱
_ = await CreateAsync(new CreateWalletTradeReq {
OwnerDeptId = toUser.DeptId
, Amount = req.Amount
, OwnerId = toUser.Id
, Summary = req.Summary
, TradeDirection = TradeDirections.Income
, TradeType = TradeTypes.TransferIncome
})
.ConfigureAwait(false);
return 1;
}
private ISelect<Sys_WalletTrade> QueryInternal(QueryReq<QueryWalletTradeReq> req)
{
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter);
return QueryInternal(req, null);
}
private ISelect<Sys_WalletTrade> QueryInternal(QueryReq<QueryWalletTradeReq> req, List<long> userIds)
{
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter)
.WhereIf(req.Filter?.Id > 0, a => a.Id == req.Filter.Id)
.WhereIf(userIds?.Count > 0, a => userIds.Contains(a.OwnerId.Value));
// ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault
switch (req.Order) {

View File

@ -72,6 +72,12 @@ public sealed class ApiCache(IDistributedCache cache, IApiService service) //
return Service.QueryAsync(req);
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryApiReq> req)
{
return Service.SumAsync(req);
}
/// <inheritdoc />
public Task SyncAsync()
{

View File

@ -65,4 +65,10 @@ public sealed class CodeTemplateCache(IDistributedCache cache, ICodeTemplateServ
{
return Service.QueryAsync(req);
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryCodeTemplateReq> req)
{
return Service.SumAsync(req);
}
}

View File

@ -83,4 +83,10 @@ public sealed class ConfigCache(IDistributedCache cache, IConfigService service)
{
return Service.SetEnabledAsync(req);
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryConfigReq> req)
{
return Service.SumAsync(req);
}
}

View File

@ -83,4 +83,10 @@ public sealed class DepositOrderCache(IDistributedCache cache, IDepositOrderServ
{
return Service.ReceivedConfirmationAsync(req);
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryDepositOrderReq> req)
{
return Service.SumAsync(req);
}
}

View File

@ -71,4 +71,10 @@ public sealed class DeptCache(IDistributedCache cache, IDeptService service) //
{
return Service.SetEnabledAsync(req);
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryDeptReq> req)
{
return Service.SumAsync(req);
}
}

View File

@ -65,4 +65,10 @@ public sealed class DicCatalogCache(IDistributedCache cache, IDicCatalogService
{
return Service.QueryAsync(req);
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryDicCatalogReq> req)
{
return Service.SumAsync(req);
}
}

View File

@ -82,4 +82,10 @@ public sealed class DicContentCache(IDistributedCache cache, IDicContentService
{
return Service.SetEnabledAsync(req);
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryDicContentReq> req)
{
return Service.SumAsync(req);
}
}

View File

@ -65,4 +65,10 @@ public sealed class DocCatalogCache(IDistributedCache cache, IDocCatalogService
{
return Service.QueryAsync(req);
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryDocCatalogReq> req)
{
return Service.SumAsync(req);
}
}

View File

@ -71,4 +71,10 @@ public sealed class DocContentCache(IDistributedCache cache, IDocContentService
{
return Service.SetEnabledAsync(req);
}
/// <inheritdoc />
public Task<decimal> SumAsync(QueryReq<QueryDocContentReq> req)
{
return Service.SumAsync(req);
}
}

Some files were not shown because too many files have changed in this diff Show More