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

View File

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

View File

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

View File

@ -16,7 +16,7 @@ public static class ISelectExtensions
{ {
if (req.IgnoreOwner) { if (req.IgnoreOwner) {
me = me.DisableGlobalFilter(Chars.FLG_FREE_SQL_GLOBAL_FILTER_SELF, Chars.FLG_FREE_SQL_GLOBAL_FILTER_DEPT 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; return me;

View File

@ -69,4 +69,9 @@ public interface ICrudModule<in TCreateReq, TCreateRsp, in TEditReq, TQueryReq,
/// 查询实体 /// 查询实体
/// </summary> /// </summary>
Task<IEnumerable<TQueryRsp>> QueryAsync(QueryReq<TQueryReq> req); 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); var update = BuildUpdate(newValue, includeFields, excludeFields, ignoreVersion).Where(whereExp).Where(whereSql);
if (disableGlobalDataFilter) { if (disableGlobalDataFilter) {
update = update.DisableGlobalFilter(Chars.FLG_FREE_SQL_GLOBAL_FILTER_SELF, Chars.FLG_FREE_SQL_GLOBAL_FILTER_DEPT 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(); return update.ExecuteEffectsAsync();

View File

@ -8,5 +8,5 @@ public interface IFieldSummary
/// <summary> /// <summary>
/// 备注 /// 备注
/// </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)] [Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_63)]
[CsvIgnore] [CsvIgnore]
[JsonIgnore] [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)] [Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
[CsvIgnore] [CsvIgnore]
[JsonIgnore] [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)] [Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
[CsvIgnore] [CsvIgnore]
[JsonIgnore] [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)] [Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
[CsvIgnore] [CsvIgnore]
[JsonIgnore] [JsonIgnore]
public virtual string Summary { get; init; } public virtual string Summary { get; set; }
/// <summary> /// <summary>
/// 键值 /// 键值

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -48,6 +48,23 @@ public record QueryReq<T> : DataAbstraction
/// </summary> /// </summary>
public string[] RequiredFields { get; init; } 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>
/// 列表表达式 /// 列表表达式
/// </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())); , 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); 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)] [CsvIndex(3)]
[CsvIgnore(false)] [CsvIgnore(false)]
[CsvName(nameof(Ln.接口描述))] [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" /> /// <inheritdoc cref="IFieldSummary.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [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" /> /// <inheritdoc cref="IFieldSummary.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [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" /> /// <inheritdoc cref="IFieldSummary.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Summary { get; init; } public override string Summary { get; set; }
/// <inheritdoc cref="IFieldVersion.Version" /> /// <inheritdoc cref="IFieldVersion.Version" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)] [JsonIgnore(Condition = JsonIgnoreCondition.Never)]

View File

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

View File

@ -23,5 +23,5 @@ public record CreateDeptReq : Sys_Dept
/// <inheritdoc cref="IFieldSummary.Summary" /> /// <inheritdoc cref="IFieldSummary.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [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)] [CsvIndex(3)]
[CsvIgnore(false)] [CsvIgnore(false)]
[CsvName(nameof(Ln.备注))] [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" /> /// <inheritdoc cref="IFieldSummary.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Summary { get; init; } public override string Summary { get; set; }
/// <inheritdoc cref="IFieldVersion.Version" /> /// <inheritdoc cref="IFieldVersion.Version" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)] [JsonIgnore(Condition = JsonIgnoreCondition.Never)]

View File

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

View File

@ -33,5 +33,5 @@ public sealed record GenerateCsCodeReq : DataAbstraction
/// <summary> /// <summary>
/// 描述 /// 描述
/// </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" /> /// <inheritdoc cref="Sys_DicContent.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Summary { get; init; } public override string Summary { get; set; }
/// <inheritdoc cref="Sys_DicContent.Value" /> /// <inheritdoc cref="Sys_DicContent.Value" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -9,7 +9,7 @@ public record QueryWalletTradeRsp : Sys_WalletTrade
{ {
/// <inheritdoc cref="Sys_WalletTrade.Amount" /> /// <inheritdoc cref="Sys_WalletTrade.Amount" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)] [JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override long Amount { get; init; } public override long Amount { get; set; }
/// <inheritdoc cref="Sys_WalletTrade.BalanceBefore" /> /// <inheritdoc cref="Sys_WalletTrade.BalanceBefore" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)] [JsonIgnore(Condition = JsonIgnoreCondition.Never)]
@ -49,7 +49,7 @@ public record QueryWalletTradeRsp : Sys_WalletTrade
/// <inheritdoc cref="IFieldSummary.Summary" /> /// <inheritdoc cref="IFieldSummary.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Summary { get; init; } public override string Summary { get; set; }
/// <inheritdoc cref="Sys_WalletTrade.TradeDirection" /> /// <inheritdoc cref="Sys_WalletTrade.TradeDirection" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)] [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>
/// 本部门和下级部门数据 /// 本部门和所有子部门数据
/// </summary> /// </summary>
[ResourceDescription<Ln>(nameof(Ln.本部门和下级部门数据))] [ResourceDescription<Ln>(nameof(Ln.本部门和所有子部门数据))]
DeptWithChild = 2 DeptWithChildren = 2
, ,
@ -43,4 +43,12 @@ public enum DataScopes
/// </summary> /// </summary>
[ResourceDescription<Ln>(nameof(Ln.指定部门数据))] [ResourceDescription<Ln>(nameof(Ln.指定部门数据))]
SpecificDept = 5 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_FIELD_TYPE_VARCHAR_7 = "varchar(7)";
public const string FLG_DB_INDEX_PREFIX = "idx_{tablename}_"; public const string FLG_DB_INDEX_PREFIX = "idx_{tablename}_";
public const string FLG_DB_TABLE_NAME_PREFIX = ""; 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_DIC_CATALOG_NEW_USER_ROLE_CONFIG = "new-user-role-config";
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_FREE_SQL_GLOBAL_FILTER_DELETE = nameof(FLG_FREE_SQL_GLOBAL_FILTER_DELETE); 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_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_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_FRONT_APP_SET_HOME_GRID = "APP_SET_HOME_GRID";
public const string FLG_HTTP_HEADER_KEY_ACCESS_TOKEN = "ACCESS-TOKEN"; 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 public enum TradeTypes
{ {
/// <summary> /// <summary>
/// 管理员充值 /// 管理员赠送
/// </summary> /// </summary>
[ResourceDescription<Ln>(nameof(Ln.管理员充值))] [ResourceDescription<Ln>(nameof(Ln.管理员赠送))]
[Trade(Direction = TradeDirections.Income)] [Trade(Direction = TradeDirections.Income)]
AdminDeposit = 1 AdminDeposit = 1
@ -30,4 +30,22 @@ public enum TradeTypes
[ResourceDescription<Ln>(nameof(Ln.自助充值))] [ResourceDescription<Ln>(nameof(Ln.自助充值))]
[Trade(Direction = TradeDirections.Income)] [Trade(Direction = TradeDirections.Income)]
SelfDeposit = 3 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; using NetAdmin.Domain.Dto.Sys.UserInvite;
namespace NetAdmin.SysComponent.Application.Modules.Sys; namespace NetAdmin.SysComponent.Application.Modules.Sys;
@ -11,8 +13,38 @@ public interface IUserInviteModule : ICrudModule<CreateUserInviteReq, QueryUserI
, DelReq // 删除类型 , DelReq // 删除类型
> >
{ {
/// <summary>
/// 创建粉丝账号
/// </summary>
Task<QueryUserRsp> CreateFansAccountAsync(CreateFansAccountReq req);
/// <summary>
/// 获取自己是否允许自助充值
/// </summary>
Task<bool> GetSelfRechargeAllowedAsync();
/// <summary>
/// 查询可分配的角色
/// </summary>
Task<IEnumerable<QueryDicContentRsp>> QueryRolesAllowApplyAsync();
/// <summary> /// <summary>
/// 设置返佣比率 /// 设置返佣比率
/// </summary> /// </summary>
Task<int> SetCommissionRatioAsync(SetCommissionRatioReq req); 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

@ -6,7 +6,7 @@ namespace NetAdmin.SysComponent.Application.Modules.Sys;
/// 用户钱包模块 /// 用户钱包模块
/// </summary> /// </summary>
public interface IUserWalletModule : ICrudModule<CreateUserWalletReq, QueryUserWalletRsp // 创建类型 public interface IUserWalletModule : ICrudModule<CreateUserWalletReq, QueryUserWalletRsp // 创建类型
, EditUserWalletReq // 编辑类型 , EditUserWalletReq // 编辑类型
, QueryUserWalletReq, QueryUserWalletRsp // 查询类型 , QueryUserWalletReq, QueryUserWalletRsp // 查询类型
, DelReq // 删除类型 , DelReq // 删除类型
>; >;

View File

@ -9,4 +9,15 @@ public interface IWalletTradeModule : ICrudModule<CreateWalletTradeReq, QueryWal
, EditWalletTradeReq // 编辑类型 , EditWalletTradeReq // 编辑类型
, QueryWalletTradeReq, QueryWalletTradeRsp // 查询类型 , QueryWalletTradeReq, QueryWalletTradeRsp // 查询类型
, DelReq // 删除类型 , 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()) .ToDictionaryAsync(a => a.Count())
.ConfigureAwait(false); .ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>( 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)) , x.Value))
.OrderByDescending(x => 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 /> /// <inheritdoc />
public async Task SyncAsync() public async Task SyncAsync()
{ {

View File

@ -44,8 +44,9 @@ public sealed class CodeTemplateService(BasicRepository<Sys_CodeTemplate, long>
y => y y => y
, y => y.Contains('.') , y => y.Contains('.')
? typeof(Sys_CodeTemplate).GetRecursiveProperty(y)!.GetValue( ? typeof(Sys_CodeTemplate).GetRecursiveProperty(y)!.GetValue(
x.Key.GetType().GetRecursiveProperty(y[..y.LastIndexOf('.')]).GetValue(x.Key))!.ToString() x.Key.GetType().GetRecursiveProperty(y[..y.LastIndexOf('.')]).GetValue(x.Key))
: typeof(Sys_CodeTemplate).GetProperty(y)!.GetValue(x.Key)!.ToString()), x.Value)) ?.ToString()
: typeof(Sys_CodeTemplate).GetProperty(y)!.GetValue(x.Key)?.ToString()), x.Value))
.OrderByDescending(x => x.Value); .OrderByDescending(x => x.Value);
} }
@ -114,6 +115,13 @@ public sealed class CodeTemplateService(BasicRepository<Sys_CodeTemplate, long>
return ret.Adapt<IEnumerable<QueryCodeTemplateRsp>>(); 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) private ISelect<Sys_CodeTemplate> QueryInternal(QueryReq<QueryCodeTemplateReq> req)
{ {
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter); 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()) .ToDictionaryAsync(a => a.Count())
.ConfigureAwait(false); .ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>( 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)) , x.Value))
.OrderByDescending(x => 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)]); 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) private ISelect<Sys_Config> QueryInternal(QueryReq<QueryConfigReq> req)
{ {
var ret = Rpo.Select.Include(a => a.UserRegisterDept) var ret = Rpo.Select.Include(a => a.UserRegisterDept)

View File

@ -8,5 +8,5 @@ public interface IUserInviteService : IService, IUserInviteModule
/// <summary> /// <summary>
/// 获取关联用户Id /// 获取关联用户Id
/// </summary> /// </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; 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) private ISelect<Sys_DepositOrder> QueryInternal(QueryReq<QueryDepositOrderReq> req)
{ {
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter); 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()) .ToDictionaryAsync(a => a.Count())
.ConfigureAwait(false); .ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>( 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)) , x.Value))
.OrderByDescending(x => 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)]); 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) private ISelect<Sys_Dept> QueryInternal(QueryReq<QueryDeptReq> req)
{ {
return QueryInternal(req, false); return QueryInternal(req, false);

View File

@ -352,7 +352,7 @@ public sealed class DevService(IApiService apiService) : ServiceBase<DevService>
/// <inheritdoc cref="IFieldSummary.Summary" /> /// <inheritdoc cref="IFieldSummary.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [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)] [Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_255)]
[CsvIgnore] [CsvIgnore]
[JsonIgnore] [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" /> /// <inheritdoc cref="IFieldSummary.Summary" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)] [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); .ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>( return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary( 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); .OrderByDescending(x => x.Value);
} }
@ -120,6 +120,13 @@ public sealed class DicCatalogService(BasicRepository<Sys_DicCatalog, long> rpo)
return ret.Adapt<IEnumerable<QueryDicCatalogRsp>>(); 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) private ISelect<Sys_DicCatalog> QueryInternal(QueryReq<QueryDicCatalogReq> req)
{ {
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter) var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter)

View File

@ -41,7 +41,7 @@ public sealed class DicContentService(BasicRepository<Sys_DicContent, long> rpo)
.ConfigureAwait(false); .ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>( return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary( 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); .OrderByDescending(x => x.Value);
} }
@ -138,6 +138,13 @@ public sealed class DicContentService(BasicRepository<Sys_DicContent, long> rpo)
return UpdateAsync(req, [nameof(Sys_DicContent.Enabled)]); 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) private ISelect<Sys_DicContent> QueryInternal(QueryReq<QueryDicContentReq> req)
{ {
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter) var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter)

View File

@ -41,7 +41,7 @@ public sealed class DocCatalogService(BasicRepository<Sys_DocCatalog, long> rpo)
.ConfigureAwait(false); .ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>( return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary( 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); .OrderByDescending(x => x.Value);
} }
@ -79,7 +79,7 @@ public sealed class DocCatalogService(BasicRepository<Sys_DocCatalog, long> rpo)
return return
#if DBTYPE_SQLSERVER #if DBTYPE_SQLSERVER
(await UpdateReturnListAsync(req).ConfigureAwait(false)).FirstOrDefault()?.Adapt<QueryDocCatalogRsp>(); (await UpdateReturnListAsync(req).ConfigureAwait(false)).FirstOrDefault()?.Adapt<QueryDocCatalogRsp>();
#else #else
await UpdateAsync(req).ConfigureAwait(false) > 0 ? await GetAsync(new QueryDocCatalogReq { Id = req.Id }).ConfigureAwait(false) : null; await UpdateAsync(req).ConfigureAwait(false) > 0 ? await GetAsync(new QueryDocCatalogReq { Id = req.Id }).ConfigureAwait(false) : null;
#endif #endif
} }
@ -121,6 +121,13 @@ public sealed class DocCatalogService(BasicRepository<Sys_DocCatalog, long> rpo)
return ret.Adapt<IEnumerable<QueryDocCatalogRsp>>(); 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) private ISelect<Sys_DocCatalog> QueryInternal(QueryReq<QueryDocCatalogReq> req)
{ {
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter); 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); .ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>( return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary( 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); .OrderByDescending(x => x.Value);
} }
@ -131,6 +131,13 @@ public sealed class DocContentService(BasicRepository<Sys_DocContent, long> rpo)
return UpdateAsync(req, [nameof(Sys_DocContent.Enabled)]); 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 /> /// <inheritdoc />
public async Task<QueryDocContentRsp> ViewAsync(QueryDocContentReq req) 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()) .ToDictionaryAsync(a => a.Count())
.ConfigureAwait(false); .ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>( 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)) , x.Value))
.OrderByDescending(x => x.Value); .OrderByDescending(x => x.Value);
} }
@ -150,6 +150,13 @@ public sealed class JobRecordService(BasicRepository<Sys_JobRecord, long> rpo) /
return ret.Adapt<IEnumerable<QueryJobRecordRsp>>(); 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) private ISelect<Sys_JobRecord> QueryInternal(QueryReq<QueryJobRecordReq> req)
{ {
var ret = Rpo.Select.Include(a => a.Job) 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()) .ToDictionaryAsync(a => a.Count())
.ConfigureAwait(false); .ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>( 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)) , x.Value))
.OrderByDescending(x => 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)]); 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) private static DateTime? GetNextExecTime(string cron)
{ {
return CronExpression.Parse(cron, CronFormat.IncludeSeconds).GetNextOccurrence(DateTime.UtcNow, TimeZoneInfo.Local)?.ToLocalTime(); 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()) .ToDictionaryAsync(a => a.Count())
.ConfigureAwait(false); .ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>( 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)) , x.Value))
.OrderByDescending(x => x.Value); .OrderByDescending(x => x.Value);
} }
@ -117,6 +117,13 @@ public sealed class LoginLogService(BasicRepository<Sys_LoginLog, long> rpo) //
return ret.Adapt<IEnumerable<QueryLoginLogRsp>>(); 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) private ISelect<Sys_LoginLog> QueryInternal(QueryReq<QueryLoginLogReq> req)
{ {
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter); 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()) .ToDictionaryAsync(a => a.Count())
.ConfigureAwait(false); .ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>( 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)) , x.Value))
.OrderByDescending(x => 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>>(); 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 /> /// <inheritdoc />
public async Task<IEnumerable<QueryMenuRsp>> UserMenusAsync() public async Task<IEnumerable<QueryMenuRsp>> UserMenusAsync()
{ {

View File

@ -42,7 +42,7 @@ public sealed class RequestLogDetailService(BasicRepository<Sys_RequestLogDetail
.ConfigureAwait(false); .ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>( return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary( 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); .OrderByDescending(x => x.Value);
} }
@ -107,6 +107,13 @@ public sealed class RequestLogDetailService(BasicRepository<Sys_RequestLogDetail
return ret.Adapt<IEnumerable<QueryRequestLogDetailRsp>>(); 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) private ISelect<Sys_RequestLogDetail> QueryInternal(QueryReq<QueryRequestLogDetailReq> req)
{ {
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter); 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); .ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>( return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary( 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); .OrderByDescending(x => x.Value);
} }
@ -190,6 +190,13 @@ public sealed class RequestLogService(BasicRepository<Sys_RequestLog, long> rpo,
return ret.Adapt<IEnumerable<QueryRequestLogRsp>>(); 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) private ISelect<Sys_RequestLog> QueryInternal(QueryReq<QueryRequestLogReq> req)
{ {
return QueryInternal(req, true); return QueryInternal(req, true);

View File

@ -41,7 +41,7 @@ public sealed class RoleService(BasicRepository<Sys_Role, long> rpo, IUserRoleSe
.ToDictionaryAsync(a => a.Count()) .ToDictionaryAsync(a => a.Count())
.ConfigureAwait(false); .ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>( 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)) , x.Value))
.OrderByDescending(x => 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)]); 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 /> /// <inheritdoc />
public Task<IOrderedEnumerable<KeyValuePair<IImmutableDictionary<string, string>, int>>> UserCountByAsync(QueryReq<QueryUserRoleReq> req) 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); .ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>( return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary( 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); .OrderByDescending(x => x.Value);
} }
@ -104,6 +104,13 @@ public sealed class SiteMsgDeptService(BasicRepository<Sys_SiteMsgDept, long> rp
return ret.Adapt<IEnumerable<QuerySiteMsgDeptRsp>>(); 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) private ISelect<Sys_SiteMsgDept> QueryInternal(QueryReq<QuerySiteMsgDeptReq> req)
{ {
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter); 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); .ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>( return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary( 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); .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); 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) private ISelect<Sys_SiteMsgFlag> QueryInternal(QueryReq<QuerySiteMsgFlagReq> req)
{ {
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter); 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); .ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>( return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary( 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); .OrderByDescending(x => x.Value);
} }
@ -104,6 +104,13 @@ public sealed class SiteMsgRoleService(BasicRepository<Sys_SiteMsgRole, long> rp
return ret.Adapt<IEnumerable<QuerySiteMsgRoleRsp>>(); 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) private ISelect<Sys_SiteMsgRole> QueryInternal(QueryReq<QuerySiteMsgRoleReq> req)
{ {
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter); 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()) .ToDictionaryAsync(a => a.Count())
.ConfigureAwait(false); .ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>( 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)) , x.Value))
.OrderByDescending(x => 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 /> /// <inheritdoc />
public async Task<long> UnreadCountAsync() public async Task<long> UnreadCountAsync()
{ {

View File

@ -41,7 +41,7 @@ public sealed class SiteMsgUserService(BasicRepository<Sys_SiteMsgUser, long> rp
.ConfigureAwait(false); .ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>( return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary( 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); .OrderByDescending(x => x.Value);
} }
@ -104,6 +104,13 @@ public sealed class SiteMsgUserService(BasicRepository<Sys_SiteMsgUser, long> rp
return ret.Adapt<IEnumerable<QuerySiteMsgUserRsp>>(); 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) private ISelect<Sys_SiteMsgUser> QueryInternal(QueryReq<QuerySiteMsgUserReq> req)
{ {
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter); var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter);

View File

@ -1,6 +1,12 @@
using NetAdmin.Application.Extensions; using NetAdmin.Application.Extensions;
using NetAdmin.Domain.Contexts;
using NetAdmin.Domain.DbMaps.Sys; 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.UserInvite;
using NetAdmin.Domain.Dto.Sys.UserRole;
using NetAdmin.Domain.Extensions; using NetAdmin.Domain.Extensions;
namespace NetAdmin.SysComponent.Application.Services.Sys; namespace NetAdmin.SysComponent.Application.Services.Sys;
@ -54,6 +60,19 @@ public sealed class UserInviteService(BasicRepository<Sys_UserInvite, long> rpo)
return ret.Adapt<QueryUserInviteRsp>(); 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 /> /// <inheritdoc />
public Task<int> DeleteAsync(DelReq req) public Task<int> DeleteAsync(DelReq req)
{ {
@ -80,17 +99,18 @@ public sealed class UserInviteService(BasicRepository<Sys_UserInvite, long> rpo)
} }
/// <inheritdoc /> /// <inheritdoc />
public Task<List<long>> GetAssociatedUserIdAsync(long userId) public Task<List<long>> GetAssociatedUserIdAsync(long userId, bool up = true)
{ {
return Rpo.Orm.Select<Sys_UserInvite>() return Rpo.Orm.Select<Sys_UserInvite>()
.DisableGlobalFilter(Chars.FLG_FREE_SQL_GLOBAL_FILTER_SELF, Chars.FLG_FREE_SQL_GLOBAL_FILTER_DEPT .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) .Where(a => a.Id == userId)
.AsTreeCte( // .AsTreeCte( //
up: true up: up
, disableGlobalFilters: [ , disableGlobalFilters: [
Chars.FLG_FREE_SQL_GLOBAL_FILTER_SELF, Chars.FLG_FREE_SQL_GLOBAL_FILTER_DEPT 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); .ToListAsync(a => a.Id);
} }
@ -103,6 +123,15 @@ public sealed class UserInviteService(BasicRepository<Sys_UserInvite, long> rpo)
return ret.Adapt<QueryUserInviteRsp>(); 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 /> /// <inheritdoc />
public async Task<PagedQueryRsp<QueryUserInviteRsp>> PagedQueryAsync(PagedQueryReq<QueryUserInviteReq> req) 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) public async Task<IEnumerable<QueryUserInviteRsp>> QueryAsync(QueryReq<QueryUserInviteReq> req)
{ {
req.ThrowIfInvalid(); 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 var ret = req.Filter?.IsPlainQuery == true
? await query.ToListAsync().ConfigureAwait(false) ? await query.ToListAsync().ConfigureAwait(false)
: await query.ToTreeListAsync().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>>(); 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 /> /// <inheritdoc />
public Task<int> SetCommissionRatioAsync(SetCommissionRatioReq req) 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); 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) private ISelect<Sys_UserInvite> QueryInternal(QueryReq<QueryUserInviteReq> req)
{ {
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter) var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter)

View File

@ -60,7 +60,7 @@ public sealed class UserProfileService(BasicRepository<Sys_UserProfile, long> rp
.ConfigureAwait(false); .ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>( return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary( 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); .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); 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) private ISelect<Sys_UserProfile> QueryInternal(QueryReq<QueryUserProfileReq> req)
{ {
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter); 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()) .ToDictionaryAsync(a => a.Count())
.ConfigureAwait(false); .ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>( 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)) , x.Value))
.OrderByDescending(x => x.Value); .OrderByDescending(x => x.Value);
} }
@ -110,6 +110,13 @@ public sealed class UserRoleService(BasicRepository<Sys_UserRole, long> rpo) //
return ret.Adapt<IEnumerable<QueryUserRoleRsp>>(); 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) private ISelect<Sys_UserRole> QueryInternal(QueryReq<QueryUserRoleReq> req)
{ {
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter); var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter);

View File

@ -24,24 +24,24 @@ public sealed class UserService(
, IEventPublisher eventPublisher) // , IEventPublisher eventPublisher) //
: RepositoryService<Sys_User, long, IUserService>(rpo), IUserService : 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 => //
Id = a.Id new Sys_User {
, Avatar = a.Avatar Id = a.Id
, Email = a.Email , Avatar = a.Avatar
, Mobile = a.Mobile , Email = a.Email
, Enabled = a.Enabled , Mobile = a.Mobile
, UserName = a.UserName , Enabled = a.Enabled
, Summary = a.Summary , UserName = a.UserName
, Version = a.Version , Summary = a.Summary
, CreatedTime = a.CreatedTime , Version = a.Version
, LastLoginTime = a.LastLoginTime , CreatedTime = a.CreatedTime
, Dept = new Sys_Dept { , LastLoginTime = a.LastLoginTime
Id = a.Dept.Id, Name = a.Dept.Name , Dept = new Sys_Dept { Id = a.Dept.Id, Name = a.Dept.Name }
} , Roles = a.Roles
, Roles = a.Roles , CreatedUserId = a.CreatedUserId
, CreatedUserId = a.CreatedUserId , CreatedUserName = a.CreatedUserName
, CreatedUserName = a.CreatedUserName , Invite = new Sys_UserInvite { Owner = new Sys_User { Id = a.Invite.Owner.Id, UserName = a.Invite.Owner.UserName } }
}; };
/// <inheritdoc /> /// <inheritdoc />
public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req) public async Task<int> BulkDeleteAsync(BulkReq<DelReq> req)
@ -99,7 +99,7 @@ public sealed class UserService(
.ToDictionaryAsync(a => a.Count()) .ToDictionaryAsync(a => a.Count())
.ConfigureAwait(false); .ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>( 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)) , x.Value))
.OrderByDescending(x => x.Value); .OrderByDescending(x => x.Value);
} }
@ -110,10 +110,10 @@ public sealed class UserService(
req.ThrowIfInvalid(); req.ThrowIfInvalid();
var roles = await CreateEditCheckAsync(req).ConfigureAwait(false); 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); 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); _ = 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(); var ret = userList.First();
@ -275,7 +277,8 @@ public sealed class UserService(
var listUserExp = req.GetToListExp<Sys_User>() ?? _listUserExp; var listUserExp = req.GetToListExp<Sys_User>() ?? _listUserExp;
var includeRoles = listUserExp == _listUserExp; var includeRoles = listUserExp == _listUserExp;
var select = await QueryInternalAsync(req, includeRoles).ConfigureAwait(false); 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() .WithNoLockNoWait()
.Count(out var total) .Count(out var total)
.ToListAsync(listUserExp) .ToListAsync(listUserExp)
@ -338,8 +341,10 @@ public sealed class UserService(
Profile = new CreateUserProfileReq() Profile = new CreateUserProfileReq()
, Invite = new CreateUserInviteReq { OwnerId = inviterId, OwnerDeptId = inviterDeptId } , 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>(); .Adapt<UserInfoRsp>();
await eventPublisher.PublishAsync(new UserRegisteredEvent(ret)).ConfigureAwait(false);
return ret;
} }
/// <inheritdoc /> /// <inheritdoc />
@ -475,6 +480,13 @@ public sealed class UserService(
return userProfileService.SetSessionUserAppConfigAsync(req); 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 /> /// <inheritdoc />
public async Task<UserInfoRsp> UserInfoAsync() public async Task<UserInfoRsp> UserInfoAsync()
{ {
@ -506,14 +518,7 @@ public sealed class UserService(
.Where(a => req.RoleIds.Contains(a.Id)) .Where(a => req.RoleIds.Contains(a.Id))
.ToDictionaryAsync(a => a.Id, a => a.DashboardLayout) .ToDictionaryAsync(a => a.Id, a => a.DashboardLayout)
.ConfigureAwait(false); .ConfigureAwait(false);
if (roles.Count != req.RoleIds.Count) { return roles.Count != req.RoleIds.Count ? throw new NetAdminInvalidOperationException(Ln.) : roles;
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;
} }
private async Task<LoginRsp> LoginInternalAsync(Sys_User dbUser) 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)) req.Filter?.RoleId > 0, a => Enumerable.Any(a.Roles, b => b.Id == req.Filter.RoleId))
.WhereIf( // .WhereIf( //
req.Keywords?.Length > 0 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)); a.Summary.Contains(req.Keywords));
// ReSharper restore InvokeAsExtensionMethod // 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) public async Task<QueryUserWalletRsp> GetAsync(QueryUserWalletReq req)
{ {
req.ThrowIfInvalid(); 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>(); return ret.Adapt<QueryUserWalletRsp>();
} }
@ -93,7 +96,8 @@ public sealed class UserWalletService(BasicRepository<Sys_UserWallet, long> rpo)
{ {
req.ThrowIfInvalid(); req.ThrowIfInvalid();
var list = await QueryInternal(req) 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) .Page(req.Page, req.PageSize)
.WithNoLockNoWait() .WithNoLockNoWait()
.Count(out var total) .Count(out var total)
@ -111,6 +115,13 @@ public sealed class UserWalletService(BasicRepository<Sys_UserWallet, long> rpo)
return ret.Adapt<IEnumerable<QueryUserWalletRsp>>(); 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) private ISelect<Sys_UserWallet> QueryInternal(QueryReq<QueryUserWalletReq> req)
{ {
IEnumerable<long> deptIds = null; IEnumerable<long> deptIds = null;

View File

@ -45,7 +45,7 @@ public sealed class VerifyCodeService(BasicRepository<Sys_VerifyCode, long> rpo,
.ConfigureAwait(false); .ConfigureAwait(false);
return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>( return ret.Select(x => new KeyValuePair<IImmutableDictionary<string, string>, int>(
req.RequiredFields.ToImmutableDictionary( 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); .OrderByDescending(x => x.Value);
} }
@ -123,6 +123,7 @@ public sealed class VerifyCodeService(BasicRepository<Sys_VerifyCode, long> rpo,
QueryVerifyCodeRsp ret; QueryVerifyCodeRsp ret;
#if !DEBUG #if !DEBUG
// 有发送记录且小于1分钟不允许 // 有发送记录且小于1分钟不允许
if (lastSent != null && (DateTime.Now - lastSent.CreatedTime).TotalMinutes < 1) { if (lastSent != null && (DateTime.Now - lastSent.CreatedTime).TotalMinutes < 1) {
throw new NetAdminInvalidOperationException(Ln._1分钟内只能发送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)]); 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 /> /// <inheritdoc />
public async Task<bool> VerifyAsync(VerifyCodeReq req) 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
, y => y.Contains('.') , y => y.Contains('.')
? typeof(Sys_WalletFrozen).GetRecursiveProperty(y)!.GetValue( ? typeof(Sys_WalletFrozen).GetRecursiveProperty(y)!.GetValue(
x.Key.GetType().GetRecursiveProperty(y[..y.LastIndexOf('.')]).GetValue(x.Key))!.ToString() x.Key.GetType().GetRecursiveProperty(y[..y.LastIndexOf('.')]).GetValue(x.Key))
: typeof(Sys_WalletFrozen).GetProperty(y)!.GetValue(x.Key)!.ToString()), x.Value)) ?.ToString()
: typeof(Sys_WalletFrozen).GetProperty(y)!.GetValue(x.Key)?.ToString()), x.Value))
.OrderByDescending(x => x.Value); .OrderByDescending(x => x.Value);
} }
@ -173,6 +174,13 @@ public sealed class WalletFrozenService(BasicRepository<Sys_WalletFrozen, long>
return 1; 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) private ISelect<Sys_WalletFrozen> QueryInternal(QueryReq<QueryWalletFrozenReq> req)
{ {
var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter); var ret = Rpo.Select.WhereDynamicFilter(req.DynamicFilter).WhereDynamic(req.Filter);

View File

@ -1,5 +1,7 @@
using NetAdmin.Application.Extensions; using NetAdmin.Application.Extensions;
using NetAdmin.Domain.DbMaps.Sys; 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.UserWallet;
using NetAdmin.Domain.Dto.Sys.WalletTrade; using NetAdmin.Domain.Dto.Sys.WalletTrade;
using NetAdmin.Domain.Extensions; using NetAdmin.Domain.Extensions;
@ -103,7 +105,7 @@ public sealed class WalletTradeService(BasicRepository<Sys_WalletTrade, long> rp
{ {
req.ThrowIfInvalid(); req.ThrowIfInvalid();
var list = await QueryInternal(req) var list = await QueryInternal(req)
.Include(a => a.Owner) .Include(a => a.Owner.Invite.Owner)
.Page(req.Page, req.PageSize) .Page(req.Page, req.PageSize)
.WithNoLockNoWait() .WithNoLockNoWait()
.Count(out var total) .Count(out var total)
@ -121,9 +123,95 @@ public sealed class WalletTradeService(BasicRepository<Sys_WalletTrade, long> rp
return ret.Adapt<IEnumerable<QueryWalletTradeRsp>>(); 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) 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 // ReSharper disable once SwitchStatementMissingSomeEnumCasesNoDefault
switch (req.Order) { switch (req.Order) {

View File

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

View File

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

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