Compare commits

...

195 Commits

Author SHA1 Message Date
2248356998 qq.com
68e5a9c546 build: 10.11.71 2025-09-26 11:51:05 +08:00
2248356998 qq.com
b2ea9f99b9 适配net10 2025-09-26 10:58:57 +08:00
2248356998 qq.com
6d7d0e468a fix: opcua连接状态 2025-09-24 11:03:23 +08:00
2248356998 qq.com
ff1f632de2 build: 10.11.67 sqldb插件 2025-09-23 22:38:05 +08:00
2248356998 qq.com
fc3d7015ee sqldb插件 清理数据cron表达式错误 2025-09-23 22:36:45 +08:00
2248356998 qq.com
40c5acb522 调整UI 2025-09-23 13:41:20 +08:00
2248356998 qq.com
f9cc1cbb05 10.11.65 2025-09-23 12:02:17 +08:00
2248356998 qq.com
cf6e8b58f0 更新内存变量 2025-09-23 01:22:02 +08:00
2248356998 qq.com
615e3bb24c 修改 脚本调试项目 依赖项 2025-09-22 14:58:03 +08:00
2248356998 qq.com
4a7534b210 添加 脚本调试项目 2025-09-22 10:36:28 +08:00
2248356998 qq.com
58e099cb93 10.11.58 2025-09-21 20:53:50 +08:00
2248356998 qq.com
a94a9c953c 10.11.57 2025-09-19 14:32:34 +08:00
Diego
35e1ffa3e9 添加文件 2025-09-18 17:54:29 +08:00
Diego
4921642151 10.11.56 2025-09-18 17:15:57 +08:00
2248356998 qq.com
d71ee29da8 10.11.54 2025-09-17 20:50:41 +08:00
2248356998 qq.com
901aa2d59f 10.11.52 2025-09-17 11:07:45 +08:00
2248356998 qq.com
764957c014 10.11.51 2025-09-16 22:19:01 +08:00
Diego
0e3898218b 10.11.44 2025-09-16 19:13:19 +08:00
Diego
61f13cef3c 10.11.43 2025-09-15 17:35:49 +08:00
2248356998 qq.com
0b663d9e01 fix: modbusRtu 0x10 2025-09-14 11:18:41 +08:00
2248356998 qq.com
6c95c6209f 10.11.41 2025-09-13 14:22:13 +08:00
2248356998 qq.com
4d223d2622 10.11.40 2025-09-13 13:00:52 +08:00
yunqi
e8d7e91b64 !74 modify dlt645_2007 buildcmd
* modify dlt645_2007 buildcmd
2025-09-13 04:59:10 +00:00
2248356998 qq.com
8175f541ec 更新基准测试 2025-09-12 23:53:36 +08:00
2248356998 qq.com
0adbdb926b 更新基准测试 2025-09-12 23:49:18 +08:00
Diego
42adee9980 更新依赖 2025-09-11 22:22:39 +08:00
2248356998 qq.com
427a7404bc 更新UI 2025-09-11 19:05:14 +08:00
2248356998 qq.com
3658199e0a 10.11.37 2025-09-11 18:30:49 +08:00
Diego
82eedee50a 更新依赖 2025-09-11 18:12:40 +08:00
2248356998 qq.com
6a18fc3e06 10.11.36 2025-09-10 12:59:54 +08:00
2248356998 qq.com
c37e314ed6 更新依赖 2025-09-09 21:53:39 +08:00
2248356998 qq.com
a937a85d90 添加项目 2025-09-08 21:51:37 +08:00
2248356998 qq.com
35dd4ae9d3 更新依赖 2025-09-08 21:27:49 +08:00
2248356998 qq.com
0b829ac85c 10.11.33 2025-09-08 21:16:37 +08:00
2248356998 qq.com
aa247422d2 10.11.31 2025-09-08 17:56:19 +08:00
2248356998 qq.com
2e00e8c135 更新依赖 2025-09-08 08:46:52 +08:00
2248356998 qq.com
34dd2cf0a7 更新依赖 2025-09-07 21:52:41 +08:00
2248356998 qq.com
8404e20c5e build: 10.11.27
refactor: 更新依赖
2025-09-06 23:34:32 +08:00
2248356998 qq.com
662aa162e9 fix: sugar无实体curd 2025-09-05 13:16:18 +08:00
2248356998 qq.com
5927738c32 10.11.25 2025-09-05 11:30:33 +08:00
2248356998 qq.com
3c9f97a5c3 10.11.24 2025-09-04 22:39:21 +08:00
2248356998 qq.com
179ca0aa0e build: 10.11.23
feat: 增加部分demo
feat: 增加管理软件桌面端
2025-09-03 17:40:19 +08:00
Diego
fc09a52da1 build: 10.11.22
refactor:性能优化
2025-09-02 11:13:54 +08:00
Diego
5436b91c89 10.11.21 2025-09-01 18:40:12 +08:00
Diego
d1c46f51a6 添加api接口 2025-09-01 16:00:53 +08:00
Diego
4539d8d198 fix: 字符串反转功能失效 2025-09-01 11:52:03 +08:00
2248356998 qq.com
9ea9529a5f 10.11.19 2025-08-29 15:43:02 +08:00
2248356998 qq.com
4e6be23aac 10.11.17 2025-08-28 17:15:08 +08:00
2248356998 qq.com
2fabbd236b 10.11.16 2025-08-28 17:05:00 +08:00
2248356998 qq.com
163a66530e fix: dlt645校验和 2025-08-28 17:04:27 +08:00
2248356998 qq.com
29073a00c4 fix: dtu连接注册包解析错误 2025-08-28 15:35:43 +08:00
2248356998 qq.com
c6d4d1ecfa fix: dtu连接注册包解析错误 2025-08-28 15:20:00 +08:00
2248356998 qq.com
ba16889cad 10.11.14 2025-08-28 14:21:58 +08:00
2248356998 qq.com
5aaed35b0f 10.11.12 2025-08-28 01:42:59 +08:00
Diego
df067c91eb 10.11.12 2025-08-28 01:39:39 +08:00
2248356998 qq.com
2078b4a60b 补充忽略的文件 2025-08-26 08:54:09 +08:00
2248356998 qq.com
20a2e3ff8e 示例 2025-08-25 20:39:26 +08:00
Diego
61a973b1b5 !73 10.11.10 2025-08-25 12:21:12 +00:00
2248356998 qq.com
cbd72e2081 添加文本日志配置json文件 2025-08-22 16:17:25 +08:00
2248356998 qq.com
4e0377b20c 添加文本日志配置json文件 2025-08-22 16:15:54 +08:00
2248356998 qq.com
fd318d3cdc 移除警告项 2025-08-22 16:12:14 +08:00
2248356998 qq.com
515bdb9700 10.11.7 2025-08-21 23:35:12 +08:00
2248356998 qq.com
46c1780017 10.11.6 2025-08-21 22:40:53 +08:00
2248356998 qq.com
fe78a4c3ca 更新依赖库 2025-08-21 22:05:30 +08:00
2248356998 qq.com
2d7effadf9 10.11.4 2025-08-21 21:13:18 +08:00
Diego
346c560f8b !72 更新依赖项 2025-08-21 11:46:58 +00:00
Diego
8e3bd89f61 修改编译项 2025-08-18 17:30:34 +08:00
Diego
6da142d080 10.10.23 2025-08-18 17:03:40 +08:00
2248356998 qq.com
ff7d029e6f 更新依赖 2025-08-14 20:25:00 +08:00
2248356998 qq.com
21b4695683 10.10.19 2025-08-14 05:47:54 +08:00
Diego
02ad494a26 !71 适配远程客户端 2025-08-12 16:00:53 +00:00
2248356998 qq.com
280366e1b2 添加写优先选项,默认false 2025-08-09 13:07:08 +08:00
2248356998 qq.com
6660ce3e34 适配远程管理客户端 2025-08-08 18:01:24 +08:00
2248356998 qq.com
7499162c1a 适配远程管理客户端 2025-08-08 02:51:42 +08:00
2248356998 qq.com
40208a5cd6 适配远程网关管理客户端 2025-08-08 02:16:05 +08:00
2248356998 qq.com
fa347f4f68 修改报警事件时间字段,增加变量表报警类 2025-08-07 19:19:36 +08:00
Diego
d7df6fc605 10.10.12 2025-08-07 11:24:57 +08:00
2248356998 qq.com
eb4bb2fd48 10.10.11 2025-08-07 10:19:28 +08:00
2248356998 qq.com
faa9858974 10.10.11 2025-08-07 10:18:22 +08:00
2248356998 qq.com
1b3d2dda49 QuestDbRestAPI 2025-08-07 10:11:37 +08:00
Diego
a8a9453611 !70 fix: questdb restapi多实例 2025-08-07 01:58:32 +00:00
2248356998 qq.com
e84f42ce14 10.10.10 2025-08-06 21:42:46 +08:00
2248356998 qq.com
6f814cf6b8 更新questdb restapi启用字段 2025-08-06 21:42:23 +08:00
2248356998 qq.com
e36432e4e9 10.10.9 2025-08-06 19:33:30 +08:00
Diego
ebd71e807b !69 更新依赖 2025-08-06 11:25:31 +00:00
Diego
34000d8d7d !68 10.10.7 2025-08-05 09:22:11 +00:00
2248356998 qq.com
e785f6660c 10.10.5 2025-08-01 21:53:47 +08:00
Diego
831c611797 10.10.4 2025-08-01 17:30:37 +08:00
Diego
453817ef86 添加IAsyncDisposable 2025-08-01 16:36:27 +08:00
2248356998 qq.com
8ce0b981c1 no message 2025-08-01 12:55:01 +08:00
2248356998 qq.com
4e5c51b54c 2025-08-01 12:47:21 +08:00
2248356998 qq.com
3cc9d31f28 修改可用内存策略 2025-08-01 12:43:39 +08:00
2248356998 qq.com
10391f869b 支持相对路径创建sqlite 2025-07-31 23:41:58 +08:00
Diego
fba0723a6d 更新依赖 2025-07-31 18:39:46 +08:00
Diego
2db3f78f0c 添加 控制写操作与读操作的比率 的插件配置属性 2025-07-31 18:18:41 +08:00
Diego
badf61fe01 10.9.99 2025-07-31 16:25:47 +08:00
Diego
d74e0952dc 10.9.98 2025-07-31 15:57:33 +08:00
Diego
fb1699ce80 10.9.97 2025-07-31 14:06:47 +08:00
Diego
44adddbcd4 10.9.97 2025-07-31 13:56:49 +08:00
Diego
0eab889452 10.9.97 2025-07-31 13:56:34 +08:00
Diego
e14d39a459 添加 rpc写入 多写日志 2025-07-31 12:52:40 +08:00
2248356998 qq.com
7575264ede 添加变量初始化标记 2025-07-31 00:40:03 +08:00
2248356998 qq.com
3e1a077b96 添加变量初始化标记 2025-07-31 00:30:53 +08:00
2248356998 qq.com
a921cb8400 refactor: 连接时判断setup 2025-07-30 23:27:35 +08:00
2248356998 qq.com
4de7c31ed7 10.9.92 2025-07-30 22:00:23 +08:00
2248356998 qq.com
08326a2cfd fix: 单属性验证异常 2025-07-30 21:11:35 +08:00
Diego
e045de5acb !67 更新依赖 2025-07-30 10:01:20 +00:00
2248356998 qq.com
d3bef31aa6 10.9.70 2025-07-30 04:32:14 +08:00
2248356998 qq.com
347d4d6e5d 10.9.69 2025-07-25 22:21:34 +08:00
2248356998 qq.com
b006a066e1 10.9.69 2025-07-25 22:14:06 +08:00
Diego
e331bc5d3c 10.9.68 2025-07-25 20:30:48 +08:00
Diego
2e81806231 优化 2025-07-25 20:20:35 +08:00
Diego
37b48cf221 BindField 2025-07-24 20:03:53 +08:00
Diego
5997487434 修改参数 2025-07-24 19:46:30 +08:00
Diego
4ce843182f build: 10.9.67
feat: 报警恢复增加延时功能
refactor: 移除通讯任务时,设置设备、变量离线状态

fix: 罗克韦尔PLC通讯超时错误
2025-07-24 13:25:55 +08:00
2248356998 qq.com
a4aa000cf0 10.9.66 2025-07-23 19:11:39 +08:00
Diego
01aa6ca066 10.9.65 2025-07-23 16:34:02 +08:00
Diego
10a0280c4a 10.9.64 2025-07-22 15:55:49 +08:00
Diego
3b8b00c783 变量类验证提示 2025-07-22 11:03:48 +08:00
Diego
232ee5d5d4 10.9.63 2025-07-22 01:17:12 +08:00
2248356998 qq.com
605830edce 10.9.62 2025-07-20 21:52:59 +08:00
2248356998 qq.com
ca86441e05 orm性能优化 2025-07-20 19:04:25 +08:00
2248356998 qq.com
b30b876c5f 更新依赖 2025-07-20 10:44:20 +08:00
2248356998 qq.com
f95590b4cb 修正拼写错误 2025-07-19 22:36:13 +08:00
2248356998 qq.com
9921130406 更新依赖 2025-07-19 21:38:19 +08:00
2248356998 qq.com
5c47589ca1 更新依赖 2025-07-19 21:31:46 +08:00
2248356998 qq.com
048abfae2e 添加可空标识 2025-07-19 13:35:55 +08:00
Diego
8e35c16edf 恢复restart标记 2025-07-18 17:46:56 +08:00
Diego
143b751213 Revert "build: 10.9.42"
This reverts commit 2cafe745b9.
2025-07-18 14:41:19 +08:00
Diego
2cafe745b9 build: 10.9.42
feat: 优化读写调度
feat: rpc日志添加执行时间字段
2025-07-18 09:48:41 +08:00
Diego
210ac2c122 更新解决方案 2025-07-18 00:02:38 +08:00
Diego
4707ce6d58 新增RemoteWebApp项目 2025-07-17 23:41:11 +08:00
2248356998 qq.com
788a8b670d 10.9.40 2025-07-16 21:18:14 +08:00
2248356998 qq.com
5e4f0057e4 更新依赖库 2025-07-15 21:24:19 +08:00
2248356998 qq.com
2960c13ef1 更新依赖库 2025-07-15 03:56:46 +08:00
2248356998 qq.com
f11b7f7ab4 10.9.37 2025-07-13 22:47:14 +08:00
Diego
9bb9cd7419 10.9.35 2025-07-11 07:14:52 +08:00
Diego
ba008ef8ba 更新.NETVersion 2025-07-09 13:35:42 +08:00
Diego
28b533decf 10.9.34 2025-07-09 13:31:08 +08:00
Diego
9ee638c2f1 更新依赖包 2025-07-08 23:59:24 +08:00
Diego
d90fdbaf35 补充更新nuget包 2025-07-08 18:15:50 +08:00
Diego
b55e3db736 10.9.29 2025-07-08 17:55:37 +08:00
Diego
dbee8496cb opcuaServer支持decimal类型 2025-07-08 16:53:28 +08:00
Diego
044e78bea9 opcuaserver回退修改 2025-07-08 15:52:12 +08:00
Diego
fe79128d90 build: 10.9.26
fix: opcuaserver添加变量属性出现错误,已回退
refactor: 网关监控树节点保持展开状态
refactor: cache插件类日志输出
2025-07-08 14:33:27 +08:00
Diego
34120da008 ToDecimal方法添加异步捕获,防止double类型值超限 2025-07-08 11:21:06 +08:00
Diego
4c62bb0b21 10.9.25 2025-07-08 10:19:01 +08:00
Diego
46b16279c7 build: 10.9.24 2025-07-08 09:41:45 +08:00
2248356998 qq.com
0779efc5dd refactor: 冗余服务代码修正 2025-07-08 02:38:05 +08:00
Diego
8acdb780e8 nuget本地源创建文件夹 2025-07-07 19:07:08 +08:00
Diego
2e310b919e 添加Keys文件夹 2025-07-07 16:54:58 +08:00
Diego
4155c07269 10.9.23 2025-07-07 15:20:39 +08:00
Diego
32fa833736 build: 10.9.22 2025-07-07 15:10:06 +08:00
Diego
2258f08555 build: 10.9.19 2025-07-07 13:44:19 +08:00
2248356998 qq.com
d90b32f165 refactor: 调整冗余服务代码 2025-07-07 00:15:46 +08:00
2248356998 qq.com
1492377322 refactor:调整部分插件父类 2025-07-06 01:33:15 +08:00
Diego
32eefbf545 build: 10.9.18
feat: 网关监控树节点添加右侧常用操作按钮
2025-07-04 13:54:35 +08:00
Diego
a825ca5f6f 网关监控树节点添加右侧常用操作按钮 2025-07-04 12:50:07 +08:00
Diego
e270b0c4f6 no message 2025-07-04 09:01:31 +08:00
Diego
6ae44ccf58 10.9.17 2025-07-04 08:36:37 +08:00
Diego
1aa0df6339 feat: 支持变量低内存导出 2025-07-03 23:24:56 +08:00
Diego
62c3693dbe 导出通道和设备支持IEnumerable低内存 2025-07-03 19:34:51 +08:00
Diego
e4e503c97b build: 添加nuget.config,自定义nuget源,方便本地调试自行编译 2025-07-03 12:43:51 +08:00
2248356998 qq.com
5ec1ee7627 fix: 上次更新导致大小端配置映射错误 2025-07-02 21:51:00 +08:00
Diego
79789388fc fix: opcuaserver动态刷新变量节点会导致新建的动态节点无法刷新订阅 2025-07-02 19:11:11 +08:00
Diego
2c4194ee18 refactor: opcua某些不存在的节点ID不再影响整体订阅,只出现日志提示 2025-07-02 15:09:52 +08:00
Diego
1b2be585af fix: 报警分析错误设置循环 2025-07-02 14:26:25 +08:00
Diego
83736647e7 feat: S7PLC增加WString支持 2025-07-02 12:49:55 +08:00
Diego
b06405717d build: 10.9.9
fix: timerx 池 max值取消
feat: mqttrpc支持脚本
2025-07-02 10:03:50 +08:00
2248356998 qq.com
298a1f2ed4 更新docker文件 2025-07-02 07:32:23 +08:00
Diego
74a47a1983 build: 10.9.8
支持redis缓存
2025-07-01 17:55:03 +08:00
Diego
a48a42abe4 modbusslave 异常捕获 2025-07-01 10:51:10 +08:00
Diego
feb1d0a3c5 feat: 增加后台服务生命周期识别 2025-06-30 10:59:18 +08:00
Diego
92bca824e6 10.9.6 2025-06-29 22:19:53 +08:00
2248356998 qq.com
025c699517 feat: s7增加请求id识别 2025-06-29 22:06:53 +08:00
2248356998 qq.com
53f8fbe4b1 refactor: 变量排序导出 2025-06-28 21:43:06 +08:00
2248356998 qq.com
77bfabc41d feat: 改用Mapperly源生成,代替Mapster 2025-06-28 00:00:43 +08:00
Diego
6427ee6ee0 refactor: 降低sqlite依赖 2025-06-27 14:44:00 +08:00
Diego
4c95997d62 build: 10.9.2
fix: taos connection dispose
refactor: opcua AddSubscriptionAsync 添加延时和重试
2025-06-27 11:16:58 +08:00
Diego
1d82cea40d build: 10.9.1
fix: 任务空错误异常
feat: 数据库插件增加字符串变量表和数值变量表两种情况
2025-06-27 03:02:03 +08:00
Diego
e78799424c 添加日志输出筛选 2025-06-25 17:09:05 +08:00
Diego
1000c8d38f docs: 更新采集插件开发文档 2025-06-25 14:22:58 +08:00
Diego
b2589fc634 build: 10.8.24
fix: 变量离线后再次上线,如果值不变,会导致在线状态不刷新
fix: s7离线恢复时,可能触发多次协议握手导致异常
2025-06-25 11:19:06 +08:00
Diego
c80e57a4e8 build: 10.8.24
fix: 变量离线后再次上线,如果值不变,会导致在线状态不刷新
fix: s7离线恢复时,可能触发多次协议握手导致异常
2025-06-25 11:17:04 +08:00
Diego
6510c3e289 feat: 增加一个变量读写表达式常用转换的友好编辑界面 2025-06-24 16:14:35 +08:00
Diego
920e407d05 恢复规则引擎脚本接口 2025-06-24 10:52:00 +08:00
Diego
7314c8901d fix: 用户编辑框初始刷新职位 2025-06-24 09:15:33 +08:00
Diego
4e9f02b48c 更新依赖包 2025-06-24 09:03:34 +08:00
2248356998 qq.com
9ae7602cb4 配置最大连接数 2025-06-24 00:09:07 +08:00
2248356998 qq.com
aa8aa36aef build: 10.8.19
fix: s7 复用地址对象导致读取异常
feat: 规则引擎node添加内部异常捕获
feat: 变量增加属性: 写入后再次读取检查值是否一致
2025-06-23 21:21:27 +08:00
2248356998 qq.com
0174f7c6f2 更新依赖 2025-06-22 23:05:12 +08:00
2248356998 qq.com
df9e7d6ff1 10.8.17 2025-06-22 21:11:37 +08:00
Diego
b40ca920d3 fix: 变量自动刷新运行态 2025-06-20 16:58:45 +08:00
Diego
5a4b0a0e93 修改插件过期提示 2025-06-20 14:43:13 +08:00
Diego
a879edd68b 10.8.12 2025-06-20 13:52:42 +08:00
2047 changed files with 93647 additions and 36199 deletions

3
.gitignore vendored
View File

@@ -364,6 +364,5 @@ FodyWeavers.xsd
/src/*Pro*/
/src/*Pro*
/src/*pro*
/src/*pro*/
/src/ThingsGateway.Server/Configuration/GiteeOAuthSettings.json
/src/.idea/

View File

@@ -85,7 +85,7 @@
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
as of the date such litigation is field.
4. Cachetribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without

View File

@@ -1,5 +1,5 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="$(SolutionDir)PackNuget.props" />
<Import Project="..\..\PackNuget.props" />
<PropertyGroup>
<TargetFrameworks>netstandard2.0;</TargetFrameworks>
<Version>$(SourceGeneratorVersion)</Version>
@@ -11,14 +11,14 @@
<IncludeBuildOutput>false</IncludeBuildOutput>
<!-- 避免 DLL 被打包到 lib/ -->
<EnableSourceGenerator>true</EnableSourceGenerator>
<!-- 可选 -->
</PropertyGroup>
<ItemGroup>
<None Include="$(OutputPath)\$(TargetFileName)" Pack="true"
PackagePath="analyzers/dotnet/cs" Visible="false" />
<None Include="$(OutputPath)\$(TargetFileName)" Pack="true" PackagePath="analyzers/dotnet/cs" Visible="false" />
</ItemGroup>
@@ -27,6 +27,6 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="3.9.0" PrivateAssets="all" />
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.12.0" PrivateAssets="all" Private="false" />
</ItemGroup>
</Project>

View File

@@ -1,31 +1,27 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
namespace BlazorSetParametersAsyncGenerator;
using System.Text;
namespace Microsoft.AspNetCore.Components;
[Generator]
public partial class SetParametersAsyncGenerator : ISourceGenerator
public sealed partial class SetParametersAsyncGenerator : IIncrementalGenerator
{
private string m_DoNotGenerateSetParametersAsyncAttribute = """
private const string m_DoNotGenerateSetParametersAsyncAttribute = """
using System;
namespace BlazorSetParametersAsyncGenerator
namespace Microsoft.AspNetCore.Components
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
internal sealed class DoNotGenerateSetParametersAsyncAttribute : Attribute
{
}
internal sealed class DoNotGenerateSetParametersAsyncAttribute : Attribute { }
}
""";
"""
;
private string m_GenerateSetParametersAsyncAttribute = """
private const string m_GenerateSetParametersAsyncAttribute = """
using System;
namespace BlazorSetParametersAsyncGenerator
namespace Microsoft.AspNetCore.Components
{
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]
internal sealed class GenerateSetParametersAsyncAttribute : Attribute
@@ -33,31 +29,20 @@ public partial class SetParametersAsyncGenerator : ISourceGenerator
public bool RequireExactMatch { get; set; }
}
}
""";
"""
;
private string m_GlobalGenerateSetParametersAsyncAttribute = """
private const string m_GlobalGenerateSetParametersAsyncAttribute = """
using System;
namespace BlazorSetParametersAsyncGenerator
namespace Microsoft.AspNetCore.Components
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
internal sealed class GlobalGenerateSetParametersAsyncAttribute : Attribute
{
public bool Enable { get; }
public GlobalGenerateSetParametersAsyncAttribute(bool enable = true)
{
Enable = enable;
public GlobalGenerateSetParametersAsyncAttribute(bool enable = true) { Enable = enable; }
}
}
}
"""
;
""";
private static readonly DiagnosticDescriptor ParameterNameConflict = new DiagnosticDescriptor(
id: "TG0001",
@@ -68,36 +53,64 @@ public partial class SetParametersAsyncGenerator : ISourceGenerator
isEnabledByDefault: true,
description: "Parameter names must be case insensitive to be usable in routes. Rename the parameter to not be in conflict with other parameters.");
public void Initialize(GeneratorInitializationContext context)
public void Initialize(IncrementalGeneratorInitializationContext context)
{
context.RegisterForPostInitialization(a =>
// 注入 attribute 源码
context.RegisterPostInitializationOutput(ctx =>
{
a.AddSource(nameof(m_DoNotGenerateSetParametersAsyncAttribute), m_DoNotGenerateSetParametersAsyncAttribute);
a.AddSource(nameof(m_GenerateSetParametersAsyncAttribute), m_GenerateSetParametersAsyncAttribute);
a.AddSource(nameof(m_GlobalGenerateSetParametersAsyncAttribute), m_GlobalGenerateSetParametersAsyncAttribute);
ctx.AddSource("DoNotGenerateSetParametersAsyncAttribute.g.cs", SourceText.From(m_DoNotGenerateSetParametersAsyncAttribute, Encoding.UTF8));
ctx.AddSource("GenerateSetParametersAsyncAttribute.g.cs", SourceText.From(m_GenerateSetParametersAsyncAttribute, Encoding.UTF8));
ctx.AddSource("GlobalGenerateSetParametersAsyncAttribute.g.cs", SourceText.From(m_GlobalGenerateSetParametersAsyncAttribute, Encoding.UTF8));
});
// Register a syntax receiver that will be created for each generation pass
context.RegisterForSyntaxNotifications(() => new SyntaxReceiver());
// 筛选 ClassDeclarationSyntax
var classDeclarations = context.SyntaxProvider
.CreateSyntaxProvider(
predicate: static (node, _) => node is ClassDeclarationSyntax,
transform: static (ctx, _) => (ClassDeclarationSyntax)ctx.Node)
.Where(static c => c is not null);
// 合并 Compilation
var compilationProvider = context.CompilationProvider;
var candidateClasses = classDeclarations.Combine(compilationProvider);
context.RegisterSourceOutput(candidateClasses, static (spc, tuple) =>
{
var (classDeclaration, compilation) = tuple;
Execute(spc, compilation, classDeclaration);
});
}
public void Execute(GeneratorExecutionContext context)
{
// https://github.com/dotnet/AspNetCore.Docs/blob/1e199f340780f407a685695e6c4d953f173fa891/aspnetcore/blazor/webassembly-performance-best-practices.md#implement-setparametersasync-manually
if (context.SyntaxReceiver is not SyntaxReceiver receiver)
private static void Execute(SourceProductionContext context, Compilation compilation, ClassDeclarationSyntax classDeclaration)
{
var model = compilation.GetSemanticModel(classDeclaration.SyntaxTree);
var classSymbol = model.GetDeclaredSymbol(classDeclaration);
if (classSymbol is null || classSymbol.Name == "_Imports")
return;
var positiveAttr = compilation.GetTypeByMetadataName("Microsoft.AspNetCore.Components.GenerateSetParametersAsyncAttribute");
var negativeAttr = compilation.GetTypeByMetadataName("Microsoft.AspNetCore.Components.DoNotGenerateSetParametersAsyncAttribute");
if (classSymbol.GetAttributes().Any(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, negativeAttr)))
return;
if (!IsPartial(classSymbol) || !IsComponent(classDeclaration, classSymbol, compilation))
return;
var globalEnable = compilation.Assembly.GetAttributes()
.FirstOrDefault(a => a.AttributeClass?.ToDisplayString() == "Microsoft.AspNetCore.Components.GlobalGenerateSetParametersAsyncAttribute")
?.ConstructorArguments.FirstOrDefault().Value as bool? ?? false;
var hasPositive = classSymbol.GetAttributes().Any(a => SymbolEqualityComparer.Default.Equals(a.AttributeClass, positiveAttr));
if (!globalEnable && !hasPositive)
return;
GenerateSetParametersAsyncMethod(context, classSymbol);
}
var candidate_classes = GetCandidateClasses(receiver, context);
foreach (var class_symbol in candidate_classes.Distinct(SymbolEqualityComparer.Default).Cast<INamedTypeSymbol>())
{
GenerateSetParametersAsyncMethod(context, class_symbol);
}
}
private static void GenerateSetParametersAsyncMethod(GeneratorExecutionContext context, INamedTypeSymbol class_symbol)
private static void GenerateSetParametersAsyncMethod(SourceProductionContext context, INamedTypeSymbol class_symbol)
{
var force_exact_match = class_symbol.GetAttributes().Any(a => a.NamedArguments.Any(na => na.Key == "RequireExactMatch" && na.Value.Value is bool v && v));
var namespaceName = class_symbol.ContainingNamespace.ToDisplayString();
@@ -109,6 +122,7 @@ using Microsoft.AspNetCore.Components;
using System.Collections.Generic;
using System.Threading.Tasks;
#pragma warning disable CA1849
#pragma warning disable CA2007
#pragma warning disable CS0162
#pragma warning disable CS8632
@@ -263,6 +277,7 @@ namespace {namespaceName}
#pragma warning restore CS8632
#pragma warning restore CS0162
#pragma warning restore CA2007
#pragma warning restore CA1849
");
var bases = class_symbol.GetTypeHierarchy().Where(t => !SymbolEqualityComparer.Default.Equals(t, class_symbol));
var members = class_symbol.GetMembers() // members of the type itself
@@ -386,6 +401,31 @@ namespace {namespaceName}
#pragma warning restore CS0162");
}
private static bool IsPartial(INamedTypeSymbol symbol)
{
return symbol.DeclaringSyntaxReferences
.Select(r => r.GetSyntax())
.OfType<ClassDeclarationSyntax>()
.Any(c => c.Modifiers.Any(m => m.IsKind(SyntaxKind.PartialKeyword)));
}
private static bool IsComponent(ClassDeclarationSyntax classDeclaration, INamedTypeSymbol symbol, Compilation compilation)
{
if (HasUserDefinedSetParametersAsync(symbol))
return false;
if (classDeclaration.SyntaxTree.FilePath.EndsWith(".razor") || classDeclaration.SyntaxTree.FilePath.EndsWith(".razor.cs"))
return true;
var iComponent = compilation.GetTypeByMetadataName("Microsoft.AspNetCore.Components.IComponent");
var componentBase = compilation.GetTypeByMetadataName("Microsoft.AspNetCore.Components.ComponentBase");
if (iComponent == null || componentBase == null)
return false;
return symbol.AllInterfaces.Contains(iComponent) || SymbolEqualityComparer.Default.Equals(symbol.BaseType, componentBase);
}
private static bool HasUserDefinedSetParametersAsync(INamedTypeSymbol classSymbol)
{
return classSymbol
@@ -397,138 +437,4 @@ namespace {namespaceName}
m.DeclaredAccessibility == Accessibility.Public &&
!m.IsStatic);
}
private static bool IsPartial(INamedTypeSymbol symbol)
{
return symbol.DeclaringSyntaxReferences
.Select(r => r.GetSyntax())
.OfType<ClassDeclarationSyntax>()
.Any(c => c.Modifiers.Any(m => m.IsKind(SyntaxKind.PartialKeyword)));
}
private static bool IsComponent(ClassDeclarationSyntax classDeclarationSyntax, INamedTypeSymbol symbol, Compilation compilation)
{
if (HasUserDefinedSetParametersAsync(symbol))
{
// 用户自己写了方法,不生成
return false;
}
if (!IsPartial(symbol))
{
return false;
}
if (classDeclarationSyntax.SyntaxTree.FilePath.EndsWith(".razor") || classDeclarationSyntax.SyntaxTree.FilePath.EndsWith(".razor.cs"))
{
return true;
}
var iComponent = compilation.GetTypeByMetadataName("Microsoft.AspNetCore.Components.IComponent");
var componentBase = compilation.GetTypeByMetadataName("Microsoft.AspNetCore.Components.ComponentBase");
if (iComponent == null || componentBase == null)
return false;
if (SymbolEqualityComparer.Default.Equals(symbol, iComponent))
return true;
if (SymbolEqualityComparer.Default.Equals(symbol, componentBase))
return true;
return false;
}
/// <summary>
/// Enumerate methods with at least one Group attribute
/// </summary>
private static IEnumerable<INamedTypeSymbol> GetCandidateClasses(SyntaxReceiver receiver, GeneratorExecutionContext context)
{
var compilation = context.Compilation;
var positiveAttributeSymbol = compilation.GetTypeByMetadataName("BlazorSetParametersAsyncGenerator.GenerateSetParametersAsyncAttribute");
var negativeAttributeSymbol = compilation.GetTypeByMetadataName("BlazorSetParametersAsyncGenerator.DoNotGenerateSetParametersAsyncAttribute");
// loop over the candidate methods, and keep the ones that are actually annotated
// 找特性
var assemblyAttributes = compilation.Assembly.GetAttributes();
var enableAttr = assemblyAttributes.FirstOrDefault(attr =>
attr.AttributeClass?.ToDisplayString() == "BlazorSetParametersAsyncGenerator.GlobalGenerateSetParametersAsyncAttribute");
var globalEnable = false;
if (enableAttr != null)
{
var arg = enableAttr.ConstructorArguments.FirstOrDefault();
if (arg.Value is bool b)
globalEnable = b;
}
foreach (ClassDeclarationSyntax class_declaration in receiver.CandidateClasses)
{
var model = compilation.GetSemanticModel(class_declaration.SyntaxTree);
var class_symbol = model.GetDeclaredSymbol(class_declaration);
if (class_symbol is null)
{
continue;
}
if (class_symbol.Name == "_Imports")
{
continue;
}
// 是否拒绝生成
var hasNegative = class_symbol.GetAttributes().Any(ad =>
ad.AttributeClass?.Equals(negativeAttributeSymbol, SymbolEqualityComparer.Default) == true);
if (hasNegative)
continue;
if (IsComponent(class_declaration, class_symbol, compilation))
{
if (globalEnable)
{
yield return class_symbol;
}
else
{
// 必须显式标注 Positive Attribute
var hasPositive = class_symbol.GetAttributes().Any(ad =>
ad.AttributeClass?.Equals(positiveAttributeSymbol, SymbolEqualityComparer.Default) == true);
if (hasPositive)
yield return class_symbol;
}
}
else
{
}
}
}
/// <summary>
/// Created on demand before each generation pass
/// </summary>
internal class SyntaxReceiver : ISyntaxReceiver
{
public List<ClassDeclarationSyntax> CandidateClasses { get; } = new List<ClassDeclarationSyntax>();
/// <summary>
/// Called for every syntax node in the compilation, we can inspect the nodes and save any information useful for generation
/// </summary>
public void OnVisitSyntaxNode(SyntaxNode syntax_node)
{
// any class with at least one attribute is a candidate for property generation
if (syntax_node is ClassDeclarationSyntax classDeclarationSyntax)
{
CandidateClasses.Add(classDeclarationSyntax);
}
else
{
}
}
}
}

View File

@@ -3,11 +3,11 @@ using Microsoft.CodeAnalysis.Text;
using System.Text;
namespace BlazorSetParametersAsyncGenerator
namespace Microsoft.AspNetCore.Components
{
internal static class SourceGeneratorContextExtension
{
public static void AddCode(this GeneratorExecutionContext context, string hint_name, string code)
public static void AddCode(this SourceProductionContext context, string hint_name, string code)
{
context.AddSource(hint_name.Replace("<", "_").Replace(">", "_"), SourceText.From(code, Encoding.UTF8));
}

View File

@@ -1,13 +0,0 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
namespace BlazorSetParametersAsyncGenerator
{
internal static class StringExtension
{
public static string NormalizeWhitespace(this string code)
{
return CSharpSyntaxTree.ParseText(code).GetRoot().NormalizeWhitespace().ToFullString();
}
}
}

View File

@@ -1,6 +1,6 @@
using Microsoft.CodeAnalysis;
namespace BlazorSetParametersAsyncGenerator
namespace Microsoft.AspNetCore.Components
{
public static class TypeSymbolExtension
{

View File

@@ -1,5 +1,5 @@
<div align="center"><h1 align="center">ThingsBlazor</a></h1></div>
<div align="center"><h1 align="center">ThingsBlazor</h1></div>
<div align="center"><h3 align="center">权限管理框架</h3></div>

View File

@@ -20,7 +20,6 @@ using System.Collections.Concurrent;
using ThingsGateway.Extension;
using ThingsGateway.FriendlyException;
using ThingsGateway.NewLife.Json.Extension;
using ThingsGateway.SqlSugar;
namespace ThingsGateway.Admin.Application;
@@ -39,9 +38,9 @@ public sealed class OperDescAttribute : MoAttribute
static OperDescAttribute()
{
// 创建长时间运行的后台任务,并将日志消息队列中数据写入存储中
Task.Factory.StartNew(ProcessQueue, TaskCreationOptions.LongRunning);
AppService = App.RootServices.GetService<IAppService>();
// 创建长时间运行的后台任务,并将日志消息队列中数据写入存储中
Task.Factory.StartNew(ProcessQueueAsync, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default);
}
public OperDescAttribute(string description, bool isRecordPar = true, object localizerType = null)
@@ -85,7 +84,6 @@ public sealed class OperDescAttribute : MoAttribute
{
if (App.HttpContext?.Request.Path.StartsWithSegments("/_blazor") == true)
{
//插入操作日志
SysOperateLog log = GetOperLog(LocalizerType, context);
OperDescAttribute.WriteToQueue(log);
@@ -95,7 +93,7 @@ public sealed class OperDescAttribute : MoAttribute
/// <summary>
/// 将日志消息写入数据库中
/// </summary>
private static async Task ProcessQueue()
private static async Task ProcessQueueAsync()
{
var appLifetime = App.RootServices!.GetService<IHostApplicationLifetime>()!;
while (!appLifetime.ApplicationStopping.IsCancellationRequested)

View File

@@ -18,7 +18,6 @@ public sealed class RolePermissionAttribute : Attribute
{
}
/// <summary>
/// 忽略角色授权权限
/// </summary>

View File

@@ -10,7 +10,6 @@
namespace ThingsGateway.Admin.Application;
[AttributeUsage(AttributeTargets.Method)]
public sealed class LoginLogAttribute : Attribute
{

View File

@@ -33,22 +33,22 @@ public static class CacheConst
/// <summary>
/// 资源表缓存Key
/// </summary>
public const string Cache_SysResource = $"{CacheConst.Cache_Prefix_Admin}SysResource:";
public const string Cache_SysResource = $"{CacheConst.Cache_Prefix_Admin}SysResource:List";
/// <summary>
/// 角色表缓存Key
/// </summary>
public const string Cache_SysRole = $"{CacheConst.Cache_Prefix_Admin}SysRole:";
public const string Cache_SysRole = $"{CacheConst.Cache_Prefix_Admin}SysRole:List";
/// <summary>
/// 用户表缓存Key
/// </summary>
public const string Cache_SysUser = $"{CacheConst.Cache_Prefix_Admin}SysUser:";
public const string Cache_SysUser = $"{CacheConst.Cache_Prefix_Admin}SysUser:Hash";
/// <summary>
/// 用户账号关系缓存Key
/// </summary>
public const string Cache_SysUserAccount = $"{CacheConst.Cache_Prefix_Admin}SysUserAccount:";
public const string Cache_SysUserAccount = $"{CacheConst.Cache_Prefix_Admin}SysUserAccount:Hash";
/// <summary>
/// 职位表缓存Key
@@ -58,7 +58,7 @@ public static class CacheConst
/// <summary>
/// 机构表缓存Key
/// </summary>
public const string Cache_SysOrg = $"{CacheConst.Cache_Prefix_Admin}SysOrg:";
public const string Cache_SysOrg = $"{CacheConst.Cache_Prefix_Admin}SysOrg:List";
/// <summary>
/// 公司表缓存Key
@@ -67,12 +67,12 @@ public static class CacheConst
/// <summary>
/// 公司表缓存Key
/// </summary>
public const string Cache_SysOrgTenant = $"{CacheConst.Cache_Prefix_Admin}OrgTenant:";
public const string Cache_SysOrgTenant = $"{CacheConst.Cache_Prefix_Admin}OrgTenant:Hash";
/// <summary>
/// Token表缓存Key
/// </summary>
public const string Cache_Token = $"{CacheConst.Cache_Prefix_Admin}Token:";
public const string Cache_Token = $"{CacheConst.Cache_Prefix_Admin}Token:Hash";
#region

View File

@@ -31,9 +31,7 @@ public class AuthController : ControllerBase
[LoginLog]
public Task<LoginOutput> LoginAsync([FromBody] LoginInput input)
{
return _authService.LoginAsync(input);
}
[HttpGet("oauth-login")]
@@ -48,7 +46,6 @@ public class AuthController : ControllerBase
return Challenge(props, scheme);
}
[HttpPost("logout")]
[Authorize]
[IgnoreRolePermission]

View File

@@ -34,17 +34,20 @@ public class FileController : ControllerBase
return BadRequest("Invalid file name.");
}
var filePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", fileName);
if (!System.IO.File.Exists(filePath))
var root = Directory.GetCurrentDirectory();
var wwwroot = Path.Combine(root, "wwwroot");
var filePath = Path.Combine(wwwroot, fileName);
#pragma warning disable CA3003
if ((!(fileName.StartsWith(@"../Logs") || fileName.StartsWith(@"..\Logs")) && filePath.Contains("..")) || !System.IO.File.Exists(filePath))
{
return NotFound();
}
#pragma warning restore CA3003
var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
Response.Headers.Append("Access-Control-Expose-Headers", "Content-Disposition");
return File(fileStream, "application/octet-stream", (fileName.Replace('/', '_')));
return File(fileStream, "application/octet-stream", (Path.GetFileName(filePath).Replace('/', '_')));
}
}

View File

@@ -8,8 +8,6 @@
// QQ群605534569
//------------------------------------------------------------------------------
using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
@@ -17,7 +15,6 @@ using System.ComponentModel;
namespace ThingsGateway.Admin.Application;
/// <summary>
/// 登录
/// </summary>
@@ -41,9 +38,9 @@ public class OpenApiController : ControllerBase
[AllowAnonymous]
public async Task<OpenApiLoginOutput> LoginAsync([FromBody] OpenApiLoginInput input)
{
var output = await _authService.LoginAsync(input.Adapt<LoginInput>(), false).ConfigureAwait(false);
var output = await _authService.LoginAsync(input.AdaptLoginInput(), false).ConfigureAwait(false);
var openApiLoginOutput = output.Adapt<OpenApiLoginOutput>();
var openApiLoginOutput = output.AdaptOpenApiLoginOutput();
return openApiLoginOutput;
}

View File

@@ -8,12 +8,8 @@
// QQ群605534569
//------------------------------------------------------------------------------
using BootstrapBlazor.Components;
using System.ComponentModel.DataAnnotations;
using ThingsGateway.SqlSugar;
namespace ThingsGateway.Admin.Application;
[SugarTable("sys_dict", TableDescription = "字典表")]

View File

@@ -8,10 +8,6 @@
// QQ群605534569
//------------------------------------------------------------------------------
using BootstrapBlazor.Components;
using ThingsGateway.SqlSugar;
namespace ThingsGateway.Admin.Application;
/// <summary>

View File

@@ -8,12 +8,8 @@
// QQ群605534569
// ------------------------------------------------------------------------------
using BootstrapBlazor.Components;
using System.ComponentModel.DataAnnotations;
using ThingsGateway.SqlSugar;
namespace ThingsGateway.Admin.Application;
/// <summary>
@@ -70,12 +66,9 @@ public class SysOrg : BaseEntity
[AutoGenerateColumn(Visible = true, Sortable = true, Filterable = true)]
public OrgEnum Category { get; set; }
[SugarColumn(ColumnName = "Status", ColumnDescription = "启用")]
[AutoGenerateColumn(Visible = true, Sortable = true, Filterable = true)]
public bool Status { get; set; } = true;
}

View File

@@ -8,12 +8,8 @@
// QQ群605534569
// ------------------------------------------------------------------------------
using BootstrapBlazor.Components;
using System.ComponentModel.DataAnnotations;
using ThingsGateway.SqlSugar;
namespace ThingsGateway.Admin.Application;
/// <summary>
@@ -46,7 +42,6 @@ public class SysPosition : BaseEntity
[AutoGenerateColumn(Visible = true, Sortable = true, Filterable = true)]
public string Code { get; set; }
[SugarColumn(ColumnName = "Status", ColumnDescription = "启用")]
[AutoGenerateColumn(Visible = true, Sortable = true, Filterable = true)]
public bool Status { get; set; } = true;
@@ -57,5 +52,4 @@ public class SysPosition : BaseEntity
[SugarColumn(ColumnName = "Category", ColumnDescription = "分类")]
[AutoGenerateColumn(Visible = true, Sortable = true, Filterable = true)]
public virtual PositionCategoryEnum Category { get; set; }
}

View File

@@ -8,8 +8,6 @@
// QQ群605534569
//------------------------------------------------------------------------------
using ThingsGateway.SqlSugar;
namespace ThingsGateway.Admin.Application;
/// <summary>

View File

@@ -8,16 +8,12 @@
// QQ群605534569
//------------------------------------------------------------------------------
using BootstrapBlazor.Components;
using Microsoft.AspNetCore.Components.Routing;
using Newtonsoft.Json;
using System.ComponentModel.DataAnnotations;
using ThingsGateway.SqlSugar;
namespace ThingsGateway.Admin.Application;
/// <summary>

View File

@@ -8,12 +8,8 @@
// QQ群605534569
//------------------------------------------------------------------------------
using BootstrapBlazor.Components;
using System.ComponentModel.DataAnnotations;
using ThingsGateway.SqlSugar;
namespace ThingsGateway.Admin.Application;
/// <summary>
@@ -75,8 +71,6 @@ public class SysRole : BaseEntity
}
}
/// <summary>
/// 默认数据范围
/// </summary>

View File

@@ -8,14 +8,9 @@
// QQ群605534569
//------------------------------------------------------------------------------
using BootstrapBlazor.Components;
using Mapster;
using Riok.Mapperly.Abstractions;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics.CodeAnalysis;
using ThingsGateway.SqlSugar;
namespace ThingsGateway.Admin.Application;
@@ -31,7 +26,7 @@ public class SysUser : BaseEntity
///</summary>
[SugarColumn(ColumnDescription = "头像", ColumnDataType = StaticConfig.CodeFirst_BigString, IsNullable = true)]
[AutoGenerateColumn(Visible = true, Sortable = false, Filterable = false)]
[AdaptIgnore]
[MapperIgnore]
public virtual string? Avatar { get; set; }
/// <summary>
@@ -175,14 +170,14 @@ public class SysUser : BaseEntity
/// </summary>
[SugarColumn(IsIgnore = true, IsJson = true)]
[AutoGenerateColumn(Ignore = true)]
public List<long> OrgAndPosIdList { get; set; } = new List<long>();
public List<long>? OrgAndPosIdList { get; set; } = new List<long>();
/// <summary>
/// 主管信息
/// </summary>
[SugarColumn(IsIgnore = true)]
[AutoGenerateColumn(Ignore = true)]
public UserSelectorOutput DirectorInfo { get; set; }
public UserSelectorOutput? DirectorInfo { get; set; }
#endregion
@@ -193,35 +188,35 @@ public class SysUser : BaseEntity
/// </summary>
[SugarColumn(IsIgnore = true)]
[AutoGenerateColumn(Ignore = true)]
public Dictionary<string, List<string>> ButtonCodeList { get; set; } = new();
public Dictionary<string, List<string>>? ButtonCodeList { get; set; } = new();
/// <summary>
/// 权限码集合
/// </summary>
[SugarColumn(IsIgnore = true)]
[AutoGenerateColumn(Ignore = true)]
public HashSet<string> PermissionCodeList { get; set; } = new();
public HashSet<string>? PermissionCodeList { get; set; } = new();
/// <summary>
/// 角色ID集合
/// </summary>
[SugarColumn(IsIgnore = true)]
[AutoGenerateColumn(Ignore = true)]
public HashSet<long> RoleIdList { get; set; } = new();
public HashSet<long>? RoleIdList { get; set; } = new();
/// <summary>
/// 机构及以下机构ID集合
/// </summary>
[SugarColumn(IsIgnore = true)]
[AutoGenerateColumn(Ignore = true)]
public HashSet<long> ScopeOrgChildList { get; set; }
public HashSet<long>? ScopeOrgChildList { get; set; }
/// <summary>
/// 模块集合
/// </summary>
[SugarColumn(IsIgnore = true)]
[AutoGenerateColumn(Ignore = true)]
public List<SysResource> ModuleList { get; set; } = new();
public List<SysResource>? ModuleList { get; set; } = new();
/// <summary>
/// 租户Id
@@ -230,7 +225,6 @@ public class SysUser : BaseEntity
[AutoGenerateColumn(Ignore = true)]
public long? TenantId { get; set; }
/// <summary>
/// 全局用戶
/// </summary>

View File

@@ -8,17 +8,13 @@
// QQ群605534569
//------------------------------------------------------------------------------
using BootstrapBlazor.Components;
using ThingsGateway.List;
using ThingsGateway.SqlSugar;
using ThingsGateway.Common.List;
namespace ThingsGateway.Admin.Application;
/// <summary>
/// 会话信息
/// </summary>
[SugarTable("verificatinfo", TableDescription = "验证缓存表")]
[Tenant(SqlSugarConst.DB_TokenCache)]
public class VerificatInfo : PrimaryIdEntity
@@ -42,6 +38,7 @@ public class VerificatInfo : PrimaryIdEntity
[AutoGenerateColumn(Filterable = true, Sortable = true)]
[SugarColumn(ColumnDescription = "Id", IsPrimaryKey = true)]
[IgnoreExcel]
[System.ComponentModel.DataAnnotations.Key]
public override long Id { get; set; }
/// <summary>
@@ -82,6 +79,4 @@ public class VerificatInfo : PrimaryIdEntity
/// </summary>
[AutoGenerateColumn(Filterable = true, Sortable = true, Width = 100)]
public string Device { get; set; }
}

View File

@@ -12,7 +12,6 @@ namespace ThingsGateway.Admin.Application;
public enum DataScopeEnum
{
/// <summary>
/// 仅自己
/// </summary>
@@ -37,5 +36,4 @@ public enum DataScopeEnum
/// 自定义
/// </summary>
SCOPE_ORG_DEFINE,
}

View File

@@ -0,0 +1,35 @@
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://thingsgateway.cn/
// QQ群605534569
//------------------------------------------------------------------------------
using ThingsGateway.Extension;
namespace ThingsGateway.Admin.Application;
/// <inheritdoc/>
[ThingsGateway.DependencyInjection.SuppressSniffer]
public static class SchemeHelper
{
public static string GetOrCreate()
{
var path = "Keys/SchemeKey.txt";
if (File.Exists(path))
{
var data = File.ReadAllText(path);
return data;
}
else
{
var data = DateTime.UtcNow.ToDefaultDateTimeFormat();
Directory.CreateDirectory("Keys");
File.WriteAllText(path, data);
return data;
}
}
}

View File

@@ -6,5 +6,4 @@ namespace System;
[SuppressSniffer, AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
public sealed class RequestAuditAttribute : Attribute
{
}

View File

@@ -61,7 +61,6 @@ public class RequestAuditData
public long TimeOperationElapsedMilliseconds { get; set; }
/// <summary>
/// 服务端
/// </summary>
@@ -98,4 +97,3 @@ public class RequestAuditData
public Validation Validation { get; set; }
public MethodInfo MethodInfo { get; set; }
}

View File

@@ -41,7 +41,6 @@ public class RequestAuditFilter : IAsyncActionFilter, IOrderedFilter
// 获取动作方法描述器
var actionMethod = controllerActionDescriptor?.MethodInfo;
// 处理 Blazor Server
if (actionMethod == null)
{
@@ -61,7 +60,6 @@ public class RequestAuditFilter : IAsyncActionFilter, IOrderedFilter
return;
}
// 只有方法贴有特性才进行审计
if (
!actionMethod.DeclaringType.IsDefined(typeof(RequestAuditAttribute), true)
@@ -71,15 +69,11 @@ public class RequestAuditFilter : IAsyncActionFilter, IOrderedFilter
return;
}
var logData = new RequestAuditData();
logData.TimeOperationElapsedMilliseconds = timeOperation.ElapsedMilliseconds;
var resultHttpContext = (resultContext as FilterContext).HttpContext;
var resultHttpContext = (resultContext as Microsoft.AspNetCore.Mvc.Filters.FilterContext).HttpContext;
// 获取 HttpContext 和 HttpRequest 对象
var httpContext = context.HttpContext;
@@ -145,8 +139,6 @@ public class RequestAuditFilter : IAsyncActionFilter, IOrderedFilter
});
}
logData.LocalIPv4 = httpContext.GetLocalIpAddressToIPv4();
logData.LogDateTime = DateTimeOffset.Now;
var parameterValues = context.ActionArguments;
@@ -167,7 +159,6 @@ public class RequestAuditFilter : IAsyncActionFilter, IOrderedFilter
_ = parameterValues.TryGetValue(name, out var value);
var par = new Parameters()
{
Name = name,
@@ -233,7 +224,6 @@ public class RequestAuditFilter : IAsyncActionFilter, IOrderedFilter
par.Value = rawValue;
}
// 获取异常对象情况
Exception exception = resultContext.Exception;
if (exception is AppFriendlyException friendlyException)
@@ -249,8 +239,6 @@ public class RequestAuditFilter : IAsyncActionFilter, IOrderedFilter
logData.Exception.Type = HandleGenericType(exception.GetType());
}
// 创建日志记录器
var logger = httpContext.RequestServices.GetRequiredService<ILogger<RequestAudit>>();
@@ -296,6 +284,4 @@ public class RequestAuditFilter : IAsyncActionFilter, IOrderedFilter
}
}

View File

@@ -6,5 +6,4 @@ namespace System;
[SuppressSniffer, AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
public sealed class SuppressRequestAuditAttribute : Attribute
{
}

View File

@@ -8,4 +8,15 @@
// QQ群605534569
//------------------------------------------------------------------------------
global using BootstrapBlazor.Components;
global using Microsoft.Extensions.Localization;
global using Microsoft.Extensions.Options;
global using System.Diagnostics.CodeAnalysis;
global using System.Globalization;
global using ThingsGateway.Common;
global using ThingsGateway.DB;
global using ThingsGateway.NewLife.Extension;
global using ThingsGateway.SqlSugar;

View File

@@ -8,8 +8,6 @@
// QQ群605534569
//------------------------------------------------------------------------------
using BootstrapBlazor.Components;
using ThingsGateway.NewLife;
namespace ThingsGateway.Admin.Application;

View File

@@ -9,9 +9,7 @@
// ------------------------------------------------------------------------------
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Runtime.InteropServices;
@@ -20,7 +18,6 @@ using ThingsGateway.NewLife;
using ThingsGateway.NewLife.Caching;
using ThingsGateway.NewLife.Threading;
using ThingsGateway.Schedule;
using ThingsGateway.SqlSugar;
namespace ThingsGateway.Admin.Application;
@@ -53,16 +50,16 @@ public class HardwareJob : IJob, IHardwareJob
#endregion
private MemoryCache MemoryCache = new() { };
private const string CacheKey = "HistoryHardwareInfo";
private ICache MemoryCache => App.CacheService;
private const string CacheKey = $"{CacheConst.Cache_HardwareInfo}HistoryHardwareInfo";
/// <inheritdoc/>
public async Task<List<HistoryHardwareInfo>> GetHistoryHardwareInfos()
{
var historyHardwareInfos = MemoryCache.Get<List<HistoryHardwareInfo>>(CacheKey);
if (historyHardwareInfos == null)
{
using var db = DbContext.GetDB<HistoryHardwareInfo>(); ;
historyHardwareInfos = await db.Queryable<HistoryHardwareInfo>().Where(a => a.Date > DateTime.Now.AddDays(-3)).ToListAsync().ConfigureAwait(false);
using var db = DbContext.GetDB<HistoryHardwareInfo>();
historyHardwareInfos = await db.Queryable<HistoryHardwareInfo>().Where(a => a.Date > DateTime.Now.AddDays(-3)).Take(1000).ToListAsync().ConfigureAwait(false);
MemoryCache.Set(CacheKey, historyHardwareInfos);
}
@@ -81,8 +78,7 @@ public class HardwareJob : IJob, IHardwareJob
{
if (HardwareInfo.MachineInfo == null)
{
MachineInfo.Register();
HardwareInfo.MachineInfo = MachineInfo.Current;
HardwareInfo.MachineInfo = MachineInfo.GetCurrent();
string currentPath = Directory.GetCurrentDirectory();
DriveInfo drive = new(Path.GetPathRoot(currentPath));
@@ -96,7 +92,6 @@ public class HardwareJob : IJob, IHardwareJob
HardwareInfo.UUID = HardwareInfo.MachineInfo.UUID;
HardwareInfo.UpdateTime = TimerX.Now.ToDefaultDateTimeFormat();
}
}
catch
@@ -133,7 +128,7 @@ public class HardwareJob : IJob, IHardwareJob
CpuUsage = (HardwareInfo.MachineInfo.CpuRate * 100).ToInt(),
Temperature = (HardwareInfo.MachineInfo.Temperature).ToInt(),
};
await _db.Insertable(his).ExecuteCommandAsync(stoppingToken).ConfigureAwait(false);
await _db.InsertableT(his).ExecuteCommandAsync(stoppingToken).ConfigureAwait(false);
MemoryCache.Remove(CacheKey);
}
var sevenDaysAgo = TimerX.Now.AddDays(-HardwareInfoOptions.DaysAgo);
@@ -158,5 +153,4 @@ public class HardwareJob : IJob, IHardwareJob
}
}
}
}

View File

@@ -8,8 +8,6 @@
// QQ群605534569
//------------------------------------------------------------------------------
using ThingsGateway.SqlSugar;
namespace ThingsGateway.Admin.Application;
/// <inheritdoc/>

View File

@@ -17,7 +17,6 @@ namespace ThingsGateway.Admin.Application;
/// </summary>
public class JobPersistence : IJobPersistence
{
/// <summary>
/// 作业调度服务启动时
/// </summary>
@@ -61,7 +60,6 @@ public class JobPersistence : IJobPersistence
public async Task OnTriggerChangedAsync(PersistenceTriggerContext context)
{
await Task.CompletedTask.ConfigureAwait(false);
}
/// <summary>

View File

@@ -21,16 +21,7 @@
"UserNoModule": "This account has not been assigned a module. Please contact the administrator",
"UserNull": "User {0} does not exist"
},
"ThingsGateway.Admin.Application.BaseDataEntity": {
"CreateOrgId": "CreateOrgId"
},
"ThingsGateway.Admin.Application.BaseEntity": {
"CreateTime": "CreateTime",
"CreateUser": "CreateUser",
"SortCode": "SortCode",
"UpdateTime": "UpdateTime",
"UpdateUser": "UpdateUser"
},
"ThingsGateway.Admin.Application.BlazorAuthenticationHandler": {
"UserExpire": "User expired, please login again"
},

View File

@@ -21,16 +21,7 @@
"UserNoModule": "该账号未分配模块,请联系管理员",
"UserNull": "用户 {0} 不存在"
},
"ThingsGateway.Admin.Application.BaseDataEntity": {
"CreateOrgId": "创建机构Id"
},
"ThingsGateway.Admin.Application.BaseEntity": {
"CreateTime": "创建时间",
"CreateUser": "创建人",
"SortCode": "排序",
"UpdateTime": "更新时间",
"UpdateUser": "更新人"
},
"ThingsGateway.Admin.Application.BlazorAuthenticationHandler": {
"UserExpire": "用户登录已过期,请重新登录"
},

View File

@@ -15,8 +15,6 @@ using ThingsGateway.Extension;
using ThingsGateway.FriendlyException;
using ThingsGateway.Logging;
using ThingsGateway.NewLife.Json.Extension;
using ThingsGateway.Razor;
using ThingsGateway.SqlSugar;
namespace ThingsGateway.Admin.Application;
@@ -107,7 +105,6 @@ public class DatabaseLoggingWriter : IDatabaseLoggingWriter
//获取结果json字符串
var resultJson = requestAuditData.ReturnInformation?.ToSystemTextJsonString();
//操作日志表实体
var sysLogOperate = new SysOperateLog
{

View File

@@ -0,0 +1,28 @@
//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权除特别声明外的代码归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库https://github.com/kimdiego2098/ThingsGateway
// 使用文档https://thingsgateway.cn/
// QQ群605534569
//------------------------------------------------------------------------------
using Riok.Mapperly.Abstractions;
namespace ThingsGateway.Admin.Application;
[Mapper(UseDeepCloning = true, EnumMappingStrategy = EnumMappingStrategy.ByName, RequiredMappingStrategy = RequiredMappingStrategy.None)]
public static partial class AdminMapper
{
public static partial LoginInput AdaptLoginInput(this OpenApiLoginInput src);
public static partial OpenApiLoginOutput AdaptOpenApiLoginOutput(this LoginOutput src);
public static partial SessionOutput AdaptSessionOutput(this SysUser src);
public static partial SysUser AdaptSysUser(this SysUser src);
public static partial UserSelectorOutput AdaptUserSelectorOutput(this SysUser src);
public static partial List<SysResource> AdaptListSysResource(this IEnumerable<SysResource> src);
public static partial AppConfig AdaptAppConfig(this AppConfig src);
public static partial WorkbenchInfo AdaptWorkbenchInfo(this WorkbenchInfo src);
public static partial QueryData<UserSelectorOutput> AdaptQueryDataUserSelectorOutput(this QueryData<SysUser> src);
public static partial LoginInput AdaptLoginInput(this LoginInput src);
}

View File

@@ -8,7 +8,7 @@
// QQ群605534569
//------------------------------------------------------------------------------
namespace ThingsGateway.Gateway.Application;
namespace ThingsGateway.Admin.Application;
public class USheetDatas
{

View File

@@ -4,7 +4,6 @@ using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using System.Collections.Concurrent;
using System.Security.Claims;
@@ -29,11 +28,9 @@ public class AdminOAuthHandler<TOptions>(
) : OAuthHandler<TOptions>(options, logger, encoder)
where TOptions : AdminOAuthOptions, new()
{
static AdminOAuthHandler()
{
Task.Factory.StartNew(Insertable, TaskCreationOptions.LongRunning);
Task.Factory.StartNew(InsertableAsync, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default);
}
/// <summary>
@@ -44,7 +41,7 @@ public class AdminOAuthHandler<TOptions>(
/// <summary>
/// 创建访问日志
/// </summary>
private static async Task Insertable()
private static async Task InsertableAsync()
{
var db = DbContext.GetDB<SysOperateLog>();
var appLifetime = App.RootServices!.GetService<IHostApplicationLifetime>()!;
@@ -67,8 +64,6 @@ public class AdminOAuthHandler<TOptions>(
await Task.Delay(3000, appLifetime.ApplicationStopping).ConfigureAwait(false);
}
}
}
protected override async Task<AuthenticationTicket> CreateTicketAsync(
@@ -98,7 +93,6 @@ public class AdminOAuthHandler<TOptions>(
identity.AddClaim(new Claim(ClaimConst.OrgId, RoleConst.DefaultTenantId.ToString()));
identity.AddClaim(new Claim(ClaimConst.TenantId, RoleConst.DefaultTenantId.ToString()));
var context = new OAuthCreatingTicketContext(
new ClaimsPrincipal(identity),
properties,
@@ -144,10 +138,6 @@ public class AdminOAuthHandler<TOptions>(
return new AuthenticationTicket(context.Principal, context.Properties, Scheme.Name);
}
private async Task<LoginEvent> GetLogin(int expire)
{
var sysUser = await sysUserService.GetUserByIdAsync(RoleConst.SuperAdminId).ConfigureAwait(false);//获取用户信息
@@ -175,7 +165,6 @@ public class AdminOAuthHandler<TOptions>(
LoginTime = loginEvent.DateTime
};
//添加到verificat列表
verificatInfoService.Add(verificatInfo);
return loginEvent;
@@ -211,7 +200,7 @@ public class AdminOAuthHandler<TOptions>(
using var db = DbContext.GetDB<SysUser>();
//更新用户登录信息
if (await db.Updateable(sysUser).UpdateColumns(it => new
if (await db.UpdateableT(sysUser).UpdateColumns(it => new
{
it.LastLoginIp,
it.LastLoginTime,

View File

@@ -34,7 +34,6 @@ public abstract class AdminOAuthOptions : OAuthOptions
/// <summary>配置 Claims 映射</summary>
protected virtual void ConfigureClaims()
{
}
public virtual string GetName(JsonElement element)
@@ -46,8 +45,6 @@ public abstract class AdminOAuthOptions : OAuthOptions
/// <summary>获得/设置 登陆后首页</summary>
public string HomePath { get; set; } = "/";
/// <summary>处理用户信息方法</summary>
public virtual async Task<JsonElement> HandleUserInfoAsync(HttpContext context, OAuthTokenResponse tokens)
{

View File

@@ -26,10 +26,7 @@ public class GiteeOAuthOptions : AdminOAuthOptions
Scope.Add("user_info");
Scope.Add("projects");
Events.OnCreatingTicket = async context =>
{
await HandlerGiteeStarredUrl(context).ConfigureAwait(false);
};
Events.OnCreatingTicket = async context => await HandlerGiteeStarredUrl(context).ConfigureAwait(false);
Events.OnRedirectToAuthorizationEndpoint = context =>
{
@@ -67,8 +64,6 @@ public class GiteeOAuthOptions : AdminOAuthOptions
return OAuthTokenResponse.Failed(new OAuthTokenException($"OAuth token endpoint failure: {await Display(response).ConfigureAwait(false)}"));
}
public override string GetName(JsonElement element)
{
JsonElement.ObjectEnumerator target = element.EnumerateObject();
@@ -109,8 +104,6 @@ public class GiteeOAuthOptions : AdminOAuthOptions
});
//throw new Exception($"Failed to star repository: {response.StatusCode}, {content}");
}
}
protected override void ConfigureClaims()
{

View File

@@ -27,10 +27,7 @@ public class GitHubOAuthOptions : AdminOAuthOptions
Scope.Add("read:user");
Scope.Add("public_repo"); // 需要用于 Star 仓库
Events.OnCreatingTicket = async context =>
{
await HandleGitHubStarAsync(context).ConfigureAwait(false);
};
Events.OnCreatingTicket = async context => await HandleGitHubStarAsync(context).ConfigureAwait(false);
Events.OnRedirectToAuthorizationEndpoint = context =>
{
@@ -66,8 +63,6 @@ public class GitHubOAuthOptions : AdminOAuthOptions
if (string.IsNullOrWhiteSpace(context.AccessToken))
throw new InvalidOperationException("Access token is missing.");
var request = new HttpRequestMessage(HttpMethod.Put, $"https://api.github.com/user/starred/{repoFullName}")
{
Headers =
@@ -93,17 +88,12 @@ public class GitHubOAuthOptions : AdminOAuthOptions
await Task.Delay(5000).ConfigureAwait(false);
await _noticeService.NavigationMesage(verificatInfoIds.ClientIds, "https://github.com/ThingsGateway/ThingsGateway", "创作不易如有帮助请star仓库").ConfigureAwait(false);
});
}
}
/// <summary>处理用户信息方法</summary>
public override async Task<JsonElement> HandleUserInfoAsync(HttpContext context, OAuthTokenResponse tokens)
{
var request = new HttpRequestMessage(HttpMethod.Get, UserInformationEndpoint);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.AccessToken);
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/vnd.github+json"));

View File

@@ -2,5 +2,4 @@
public class GithubOAuthSettings : GiteeOAuthSettings
{
}

View File

@@ -12,10 +12,7 @@ using ThingsGateway.ConfigurableOptions;
namespace ThingsGateway.Admin.Application;
public sealed class AdminLogOptions : IConfigurableOptions
{
public int OperateLogDaysAgo { get; set; }
}

View File

@@ -12,7 +12,6 @@ using ThingsGateway.ConfigurableOptions;
namespace ThingsGateway.Admin.Application;
/// <summary>
/// 邮件配置选项
/// </summary>

View File

@@ -12,12 +12,10 @@ using ThingsGateway.ConfigurableOptions;
namespace ThingsGateway.Admin.Application;
public sealed class TenantOptions : IConfigurableOptions
{
/// <summary>
/// 启用
/// </summary>
public bool Enable { get; set; }
}

View File

@@ -10,7 +10,6 @@
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Http;
using System.Security.Claims;
@@ -53,7 +52,6 @@ public class BlazorAuthenticationHandler : AppAuthorizeHandler
{
await Fail(context).ConfigureAwait(false);// 授权失败
}
}
static async Task Fail(AuthorizationHandlerContext context)
{
@@ -116,7 +114,7 @@ public class BlazorAuthenticationHandler : AppAuthorizeHandler
{
// 路由名称
var routeName = routeData.PageType.CustomAttributes.FirstOrDefault(x =>
x.AttributeType == typeof(RouteAttribute))?.ConstructorArguments?[0].Value as string;
x.AttributeType == typeof(Microsoft.AspNetCore.Components.RouteAttribute))?.ConstructorArguments?[0].Value as string;
if (routeName == null) return true;
if ((!user.PermissionCodeList.Contains(routeName.CutStart("/")) && !user.PermissionCodeList.Contains(routeName))) //如果当前路由信息不包含在角色授权路由列表中则认证失败
@@ -264,15 +262,12 @@ public class BlazorAuthenticationHandler : AppAuthorizeHandler
{
verificatInfo.VerificatTimeout = verificatInfo.VerificatTimeout.AddMinutes(verificatInfo.Expire); //新的过期时间
VerificatInfoService.Update(verificatInfo); //更新tokne信息到cache
}
//无法在server中刷新cookies单页面应用会一直保持登录状态所以这里不需要刷新cookies但是F5刷新后会重新登录
}
return true;
}
else

View File

@@ -13,9 +13,7 @@ namespace ThingsGateway.Admin.Application;
/// <inheritdoc/>
public class BlazorHybridAuthorizationHandler : BlazorAuthenticationHandler
{
public BlazorHybridAuthorizationHandler(ISysUserService sysUserService, ISysRoleService sysRoleService, ISysDictService sysDictService) : base(sysUserService, sysRoleService, sysDictService)
{
}
}

View File

@@ -11,11 +11,9 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Localization;
using ThingsGateway.DataValidation;
using ThingsGateway.FriendlyException;
using ThingsGateway.Razor;
using ThingsGateway.UnifyResult;
namespace ThingsGateway.Admin.Application;
@@ -59,8 +57,6 @@ public class UnifyResultProvider : IUnifyResultProvider
return new JsonResult(RESTfulResult(StatusCodes.Status200OK, true, data));
}
/// <summary>
/// 返回 RESTful 风格结果集
/// </summary>
@@ -97,6 +93,4 @@ public class UnifyResultProvider : IUnifyResultProvider
return new JsonResult(RESTfulResult(metadata.StatusCode ?? StatusCodes.Status400BadRequest, data: metadata.Data, errors: metadata.ValidationResult) // 如果需要只显示第一条错误修改为errors: metadata.FirstErrorMessage
, UnifyContext.GetSerializerSettings(context));
}
}

View File

@@ -23,6 +23,4 @@ public class SysDictSeedData : ISqlSugarEntitySeedData<SysDict>
var assembly = GetType().Assembly;
return SeedDataUtil.GetSeedDataByJson<SysDict>(SeedDataUtil.GetManifestResourceStream(assembly, "SeedData.Admin.seed_sys_dict.json")).Concat(data);
}
}

View File

@@ -37,6 +37,5 @@ public class SysOrgSeedData : ISqlSugarEntitySeedData<SysOrg>
SortCode=0
}
}.Concat(SeedDataUtil.GetSeedDataByJson<SysOrg>(SeedDataUtil.GetManifestResourceStream(assembly, "SeedData.Admin.seed_sys_org.json")).Concat(data));
}
}

View File

@@ -36,6 +36,5 @@ public class SysPositionSeedData : ISqlSugarEntitySeedData<SysPosition>
SortCode=0
}
}.Concat(SeedDataUtil.GetSeedDataByJson<SysPosition>(SeedDataUtil.GetManifestResourceStream(assembly, "SeedData.Admin.seed_sys_position.json")).Concat(data));
}
}

View File

@@ -31,6 +31,5 @@ public class SysResourceSeedData : ISqlSugarEntitySeedData<SysResource>
.Concat(data2)
.Concat(data3)
;
}
}

View File

@@ -35,6 +35,4 @@ public class SysUserSeedData : ISqlSugarEntitySeedData<SysUser>
}
}.Concat(SeedDataUtil.GetSeedDataByJson<SysUser>(SeedDataUtil.GetManifestResourceStream(assembly, "SeedData.Admin.seed_sys_user.json"))).Concat(data);
}
}

View File

@@ -8,20 +8,15 @@
// QQ群605534569
// ------------------------------------------------------------------------------
using BootstrapBlazor.Components;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.ApiExplorer;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.Options;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Globalization;
using System.Reflection;
using ThingsGateway.Extension;
using ThingsGateway.Common.Extension;
namespace ThingsGateway.Admin.Application;
@@ -67,10 +62,8 @@ internal sealed class ApiPermissionService : IApiPermissionService
//foreach (var groupOpenApi in groupOpenApis)
{
foreach (var apiDescriptionGroup in apiDescriptions)
{
var routes = apiDescriptionGroup.Items.Where(api => api.ActionDescriptor is ControllerActionDescriptor);
Dictionary<string, OpenApiPermissionTreeSelector> openApiPermissionTreeSelectorDict = new();
@@ -84,7 +77,6 @@ internal sealed class ApiPermissionService : IApiPermissionService
if (openApiPermissionTreeSelectorDict.TryGetValue(actionDesc.ControllerName, out var openApiControllerGroup))
{
}
else
{
@@ -108,12 +100,9 @@ internal sealed class ApiPermissionService : IApiPermissionService
});
}
if (openApiPermissionTreeSelectorDict.Values.Any(a => a.Children.Count > 0))
permissions.AddRange(openApiPermissionTreeSelectorDict.Values);
}
}
App.CacheService.Set(cacheKey, permissions);
@@ -121,7 +110,6 @@ internal sealed class ApiPermissionService : IApiPermissionService
return permissions;
}
/// <summary>
/// 获取路由地址名称
/// </summary>

View File

@@ -8,7 +8,6 @@
// QQ群605534569
// ------------------------------------------------------------------------------
using ThingsGateway.Admin.Application;
public interface IApiPermissionService

View File

@@ -59,8 +59,6 @@ public class AppService : IAppService
}
}
public async Task LoginAsync(ClaimsIdentity identity, int expire)
{
var diffTime = DateTime.Now + TimeSpan.FromMinutes(expire);

View File

@@ -71,5 +71,4 @@ public class HybridAppService : IAppService
User = new ClaimsPrincipal(claimsIdentity);
return Task.CompletedTask;
}
}

View File

@@ -20,5 +20,4 @@ public class HybridClaimsPrincipalService : IClaimsPrincipalService
_hybridAppService = hybridAppService;
}
public ClaimsPrincipal? User => _hybridAppService.User;
}

View File

@@ -8,7 +8,6 @@
// QQ群605534569
//------------------------------------------------------------------------------
using System.Security.Claims;
namespace ThingsGateway.Admin.Application;
@@ -47,7 +46,4 @@ public interface IAppService
/// </summary>
/// <returns></returns>
public Task LoginAsync(ClaimsIdentity claimsIdentity, int expire);
}

View File

@@ -10,7 +10,6 @@
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Localization;
using System.Security.Claims;
@@ -63,9 +62,6 @@ public class AuthService : IAuthService
throw Oops.Bah(appConfig.WebsitePolicy.CloseTip);
}
string? password = input.Password;
if (isCookie) //openApi登录不再需要解密
{
@@ -326,7 +322,7 @@ public class AuthService : IAuthService
using var db = DbContext.GetDB<SysUser>();
//更新用户登录信息
if (await db.Updateable(sysUser).UpdateColumns(it => new
if (await db.UpdateableT(sysUser).UpdateColumns(it => new
{
it.LastLoginIp,
it.LastLoginTime,

View File

@@ -31,7 +31,6 @@ public class OpenApiLoginInput
[Required]
public string Password { get; set; }
/// <summary>
/// 租户Id
///</summary>
@@ -63,5 +62,4 @@ public class LoginInput
/// </summary>
///<example>252885263003720</example>
public long? TenantId { get; set; } = RoleConst.DefaultTenantId;
}

View File

@@ -58,7 +58,7 @@ public class LoginOutput
/// <summary>
/// 模块列表
/// </summary>
public IEnumerable<SysResource> ModuleList { get; set; } = Enumerable.Empty<SysResource>();
public IEnumerable<SysResource>? ModuleList { get; set; } = Enumerable.Empty<SysResource>();
/// <summary>
/// 刷新Token

View File

@@ -15,17 +15,17 @@ public class AppConfig
/// <summary>
/// 登录策略
/// </summary>
public LoginPolicy LoginPolicy { get; set; }
public LoginPolicy? LoginPolicy { get; set; }
/// <summary>
/// 页面策略
/// </summary>
public PagePolicy PagePolicy { get; set; }
public PagePolicy? PagePolicy { get; set; }
/// <summary>
/// 密码策略
/// </summary>
public PasswordPolicy PasswordPolicy { get; set; }
public PasswordPolicy? PasswordPolicy { get; set; }
public WebsitePolicy WebsitePolicy { get; set; }
public WebsitePolicy? WebsitePolicy { get; set; }
}

View File

@@ -15,5 +15,5 @@ public class PagePolicy
/// <summary>
/// 系统默认快捷方式菜单ID列表
/// </summary>
public List<long> Shortcuts { get; set; } = new();
public List<long>? Shortcuts { get; set; } = new();
}

View File

@@ -8,8 +8,6 @@
// QQ群605534569
//------------------------------------------------------------------------------
using BootstrapBlazor.Components;
namespace ThingsGateway.Admin.Application;
/// <summary>
@@ -62,7 +60,6 @@ public interface ISysDictService
/// <returns>系统字典项</returns>
Task<SysDict> GetByKeyAsync(string category, string name);
/// <summary>
/// 从缓存/数据库获取自定义配置列表
/// </summary>

View File

@@ -8,11 +8,8 @@
// QQ群605534569
//------------------------------------------------------------------------------
using BootstrapBlazor.Components;
using ThingsGateway.FriendlyException;
using ThingsGateway.NewLife.Json.Extension;
using ThingsGateway.Razor;
namespace ThingsGateway.Admin.Application;
@@ -248,7 +245,6 @@ internal sealed class SysDictService : BaseService<SysDict>, ISysDictService
return sysDicts;
}
/// <summary>
/// 从缓存/数据库获取系统配置列表
/// </summary>
@@ -267,7 +263,6 @@ internal sealed class SysDictService : BaseService<SysDict>, ISysDictService
return sysDicts;
}
/// <summary>
/// 表格查询
/// </summary>
@@ -304,7 +299,6 @@ internal sealed class SysDictService : BaseService<SysDict>, ISysDictService
/// <param name="input">配置项</param>
private async Task CheckInput(SysDict input)
{
//设置类型为业务
input.DictType = DictTypeEnum.Define;
@@ -316,7 +310,6 @@ internal sealed class SysDictService : BaseService<SysDict>, ISysDictService
{
throw Oops.Bah(Localizer["DictDup", input.Category, input.Name]);
}
}
/// <summary>
@@ -331,6 +324,5 @@ internal sealed class SysDictService : BaseService<SysDict>, ISysDictService
App.CacheService.Remove($"{CacheConst.Cache_SysDict}{define}{nameof(AppConfig)}");
}
#endregion
}

View File

@@ -10,6 +10,8 @@
using System.Collections.Concurrent;
using ThingsGateway.NewLife.DictionaryExtensions;
namespace ThingsGateway.Admin.Application;
/// <summary>

View File

@@ -10,7 +10,6 @@
using Microsoft.AspNetCore.Components.Forms;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Localization;
using System.Text;
using System.Web;
@@ -26,7 +25,6 @@ internal sealed class FileService : IFileService
IStringLocalizer<FileService> localizer)
{
_localizer = localizer;
}
/// <summary>
/// 获取本地存储文件流
@@ -89,8 +87,4 @@ internal sealed class FileService : IFileService
string[] allowTypeS = allowTypes == null ? ["xlsx"] : allowTypes;//允许上传的文件类型
if (!allowTypeS.Contains(fileSuffix)) throw Oops.Bah(_localizer["FileTypeError", fileSuffix]);
}
#region
#endregion
}

View File

@@ -37,7 +37,6 @@ internal sealed class ImportExportService : IImportExportService
/// <returns></returns>
public async Task<FileStreamResult> ExportAsync<T>(object input, string fileName, bool isDynamicExcelColumn = true) where T : class
{
var path = ImportExportUtil.GetFileDir(ref fileName);
fileName = CommonUtils.GetSingleId() + fileName;
@@ -95,7 +94,5 @@ internal sealed class ImportExportService : IImportExportService
return fileName;
}
#endregion
}

View File

@@ -9,6 +9,7 @@
//------------------------------------------------------------------------------
namespace ThingsGateway.Admin.Application;
internal sealed class NoticeService : INoticeService
{
private IEventService<AppMessage>? MessageDispatchService { get; set; }
@@ -24,7 +25,6 @@ internal sealed class NoticeService : INoticeService
NavigationMesageDispatchService = navigationMesageDispatchService;
}
/// <inheritdoc/>
public async Task NewMesage(IEnumerable<string>? clientIds, AppMessage message)
{
@@ -51,8 +51,6 @@ internal sealed class NoticeService : INoticeService
}
}
/// <inheritdoc/>
public async Task NavigationMesage(IEnumerable<string>? clientIds, string uri, string message)
{

View File

@@ -32,5 +32,4 @@ public interface ISysHub
/// <param name="message">消息内容</param>
/// <returns>异步操作结果</returns>
Task NewMesage(AppMessage message);
}

View File

@@ -63,5 +63,4 @@ public class SysHub : Hub<ISysHub>
VerificatInfoUtil.UpdateVerificat(userIdentifier, VerificatId, false);//更新cache
return base.OnDisconnectedAsync(exception);
}
}

View File

@@ -8,8 +8,6 @@
// QQ群605534569
//------------------------------------------------------------------------------
using BootstrapBlazor.Components;
using ThingsGateway.Extension.Generic;
namespace ThingsGateway.Admin.Application;

View File

@@ -8,8 +8,6 @@
// QQ群605534569
//------------------------------------------------------------------------------
using BootstrapBlazor.Components;
namespace ThingsGateway.Admin.Application;
/// <summary>

View File

@@ -8,17 +8,12 @@
// QQ群605534569
//------------------------------------------------------------------------------
using BootstrapBlazor.Components;
using System.Data;
using ThingsGateway.SqlSugar;
namespace ThingsGateway.Admin.Application;
internal sealed class SysOperateLogService : BaseService<SysOperateLog>, ISysOperateLogService
{
#region
/// <summary>
@@ -90,6 +85,4 @@ internal sealed class SysOperateLogService : BaseService<SysOperateLog>, ISysOpe
#endregion
}

View File

@@ -8,10 +8,6 @@
// QQ群605534569
// ------------------------------------------------------------------------------
using BootstrapBlazor.Components;
using ThingsGateway.SqlSugar;
namespace ThingsGateway.Admin.Application;
/// <summary>
@@ -59,7 +55,6 @@ public interface ISysOrgService
/// <returns></returns>
Task<HashSet<long>> GetOrgChildIdsAsync(long orgId, bool isContainOneself = true, List<SysOrg> sysOrgList = null);
/// <summary>
/// 根据组织ID获取租户ID
/// </summary>

View File

@@ -8,11 +8,8 @@
// QQ群605534569
//------------------------------------------------------------------------------
using BootstrapBlazor.Components;
using ThingsGateway.Extension.Generic;
using ThingsGateway.FriendlyException;
using ThingsGateway.SqlSugar;
namespace ThingsGateway.Admin.Application;
@@ -125,26 +122,25 @@ internal sealed class SysOrgService : BaseService<SysOrg>, ISysOrgService
{
throw new(result.ErrorMessage, result.ErrorException);
}
}
}
[OperDesc("DeleteOrg")]
public async Task<bool> DeleteOrgAsync(IEnumerable<long> ids)
{
//获取所有ID
if (ids.Any())
{
using var db = GetDB();
var sysOrgList = await GetAllAsync().ConfigureAwait(false);//获取所有组织
var sysDeleteOrgList = new List<long>();//需要删除的组织ID集合
var sysOrgList = await GetAllAsync().ConfigureAwait(false);//获取所有组织
foreach (var it in ids)
{
var children = SysOrgService.GetSysOrgChildren(sysOrgList, it);//查找下级组织
sysDeleteOrgList.AddRange(children.Select(it => it.Id).ToList());
sysDeleteOrgList.Add(it);
}
//获取所有ID
if (sysDeleteOrgList.Count != 0)
{
using var db = GetDB();
//如果组织下有用户则不能删除
if (await db.Queryable<SysUser>().AnyAsync(it => sysDeleteOrgList.Contains(it.OrgId)).ConfigureAwait(false))
{
@@ -168,10 +164,8 @@ internal sealed class SysOrgService : BaseService<SysOrg>, ISysOrgService
{
return false;
}
}
/// <summary>
/// 从缓存/数据库获取系统配置列表
/// </summary>
@@ -246,7 +240,6 @@ internal sealed class SysOrgService : BaseService<SysOrg>, ISysOrgService
return reuslt;
}
/// <inheritdoc />
public async Task<HashSet<long>> GetOrgChildIdsAsync(long orgId, bool isContainOneself = true, List<SysOrg> sysOrgList = null)
{
@@ -276,8 +269,6 @@ internal sealed class SysOrgService : BaseService<SysOrg>, ISysOrgService
return childList;
}
/// <inheritdoc />
public async Task<List<SysOrg>> GetTenantListAsync()
{
@@ -383,7 +374,6 @@ internal sealed class SysOrgService : BaseService<SysOrg>, ISysOrgService
);
}
/// <summary>
/// 获取组织所有下级
/// </summary>
@@ -408,7 +398,6 @@ internal sealed class SysOrgService : BaseService<SysOrg>, ISysOrgService
return new List<SysOrg>();
}
/// <summary>
/// 重新生成组织实体
/// </summary>
@@ -428,7 +417,6 @@ internal sealed class SysOrgService : BaseService<SysOrg>, ISysOrgService
/// </summary>
private async Task CheckInput(SysOrg input)
{
if (!(await SysUserService.GetUserByIdAsync(UserManager.UserId).ConfigureAwait(false)).IsGlobal)
{
if (input.ParentId == 0)
@@ -470,8 +458,6 @@ internal sealed class SysOrgService : BaseService<SysOrg>, ISysOrgService
}
}
/// <summary>
/// 刷新缓存
/// </summary>
@@ -486,7 +472,6 @@ internal sealed class SysOrgService : BaseService<SysOrg>, ISysOrgService
_dispatchService.Dispatch(null);
}
/// <summary>
/// 获取全称
/// </summary>
@@ -509,7 +494,6 @@ internal sealed class SysOrgService : BaseService<SysOrg>, ISysOrgService
return parentIdList;
}
/// <inheritdoc />
private static List<SysOrg> GetOrgParents(List<SysOrg> allOrgList, long orgId, bool includeSelf = true)
{

View File

@@ -10,9 +10,6 @@
namespace ThingsGateway.Admin.Application;
public class PositionSelectorInput : UserSelectorInput
{
}

View File

@@ -10,7 +10,6 @@
namespace ThingsGateway.Admin.Application;
public class PositionTreeOutput
{
/// <summary>
@@ -34,7 +33,6 @@ public class PositionTreeOutput
public List<PositionTreeOutput> Children { get; set; } = new List<PositionTreeOutput>();
}
public class PositionSelectorOutput
{
/// <summary>

View File

@@ -8,10 +8,6 @@
// QQ群605534569
// ------------------------------------------------------------------------------
using BootstrapBlazor.Components;
using ThingsGateway.SqlSugar;
namespace ThingsGateway.Admin.Application;
/// <summary>
@@ -66,8 +62,6 @@ public interface ISysPositionService
/// <returns></returns>
Task<List<PositionSelectorOutput>> SelectorAsync(PositionSelectorInput input);
#endregion
}

View File

@@ -8,10 +8,7 @@
// QQ群605534569
// ------------------------------------------------------------------------------
using BootstrapBlazor.Components;
using ThingsGateway.FriendlyException;
using ThingsGateway.SqlSugar;
namespace ThingsGateway.Admin.Application;
@@ -78,7 +75,7 @@ public class SysPositionService : BaseService<SysPosition>, ISysPositionService
}
var dels = (await GetAllAsync().ConfigureAwait(false)).Where(a => ids.Contains(a.Id));
await SysUserService.CheckApiDataScopeAsync(dels.Select(a => a.OrgId).ToList(), dels.Select(a => a.CreateUserId).ToList()).ConfigureAwait(false);
await SysUserService.CheckApiDataScopeAsync(dels.Select(a => a.OrgId), dels.Select(a => a.CreateUserId)).ConfigureAwait(false);
//删除职位
var result = await base.DeleteAsync(ids).ConfigureAwait(false);
if (result)
@@ -89,7 +86,6 @@ public class SysPositionService : BaseService<SysPosition>, ISysPositionService
{
return false;
}
}
/// <summary>
@@ -283,6 +279,4 @@ public class SysPositionService : BaseService<SysPosition>, ISysPositionService
}
}

View File

@@ -137,7 +137,7 @@ internal sealed class RelationService : BaseService<SysRelation>, IRelationServi
{
if (clear)
await db.Deleteable<SysRelation>().Where(it => it.ObjectId == objectId && it.Category == category).ExecuteCommandAsync().ConfigureAwait(false);//删除老的
await db.Insertable(sysRelation).ExecuteCommandAsync().ConfigureAwait(false);//添加新的
await db.InsertableT(sysRelation).ExecuteCommandAsync().ConfigureAwait(false);//添加新的
}).ConfigureAwait(false);
if (result.IsSuccess)//如果成功了
{

View File

@@ -8,8 +8,6 @@
// QQ群605534569
//------------------------------------------------------------------------------
using BootstrapBlazor.Components;
using System.ComponentModel.DataAnnotations;
using ThingsGateway.Extension.Generic;

View File

@@ -8,8 +8,6 @@
// QQ群605534569
//------------------------------------------------------------------------------
using BootstrapBlazor.Components;
namespace ThingsGateway.Admin.Application;
/// <summary>
@@ -31,8 +29,7 @@ public interface ISysResourceService
/// <param name="resourceList">资源列表</param>
/// <param name="parentId">父ID</param>
/// <returns></returns>
IEnumerable<SysResource> ConstructMenuTrees(IEnumerable<SysResource> resourceList, long parentId = 0);
IEnumerable<SysResource> ConstructMenuTrees(List<SysResource> resourceList, long parentId = 0);
/// <summary>
/// 复制资源到其他模块
@@ -47,7 +44,7 @@ public interface ISysResourceService
/// </summary>
/// <param name="ids">id列表</param>
/// <returns></returns>
Task<bool> DeleteResourceAsync(IEnumerable<long> ids);
Task<bool> DeleteResourceAsync(HashSet<long> ids);
/// <summary>
/// 从缓存/数据库读取全部资源列表

View File

@@ -8,14 +8,9 @@
// QQ群605534569
//------------------------------------------------------------------------------
using BootstrapBlazor.Components;
using Microsoft.Extensions.DependencyInjection;
using System.Globalization;
using ThingsGateway.FriendlyException;
using ThingsGateway.SqlSugar;
namespace ThingsGateway.Admin.Application;
@@ -23,7 +18,7 @@ internal sealed class SysResourceService : BaseService<SysResource>, ISysResourc
{
private readonly IRelationService _relationService;
private string CacheKey = $"{CacheConst.Cache_SysResource}-{CultureInfo.CurrentUICulture.Name}";
private string CacheKey = $"{CacheConst.Cache_SysResource}";
public SysResourceService(IRelationService relationService)
{
@@ -32,7 +27,6 @@ internal sealed class SysResourceService : BaseService<SysResource>, ISysResourc
#region
[OperDesc("CopyResource")]
public async Task CopyAsync(IEnumerable<long> ids, long moduleId)
{
@@ -69,7 +63,7 @@ internal sealed class SysResourceService : BaseService<SysResource>, ISysResourc
var resource = resourceList.First(a => a.Id == id);
resource.ParentId = parentMenuId;
using var db = GetDB();
var result = await db.Updateable(resource).ExecuteCommandAsync().ConfigureAwait(false);
var result = await db.UpdateableT(resource).ExecuteCommandAsync().ConfigureAwait(false);
RefreshCache();//刷新缓存
_relationService.RefreshCache(RelationCategoryEnum.RoleHasResource);//关系表刷新缓存
_relationService.RefreshCache(RelationCategoryEnum.UserHasResource);//关系表刷新缓存
@@ -81,10 +75,10 @@ internal sealed class SysResourceService : BaseService<SysResource>, ISysResourc
/// <param name="ids">id列表</param>
/// <returns></returns>
[OperDesc("DeleteResource")]
public async Task<bool> DeleteResourceAsync(IEnumerable<long> ids)
public async Task<bool> DeleteResourceAsync(HashSet<long> ids)
{
//删除
if (ids.Any())
if (ids.Count != 0)
{
//获取所有菜单和按钮
var resourceList = await GetAllAsync().ConfigureAwait(false);
@@ -92,10 +86,11 @@ internal sealed class SysResourceService : BaseService<SysResource>, ISysResourc
var delSysResources = resourceList.Where(it => ids.Contains(it.Id));
//找到要删除的模块
var delModules = resourceList.Where(a => a.Category == ResourceCategoryEnum.Module).Where(it => ids.Contains(it.Id));
if (delModules.Any())
{
//获取模块下的所有列表
var delHashSet = delModules.Select(a => a.Id).ToHashSet();
if (delHashSet.Count != 0)
{
var delModuleResources = resourceList.Where(it => delHashSet.Contains(it.Module));
delSysResources = delSysResources.Concat(delModuleResources).ToHashSet();
}
@@ -143,12 +138,12 @@ internal sealed class SysResourceService : BaseService<SysResource>, ISysResourc
/// <returns>全部资源列表</returns>
public async Task<List<SysResource>> GetAllAsync()
{
var sysResources = App.CacheService.Get<List<SysResource>>(CacheKey);
var sysResources = App.CacheService.Get<List<SysResource>>(CacheConst.Cache_SysResource);
if (sysResources == null)
{
using var db = GetDB();
sysResources = await db.Queryable<SysResource>().ToListAsync().ConfigureAwait(false);
App.CacheService.Set(CacheKey, sysResources);
App.CacheService.Set(CacheConst.Cache_SysResource, sysResources);
}
return sysResources;
}
@@ -201,7 +196,7 @@ internal sealed class SysResourceService : BaseService<SysResource>, ISysResourc
if (type == ItemChangedType.Add)
{
var result = await db.Insertable(input).ExecuteCommandAsync().ConfigureAwait(false);
var result = await db.InsertableT(input).ExecuteCommandAsync().ConfigureAwait(false);
RefreshCache();//刷新缓存
return result > 0;
}
@@ -226,7 +221,7 @@ internal sealed class SysResourceService : BaseService<SysResource>, ISysResourc
//事务
var result = await db.UseTranAsync(async () =>
{
await db.Updateable(input).ExecuteCommandAsync().ConfigureAwait(false);//更新数据
await db.UpdateableT(input).ExecuteCommandAsync().ConfigureAwait(false);//更新数据
if (permissions.Count > 0)//如果权限列表大于0就更新
{
await db.Updateable(permissions).ExecuteCommandAsync().ConfigureAwait(false);//更新关系表
@@ -258,7 +253,7 @@ internal sealed class SysResourceService : BaseService<SysResource>, ISysResourc
/// </summary>
public void RefreshCache()
{
App.CacheService.Remove(CacheKey);
App.CacheService.Remove(CacheConst.Cache_SysResource);
//删除超级管理员的缓存
App.RootServices.GetRequiredService<ISysUserService>().DeleteUserFromCache(RoleConst.SuperAdminId);
}
@@ -321,7 +316,6 @@ internal sealed class SysResourceService : BaseService<SysResource>, ISysResourc
#endregion
/// <inheritdoc/>
private static List<SysResource> MenuTreesToSaveLevel(IEnumerable<SysResource> resourceList)
{
@@ -351,24 +345,19 @@ internal sealed class SysResourceService : BaseService<SysResource>, ISysResourc
return flatList;
}
/// <inheritdoc/>
public IEnumerable<SysResource> ConstructMenuTrees(IEnumerable<SysResource> resourceList, long parentId = 0)
public IEnumerable<SysResource> ConstructMenuTrees(List<SysResource> resourceList, long parentId = 0)
{
//找下级资源ID列表
var resources = resourceList.Where(it => it.ParentId == parentId).OrderBy(it => it.SortCode);
if (resources.Any())//如果数量大于0
{
foreach (var item in resources)//遍历资源
{
var children = ConstructMenuTrees(resourceList, item.Id).ToList();//添加子节点
item.Children = children.Count > 0 ? children : null;
}
}
return resources;
}
/// <inheritdoc/>
public IEnumerable<SysResource> GetMyParentResources(IEnumerable<SysResource> allMenuList, IEnumerable<SysResource> myMenus)
{
@@ -381,7 +370,6 @@ internal sealed class SysResourceService : BaseService<SysResource>, ISysResourc
return parentList;
}
/// <inheritdoc/>
public IEnumerable<SysResource> GetResourceChilden(IEnumerable<SysResource> resourceList, long parentId)
{
@@ -398,6 +386,4 @@ internal sealed class SysResourceService : BaseService<SysResource>, ISysResourc
.SelectMany(item => new List<SysResource> { item }.Concat(GetResourceParent(resourceList, item.ParentId)));
}
}

View File

@@ -10,7 +10,6 @@
namespace ThingsGateway.Admin.Application;
/// <summary>
/// 角色树输出参数
/// </summary>

View File

@@ -8,10 +8,6 @@
// QQ群605534569
//------------------------------------------------------------------------------
using BootstrapBlazor.Components;
using ThingsGateway.SqlSugar;
namespace ThingsGateway.Admin.Application;
/// <summary>
@@ -34,7 +30,7 @@ public interface ISysRoleService
/// 删除角色
/// </summary>
/// <param name="ids">id列表</param>
Task<bool> DeleteRoleAsync(IEnumerable<long> ids);
Task<bool> DeleteRoleAsync(HashSet<long> ids);
/// <summary>
/// 从缓存/数据库获取全部角色信息
@@ -47,7 +43,7 @@ public interface ISysRoleService
/// </summary>
/// <param name="input">角色id列表</param>
/// <returns>角色列表</returns>
Task<IEnumerable<SysRole>> GetRoleListByIdListAsync(IEnumerable<long> input);
Task<IEnumerable<SysRole>> GetRoleListByIdListAsync(HashSet<long> input);
/// <summary>
/// 根据用户id获取角色列表

View File

@@ -8,11 +8,8 @@
// QQ群605534569
//------------------------------------------------------------------------------
using BootstrapBlazor.Components;
using ThingsGateway.FriendlyException;
using ThingsGateway.NewLife.Json.Extension;
using ThingsGateway.SqlSugar;
namespace ThingsGateway.Admin.Application;
@@ -64,42 +61,46 @@ internal sealed class SysRoleService : BaseService<SysRole>, ISysRoleService
var topOrgList = sysOrgList.Where(it => it.ParentId == 0);//获取顶级机构
var globalRole = sysRoles.Where(it => it.Category == RoleCategoryEnum.Global);//获取全局角色
if (globalRole.Any())
{
result.Add(new RoleTreeOutput()
{
Id = CommonUtils.GetSingleId(),
Name = Localizer["Global"],
Children = globalRole.Select(it => new RoleTreeOutput
var children = globalRole.Select(it => new RoleTreeOutput
{
Id = it.Id,
Name = it.Name,
IsRole = true
}).ToList()
}).ToList();
result.Add(new RoleTreeOutput()
{
Id = CommonUtils.GetSingleId(),
Name = Localizer["Global"],
Children = children
});//添加全局角色
}
//遍历顶级机构
foreach (var org in topOrgList)
{
var childIds = await _sysOrgService.GetOrgChildIdsAsync(org.Id, true, sysOrgList).ConfigureAwait(false);//获取机构下的所有子级ID
var childRoles = sysRoles.Where(it => it.OrgId != 0 && childIds.Contains(it.OrgId));//获取机构下的所有角色
if (childRoles.Any())
{
var roleTreeOutput = new RoleTreeOutput
{
Id = org.Id,
Name = org.Name,
IsRole = false
};//实例化角色树
List<RoleTreeOutput> childrenRoleTreeOutputs = new();
foreach (var it in childRoles)
{
roleTreeOutput.Children.Add(new RoleTreeOutput()
childrenRoleTreeOutputs.Add(new RoleTreeOutput()
{
Id = it.Id,
Name = it.Name,
IsRole = true
});
}
if (childrenRoleTreeOutputs.Count > 0)
{
var roleTreeOutput = new RoleTreeOutput
{
Id = org.Id,
Name = org.Name,
IsRole = false,
Children = childrenRoleTreeOutputs
};//实例化角色树
result.Add(roleTreeOutput);
}
}
@@ -150,7 +151,7 @@ internal sealed class SysRoleService : BaseService<SysRole>, ISysRoleService
/// </summary>
/// <param name="input">角色id列表</param>
/// <returns>角色列表</returns>
public async Task<IEnumerable<SysRole>> GetRoleListByIdListAsync(IEnumerable<long> input)
public async Task<IEnumerable<SysRole>> GetRoleListByIdListAsync(HashSet<long> input)
{
var roles = await GetAllAsync().ConfigureAwait(false);
var roleList = roles.Where(it => input.Contains(it.Id));
@@ -165,19 +166,18 @@ internal sealed class SysRoleService : BaseService<SysRole>, ISysRoleService
/// </summary>
/// <param name="ids">id列表</param>
[OperDesc("DeleteRole")]
public async Task<bool> DeleteRoleAsync(IEnumerable<long> ids)
public async Task<bool> DeleteRoleAsync(HashSet<long> ids)
{
var sysRoles = await GetAllAsync().ConfigureAwait(false);//获取所有角色
var hasSuperAdmin = sysRoles.Any(it => it.Id == RoleConst.SuperAdminRoleId && ids.Contains(it.Id));//判断是否有超级管理员
if (hasSuperAdmin)
throw Oops.Bah(Localizer["CanotDeleteAdmin"]);
var dels = (await GetAllAsync().ConfigureAwait(false)).Where(a => ids.Contains(a.Id));
await SysUserService.CheckApiDataScopeAsync(dels.Select(a => a.OrgId).ToList(), dels.Select(a => a.CreateUserId).ToList()).ConfigureAwait(false);
await SysUserService.CheckApiDataScopeAsync(dels.Select(a => a.OrgId), dels.Select(a => a.CreateUserId)).ConfigureAwait(false);
//数据库是string所以这里转下
var targetIds = ids.Select(it => it.ToString());
var targetIds = ids.Select(it => it.ToString()).ToList();
//定义删除的关系
var delRelations = new List<RelationCategoryEnum> {
RelationCategoryEnum.RoleHasResource,
@@ -188,7 +188,7 @@ internal sealed class SysRoleService : BaseService<SysRole>, ISysRoleService
//事务
var result = await db.UseTranAsync(async () =>
{
await db.Deleteable<SysRole>().In(ids.ToList()).ExecuteCommandHasChangeAsync().ConfigureAwait(false);//删除
await db.Deleteable<SysRole>().In(ids).ExecuteCommandHasChangeAsync().ConfigureAwait(false);//删除
//删除关系表角色与资源关系,角色与权限关系
await db.Deleteable<SysRelation>(it => ids.Contains(it.ObjectId) && delRelations.Contains(it.Category)).ExecuteCommandAsync().ConfigureAwait(false);
//删除关系表角色与用户关系
@@ -219,7 +219,6 @@ internal sealed class SysRoleService : BaseService<SysRole>, ISysRoleService
[OperDesc("SaveRole")]
public async Task<bool> SaveRoleAsync(SysRole input, ItemChangedType type)
{
await CheckInput(input).ConfigureAwait(false);//检查参数
if (type == ItemChangedType.Add)
@@ -247,8 +246,6 @@ internal sealed class SysRoleService : BaseService<SysRole>, ISysRoleService
#region
#region
/// <summary>
@@ -285,7 +282,7 @@ internal sealed class SysRoleService : BaseService<SysRole>, ISysRoleService
if (sysRole != null)
{
var resources = await _sysResourceService.GetAllAsync().ConfigureAwait(false);
var menusList = resources.Where(a => a.Category == ResourceCategoryEnum.Menu).Where(a => menuIds.Contains(a.Id));
var menusList = resources.Where(a => a.Category == ResourceCategoryEnum.Menu && menuIds.Contains(a.Id));
#region
@@ -324,7 +321,7 @@ internal sealed class SysRoleService : BaseService<SysRole>, ISysRoleService
#region .
var defaultDataScope = sysRole.DefaultDataScope;//获取默认数据范围
if (menusList.Any())
if (relationRoles.Count != 0)
{
//获取权限授权树
var permissions = App.GetService<IApiPermissionService>().PermissionTreeSelector(menusList.Select(it => it.Href));
@@ -427,7 +424,6 @@ internal sealed class SysRoleService : BaseService<SysRole>, ISysRoleService
return relations.Select(it => it.ObjectId);
}
/// <summary>
/// 授权用户
/// </summary>
@@ -470,7 +466,6 @@ internal sealed class SysRoleService : BaseService<SysRole>, ISysRoleService
}
}
#endregion
/// <inheritdoc/>
@@ -479,7 +474,6 @@ internal sealed class SysRoleService : BaseService<SysRole>, ISysRoleService
App.CacheService.Remove(CacheConst.Cache_SysRole);//删除KEY
_dispatchService.Dispatch(null);
}
#endregion
@@ -520,10 +514,7 @@ internal sealed class SysRoleService : BaseService<SysRole>, ISysRoleService
//判断是否有相同的Code
if (sysRoles.Any(it => it.Code == sysRole.Code && it.Id != sysRole.Id))
throw Oops.Bah(Localizer["CodeDup", sysRole.Code]);
}
#endregion
}

View File

@@ -8,8 +8,6 @@
// QQ群605534569
//------------------------------------------------------------------------------
using BootstrapBlazor.Components;
namespace ThingsGateway.Admin.Application;
/// <summary>
@@ -20,6 +18,7 @@ public class SessionOutput : PrimaryIdEntity
/// <summary>
/// 主键Id
/// </summary>
[System.ComponentModel.DataAnnotations.Key]
public override long Id { get; set; }
/// <summary>

View File

@@ -8,8 +8,6 @@
// QQ群605534569
//------------------------------------------------------------------------------
using BootstrapBlazor.Components;
namespace ThingsGateway.Admin.Application;
public interface ISessionService

View File

@@ -8,12 +8,6 @@
// QQ群605534569
//------------------------------------------------------------------------------
using BootstrapBlazor.Components;
using Mapster;
using ThingsGateway.SqlSugar;
namespace ThingsGateway.Admin.Application;
internal sealed class SessionService : BaseService<SysUser>, ISessionService
@@ -69,7 +63,7 @@ internal sealed class SessionService : BaseService<SysUser>, ISessionService
var r = items.Select((it) =>
{
var reuslt = it.Adapt<SessionOutput>();
var reuslt = it.AdaptSessionOutput();
if (verificatInfoDicts.TryGetValue(it.Id, out var verificatInfos))
{
reuslt.VerificatCount = verificatInfos.Count;//令牌数量
@@ -94,7 +88,7 @@ internal sealed class SessionService : BaseService<SysUser>, ISessionService
var r = items.Select((it) =>
{
var reuslt = it.Adapt<SessionOutput>();
var reuslt = it.AdaptSessionOutput();
if (verificatInfoDicts.TryGetValue(it.Id, out var verificatInfos))
{
reuslt.VerificatCount = verificatInfos.Count;//令牌数量
@@ -117,7 +111,7 @@ internal sealed class SessionService : BaseService<SysUser>, ISessionService
var r = items.Select((it) =>
{
var reuslt = it.Adapt<SessionOutput>();
var reuslt = it.AdaptSessionOutput();
if (verificatInfoDicts.TryGetValue(it.Id, out var verificatInfos))
{
reuslt.VerificatCount = verificatInfos.Count;//令牌数量

View File

@@ -28,5 +28,4 @@ public class UserSelectorInput
/// 角色ID
/// </summary>
public long RoleId { get; set; }
}

View File

@@ -8,8 +8,6 @@
// QQ群605534569
//------------------------------------------------------------------------------
using BootstrapBlazor.Components;
namespace ThingsGateway.Admin.Application;
/// <summary>

View File

@@ -8,8 +8,6 @@
// QQ群605534569
//------------------------------------------------------------------------------
using BootstrapBlazor.Components;
namespace ThingsGateway.Admin.Application;
/// <summary>
@@ -60,7 +58,7 @@ public interface ISysUserService
/// </summary>
/// <param name="ids">用户ID列表。</param>
/// <returns>是否删除成功。</returns>
Task<bool> DeleteUserAsync(IEnumerable<long> ids);
Task<bool> DeleteUserAsync(HashSet<long> ids);
/// <summary>
/// 从缓存中删除用户信息。

View File

@@ -8,16 +8,12 @@
// QQ群605534569
//------------------------------------------------------------------------------
using BootstrapBlazor.Components;
using Mapster;
using ThingsGateway.Common.Extension;
using ThingsGateway.Common.Extension.Generic;
using ThingsGateway.DataEncryption;
using ThingsGateway.Extension;
using ThingsGateway.Extension.Generic;
using ThingsGateway.FriendlyException;
using ThingsGateway.NewLife.Json.Extension;
using ThingsGateway.SqlSugar;
namespace ThingsGateway.Admin.Application;
@@ -49,7 +45,6 @@ internal sealed class SysUserService : BaseService<SysUser>, ISysUserService
_verificatInfoService = verificatInfoService;
}
#region
/// <inheritdoc/>
@@ -104,7 +99,6 @@ internal sealed class SysUserService : BaseService<SysUser>, ISysUserService
return hasPermission;
}
public async Task<bool> CheckApiDataScopeAsync(IEnumerable<long> orgIds, IEnumerable<long> createUerIds, bool throwEnable = true)
{
var hasPermission = true;
@@ -131,7 +125,6 @@ internal sealed class SysUserService : BaseService<SysUser>, ISysUserService
#region
/// <inheritdoc/>
public async Task<SysUser?> GetUserByAccountAsync(string account, long? tenantId)
{
@@ -182,7 +175,6 @@ internal sealed class SysUserService : BaseService<SysUser>, ISysUserService
var userId = App.CacheService.HashGetOne<long>(key, account);
if (userId == 0)
{
//单查获取用户账号对应ID
using var db = GetDB();
userId = await db.Queryable<SysUser>()
@@ -276,7 +268,6 @@ internal sealed class SysUserService : BaseService<SysUser>, ISysUserService
ApiUrl = it.Key,
});
}
}
#endregion Razor页面权限
@@ -307,7 +298,6 @@ internal sealed class SysUserService : BaseService<SysUser>, ISysUserService
ApiUrl = it.Key,
});
}
}
#endregion API权限
@@ -356,7 +346,6 @@ internal sealed class SysUserService : BaseService<SysUser>, ISysUserService
u.Phone = DESEncryption.Decrypt(u.Phone);//解密手机号
#pragma warning restore CS8625 // 无法将 null 字面量转换为非 null 的引用类型。
})).ConfigureAwait(false);
}
else
{
@@ -371,8 +360,6 @@ internal sealed class SysUserService : BaseService<SysUser>, ISysUserService
}
}
/// <summary>
@@ -390,9 +377,9 @@ internal sealed class SysUserService : BaseService<SysUser>, ISysUserService
/// 获取用户拥有的资源
/// </summary>
/// <param name="id">用户id</param>
public async Task<GrantResourceData> OwnResourceAsync(long id)
public Task<GrantResourceData> OwnResourceAsync(long id)
{
return await _roleService.OwnResourceAsync(id, RelationCategoryEnum.UserHasResource).ConfigureAwait(false);
return _roleService.OwnResourceAsync(id, RelationCategoryEnum.UserHasResource);
}
/// <summary>
@@ -452,7 +439,7 @@ internal sealed class SysUserService : BaseService<SysUser>, ISysUserService
if (changedType == ItemChangedType.Add)
{
var sysUser = input.Adapt<SysUser>();
var sysUser = input.AdaptSysUser();
//获取默认密码
sysUser.Avatar = input.Avatar;
sysUser.Password = await GetDefaultPassWord(true).ConfigureAwait(false);//设置密码
@@ -474,7 +461,7 @@ internal sealed class SysUserService : BaseService<SysUser>, ISysUserService
var sysUser = input;//实体转换
using var db = GetDB();
var result = await db.Updateable(sysUser).IgnoreColumns(it =>
var result = await db.UpdateableT(sysUser).IgnoreColumns(it =>
new
{
//忽略更新字段
@@ -518,10 +505,10 @@ internal sealed class SysUserService : BaseService<SysUser>, ISysUserService
var password = await GetDefaultPassWord(true).ConfigureAwait(false);//获取默认密码,这里不走Aop所以需要加密一下
using var db = GetDB();
//重置密码
if (await db.UpdateSetColumnsTrueAsync<SysUser>(it => new SysUser
if ((await db.UpdateSetColumnsTrueAsync<SysUser>(it => new SysUser
{
Password = password
}, it => it.Id == id).ConfigureAwait(false))
}, it => it.Id == id).ConfigureAwait(false)) > 0)
{
DeleteUserFromCache(id);//从cache删除用户信息
var verificatInfoIds = _verificatInfoService.GetListByUserId(id);
@@ -563,8 +550,7 @@ internal sealed class SysUserService : BaseService<SysUser>, ISysUserService
if (sysUser != null)
{
var resources = await _sysResourceService.GetAllAsync().ConfigureAwait(false);
var menusList = resources.Where(a => a.Category == ResourceCategoryEnum.Menu).Where(a => menuIds.Contains(a.Id));
var menusList = resources.Where(a => a.Category == ResourceCategoryEnum.Menu && menuIds.Contains(a.Id));
#region
@@ -601,7 +587,7 @@ internal sealed class SysUserService : BaseService<SysUser>, ISysUserService
#region .
//获取菜单信息
if (menusList.Any())
if (relationUsers.Count != 0)
{
//获取权限授权树
var permissions = App.GetService<IApiPermissionService>().PermissionTreeSelector(menusList.Select(it => it.Href));
@@ -656,7 +642,7 @@ internal sealed class SysUserService : BaseService<SysUser>, ISysUserService
/// <inheritdoc/>
[OperDesc("DeleteUser")]
public async Task<bool> DeleteUserAsync(IEnumerable<long> ids)
public async Task<bool> DeleteUserAsync(HashSet<long> ids)
{
using var db = GetDB();
var containsSuperAdmin = await db.Queryable<SysUser>().Where(it => it.Id == RoleConst.SuperAdminId && ids.Contains(it.Id)).AnyAsync().ConfigureAwait(false);//判断是否有超管
@@ -686,14 +672,13 @@ internal sealed class SysUserService : BaseService<SysUser>, ISysUserService
.ExecuteCommandAsync().ConfigureAwait(false);
//删除用户
await db.Deleteable<SysUser>().In(ids.ToList()).ExecuteCommandHasChangeAsync().ConfigureAwait(false);//删除
await db.Deleteable<SysUser>().In(ids).ExecuteCommandHasChangeAsync().ConfigureAwait(false);//删除
//删除关系表用户与资源关系,用户与权限关系,用户与角色关系
await db.Deleteable<SysRelation>(it => ids.Contains(it.ObjectId) && delRelations.Contains(it.Category)).ExecuteCommandAsync().ConfigureAwait(false);
//删除组织表主管信息
await db.Deleteable<SysOrg>(it => ids.Contains(it.DirectorId.Value)).ExecuteCommandAsync().ConfigureAwait(false);
}).ConfigureAwait(false);
if (result.IsSuccess)//如果成功了
@@ -733,16 +718,16 @@ internal sealed class SysUserService : BaseService<SysUser>, ISysUserService
public void DeleteUserFromCache(IEnumerable<long> ids)
{
var userIds = ids.Select(it => it.ToString()).ToArray();//id转string列表
var sysUsers = App.CacheService.HashGet<SysUser>(CacheConst.Cache_SysUser, userIds).Where(it => it != null);//获取用户列表
if (sysUsers.Any() == true)
var sysUsers = App.CacheService.HashGet<SysUser>(CacheConst.Cache_SysUser, userIds);//获取用户列表
if (sysUsers.Count != 0)
{
var accounts = sysUsers.Where(it => it != null).Select(it => it.Account).ToArray();//账号集合
var phones = sysUsers.Select(it => it.Phone);//手机号集合
var phones = sysUsers.Select(it => it?.Phone);//手机号集合
if (sysUsers.Any(it => it.TenantId != null))//如果有租户id不是空的表示是多租户模式
if (sysUsers.Any(it => it?.TenantId != null))//如果有租户id不是空的表示是多租户模式
{
var userAccountKey = CacheConst.Cache_SysUserAccount;
var tenantIds = sysUsers.Where(it => it.TenantId != null).Select(it => it.TenantId.Value).Distinct().ToArray();//租户id列表
var tenantIds = sysUsers.Where(it => it?.TenantId != null).Select(it => it.TenantId.Value).Distinct().ToArray();//租户id列表
foreach (var tenantId in tenantIds)
{
userAccountKey = $"{userAccountKey}:{tenantId}";
@@ -756,8 +741,6 @@ internal sealed class SysUserService : BaseService<SysUser>, ISysUserService
App.CacheService.HashDel<long>(CacheConst.Cache_SysUserAccount, accounts);
App.CacheService.HashDel<VerificatInfo>(CacheConst.Cache_Token, userIds.Select(it => it.ToString()).ToArray());
}
}
@@ -796,7 +779,6 @@ internal sealed class SysUserService : BaseService<SysUser>, ISysUserService
/// <param name="sysUser"></param>
private async Task CheckInput(SysUser sysUser)
{
var sysOrgList = await _sysOrgService.GetAllAsync().ConfigureAwait(false);//获取组织列表
var userOrg = sysOrgList.FirstOrDefault(it => it.Id == sysUser.OrgId);
if (userOrg == null)
@@ -872,7 +854,7 @@ internal sealed class SysUserService : BaseService<SysUser>, ISysUserService
sysUser.OrgAndPosIdList.AddRange(sysUser.OrgId, sysUser.PositionId ?? 0);//添加组织和职位Id
if (sysUser.DirectorId != null)
{
sysUser.DirectorInfo = (await GetUserByIdAsync(sysUser.DirectorId.Value).ConfigureAwait(false)).Adapt<UserSelectorOutput>();//获取主管信息
sysUser.DirectorInfo = (await GetUserByIdAsync(sysUser.DirectorId.Value).ConfigureAwait(false)).AdaptUserSelectorOutput();//获取主管信息
}
//获取按钮码
@@ -889,8 +871,6 @@ internal sealed class SysUserService : BaseService<SysUser>, ISysUserService
sysUser.PermissionCodeList = permissionCodeList;
sysUser.IsGlobal = roleCodeList.Any(a => a.Category == RoleCategoryEnum.Global);
var sysOrgList = await _sysOrgService.GetAllAsync().ConfigureAwait(false);
var scopeOrgChildList =
(await _sysOrgService.GetChildListByIdAsync(sysUser.OrgId, true, sysOrgList).ConfigureAwait(false)).Select(it => it.Id).ToHashSet();//获取所属机构的下级机构Id列表

View File

@@ -42,5 +42,4 @@ public class UpdatePasswordInput
/// </summary>
[Required]
public string ConfirmPassword { get; set; }
}

View File

@@ -7,5 +7,3 @@
// 使用文档https://thingsgateway.cn/
// QQ群605534569
//------------------------------------------------------------------------------
namespace ThingsGateway.Admin.Application;

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