94 Commits

Author SHA1 Message Date
tk
c68f695555 chore(release): 2.1.0 2024-11-15 16:48:25 +08:00
587b22014d style: 💄 code format (#202)
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-15 16:44:54 +08:00
2f300285aa feat: 首页仪表板自定义布局 (#201)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-15 15:46:15 +08:00
1743f4ff28 build: 📦 添加git子模块 (#200)
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-13 19:00:15 +08:00
7fc5fca5d9 build: 📦 nuget package与 project refrence 切换脚本 (#199)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-13 18:50:24 +08:00
d8dbb28cfc fix: 🐛 404 (#198)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-12 19:01:07 +08:00
27aafacd54 Tk (#197)
* refactor: ♻️ 业务代码项目文件名与框架代码项目文件名区分

* refactor: ♻️ 业务代码项目文件名与框架代码项目文件名区分

---------

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-12 18:44:13 +08:00
e6ce5afd99 refactor: ♻️ 业务代码项目文件名与框架代码项目文件名区分 (#196)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-12 18:34:14 +08:00
d1503a859b docs: 📝 rEADME (#195)
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-12 17:57:36 +08:00
26e3698f57 fix: 🐛 --el-color-primary 变量有闪烁现象 (#194)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-12 10:33:53 +08:00
3069b8fbc4 fix: 🐛 module name (#193)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-11 16:36:19 +08:00
4d63bd6bf5 refactor: ♻️ 主题颜色变量封装 (#192)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-11 16:14:51 +08:00
f00046265a refactor: ♻️ 取消插入种子数据后退出程序 (#191) 2024-11-08 20:43:20 +08:00
0848c8b7e5 refactor: ♻️ seedDataInsertedEventAsync (#190)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-08 14:55:35 +08:00
8479f69bdc feat: 用户选择器 (#189)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-06 11:48:36 +08:00
a454f2ab2d Merge pull request #187 from nsnail/release
chore(release): 2.0.0
[skip ci]
2024-11-04 17:23:27 +08:00
tk
3293683835 chore(release): 2.0.0 2024-11-04 17:23:02 +08:00
e71661663f refactor: ♻️ 移除Newtonsoft.Json包 (#186)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-04 16:18:47 +08:00
13ba536df2 refactor: ♻️ 框架&业务代码分离 (#185)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-04 12:06:50 +08:00
072cc1e491 docs: 📝 在线预览地址变更 (#184)
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-10-31 10:19:07 +08:00
6fbb519256 refactor: ♻️ projectUsings (#183)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-10-30 16:20:18 +08:00
a4e63c971d refactor: ♻️ projectUsings (#182)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-10-30 15:27:25 +08:00
bac4a39544 refactor: ♻️ 框架代码同步 (#181)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-10-30 14:40:52 +08:00
f0c3ec109f revert: appConfig.js (#180)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-10-14 15:58:51 +08:00
000e3d68a8 fix: 🐛 public const int SECS_CACHE_LOGIN_BY_USER_ID = 3600 * 24 * 30; // 秒:缓存时间-通过用户编号登录的用户信息 (#179)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-10-14 14:15:32 +08:00
58e4572723 feat: 框架代码同步 (#178)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-10-14 13:55:53 +08:00
dfe6b03b21 style: 💄 code format (#175)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-08-29 17:41:28 +08:00
135f082b06 style: 💄 code format (#174)
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-08-29 17:31:11 +08:00
c088492cfa feat: 框架代码同步 (#173)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-08-29 17:21:06 +08:00
b9b228c9e1 Merge pull request #171 from nsnail/tk
feat:  查询过滤器保存
2024-08-13 11:34:49 +08:00
tk
779d8e511a feat: 查询过滤器保存
页面定时刷新
WebSocket断线自动重连
2024-08-13 11:34:28 +08:00
6922a863ec Merge pull request #170 from nsnail/release
chore(release): 1.6.0
2024-08-12 11:44:45 +08:00
tk
5b69ce8688 chore(release): 1.6.0 2024-08-12 11:44:27 +08:00
cd8ed674e0 feat: 移除RedLocker,更改为自实现 (#169)
用户表增加最后登录时间字段
列表查询多字段模糊查询改为单字段精确查询
WebSocket版本更新检查
前端自定义字段筛选
暗黑模式样式调整
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-08-12 11:44:14 +08:00
4733adede5 fix: 🐛 ip归属地查询接口地址更新 (#168)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-08-02 09:26:37 +08:00
e00c30c961 fix: 🐛 站内信角标颜色 (#167)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-29 18:28:20 +08:00
6b63250039 fix: 🐛 ip显示问题 (#166)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-29 18:19:58 +08:00
2fa8b56f9c chore: 🔨 前端布局样式调整 (#165)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-29 16:54:00 +08:00
2b4c25c07c refactor: ♻️ 批量查询ip归属地 (#164)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-29 11:35:26 +08:00
7c56c8d571 fix: 🐛 trimSuffix (#163)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-26 19:03:21 +08:00
5fb6f7bea7 Merge pull request #162 from nsnail/release
chore(release): 1.5.0
2024-07-26 17:48:07 +08:00
tk
e48b425121 chore(release): 1.5.0 2024-07-26 17:47:40 +08:00
faaf5aa0fc feat: 登录日志独立存储 (#161)
请求日志自动分表
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-26 17:46:56 +08:00
e1bea2ec31 chore: 🔨 更换ip归属地查询接口 (#160)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-23 09:38:07 +08:00
33e60a5bd7 style: 💄 code format (#159)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-23 09:34:57 +08:00
1a28e8d5a6 feat: 框架代码同步 (#158)
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-22 12:58:10 +08:00
60ec6ea2c1 chore: 🔨 默认过滤禁用数据 (#157)
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-11 16:17:15 +08:00
6d4ccf3445 feat: cron表达式的自然语言表达 (#156)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-09 14:17:17 +08:00
1733802e02 fix: 🐛 error CS0117: 'Numbers' does not contain a definition for 'SECS_CACHE_DIC_CATALOG_CODE' (#155)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-08 21:25:33 +08:00
aaea28389a feat: 请求日志增加TraceId (#154)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-08 20:50:53 +08:00
be5b9a160d feat: logoBar显示程序版本号 (#153)
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-04 21:14:16 +08:00
67eaa5b783 refactor: ♻️ 抽取公共导出方法 (#152)
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-04 09:29:18 +08:00
8b01112f42 Merge pull request #151 from nsnail/release
chore(release): 1.4.0
2024-07-03 22:11:37 +08:00
tk
d6a479b693 chore(release): 1.4.0 2024-07-03 22:11:18 +08:00
e1b0030193 feat: 框架代码同步 (#150)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-07-03 22:09:58 +08:00
beba4124b0 Merge pull request #149 from nsnail/release
chore(release): 1.3.0
2024-06-24 16:06:05 +08:00
tk
8a29640aeb chore(release): 1.3.0 2024-06-24 16:05:37 +08:00
8bc8aa960c feat: 框架代码同步 (#148)
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-06-24 16:04:28 +08:00
d00f0d2d9c fix: 🐛 补充多语种文件 (#147)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-06-18 17:33:23 +08:00
1442e0a37c feat: 补充多语种文件 (#146)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-06-18 17:31:22 +08:00
6100e9e9c8 feat: 前端版本更新器 (#145)
替换tinymce编辑器为aiEditor

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-06-17 21:47:04 +08:00
ae2d1c4932 feat: 框架代码同步 (#144)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-06-15 21:41:03 +08:00
366a26a5cd docs: 📝 readme文档更新 (#143)
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-06-12 22:49:59 +08:00
8b53f66331 perf: 升级至.net9 prev5 (#142)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-06-12 21:50:36 +08:00
705d027da4 fix: 🐛 操作日志不显示userName (#141)
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-06-12 21:47:08 +08:00
a3ab97019d feat: 更新实体增加sql过滤参数 (#140)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-06-11 18:10:02 +08:00
608a1ded5c feat: 框架代码同步 (#139)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-06-09 22:46:54 +08:00
366ca0d237 chore: 🔨 参数配置忽略版本锁 (#138)
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-06-07 11:05:05 +08:00
56b111b1cf refactor: ♻️ 基础框架的实体更新逻辑 (#137)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-06-07 00:13:14 +08:00
f5bd69ef60 Merge pull request #136 from nsnail/release
chore(release): 1.2.0
2024-06-07 00:05:44 +08:00
tk
ddf891e3bc chore(release): 1.2.0 2024-06-07 00:05:05 +08:00
7ae473d492 feat: 增强作业执行记录页面 (#135) 2024-06-04 16:08:18 +08:00
c20a6c369d fix: 🐛 字段长度 (#134)
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-06-04 15:26:28 +08:00
57b71e1354 feat: 计划作业-上次执行耗时 (#133)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-06-04 11:57:15 +08:00
127f6e9f6c feat: 默认头像根据用户名绘制svg (#132) 2024-05-31 16:48:11 +08:00
d1951dbcb5 fix: 🐛 字段顺序 (#131)
[skip ci]
2024-05-30 16:55:43 +08:00
5edcf63e24 feat: 框架代码同步 (#130)
[skip ci]
2024-05-29 15:03:05 +08:00
b01b8b24ba feat: 框架代码同步 (#129)
[skip ci]
2024-05-29 14:40:10 +08:00
d9c7085472 docs: 📝 readme (#128)
[skip ci]
2024-05-23 18:48:37 +08:00
a01acddb9c chore: 🔨 喜欢就点个 Star️ 吧! (#127) 2024-05-22 19:23:36 +08:00
e5208cd751 docs: 📝 更新 readme (#126) 2024-05-22 18:57:05 +08:00
dc326c324c perf: 升级至.net9 prev4 (#125)
[skip ci]
2024-05-22 18:55:08 +08:00
e0d15f8039 feat(frontend): 手机端分页控件显示总条数 (#124) 2024-05-17 16:23:30 +08:00
169ab08b88 chore: 🔨 switcher (#123)
[skip ci]
2024-05-16 09:44:02 +08:00
3b8336105a feat: 手动执行计划作业 (#122) 2024-05-15 14:50:26 +08:00
7214a22ea5 docs: 📝 更新 README (#121)
[skip ci]
2024-05-14 17:24:56 +08:00
3152a8d3e8 fix(backend): 🐛 更新计划作业在sqlite数据库环境报错 (#120) 2024-05-14 15:37:51 +08:00
40e8eff5f3 perf(backend): nuget update (#119)
[skip ci]
2024-05-13 16:12:10 +08:00
47e67dd503 feat: naColId组件 (#118) 2024-05-13 11:34:43 +08:00
903ea1820a Merge pull request #117 from nsnail/tk
fix: 🐛 take count
2024-04-30 11:27:49 +08:00
tk
c08ea62064 fix: 🐛 take count
[skip ci]
2024-04-30 11:27:26 +08:00
4860299959 Merge pull request #116 from nsnail/tk
docs: 📝 更新日志修改
2024-04-29 19:02:56 +08:00
tk
72f9d1a3ec docs: 📝 更新日志修改 2024-04-29 19:02:36 +08:00
98718a010c Merge pull request #115 from nsnail/release
chore(release): 1.1.1
2024-04-29 18:53:23 +08:00
865 changed files with 25500 additions and 30996 deletions

View File

@ -10,6 +10,7 @@ ij_xml_text_wrap = off # IntelliJ IDEA 中 XML 文本不换行
indent_size = 4 # 缩进大小为 4 个空格
indent_style = space # 使用空格进行缩进
insert_final_newline = false # 不在文件末尾插入空行
max_line_length = 150 # 行长度限制为 150 个字符
trim_trailing_whitespace = true # 删除行尾的空格
[{*.json,*.yml}]

1
.github/workflows/README.md vendored Normal file
View File

@ -0,0 +1 @@
github workflows

View File

@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [ 20.x ]
node-version: [ 22.x ]
steps:
- uses: actions/checkout@v3
with:
@ -37,8 +37,8 @@ jobs:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
restore-keys: ${{ runner.os }}-nuget
- working-directory: ./src/backend/NetAdmin.AdmServer.Host
run: dotnet publish NetAdmin.AdmServer.Host.csproj -c Release
- working-directory: ./src/backend/YourSolution.AdmServer.Host
run: dotnet publish YourSolution.AdmServer.Host.csproj -c Release
- run: docker build -t nsnail/netadmin:nightly .
- uses: docker/login-action@v3
with:

View File

@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [ 20.x ]
node-version: [ 22.x ]
steps:
- uses: actions/checkout@v3
with:
@ -37,8 +37,8 @@ jobs:
path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
restore-keys: ${{ runner.os }}-nuget
- working-directory: ./src/backend/NetAdmin.AdmServer.Host
run: dotnet publish NetAdmin.AdmServer.Host.csproj -c Release
- working-directory: ./src/backend/YourSolution.AdmServer.Host
run: dotnet publish YourSolution.AdmServer.Host.csproj -c Release
- uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

1
.gitignore vendored
View File

@ -397,6 +397,7 @@ FodyWeavers.xsd
# JetBrains Rider
*.sln.iml
.idea/
!src/backend/CloudCode.DataGrip/.idea
# User Define
dist/

6
.gitmodules vendored
View File

@ -1,6 +1,6 @@
[submodule "refs/Furion"]
path = refs/Furion
url = https://github.com/nsnail/Furion.git
[submodule "refs/Gurion"]
path = refs/Gurion
url = https://github.com/nsnail/Gurion.git
[submodule "refs/ns-ext"]
path = refs/ns-ext
url = https://github.com/nsnail/ns-ext.git

View File

@ -2,33 +2,114 @@
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
### [1.1.1](https://github.com/nsnail/NetAdmin/compare/v1.0.0...v1.1.1) (2024-04-29)
## [2.1.0](https://github.com/nsnail/NetAdmin/compare/v2.0.0...v2.1.0) (2024-11-15)
### Features
*版本更新日志组件 ([#96](https://github.com/nsnail/NetAdmin/issues/96)) ([a37acc4](https://github.com/nsnail/NetAdmin/commit/a37acc4b55c91d57d51c7fa079da8700530412a5))
*计划作业 ([#87](https://github.com/nsnail/NetAdmin/issues/87)) ([8293ec0](https://github.com/nsnail/NetAdmin/commit/8293ec0297875ebc9ad75cce9465bd587929c0bf))
* ✨ 计划作业执行记录 ([#89](https://github.com/nsnail/NetAdmin/issues/89)) ([6f89015](https://github.com/nsnail/NetAdmin/commit/6f890151989ad733e35653933b7597eec478cc3b))
* ✨ 将数据库结构同步和种子数据初始化作为命令行开关 ([#78](https://github.com/nsnail/NetAdmin/issues/78)) ([05ed3d3](https://github.com/nsnail/NetAdmin/commit/05ed3d3746aa274a0f88f7afadfea12a3c8a80ff))
* ✨ 快捷启用/禁用用户 ([#91](https://github.com/nsnail/NetAdmin/issues/91)) ([6c2d167](https://github.com/nsnail/NetAdmin/commit/6c2d1676e45b9f1ecf3be3ae5a172db49b62a81d))
* ✨ 前端表格高级筛选 ([#100](https://github.com/nsnail/NetAdmin/issues/100)) ([3847d6f](https://github.com/nsnail/NetAdmin/commit/3847d6fdbbd27efb53921bcc8374157f0da47155))
* ✨ 日志管理独立出来、增加登录日志界面 ([#65](https://github.com/nsnail/NetAdmin/issues/65)) ([9134c4f](https://github.com/nsnail/NetAdmin/commit/9134c4fe01165a87ebc7e2cbd0a2abff3c9fb3ea))
* ✨ 首页仪表面板 ([#103](https://github.com/nsnail/NetAdmin/issues/103)) ([149e1af](https://github.com/nsnail/NetAdmin/commit/149e1afa533b142a3666a325ec84a091d53c1840))
* ✨ cron表达式选择器 ([#92](https://github.com/nsnail/NetAdmin/issues/92)) ([bde9fb1](https://github.com/nsnail/NetAdmin/commit/bde9fb1ea264bd0b786ac68d590691892d7ce067))
*首页仪表板自定义布局 ([#201](https://github.com/nsnail/NetAdmin/issues/201)) ([2f30028](https://github.com/nsnail/NetAdmin/commit/2f300285aa2afbfaea1fd9ffe299cc2badf98e0f))
*用户选择器 ([#189](https://github.com/nsnail/NetAdmin/issues/189)) ([8479f69](https://github.com/nsnail/NetAdmin/commit/8479f69bdccac93a497e039dd01e18333ec2bbdc))
### Bug Fixes
* 🐛 'Numbers' does not contain a definition for 'CACHE_SECS_DEFAULT' ([#102](https://github.com/nsnail/NetAdmin/issues/102)) ([8f69c29](https://github.com/nsnail/NetAdmin/commit/8f69c2907be282b1b39f4a179badb11502aa2403))
* 🐛 低版本jetbrains.resharper.globaltools搞乱了代码 ([#97](https://github.com/nsnail/NetAdmin/issues/97)) ([c117ddf](https://github.com/nsnail/NetAdmin/commit/c117ddfe7a433215b3449cdd6b19318a1f3cbf37))
* 🐛 前端样式问题 ([#84](https://github.com/nsnail/NetAdmin/issues/84)) ([6615df3](https://github.com/nsnail/NetAdmin/commit/6615df339934f6d19880c9822b44d5305c2f2a75))
* 🐛 请求日志客户端IP显示不正确 ([#60](https://github.com/nsnail/NetAdmin/issues/60)) ([ec698ce](https://github.com/nsnail/NetAdmin/commit/ec698ce4db49861eaaeb8bf5080764939e6d7231))
* 🐛 时区问题 ([#107](https://github.com/nsnail/NetAdmin/issues/107)) ([59c85ce](https://github.com/nsnail/NetAdmin/commit/59c85cef217c121b36d52993b6b5a774fe22df9e))
* 🐛 小问题 ([#76](https://github.com/nsnail/NetAdmin/issues/76)) ([52ddf27](https://github.com/nsnail/NetAdmin/commit/52ddf273c856d8f7e363ce23e5886b9eedf4604f))
* 🐛 在弹窗界面中引用的列表组件点击重置搜索条件按钮时会关闭弹窗的bug ([#95](https://github.com/nsnail/NetAdmin/issues/95)) ([8fee14c](https://github.com/nsnail/NetAdmin/commit/8fee14cd6ebd86456956fc59bbb61c545faa1fdd))
* 🐛 tinymce editor css 加载路径错误 ([#93](https://github.com/nsnail/NetAdmin/issues/93)) ([5fe7387](https://github.com/nsnail/NetAdmin/commit/5fe73878a2a53dc5e7e2dcbcbf22f91ffb4376dd))
* 🐛 tinymce editor css 加载路径错误 ([#94](https://github.com/nsnail/NetAdmin/issues/94)) ([802251e](https://github.com/nsnail/NetAdmin/commit/802251e42347bfe4fa0bcb4867b615d7c03abf19))
* 🐛 --el-color-primary 变量有闪烁现象 ([#194](https://github.com/nsnail/NetAdmin/issues/194)) ([26e3698](https://github.com/nsnail/NetAdmin/commit/26e3698f57a2986f3b727fa38f293ca40c89f3ab))
* 🐛 404 ([#198](https://github.com/nsnail/NetAdmin/issues/198)) ([d8dbb28](https://github.com/nsnail/NetAdmin/commit/d8dbb28cfc8ad427062eb8d81be67cc25ded6fb6))
* 🐛 module name ([#193](https://github.com/nsnail/NetAdmin/issues/193)) ([3069b8f](https://github.com/nsnail/NetAdmin/commit/3069b8fbc451c4c257becf0523ab6ea6cc9af7e2))
## [2.0.0](https://github.com/nsnail/NetAdmin/compare/v1.6.0...v2.0.0) (2024-11-04)
### Features
* ✨ 查询过滤器保存 ([779d8e5](https://github.com/nsnail/NetAdmin/commit/779d8e511a84d2be91d74ea308c22b969d6963f3))
* ✨ 框架代码同步 ([#173](https://github.com/nsnail/NetAdmin/issues/173)) ([c088492](https://github.com/nsnail/NetAdmin/commit/c088492cfabada198ad563e43278ab7e869029bc))
* ✨ 框架代码同步 ([#178](https://github.com/nsnail/NetAdmin/issues/178)) ([58e4572](https://github.com/nsnail/NetAdmin/commit/58e4572723ba68700fb6414167cb27b03c864db1))
### Bug Fixes
* 🐛 public const int SECS_CACHE_LOGIN_BY_USER_ID = 3600 * 24 * 30; // 秒:缓存时间-通过用户编号登录的用户信息 ([#179](https://github.com/nsnail/NetAdmin/issues/179)) ([000e3d6](https://github.com/nsnail/NetAdmin/commit/000e3d68a85eaee7758b4160d1d0ffa52aa4aae0))
## [1.6.0](https://github.com/nsnail/NetAdmin/compare/v1.5.0...v1.6.0) (2024-08-12)
### Features
* ✨ 移除RedLocker更改为自实现 ([#169](https://github.com/nsnail/NetAdmin/issues/169)) ([cd8ed67](https://github.com/nsnail/NetAdmin/commit/cd8ed674e0615b33fc0e025b9412c2f16d252f0f))
### Bug Fixes
* 🐛 站内信角标颜色 ([#167](https://github.com/nsnail/NetAdmin/issues/167)) ([e00c30c](https://github.com/nsnail/NetAdmin/commit/e00c30c96123769d8a9e6f30cc9a2c3e8099e34c))
* 🐛 ip归属地查询接口地址更新 ([#168](https://github.com/nsnail/NetAdmin/issues/168)) ([4733ade](https://github.com/nsnail/NetAdmin/commit/4733adede5e8993f741e9b94541aafeb6a733859))
* 🐛 ip显示问题 ([#166](https://github.com/nsnail/NetAdmin/issues/166)) ([6b63250](https://github.com/nsnail/NetAdmin/commit/6b6325003924b1605b610f759b2131c15013ffa0))
* 🐛 trimSuffix ([#163](https://github.com/nsnail/NetAdmin/issues/163)) ([7c56c8d](https://github.com/nsnail/NetAdmin/commit/7c56c8d571d4f29fcb20f238893dbf61e5e538f0))
## [1.5.0](https://github.com/nsnail/NetAdmin/compare/v1.4.0...v1.5.0) (2024-07-26)
### Features
* ✨ 登录日志独立存储 ([#161](https://github.com/nsnail/NetAdmin/issues/161)) ([faaf5aa](https://github.com/nsnail/NetAdmin/commit/faaf5aa0fc5299633ca4f384d6287171bb241ff4))
* ✨ 框架代码同步 ([#158](https://github.com/nsnail/NetAdmin/issues/158)) ([1a28e8d](https://github.com/nsnail/NetAdmin/commit/1a28e8d5a62aeab7e4fda5049b4f733a16480b67))
* ✨ 请求日志增加TraceId ([#154](https://github.com/nsnail/NetAdmin/issues/154)) ([aaea283](https://github.com/nsnail/NetAdmin/commit/aaea28389a56566e055b6651cf48a89194a72cb7))
* ✨ cron表达式的自然语言表达 ([#156](https://github.com/nsnail/NetAdmin/issues/156)) ([6d4ccf3](https://github.com/nsnail/NetAdmin/commit/6d4ccf344595e128a445f1cb7596a7a1c28fd4cd))
* ✨ logoBar显示程序版本号 ([#153](https://github.com/nsnail/NetAdmin/issues/153)) ([be5b9a1](https://github.com/nsnail/NetAdmin/commit/be5b9a160d1f06cfdf36cea4e5eb95908523fed2))
### Bug Fixes
* 🐛 error CS0117: 'Numbers' does not contain a definition for 'SECS_CACHE_DIC_CATALOG_CODE' ([#155](https://github.com/nsnail/NetAdmin/issues/155)) ([1733802](https://github.com/nsnail/NetAdmin/commit/1733802e02b7e69e4c8646f259da5098b87888f7))
## [1.4.0](https://github.com/nsnail/NetAdmin/compare/v1.3.0...v1.4.0) (2024-07-03)
### Features
* ✨ 框架代码同步 ([#150](https://github.com/nsnail/NetAdmin/issues/150)) ([e1b0030](https://github.com/nsnail/NetAdmin/commit/e1b0030193556fa0564ea059657b4b43c98085c2))
## [1.3.0](https://github.com/nsnail/NetAdmin/compare/v1.2.0...v1.3.0) (2024-06-24)
### Features
* ✨ 补充多语种文件 ([#146](https://github.com/nsnail/NetAdmin/issues/146)) ([1442e0a](https://github.com/nsnail/NetAdmin/commit/1442e0a37cb2f27d8ba7b77bed91feaa5d7b1fdd))
* ✨ 更新实体增加sql过滤参数 ([#140](https://github.com/nsnail/NetAdmin/issues/140)) ([a3ab970](https://github.com/nsnail/NetAdmin/commit/a3ab97019dd1fc2267db987ade80fa6749e24e4d))
* ✨ 框架代码同步 ([#139](https://github.com/nsnail/NetAdmin/issues/139)) ([608a1de](https://github.com/nsnail/NetAdmin/commit/608a1ded5c0e9987161444efd48597a687c693e1))
* ✨ 框架代码同步 ([#144](https://github.com/nsnail/NetAdmin/issues/144)) ([ae2d1c4](https://github.com/nsnail/NetAdmin/commit/ae2d1c4932bf1229ea36d28d486beaee8de16d53))
* ✨ 框架代码同步 ([#148](https://github.com/nsnail/NetAdmin/issues/148)) ([8bc8aa9](https://github.com/nsnail/NetAdmin/commit/8bc8aa960cdd1ed5036927bd508fce4c218618c7))
* ✨ 前端版本更新器 ([#145](https://github.com/nsnail/NetAdmin/issues/145)) ([6100e9e](https://github.com/nsnail/NetAdmin/commit/6100e9e9c88005d6a2f3c2706ca750a6ad62d2c7))
### Bug Fixes
* 🐛 补充多语种文件 ([#147](https://github.com/nsnail/NetAdmin/issues/147)) ([d00f0d2](https://github.com/nsnail/NetAdmin/commit/d00f0d2d9cc2243908a8b6979b9c4a5811b2a57e))
* 🐛 操作日志不显示userName ([#141](https://github.com/nsnail/NetAdmin/issues/141)) ([705d027](https://github.com/nsnail/NetAdmin/commit/705d027da44af159d29db9c93e47b549317c793e))
## [1.2.0](https://github.com/nsnail/NetAdmin/compare/v1.1.1...v1.2.0) (2024-06-06)
### Features
* ✨ 计划作业-上次执行耗时 ([#133](https://github.com/nsnail/NetAdmin/issues/133)) ([57b71e1](https://github.com/nsnail/NetAdmin/commit/57b71e1354ab8b0be995b5f563dd8c3fb7965d5f))
* ✨ 框架代码同步 ([#129](https://github.com/nsnail/NetAdmin/issues/129)) ([b01b8b2](https://github.com/nsnail/NetAdmin/commit/b01b8b24ba574c08ba5605e103ff2ccf15e5830a))
* ✨ 框架代码同步 ([#130](https://github.com/nsnail/NetAdmin/issues/130)) ([5edcf63](https://github.com/nsnail/NetAdmin/commit/5edcf63e24f6b13f5515e01ee8cf120b1a814d40))
* ✨ 默认头像根据用户名绘制svg ([#132](https://github.com/nsnail/NetAdmin/issues/132)) ([127f6e9](https://github.com/nsnail/NetAdmin/commit/127f6e9f6c8c12974e5340e9697281250737bed3))
* ✨ 手动执行计划作业 ([#122](https://github.com/nsnail/NetAdmin/issues/122)) ([3b83361](https://github.com/nsnail/NetAdmin/commit/3b8336105a908ba6bc300bec6ac4f49747ea66e9))
* ✨ 增强作业执行记录页面 ([#135](https://github.com/nsnail/NetAdmin/issues/135)) ([7ae473d](https://github.com/nsnail/NetAdmin/commit/7ae473d492b9ba60cbb1c355894917d14f5ffa8f))
* ✨ naColId组件 ([#118](https://github.com/nsnail/NetAdmin/issues/118)) ([47e67dd](https://github.com/nsnail/NetAdmin/commit/47e67dd503dd0ba6818e8b798e41c62420363f58))
* **frontend:** ✨ 手机端分页控件显示总条数 ([#124](https://github.com/nsnail/NetAdmin/issues/124)) ([e0d15f8](https://github.com/nsnail/NetAdmin/commit/e0d15f8039a74a9826a0395983960ab620308899))
### Bug Fixes
* 🐛 字段顺序 ([#131](https://github.com/nsnail/NetAdmin/issues/131)) ([d1951db](https://github.com/nsnail/NetAdmin/commit/d1951dbcb5fa50a7ff308f6b6d554da5f791bcf2))
* 🐛 字段长度 ([#134](https://github.com/nsnail/NetAdmin/issues/134)) ([c20a6c3](https://github.com/nsnail/NetAdmin/commit/c20a6c369d7b6d6dcfd07b3f3eaeab0fa309e766))
* 🐛 take count ([c08ea62](https://github.com/nsnail/NetAdmin/commit/c08ea62064cc522d7cca9c90a5f15f23d833b6e3))
* **backend:** 🐛 更新计划作业在sqlite数据库环境报错 ([#120](https://github.com/nsnail/NetAdmin/issues/120)) ([3152a8d](https://github.com/nsnail/NetAdmin/commit/3152a8d3e8054524470883c336fb6e93903a8426))
### [1.1.1](https://github.com/nsnail/NetAdmin/compare/v1.1.0...v1.1.1) (2024-04-29)
## [1.1.0](https://github.com/nsnail/NetAdmin/compare/v1.0.0...v1.1.0) (2024-04-29)

View File

@ -1,6 +1,7 @@
<!-- 注意此文件名大小写不可变更 -->
<Project>
<PropertyGroup>
<DefineConstants>DBTYPE_SQLITE</DefineConstants>
<SolutionDir>$(MSBuildThisFileDirectory)</SolutionDir>
</PropertyGroup>
<Import Project="$(SolutionDir)/build/minver.targets" />
@ -25,12 +26,12 @@
<Title>$(AssemblyName)</Title>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="MinVer" Version="5.0.0">
<PackageReference Include="MinVer" Version="6.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<Compile Include="../GlobalUsings.cs" Link="GlobalUsings.cs" />
<Compile Include="$(SolutionDir)/src/backend/GlobalUsings.cs" Link="GlobalUsings.cs" />
</ItemGroup>
</Project>

View File

@ -1,7 +1,7 @@
FROM mcr.microsoft.com/dotnet/aspnet:9.0.0-preview.3 AS base
FROM mcr.microsoft.com/dotnet/aspnet:9.0 AS base
WORKDIR /app
EXPOSE 8080
RUN apt update
RUN apt install -y redis
COPY ./dist/backend/NetAdmin.AdmServer.Host/bin/Release/net9.0/publish .
ENTRYPOINT redis-server --daemonize yes && dotnet NetAdmin.AdmServer.Host.dll -is
COPY ./dist/backend/YourSolution.AdmServer.Host/bin/Release/net9.0/publish .
ENTRYPOINT redis-server --daemonize yes && dotnet YourSolution.AdmServer.Host.dll -is

View File

@ -31,6 +31,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{BB0B
1.git.pull.request.ps1 = scripts/1.git.pull.request.ps1
2.git.release.ps1 = scripts/2.git.release.ps1
3.git.recreate.branch.ps1 = scripts/3.git.recreate.branch.ps1
4.git.del.obsolete.tags.ps1 = scripts/4.git.del.obsolete.tags.ps1
clean.ln.csx = scripts/clean.ln.csx
code.clean.csx = scripts/code.clean.csx
code.clean.ps1 = scripts/code.clean.ps1
@ -43,11 +44,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{BB0B
install.as.tpl.ps1 = scripts/install.as.tpl.ps1
rename.csx = scripts/rename.csx
resharper.full.ps1 = scripts/resharper.full.ps1
switcher.freesql.json = scripts/switcher.freesql.json
switcher.furion.json = scripts/switcher.furion.json
switcher.nsext.json = scripts/switcher.nsext.json
switcher.ps1 = scripts/switcher.ps1
switch.nuget.or.project.csx = scripts/switch.nuget.or.project.csx
sync.sln.files.csx = scripts/sync.sln.files.csx
wait.server.stop.sh = scripts/wait.server.stop.sh
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{1129FE25-466B-4F4F-85FC-3752664245E1}"
@ -55,6 +54,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{3C6F049E-3EE8-4D66-9AFF-E8A369032487}"
ProjectSection(SolutionItems) = preProject
nightly-build.yml = .github/workflows/nightly-build.yml
README.md = .github/workflows/README.md
release.yml = .github/workflows/release.yml
EndProjectSection
EndProject
@ -67,29 +67,29 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{8E4C93BA
stylecop.analyzers.ruleset = build/stylecop.analyzers.ruleset
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetAdmin.Infrastructure", "src\backend\NetAdmin.Infrastructure\NetAdmin.Infrastructure.csproj", "{1E62C322-EE42-4699-A6F1-791C53EFA62D}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetAdmin.Infrastructure", "src\backend\NetAdmin\NetAdmin.Infrastructure\NetAdmin.Infrastructure.csproj", "{1E62C322-EE42-4699-A6F1-791C53EFA62D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetAdmin.AdmServer.Application", "src\backend\NetAdmin.AdmServer.Application\NetAdmin.AdmServer.Application.csproj", "{E38B2EB4-D7A5-4777-9236-3B348919DF23}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YourSolution.AdmServer.Application", "src\backend\YourSolution.AdmServer.Application\YourSolution.AdmServer.Application.csproj", "{E38B2EB4-D7A5-4777-9236-3B348919DF23}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetAdmin.AdmServer.Host", "src\backend\NetAdmin.AdmServer.Host\NetAdmin.AdmServer.Host.csproj", "{CE895E44-EEC3-4ECE-A56A-8A82E7D863E3}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YourSolution.AdmServer.Host", "src\backend\YourSolution.AdmServer.Host\YourSolution.AdmServer.Host.csproj", "{CE895E44-EEC3-4ECE-A56A-8A82E7D863E3}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "03.hosted-servers", "03.hosted-servers", "{12AE5B4B-CB1A-498E-83B8-04E201E31D86}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetAdmin.Domain", "src\backend\NetAdmin.Domain\NetAdmin.Domain.csproj", "{58509C57-09FA-4E3C-BC07-78E786A2A326}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetAdmin.Domain", "src\backend\NetAdmin\NetAdmin.Domain\NetAdmin.Domain.csproj", "{58509C57-09FA-4E3C-BC07-78E786A2A326}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetAdmin.Application", "src\backend\NetAdmin.Application\NetAdmin.Application.csproj", "{70C54E1B-2083-4196-AB68-34CAF0075D82}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetAdmin.Application", "src\backend\NetAdmin\NetAdmin.Application\NetAdmin.Application.csproj", "{70C54E1B-2083-4196-AB68-34CAF0075D82}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetAdmin.Host", "src\backend\NetAdmin.Host\NetAdmin.Host.csproj", "{91839A15-D08F-4848-A301-F793412BC688}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetAdmin.Host", "src\backend\NetAdmin\NetAdmin.Host\NetAdmin.Host.csproj", "{91839A15-D08F-4848-A301-F793412BC688}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetAdmin.Cache", "src\backend\NetAdmin.Cache\NetAdmin.Cache.csproj", "{91452C22-4B57-4F16-9AF6-42C7BF830504}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetAdmin.Cache", "src\backend\NetAdmin\NetAdmin.Cache\NetAdmin.Cache.csproj", "{91452C22-4B57-4F16-9AF6-42C7BF830504}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetAdmin.AdmServer.Cache", "src\backend\NetAdmin.AdmServer.Cache\NetAdmin.AdmServer.Cache.csproj", "{7CB632D3-3635-4F8D-AFE7-F496D37D422B}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YourSolution.AdmServer.Cache", "src\backend\YourSolution.AdmServer.Cache\YourSolution.AdmServer.Cache.csproj", "{7CB632D3-3635-4F8D-AFE7-F496D37D422B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetAdmin.SysComponent.Host", "src\backend\NetAdmin.SysComponent.Host\NetAdmin.SysComponent.Host.csproj", "{C2CC1596-3BEE-43EA-A9BE-4EDE5716296C}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetAdmin.SysComponent.Host", "src\backend\NetAdmin\NetAdmin.SysComponent.Host\NetAdmin.SysComponent.Host.csproj", "{C2CC1596-3BEE-43EA-A9BE-4EDE5716296C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetAdmin.SysComponent.Cache", "src\backend\NetAdmin.SysComponent.Cache\NetAdmin.SysComponent.Cache.csproj", "{19872A4C-3C9A-4C62-A33B-74F5B8D6F77C}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetAdmin.SysComponent.Cache", "src\backend\NetAdmin\NetAdmin.SysComponent.Cache\NetAdmin.SysComponent.Cache.csproj", "{19872A4C-3C9A-4C62-A33B-74F5B8D6F77C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetAdmin.SysComponent.Application", "src\backend\NetAdmin.SysComponent.Application\NetAdmin.SysComponent.Application.csproj", "{34650E82-D257-46DA-BD6B-DE307113347B}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetAdmin.SysComponent.Application", "src\backend\NetAdmin\NetAdmin.SysComponent.Application\NetAdmin.SysComponent.Application.csproj", "{34650E82-D257-46DA-BD6B-DE307113347B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "02.components", "02.components", "{3F23258D-8299-4992-9F51-2EE9B52CF9D2}"
EndProject
@ -97,10 +97,33 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "01.frameworks", "01.framewo
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "04.tests", "04.tests", "{89260294-80FC-49F1-8D73-AECD39AFF2B7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetAdmin.AdmServer.Tests", "src\backend\NetAdmin.AdmServer.Tests\NetAdmin.AdmServer.Tests.csproj", "{C7F27698-DA05-4ACD-B0D7-4791B3972002}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "05.tools", "05.tools", "{79409163-5006-405D-AC96-406FA0AD77B7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetAdmin.Tests", "src\backend\NetAdmin.Tests\NetAdmin.Tests.csproj", "{00604162-C444-478B-B773-3AB23C856CA7}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnitTests", "src\backend\UnitTests\UnitTests.csproj", "{C7F27698-DA05-4ACD-B0D7-4791B3972002}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetAdmin.Tests", "src\backend\NetAdmin\NetAdmin.Tests\NetAdmin.Tests.csproj", "{00604162-C444-478B-B773-3AB23C856CA7}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docker", "docker", "{E80A1018-C354-4A26-9029-8847BB9DA864}"
ProjectSection(SolutionItems) = preProject
README.md = docker/README.md
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetAdmin.SysComponent.Domain", "src\backend\NetAdmin\NetAdmin.SysComponent.Domain\NetAdmin.SysComponent.Domain.csproj", "{51D6E603-0749-4A11-A78C-9E5BB127E03A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YourSolution.AdmServer.Domain", "src\backend\YourSolution.AdmServer.Domain\YourSolution.AdmServer.Domain.csproj", "{932520DF-D312-415A-A128-1117F8221D68}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "YourSolution.AdmServer.Infrastructure", "src\backend\YourSolution.AdmServer.Infrastructure\YourSolution.AdmServer.Infrastructure.csproj", "{C3DE6F6A-D1FC-4B8E-9033-980FBEBBD2BA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetAdmin.SysComponent.Infrastructure", "src\backend\NetAdmin\NetAdmin.SysComponent.Infrastructure\NetAdmin.SysComponent.Infrastructure.csproj", "{48EE6FC4-B64A-40D3-B889-36837E067880}"
EndProject
##Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Gurion", "refs\Gurion\src\Gurion\Gurion.csproj", "{CCD098FE-4F95-4FA4-8CC0-9A6DE921FBAE}"#refs
##EndProject#refs
##Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSql", "refs\FreeSql\FreeSql\FreeSql.csproj", "{3C65DA42-877D-46FF-B754-C12214302A29}"#refs
##EndProject#refs
##Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSql.Provider.Sqlite", "refs\FreeSql\Providers\FreeSql.Provider.Sqlite\FreeSql.Provider.Sqlite.csproj", "{CF5EFA63-4631-4A64-B4F3-98A7DD532F68}"#refs
##EndProject#refs
##Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSql.DbContext", "refs\FreeSql\FreeSql.DbContext\FreeSql.DbContext.csproj", "{FE03DF27-EC56-48DB-81B0-F99947259A7C}"#refs
##EndProject#refs
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -162,6 +185,38 @@ Global
{00604162-C444-478B-B773-3AB23C856CA7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{00604162-C444-478B-B773-3AB23C856CA7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{00604162-C444-478B-B773-3AB23C856CA7}.Release|Any CPU.Build.0 = Release|Any CPU
{51D6E603-0749-4A11-A78C-9E5BB127E03A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{51D6E603-0749-4A11-A78C-9E5BB127E03A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{51D6E603-0749-4A11-A78C-9E5BB127E03A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{51D6E603-0749-4A11-A78C-9E5BB127E03A}.Release|Any CPU.Build.0 = Release|Any CPU
{932520DF-D312-415A-A128-1117F8221D68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{932520DF-D312-415A-A128-1117F8221D68}.Debug|Any CPU.Build.0 = Debug|Any CPU
{932520DF-D312-415A-A128-1117F8221D68}.Release|Any CPU.ActiveCfg = Release|Any CPU
{932520DF-D312-415A-A128-1117F8221D68}.Release|Any CPU.Build.0 = Release|Any CPU
{C3DE6F6A-D1FC-4B8E-9033-980FBEBBD2BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C3DE6F6A-D1FC-4B8E-9033-980FBEBBD2BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C3DE6F6A-D1FC-4B8E-9033-980FBEBBD2BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C3DE6F6A-D1FC-4B8E-9033-980FBEBBD2BA}.Release|Any CPU.Build.0 = Release|Any CPU
{48EE6FC4-B64A-40D3-B889-36837E067880}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{48EE6FC4-B64A-40D3-B889-36837E067880}.Debug|Any CPU.Build.0 = Debug|Any CPU
{48EE6FC4-B64A-40D3-B889-36837E067880}.Release|Any CPU.ActiveCfg = Release|Any CPU
{48EE6FC4-B64A-40D3-B889-36837E067880}.Release|Any CPU.Build.0 = Release|Any CPU
##{CCD098FE-4F95-4FA4-8CC0-9A6DE921FBAE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
##{CCD098FE-4F95-4FA4-8CC0-9A6DE921FBAE}.Debug|Any CPU.Build.0 = Debug|Any CPU
##{CCD098FE-4F95-4FA4-8CC0-9A6DE921FBAE}.Release|Any CPU.ActiveCfg = Release|Any CPU
##{CCD098FE-4F95-4FA4-8CC0-9A6DE921FBAE}.Release|Any CPU.Build.0 = Release|Any CPU
##{3C65DA42-877D-46FF-B754-C12214302A29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
##{3C65DA42-877D-46FF-B754-C12214302A29}.Debug|Any CPU.Build.0 = Debug|Any CPU
##{3C65DA42-877D-46FF-B754-C12214302A29}.Release|Any CPU.ActiveCfg = Release|Any CPU
##{3C65DA42-877D-46FF-B754-C12214302A29}.Release|Any CPU.Build.0 = Release|Any CPU
##{CF5EFA63-4631-4A64-B4F3-98A7DD532F68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
##{CF5EFA63-4631-4A64-B4F3-98A7DD532F68}.Debug|Any CPU.Build.0 = Debug|Any CPU
##{CF5EFA63-4631-4A64-B4F3-98A7DD532F68}.Release|Any CPU.ActiveCfg = Release|Any CPU
##{CF5EFA63-4631-4A64-B4F3-98A7DD532F68}.Release|Any CPU.Build.0 = Release|Any CPU
##{FE03DF27-EC56-48DB-81B0-F99947259A7C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
##{FE03DF27-EC56-48DB-81B0-F99947259A7C}.Debug|Any CPU.Build.0 = Debug|Any CPU
##{FE03DF27-EC56-48DB-81B0-F99947259A7C}.Release|Any CPU.ActiveCfg = Release|Any CPU
##{FE03DF27-EC56-48DB-81B0-F99947259A7C}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{4DAF9366-855F-46BB-AE4C-660C92FA0697} = {C84EB5A0-37AD-4B17-A51E-E36888C4441E}
@ -178,10 +233,15 @@ Global
{CE895E44-EEC3-4ECE-A56A-8A82E7D863E3} = {12AE5B4B-CB1A-498E-83B8-04E201E31D86}
{89260294-80FC-49F1-8D73-AECD39AFF2B7} = {4DAF9366-855F-46BB-AE4C-660C92FA0697}
{C7F27698-DA05-4ACD-B0D7-4791B3972002} = {89260294-80FC-49F1-8D73-AECD39AFF2B7}
{3C6F049E-3EE8-4D66-9AFF-E8A369032487} = {1129FE25-466B-4F4F-85FC-3752664245E1}
{00604162-C444-478B-B773-3AB23C856CA7} = {D9C3EF66-2757-473D-A26B-54FD08DA203F}
{34650E82-D257-46DA-BD6B-DE307113347B} = {3F23258D-8299-4992-9F51-2EE9B52CF9D2}
{19872A4C-3C9A-4C62-A33B-74F5B8D6F77C} = {3F23258D-8299-4992-9F51-2EE9B52CF9D2}
{C2CC1596-3BEE-43EA-A9BE-4EDE5716296C} = {3F23258D-8299-4992-9F51-2EE9B52CF9D2}
{79409163-5006-405D-AC96-406FA0AD77B7} = {4DAF9366-855F-46BB-AE4C-660C92FA0697}
{51D6E603-0749-4A11-A78C-9E5BB127E03A} = {3F23258D-8299-4992-9F51-2EE9B52CF9D2}
{932520DF-D312-415A-A128-1117F8221D68} = {12AE5B4B-CB1A-498E-83B8-04E201E31D86}
{C3DE6F6A-D1FC-4B8E-9033-980FBEBBD2BA} = {12AE5B4B-CB1A-498E-83B8-04E201E31D86}
{48EE6FC4-B64A-40D3-B889-36837E067880} = {3F23258D-8299-4992-9F51-2EE9B52CF9D2}
{3C6F049E-3EE8-4D66-9AFF-E8A369032487} = {1129FE25-466B-4F4F-85FC-3752664245E1}
EndGlobalSection
EndGlobal

View File

@ -27,6 +27,256 @@
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_ACCESSOR_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_FIELD_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/PLACE_RECORD_FIELD_ATTRIBUTE_ON_SAME_LINE_EX/@EntryValue">NEVER</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AD/@EntryIndexedValue">AD</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AE/@EntryIndexedValue">AE</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AF/@EntryIndexedValue">AF</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AG/@EntryIndexedValue">AG</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AI/@EntryIndexedValue">AI</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AL/@EntryIndexedValue">AL</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AM/@EntryIndexedValue">AM</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AO/@EntryIndexedValue">AO</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AQ/@EntryIndexedValue">AQ</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AR/@EntryIndexedValue">AR</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AS/@EntryIndexedValue">AS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AT/@EntryIndexedValue">AT</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AU/@EntryIndexedValue">AU</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AW/@EntryIndexedValue">AW</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AX/@EntryIndexedValue">AX</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=AZ/@EntryIndexedValue">AZ</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BA/@EntryIndexedValue">BA</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BB/@EntryIndexedValue">BB</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BD/@EntryIndexedValue">BD</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BE/@EntryIndexedValue">BE</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BF/@EntryIndexedValue">BF</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BG/@EntryIndexedValue">BG</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BH/@EntryIndexedValue">BH</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BI/@EntryIndexedValue">BI</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BJ/@EntryIndexedValue">BJ</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BL/@EntryIndexedValue">BL</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BM/@EntryIndexedValue">BM</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BN/@EntryIndexedValue">BN</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BO/@EntryIndexedValue">BO</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BQ/@EntryIndexedValue">BQ</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BR/@EntryIndexedValue">BR</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BS/@EntryIndexedValue">BS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BT/@EntryIndexedValue">BT</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BV/@EntryIndexedValue">BV</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BW/@EntryIndexedValue">BW</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BY/@EntryIndexedValue">BY</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=BZ/@EntryIndexedValue">BZ</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CA/@EntryIndexedValue">CA</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CC/@EntryIndexedValue">CC</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CD/@EntryIndexedValue">CD</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CF/@EntryIndexedValue">CF</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CG/@EntryIndexedValue">CG</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CH/@EntryIndexedValue">CH</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CI/@EntryIndexedValue">CI</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CK/@EntryIndexedValue">CK</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CL/@EntryIndexedValue">CL</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CM/@EntryIndexedValue">CM</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CN/@EntryIndexedValue">CN</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CO/@EntryIndexedValue">CO</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CR/@EntryIndexedValue">CR</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CU/@EntryIndexedValue">CU</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CV/@EntryIndexedValue">CV</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CW/@EntryIndexedValue">CW</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CX/@EntryIndexedValue">CX</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CY/@EntryIndexedValue">CY</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=CZ/@EntryIndexedValue">CZ</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DE/@EntryIndexedValue">DE</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DJ/@EntryIndexedValue">DJ</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DK/@EntryIndexedValue">DK</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DM/@EntryIndexedValue">DM</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DO/@EntryIndexedValue">DO</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=DZ/@EntryIndexedValue">DZ</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=EC/@EntryIndexedValue">EC</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=EE/@EntryIndexedValue">EE</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=EG/@EntryIndexedValue">EG</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=EH/@EntryIndexedValue">EH</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ER/@EntryIndexedValue">ER</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ES/@EntryIndexedValue">ES</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ET/@EntryIndexedValue">ET</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=FI/@EntryIndexedValue">FI</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=FJ/@EntryIndexedValue">FJ</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=FK/@EntryIndexedValue">FK</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=FM/@EntryIndexedValue">FM</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=FO/@EntryIndexedValue">FO</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=FR/@EntryIndexedValue">FR</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GA/@EntryIndexedValue">GA</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GB/@EntryIndexedValue">GB</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GD/@EntryIndexedValue">GD</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GE/@EntryIndexedValue">GE</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GF/@EntryIndexedValue">GF</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GG/@EntryIndexedValue">GG</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GH/@EntryIndexedValue">GH</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GI/@EntryIndexedValue">GI</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GL/@EntryIndexedValue">GL</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GM/@EntryIndexedValue">GM</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GN/@EntryIndexedValue">GN</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GP/@EntryIndexedValue">GP</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GQ/@EntryIndexedValue">GQ</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GR/@EntryIndexedValue">GR</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GS/@EntryIndexedValue">GS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GT/@EntryIndexedValue">GT</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GU/@EntryIndexedValue">GU</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GW/@EntryIndexedValue">GW</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=GY/@EntryIndexedValue">GY</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=HK/@EntryIndexedValue">HK</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=HM/@EntryIndexedValue">HM</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=HN/@EntryIndexedValue">HN</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=HR/@EntryIndexedValue">HR</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=HT/@EntryIndexedValue">HT</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=HU/@EntryIndexedValue">HU</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ID/@EntryIndexedValue">ID</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IE/@EntryIndexedValue">IE</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IL/@EntryIndexedValue">IL</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IM/@EntryIndexedValue">IM</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IN/@EntryIndexedValue">IN</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IO/@EntryIndexedValue">IO</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IQ/@EntryIndexedValue">IQ</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IR/@EntryIndexedValue">IR</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IS/@EntryIndexedValue">IS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=IT/@EntryIndexedValue">IT</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=JE/@EntryIndexedValue">JE</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=JM/@EntryIndexedValue">JM</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=JO/@EntryIndexedValue">JO</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=JP/@EntryIndexedValue">JP</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=KE/@EntryIndexedValue">KE</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=KG/@EntryIndexedValue">KG</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=KH/@EntryIndexedValue">KH</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=KI/@EntryIndexedValue">KI</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=KM/@EntryIndexedValue">KM</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=KN/@EntryIndexedValue">KN</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=KP/@EntryIndexedValue">KP</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=KR/@EntryIndexedValue">KR</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=KW/@EntryIndexedValue">KW</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=KY/@EntryIndexedValue">KY</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=KZ/@EntryIndexedValue">KZ</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LA/@EntryIndexedValue">LA</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LB/@EntryIndexedValue">LB</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LC/@EntryIndexedValue">LC</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LI/@EntryIndexedValue">LI</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LK/@EntryIndexedValue">LK</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LR/@EntryIndexedValue">LR</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LS/@EntryIndexedValue">LS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LT/@EntryIndexedValue">LT</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LU/@EntryIndexedValue">LU</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LV/@EntryIndexedValue">LV</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LY/@EntryIndexedValue">LY</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MA/@EntryIndexedValue">MA</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MC/@EntryIndexedValue">MC</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MD/@EntryIndexedValue">MD</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ME/@EntryIndexedValue">ME</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MF/@EntryIndexedValue">MF</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MG/@EntryIndexedValue">MG</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MH/@EntryIndexedValue">MH</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MK/@EntryIndexedValue">MK</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ML/@EntryIndexedValue">ML</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MM/@EntryIndexedValue">MM</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MN/@EntryIndexedValue">MN</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MO/@EntryIndexedValue">MO</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MP/@EntryIndexedValue">MP</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MQ/@EntryIndexedValue">MQ</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MR/@EntryIndexedValue">MR</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MS/@EntryIndexedValue">MS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MT/@EntryIndexedValue">MT</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MU/@EntryIndexedValue">MU</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MV/@EntryIndexedValue">MV</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MW/@EntryIndexedValue">MW</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MX/@EntryIndexedValue">MX</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MY/@EntryIndexedValue">MY</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=MZ/@EntryIndexedValue">MZ</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=NA/@EntryIndexedValue">NA</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=NC/@EntryIndexedValue">NC</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=NE/@EntryIndexedValue">NE</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=NF/@EntryIndexedValue">NF</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=NG/@EntryIndexedValue">NG</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=NI/@EntryIndexedValue">NI</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=NL/@EntryIndexedValue">NL</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=NO/@EntryIndexedValue">NO</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=NP/@EntryIndexedValue">NP</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=NR/@EntryIndexedValue">NR</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=NU/@EntryIndexedValue">NU</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=NZ/@EntryIndexedValue">NZ</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=OM/@EntryIndexedValue">OM</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=OTP/@EntryIndexedValue">OTP</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PA/@EntryIndexedValue">PA</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PE/@EntryIndexedValue">PE</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PF/@EntryIndexedValue">PF</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PG/@EntryIndexedValue">PG</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PH/@EntryIndexedValue">PH</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PK/@EntryIndexedValue">PK</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PL/@EntryIndexedValue">PL</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PM/@EntryIndexedValue">PM</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PN/@EntryIndexedValue">PN</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PR/@EntryIndexedValue">PR</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PS/@EntryIndexedValue">PS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PT/@EntryIndexedValue">PT</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PW/@EntryIndexedValue">PW</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=PY/@EntryIndexedValue">PY</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=QA/@EntryIndexedValue">QA</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RE/@EntryIndexedValue">RE</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RO/@EntryIndexedValue">RO</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RS/@EntryIndexedValue">RS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RU/@EntryIndexedValue">RU</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RW/@EntryIndexedValue">RW</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SA/@EntryIndexedValue">SA</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SB/@EntryIndexedValue">SB</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SC/@EntryIndexedValue">SC</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SD/@EntryIndexedValue">SD</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SE/@EntryIndexedValue">SE</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SG/@EntryIndexedValue">SG</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SH/@EntryIndexedValue">SH</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SI/@EntryIndexedValue">SI</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SJ/@EntryIndexedValue">SJ</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SK/@EntryIndexedValue">SK</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SL/@EntryIndexedValue">SL</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SM/@EntryIndexedValue">SM</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SN/@EntryIndexedValue">SN</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SO/@EntryIndexedValue">SO</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SR/@EntryIndexedValue">SR</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SS/@EntryIndexedValue">SS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ST/@EntryIndexedValue">ST</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SV/@EntryIndexedValue">SV</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SX/@EntryIndexedValue">SX</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SY/@EntryIndexedValue">SY</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=SZ/@EntryIndexedValue">SZ</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TC/@EntryIndexedValue">TC</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TD/@EntryIndexedValue">TD</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TF/@EntryIndexedValue">TF</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TG/@EntryIndexedValue">TG</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TH/@EntryIndexedValue">TH</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TJ/@EntryIndexedValue">TJ</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TK/@EntryIndexedValue">TK</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TL/@EntryIndexedValue">TL</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TM/@EntryIndexedValue">TM</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TN/@EntryIndexedValue">TN</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TO/@EntryIndexedValue">TO</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TR/@EntryIndexedValue">TR</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TT/@EntryIndexedValue">TT</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TV/@EntryIndexedValue">TV</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TW/@EntryIndexedValue">TW</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=TZ/@EntryIndexedValue">TZ</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=UA/@EntryIndexedValue">UA</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=UG/@EntryIndexedValue">UG</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=UM/@EntryIndexedValue">UM</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=US/@EntryIndexedValue">US</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=UY/@EntryIndexedValue">UY</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=UZ/@EntryIndexedValue">UZ</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=VA/@EntryIndexedValue">VA</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=VC/@EntryIndexedValue">VC</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=VE/@EntryIndexedValue">VE</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=VG/@EntryIndexedValue">VG</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=VI/@EntryIndexedValue">VI</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=VN/@EntryIndexedValue">VN</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=VU/@EntryIndexedValue">VU</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=WF/@EntryIndexedValue">WF</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=WS/@EntryIndexedValue">WS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=YE/@EntryIndexedValue">YE</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=YT/@EntryIndexedValue">YT</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ZA/@EntryIndexedValue">ZA</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ZM/@EntryIndexedValue">ZM</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=ZW/@EntryIndexedValue">ZW</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=15b5b1f1_002D457c_002D4ca6_002Db278_002D5615aedc07d3/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Static" AccessRightKinds="Private" Description="Static readonly fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="READONLY_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=236f7aa5_002D7b06_002D43ca_002Dbf2a_002D9b31bfcff09a/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Private" Description="Constant fields (private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="CONSTANT_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="_" Suffix="" Style="AA_BB" /&gt;&lt;/Policy&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/UserRules/=669e5282_002Dfb4b_002D4e90_002D91e7_002D07d269d04b60/@EntryIndexedValue">&lt;Policy&gt;&lt;Descriptor Staticness="Any" AccessRightKinds="Protected, ProtectedInternal, Internal, Public, PrivateProtected" Description="Constant fields (not private)"&gt;&lt;ElementKinds&gt;&lt;Kind Name="CONSTANT_FIELD" /&gt;&lt;/ElementKinds&gt;&lt;/Descriptor&gt;&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /&gt;&lt;/Policy&gt;</s:String>
@ -78,6 +328,7 @@
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002EMemberReordering_002EMigrations_002ECSharpFileLayoutPatternRemoveIsAttributeUpgrade/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EPredefinedNamingRulesToUserRulesUpgrade/@EntryIndexedValue">True</s:Boolean>

133
README.md
View File

@ -2,112 +2,107 @@
通用后台权限管理系统、快速开发框架基于C#12/.NET9、Vue3/Vite、Element Plus等现代技术构建具有十分整洁、优雅的编码规范
[![.NET](https://github.com/nsnail/NetAdmin/actions/workflows/ci.yml/badge.svg)](https://github.com/nsnail/NetAdmin/actions/workflows/ci.yml)
[![.NET](https://github.com/nsnail/NetAdmin/actions/workflows/nightly-build.yml/badge.svg)](https://github.com/nsnail/NetAdmin/actions/workflows/nightly-build.yml)
[![MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/nsnail/NetAdmin/blob/main/LICENSE)
[![Furion](https://img.shields.io/badge/Furion-4.x-blueviolet.svg)](https://github.com/nsnail/NetAdmin/blob/main/LICENSE)
[![FreeSql](https://img.shields.io/badge/FreeSql-3.x-orange.svg)](https://github.com/nsnail/NetAdmin/blob/main/LICENSE)
## 在线预览
http://na.yaopy.com 演示站点仅300kbps带宽访问较慢
https://na.tools92.top
## 一键运行
```shell
docker run -p 8080:8080 nsnail/netadmin
# 需魔法上网
```
## 构建步骤
- 后端
1. 检查dotnet-sdk版本>=9.0.0
``` shell
dotnet --list-sdks
```shell
# 1. 检查 dotnet sdk 版本 >=9.0.0
dotnet --list-sdks
# 下载 dotnethttps://dotnet.microsoft.com/zh-cn/download/dotnet
# 下载 dotnet https://dotnet.microsoft.com/zh-cn/download/dotnet
```
2. 克隆代码仓库
``` shell
git clone https://github.com/nsnail/NetAdmin.git
cd ./NetAdmin
# 2. 克隆代码仓库
git clone https://github.com/nsnail/NetAdmin.git && cd ./NetAdmin
# 下载 git https://git-scm.com/downloads
```
3. 确保本机redis处于运行状态
``` shell
redis-cli
# 3. 确认本机 redis 处于运行状态
redis-server # 启动
redis-cli # 连接测试
# 下载 redis for windowshttps://github.com/redis-windows/redis-windows/releases
# 下载 redis for linux/machttps://redis.io/download
# 下载 redis for windows https://github.com/redis-windows/redis-windows/releases
# 下载 redis for linux/mac https://redis.io/download
```
4. 运行后端WebApi
``` shell
dotnet run --project ./src/backend/NetAdmin.AdmServer.Host/NetAdmin.AdmServer.Host.csproj --urls http://[::]:5010 -is
```
5. 体验WebApi程序
- 浏览器打开 http://localhost:5010 将看到SwaggerKnife4jUI界面
# 4. 运行后端 WebApi
dotnet run --project ./src/backend/YourSolution.AdmServer.Host/YourSolution.AdmServer.Host.csproj --urls http://[::]:5010 -is
# -i 插入种子数据
# -s 同步数据库结构
# 浏览器访问 http://localhost:5010 将看到SwaggerKnife4jUI界面
---
# 5. 检查 nodejs 版本 >=20
node -v
# 下载 nodejshttps://nodejs.org/en/download
- 前端
1. 检查nodejs版本>=20
``` shell
node -v
# 6. 安装 npm 依赖包
cd ./src/frontend/admin && npm install
# 下载 nodejs https://nodejs.org/en/download
```
2. 安装npm依赖包
``` shell
cd ./src/frontend/admin
npm install
```
3. 运行前端项目
``` shell
npm run dev
```
4. 体验前端程序
- 浏览器打开 http://localhost:5020 将看到管理界面默认用户名root密码1234qwer
# 7. 运行前端项目
npm run dev
# 浏览器访问 http://localhost:5020 将看到管理界面默认用户名密码root 1234qwer
```
## 文件目录
## 文件目录
```
+---.github # github 工程文件目录
+---.template.config # dotnet 项目模板配置目录
+---assets # 程序运行需要的资源文件目录
+---dist # 程序编译与分发的二进制文件目录
+---docs # 项目文档目录
+---refs # 引用的第三方项目仓库目录
+---src # 项目源文件目录
+---assets # 项目资源文件目录
+---build # 构建相关的工程文件目录
+---dist # 编译生成的二进制文件目录
+---docker # docker 镜像构建文件目录
+---docs # 项目开发文档目录
+---refs # 引用的第三方包的仓库目录
+---scripts # 各种工具脚本文件目录
+---src # 项目源码文件目录
```
## 后端项目架构
## 项目架构
```mermaid
flowchart TD
H["NetAdmin.Host\n公共主机层\n.Net自托管主机程序\n输入输出格式化\n数据校验、鉴权\n...所有HTTP管道过滤器中间件"] --> C["NetAdmin.Cache\n公共缓存层\n基于Redis或MemoryCache的缓存策略实现"]
C --> A["NetAdmin.Application\n公共业务逻辑层\n内部服务增删改查\n外部服务增删改查\n...所有业务用例的计算与组合逻辑的模块化"]
A --> D["NetAdmin.Domain\n数据实体层\n数据库关系实体映射\nDTO数据传输对象\n...所有数据模型的抽象与封装"]
D --> I["NetAdmin.Infrastructure\n基础设施层\n第三方组件和Nuget包引用\n公共构建和程序运行配置\n公共常量枚举异常定义\n全球化化和多语言\n...所有公共Utility工具"]
XH["NetAdmin.XXX.Host\nWebApi"]-->H
XS["NetAdmin.XXXService\n常驻内存服务"]-->H
XS["NetAdmin.XXXService\n常驻内存服务"]-->XC
XC["NetAdmin.XXX.Cache\n缓存层实例"]-->C
XA["NetAdmin.XXX.Application\n业务逻辑层实例"]-->A
XH-->XC
XC-->XA
sys-host["NetAdmin.SysComponent.Host\n系统组件主机层"]
sys-cache["NetAdmin.SysComponent.Cache\n系统组件缓存层"]
sys-app["NetAdmin.SysComponent.Application\n系统组件应用层"]
sys-domain["NetAdmin.SysComponent.Domain\n系统组件数据实体层"]
sys-infra["NetAdmin.SysComponent.Infrastructure\n系统组件基础设施层"]
host["NetAdmin.Host\n框架:主机层\n.Net自托管主机程序\n输入输出格式化\n数据校验、鉴权\n...所有HTTP管道过滤器中间件"]
cache["NetAdmin.Cache\n框架缓存层\n基于Redis或MemoryCache的缓存策略实现"]
app["NetAdmin.Application\n框架业务应用层\n内部服务增删改查\n外部服务增删改查\n...所有业务用例的计算与组合逻辑的模块化)"]
domain["NetAdmin.Domain\n框架数据实体层\n数据库关系实体映射\nDTO数据传输对象\n...所有数据模型的抽象与封装)"]
infra["NetAdmin.Infrastructure\n框架基础设施层\n第三方组件和Nuget包引用\n公共构建和程序运行配置\n公共常量枚举异常定义\n全球化化和多语言\n...所有公共Utility工具"]
biz-host["YourSolution.XXX.Host\n业务实例主机层"]
biz-cache["YourSolution.XXX.Cache\n业务实例缓存层"]
biz-app["YourSolution.XXX.Application\n业务实例应用层"]
biz-domain["YourSolution.XXX.Domain\n业务实例数据实体层"]
biz-infra["YourSolution.XXX.Infrastructure\n业务实例基础设施层"]
biz-host-->biz-cache-->biz-app-->biz-domain-->biz-infra
sys-host-->sys-cache-->sys-app-->sys-domain-->sys-infra
host-->cache-->app-->domain-->infra
biz-host-->sys-host-->host
biz-cache-->sys-cache-->cache
biz-app-->sys-app-->app
biz-domain-->sys-domain-->domain
biz-infra-->sys-infra-->infra
```
## 引用的开源代码 / 特别鸣谢
## 特别鸣谢
| 语言 | 集成领域 | 开源库 |
|------------|---------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| C# | Web基础框架 | [ASP.NET Core](https://github.com/dotnet/aspnetcore) |
| C# | 快速开发脚手架 | [Furion](https://gitee.com/dotnetchina/Furion) |
| C# | 数据库关系映射 | [FreeSql](https://github.com/dotnetcore/FreeSql) |
| C# | 代码质量检查 | [Roslynator.Analyzers](https://github.com/josefpihrt/roslynator) \| [SonarAnalyzer.CSharp](https://github.com/SonarSource/sonar-dotnet) \| [StyleCop.Analyzers](https://github.com/DotNetAnalyzers/StyleCopAnalyzers) |
| C# | 单元测试框架 | [xunit](https://github.com/xunit/xunit) \| [coverlet.collector](https://github.com/coverlet-coverage/coverlet) |
| C# | 分布式锁 | [RedLock.net](https://github.com/samcook/RedLock.net) |
| C# | 控制台终端界面库 | [Spectre.Console](https://github.com/spectreconsole/spectre.console) |
| C# | 扩展函数库 | [NSExt](https://github.com/nsnail/ns-ext.git) |
| C# | 图形处理库 | [SixLabors.ImageSharp](https://github.com/SixLabors/ImageSharp) |
@ -115,8 +110,6 @@ XC-->XA
| C# | 性能监控采集 | [prometheus-net.AspNetCore](https://github.com/prometheus-net/prometheus-net) |
| C# | 雪花ID生成器 | [Yitter.IdGenerator](https://github.com/yitter/idgenerator) |
| C# | 自动化版本管理 | [MinVer](https://github.com/adamralph/minver) |
| C# | JavaScript引擎 | [MsieJavaScriptEngine](https://github.com/Taritsyn/MsieJavaScriptEngine) |
| C# | WebApi图形界面 | [IGeekFan.AspNetCore.Knife4jUI](https://github.com/luoyunchong/IGeekFan.AspNetCore.Knife4jUI) |
| TypeScript | SPA基础框架 | [Vue](https://github.com/vuejs/core) |
| TypeScript | 前端构建工具 | [Vite](https://github.com/vitejs/vite) |
| TypeScript | UI控件库 | [Element Plus](https://github.com/element-plus/element-plus) |

249
assets/res/CountryCodes.ln Normal file
View File

@ -0,0 +1,249 @@
不丹
东帝汶
中国
中非
丹麦
乌克兰
乌兹别克斯坦
乌干达
乌拉圭
乍得
也门
亚美尼亚
以色列
伊拉克
伊朗
伯利兹
佛得角
俄罗斯
保加利亚
克罗地亚
关岛
冈比亚
冰岛
几内亚
几内亚比绍
列支敦士登
刚果共和国
刚果民主共和国
利比亚
利比里亚
加拿大
加纳
加蓬
匈牙利
北马其顿
北马里亚纳群岛
南乔治亚和南桑威奇群岛
南极洲
南苏丹
南非
博茨瓦纳
卡塔尔
卢旺达
卢森堡
印度
印度尼西亚
危地马拉
厄瓜多尔
厄立特里亚
叙利亚
古巴
台湾
吉尔吉斯斯坦
吉布提
哈萨克斯坦
哥伦比亚
哥斯达黎加
喀麦隆
图瓦卢
土库曼斯坦
土耳其
圣卢西亚
圣基茨和尼维斯
圣多美和普林西比
圣巴泰勒米
圣文森特和格林纳丁斯
圣皮埃尔和密克隆
圣诞岛
圣赫勒拿
圣马力诺
圭亚那
坦桑尼亚
埃及
埃塞俄比亚
基里巴斯
塔吉克斯坦
塞内加尔
塞尔维亚
塞拉利昂
塞浦路斯
塞舌尔
墨西哥
多哥
多米尼克
多米尼加
奥兰
奥地利
委内瑞拉
孟加拉国
安哥拉
安圭拉
安提瓜和巴布达
安道尔
密克罗尼西亚联邦
尼加拉瓜
尼日利亚
尼日尔
尼泊尔
巴勒斯坦
巴哈马
巴基斯坦
巴巴多斯
巴布亚新几内亚
巴拉圭
巴拿马
巴林
巴西
布基纳法索
布隆迪
布韦岛
希腊
帕劳
库克群岛
库拉索
开曼群岛
德国
意大利
所罗门群岛
托克劳
拉脱维亚
挪威
捷克
摩尔多瓦
摩洛哥
摩纳哥
文莱
斐济
斯威士兰
斯洛伐克
斯洛文尼亚
斯瓦尔巴和扬马延
斯里兰卡
新加坡
新喀里多尼亚
新西兰
日本
智利
朝鲜
柬埔寨
根西
格林纳达
格陵兰
格鲁吉亚
梵蒂冈
比利时
毛里塔尼亚
毛里求斯
汤加
沙特阿拉伯
法国
法属南部和南极领地
法属圣马丁
法属圭亚那
法属波利尼西亚
法罗群岛
波兰
波多黎各
波黑
泰国
泽西
津巴布韦
洪都拉斯
海地
澳大利亚
澳门
爱尔兰
爱沙尼亚
牙买加
特克斯和凯科斯群岛
特立尼达和多巴哥
玻利维亚
瑙鲁
瑞典
瑞士
瓜德罗普
瓦利斯和富图纳
瓦努阿图
留尼汪
白俄罗斯
百慕大
皮特凯恩群岛
直布罗陀
福克兰群岛
科威特
科摩罗
科特迪瓦
科科斯基林群岛
秘鲁
突尼斯
立陶宛
索马里
约旦
纳米比亚
纽埃
缅甸
罗马尼亚
美国
美国本土外小岛屿
美属维尔京群岛
美属萨摩亚
老挝
肯尼亚
芬兰
苏丹
苏里南
英国
英属印度洋领地
英属维尔京群岛
荷兰
荷兰加勒比区
荷属圣马丁
莫桑比克
莱索托
菲律宾
萨尔瓦多
萨摩亚
葡萄牙
蒙古
蒙特塞拉特
西撒哈拉
西班牙
诺福克岛
贝宁
赞比亚
赤道几内亚
赫德岛和麦克唐纳群岛
越南
阿塞拜疆
阿富汗
阿尔及利亚
阿尔巴尼亚
阿曼
阿根廷
阿联酋
阿鲁巴
韩国
香港
马尔代夫
马恩岛
马拉维
马提尼克
马来西亚
马约特
马绍尔群岛
马耳他
马达加斯加
马里
黎巴嫩
黑山

View File

@ -4,7 +4,6 @@
不包含
不排序
不等于
管理模块
丧偶
中专
中共党员
@ -12,79 +11,59 @@
以什么开始
以什么结束
保密
保密
信息
倒序排序
全部数据
公告
共青团员
出生证
初中
删除
包含
博士
博士后
发送失败
同步数据库结构
外国人居留证
外部错误
大专
大于
大于等于
宕机
小于
小于等于
小学
已发送
已婚
已校验
已读
并且
意外错误
成功
或者
手机
护照
指定部门数据
按钮
插入种子数据
无效操作
无效输入
日期范围
未处理异常
未婚
未读
本人数据
本科
本部门和下级部门数据
本部门数据
框架
比较数据库结构
注册
港澳台通行证
电子邮箱
登录
硕士
示例导出
离异
私信
空闲
等于
待发送
等于
管理模块
系统模块
绑定手机号
结果非预期
群众
自定义
范围
菜单
解绑手机号
警告
调试
跟踪
身份证
运行
通知
重设密码
链接
错误
随机排序
顺序排序

View File

@ -0,0 +1,23 @@
6位数字
8位以上数字字母组合
XML注释文件不存在
中文姓名
事务已回滚
事务已提交
区号电话号码分机号
参数格式不正确
开始事务
支付宝账号
数据库同步开始
数据库结构同步完成
无效端口号
无效证件号码
时间表达式
用户名不能是手机号码
用户名长度4位以上
种子数据插入完成
记录已存在
请求对象不能为空
邀请码不正确
配置文件初始化完毕
非JSON字符串

View File

@ -0,0 +1,81 @@
上次执行时间
上次执行状态
上次执行耗时
下次执行时间
人工审核
作业名称
作业状态
全部数据
公告
创建时间
删除
发送失败
响应体
响应状态码
唯一编码
备注
字典内容导出
客户端IP
已发送
已校验
已读
所属角色
所属部门
手机
手机号
执行耗时
执行计划
指定部门数据
按钮
排序
接口名称
接口导出
接口描述
接口路径
操作系统
数据范围
无限权限
是否启用
显示仪表板
最后登录时间
未读
本人数据
本部门和下级部门数据
本部门数据
框架
注册
消息主题
消息摘要
消息类型
用户代理
用户名
用户导出
电子邮箱
登录
登录名
登录日志导出
空闲
站内信导出
等待发送
绑定手机号码
菜单
角色名称
角色导出
解绑手机号码
计划作业导出
计划作业执行记录导出
请求方式
请求日志导出
跟踪标识
运行
通知
邮箱号
部门名称
部门导出
配置导出
重设密码
链接
项值
项名
默认角色
默认部门

View File

@ -1,17 +1,9 @@
1分钟内只能发送1次
6位数字
8位以上数字字母组合
XML注释文件不存在
中文姓名
事务已回滚
事务已提交
人机校验请求不能为空
人机验证未通过
作业名称不能为空
允许的文件大小
允许的文件格式
区号电话号码分机号
参数格式不正确
唯一编码不能为空
图标代码不能为空
图标名称不能为空
@ -19,57 +11,60 @@ XML注释文件不存在
字典名称不能为空
字典目录不存在
字典目录编号不能为空
字典目录编号不能为空
字典编码不能为空
学历不正确
密码不能为空
密码不能为空
密码不能为空
密码不能为空
已处理完毕
开始事务
已处理完毕
已处理完毕
并发冲突_请稍后重试
性别不正确
手机号码不正确
手机号码不能为空
接口编码不存在
支付宝账号
政治面貌不正确
数据库同步开始
数据库服务器时钟偏移
数据库结构同步完成
数据版本不能为空
文件不能为空
新密码不能为空
新手机号码验证码不正确
无效端口号
无效证件号码
日志长度超过限制
旧密码不正确
旧密码不能为空
旧手机号码不正确
旧手机号码验证码不正确
时间戳缺失或误差过大
时间表达式
时间计划不能为空
未指定部门
未获取到待执行任务
模块名称不能为空
模块类型不能为空
模块说明不能为空
此节点已下线
此节点已下线
民族不正确
消息主题不能为空
消息内容不能为空
父节点不存在
用户不存在
用户名不能为空
用户名不能是手机号
用户名不能为空
用户名不能为空
用户名或密码错误
用户名长度4位以上
用户头像不能为空
用户档案不能为空
用户编号不存在
用户编号不能为空
目标设备不能为空
目标设备不能为空
短信验证请求不能为空
短信验证请求不能为空
短信验证请求不能为空
站内信不存在
站内信状态不正确
站内信类型不正确
签名缺失
缓存键不能为空
网络地址不正确
网络地址不正确
网络地址不正确
菜单名称不能为空
菜单标题不能为空
@ -86,18 +81,19 @@ XML注释文件不存在
该部门下存在子部门
该部门下存在用户
请求地址不能为空
请求对象不能为空
请求方法不正确
请稍后重试
请联系管理员激活账号
读取用户令牌出错
账号不能为空
邀请码不正确
邮箱验证码不正确
部门不存在
部门名称不能为空
配置文件初始化完毕
键值不能为空
键名称不能为空
键名称不能为空
随机延时结束时间不正确
随机延时起始时间不正确
验证数据不能为空
验证码不正确
验证码不能为空

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
"ExecutionCron": "0 * * * * ?",
"HttpMethod": 3,
"JobName": "HTTP 请求测试",
"NextExecTime": "2020/9/13 12:26:40",
"NextExecTime": "2020-09-13 12:26:40",
"NextTimeId": 1600000000,
"RequestUrl": "https://httpbin.org/ip",
"Status": 1,

View File

@ -6,7 +6,7 @@
"Id": 373837717815301,
"Name": "home",
"Path": "/home",
"Sort": 100,
"Sort": 999,
"Title": "主控面板",
"Type": 1
},
@ -24,7 +24,7 @@
"Component": "sys/user",
"Icon": "el-icon-user",
"Id": 373837957840901,
"Name": "sys-user",
"Name": "sys/user",
"ParentId": 373837917724677,
"Path": "/sys/user",
"Sort": 100,
@ -35,7 +35,7 @@
"Component": "sys/role",
"Icon": "sc-icon-role",
"Id": 373838018527237,
"Name": "sys-role",
"Name": "sys/role",
"ParentId": 373837917724677,
"Path": "/sys/role",
"Sort": 99,
@ -46,7 +46,7 @@
"Component": "sys/dept",
"Icon": "sc-icon-dept",
"Id": 373838045605893,
"Name": "sys-dept",
"Name": "sys/dept",
"ParentId": 373837917724677,
"Path": "/sys/dept",
"Sort": 98,
@ -57,7 +57,7 @@
"Component": "sys/menu",
"Icon": "el-icon-fold",
"Id": 373838070898693,
"Name": "sys-menu",
"Name": "sys/menu",
"ParentId": 373837917724677,
"Path": "/sys/menu",
"Sort": 97,
@ -78,7 +78,7 @@
"Component": "sys/config",
"Icon": "el-icon-set-up",
"Id": 380415005847557,
"Name": "sys-config",
"Name": "sys/config",
"ParentId": 485278637670422,
"Path": "/sys/config",
"Sort": 100,
@ -89,7 +89,7 @@
"Component": "sys/job",
"Icon": "sc-icon-ScheduledJob",
"Id": 510067557638158,
"Name": "sys-job",
"Name": "sys/job",
"ParentId": 485278637670422,
"Path": "/sys/job",
"Sort": 99,
@ -100,7 +100,7 @@
"Component": "sys/dic",
"Icon": "sc-icon-dic",
"Id": 375315654221829,
"Name": "sys-dic",
"Name": "sys/dic",
"ParentId": 485278637670422,
"Path": "/sys/dic",
"Sort": 98,
@ -111,7 +111,7 @@
"Component": "sys/msg",
"Icon": "el-icon-message",
"Id": 482779610341392,
"Name": "sys-msg",
"Name": "sys/msg",
"ParentId": 485278637670422,
"Path": "/sys/msg",
"Sort": 97,
@ -122,7 +122,7 @@
"Component": "sys/api",
"Icon": "sc-icon-api",
"Id": 397880678895621,
"Name": "sys-api",
"Name": "sys/api",
"ParentId": 485278637670422,
"Path": "/sys/api",
"Sort": 96,
@ -133,7 +133,7 @@
"Component": "sys/cache",
"Icon": "sc-icon-memory",
"Id": 374911555702789,
"Name": "sys-cache",
"Name": "sys/cache",
"ParentId": 485278637670422,
"Path": "/sys/cache",
"Sort": 95,
@ -154,7 +154,7 @@
"Component": "sys/log/operation",
"Icon": "el-icon-pointer",
"Id": 485285246504976,
"Name": "sys-log-operation",
"Name": "sys/log/operation",
"ParentId": 374792687640581,
"Path": "/sys/log/operation",
"Sort": 100,
@ -165,7 +165,7 @@
"Component": "sys/log/login",
"Icon": "sc-icon-OpenDoor",
"Id": 485285246504970,
"Name": "sys-log-login",
"Name": "sys/log/login",
"ParentId": 374792687640581,
"Path": "/sys/log/login",
"Sort": 99,
@ -186,7 +186,7 @@
"Component": "dev/code",
"Icon": "sc-icon-code2",
"Id": 373838147022853,
"Name": "dev-code",
"Name": "dev/code",
"ParentId": 373838105399301,
"Path": "/dev/code",
"Sort": 100,
@ -197,10 +197,20 @@
"Id": 482777529417739,
"ParentId": 373838105399301,
"Icon": "el-icon-eleme-filled",
"Name": "dev-element",
"Path": "https://element-plus.gitee.io/zh-CN/component/button.html",
"Name": "dev/element",
"Path": "http://element-plus.org/zh-CN/component/overview.html",
"Sort": 99,
"Title": "Element",
"Type": 3,
},
{
"Id": 560217289232398,
"ParentId": 373838105399301,
"Icon": "sc-icon-FreeSql",
"Name": "dev/freesql",
"Path": "https://freesql.net/guide",
"Sort": 99,
"Title": "FreeSql",
"Type": 3,
}
]

View File

@ -9,7 +9,7 @@
"Sort": 100
},
{
"DataScope": 1,
"DataScope": 4,
"Enabled": true,
"Id": 371729946431493,
"Name": "普通用户",

View File

@ -14,5 +14,33 @@
{
"ApiId": "api/sys/user",
"RoleId": 371729946431493
},
{
"ApiId": "api/sys/site.msg/unread.count",
"RoleId": 371729946431493,
},
{
"ApiId": "api/sys/site.msg",
"RoleId": 371729946431493,
},
{
"ApiId": "api/sys/site.msg/get.mine",
"RoleId": 371729946431493,
},
{
"ApiId": "api/sys/site.msg/paged.query.mine",
"RoleId": 371729946431493,
},
{
"ApiId": "api/sys/site.msg/set.site.msg.status",
"RoleId": 371729946431493,
},
{
"ApiId": "api/sys/user/get.session.user.app.config",
"RoleId": 371729946431493,
},
{
"ApiId": "api/sys/user/set.session.user.app.config",
"RoleId": 371729946431493,
}
]

View File

@ -1,11 +1,9 @@
[
{
"Id": 396423792566281,
"MenuId": 373837717815301,
"RoleId": 371729946431493
},
{
"Id": 396423792566282,
"MenuId": 374967228141573,
"RoleId": 371729946431493
}

View File

@ -6,5 +6,13 @@
"Password": "A8E87D23-49BC-25A1-1C7C-59186BEF5D15",
"Token": "A9AFD92E-A33D-4152-9A6C-A9C141D24887",
"UserName": "root"
},
{
"DeptId": 372119301627909,
"Enabled": true,
"Id": 560217289236492,
"Password": "A8E87D23-49BC-25A1-1C7C-59186BEF5D15",
"Token": "4208EA97-B32F-4E39-A290-4C0D27B61EBF",
"UserName": "user"
}
]

View File

@ -1,5 +1,10 @@
[
{
"Id": 370942943322181
"Id": 370942943322181,
"AppConfig": "[]"
},
{
"Id": 560217289236492,
"AppConfig": "[]"
}
]

View File

@ -2,5 +2,9 @@
{
"RoleId": 370943613149253,
"UserId": 370942943322181
},
{
"RoleId": 371729946431493,
"UserId": 560217289236492
}
]

View File

@ -15,15 +15,15 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.10.12-preview">
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.12.19">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Roslynator.Analyzers" Version="4.12.2">
<PackageReference Include="Roslynator.Analyzers" Version="4.12.9">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="SonarAnalyzer.CSharp" Version="9.24.0.89429">
<PackageReference Include="SonarAnalyzer.CSharp" Version="9.32.0.97167">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View File

@ -9,22 +9,4 @@
Command="dotnet t4 ./gen.cs.tt -o ../dist/backend/$(ProjectName)/Ln.cs"
StdOutEncoding="utf-8" />
</Target>
<ItemGroup>
<None Include="$(SolutionDir)/assets/res/Statements.ln">
<Link>Languages/Statements.ln</Link>
</None>
<None Include="$(SolutionDir)/assets/res/Nations.ln">
<Link>Languages/Nations.ln</Link>
</None>
<None Include="$(SolutionDir)/assets/res/Enums.ln">
<Link>Languages/Enums.ln</Link>
</None>
<EmbeddedResource Include="$(SolutionDir)/assets/res/Ln.resx">
<Link>Languages/Ln.resx</Link>
<Generator>PublicResXFileCodeGenerator</Generator>
</EmbeddedResource>
<Compile Include="$(SolutionDir)/dist/backend/$(ProjectName)/Ln.Designer.cs">
<Link>Languages/Ln.Designer.cs</Link>
</Compile>
</ItemGroup>
</Project>

1
docker/README.md Normal file
View File

@ -0,0 +1 @@
docker

View File

@ -3,7 +3,7 @@
"isRoot": true,
"tools": {
"dotnet-t4": {
"version": "2.3.1",
"version": "3.0.0",
"commands": [
"t4"
]

View File

@ -1,9 +1,9 @@
{
"version": "1.1.1",
"version": "2.1.0",
"devDependencies": {
"cz-git": "^1.9.1",
"commitizen": "^4.3.0",
"prettier": "^3.2.5",
"cz-git": "^1.11.0",
"commitizen": "^4.3.1",
"prettier": "^3.3.3",
"standard-version": "^9.5.0"
},
"config": {

Submodule refs/Furion deleted from d23c7cca55

1
refs/Gurion Submodule

Submodule refs/Gurion added at d54b0b7cf8

View File

@ -20,8 +20,10 @@ git tag -d $tag
git tag $tag
git push --tags origin release
Start-Process -FilePath "https://github.com/nsnail/NetAdmin/compare/main...release"
Write-Host "按『Enter』回到分支『Ctrl+C』退出"
Write-Host "按『Enter』回到tk分支『Ctrl+C』退出"
Pause
git checkout main
git pull
git branch -D release
git branch -D tk
git checkout -b tk

View File

@ -0,0 +1,2 @@
git push origin :refs/tags/$(git tag -l "*-*")
git tag -d $(git tag -l "*-*")

View File

@ -1,6 +1,7 @@
<#@ template language="C#" #>
<#@ output encoding="utf-8" extension="resx" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text.RegularExpressions" #>
<?xml version="1.0" encoding="utf-8"?>
<root>
@ -28,14 +29,11 @@
</resheader>
<#
var regex = new Regex(@"^\d", RegexOptions.Compiled);
foreach (var file in Directory.GetFiles("../assets/res/", "*.ln"))
foreach (var line in Directory.GetFiles("../assets/res/", "*.ln").SelectMany(x => File.ReadLines(x)).Distinct())
{
foreach (var line in File.ReadLines(file))
{
#>
<data name="<#= regex.IsMatch(line) ? "_" : "" #><#= line #>" xml:space="preserve"><value><#= line #></value></data>
<#
}
}
#>
</root>

View File

@ -1,4 +1,4 @@
#r "nuget: NSExt, 2.1.0"
#r "nuget: NSExt, 2.2.0"
using NSExt.Extensions;
Console.WriteLine("请输入原始名称NetAdmin");

View File

@ -0,0 +1,42 @@
using System.Text.RegularExpressions;
string input = string.Empty;
while (!new[] { "1", "2" }.Contains(input))
{
Console.WriteLine("1.nuget 2.project");
input = Console.ReadLine();
}
var slnFile = Directory.GetFiles(@"../", "*.sln").First();
var csprojFiles = Directory.GetFiles(@"../src", "*.csproj", new EnumerationOptions { RecurseSubdirectories = true });
var slnContent = File.ReadAllText(slnFile);
if (input == "1")
{
slnContent = Regex.Replace(slnContent, "\\nProject\\((.*)#refs", "\n##Project($1#refs");
slnContent = Regex.Replace(slnContent, "\\nEndProject#refs", "\n##EndProject#refs");
foreach (Match m in Regex.Matches(slnContent, "\"(\\{[A-Z0-9]{8}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{12}\\})\"#refs"))
{
slnContent = slnContent.Replace($" {m.Groups[1].Value}.", $" ##{m.Groups[1].Value}.");
}
foreach (var csprojFile in csprojFiles)
{
var csprojContent = File.ReadAllText(csprojFile);
csprojContent = Regex.Replace(csprojContent," <ProjectReference(.*)Label=\"refs\"(.*)>", " <!--<ProjectReference$1Label=\"refs\"$2>-->");
csprojContent = Regex.Replace(csprojContent," <!--<PackageReference(.*)Label=\"refs\"(.*)>-->", " <PackageReference$1Label=\"refs\"$2>");
File.WriteAllText(csprojFile, csprojContent);
}
}
else
{
slnContent = Regex.Replace(slnContent, "##", "");
foreach (var csprojFile in csprojFiles)
{
var csprojContent = File.ReadAllText(csprojFile);
csprojContent = Regex.Replace(csprojContent," <!--<ProjectReference(.*)Label=\"refs\"(.*)>-->", " <ProjectReference$1Label=\"refs\"$2>");
csprojContent = Regex.Replace(csprojContent," <PackageReference(.*)Label=\"refs\"(.*)>", " <!--<PackageReference$1Label=\"refs\"$2>-->");
File.WriteAllText(csprojFile, csprojContent);
}
}
Console.WriteLine(slnContent);
File.WriteAllText(slnFile, slnContent);

View File

@ -1,22 +0,0 @@
{
"solution": "NetAdmin.sln",
"mappings": {
"FreeSql.NS": "../refs/FreeSql/FreeSql/FreeSql.csproj",
"FreeSql.DbContext.NS": "../refs/FreeSql/FreeSql.DbContext/FreeSql.DbContext.csproj"
},
"restore": [
{
"name": "NetAdmin.Infrastructure",
"packages": [
{
"packageName": "FreeSql.NS",
"version": "3.2.821-ns1"
},
{
"packageName": "FreeSql.DbContext.NS",
"version": "3.2.821-ns1"
}
]
}
]
}

View File

@ -1,17 +0,0 @@
{
"solution": "NetAdmin.sln",
"mappings": {
"Furion.Pure.NS": "../refs/Furion/framework/Furion.Pure/Furion.Pure.csproj"
},
"restore": [
{
"name": "NetAdmin.Infrastructure",
"packages": [
{
"packageName": "Furion.Pure.NS",
"version": "4.9.2.31-ns3"
}
]
}
]
}

View File

@ -1,17 +0,0 @@
{
"solution": "NetAdmin.sln",
"mappings": {
"NSExt": "../refs/ns-ext/src/NSExt/NSExt.csproj"
},
"restore": [
{
"name": "NetAdmin.Infrastructure",
"packages": [
{
"packageName": "NSExt",
"version": "2.1.0"
}
]
}
]
}

View File

@ -1,27 +0,0 @@
# https://github.com/RicoSuter/DNT#switch-to-projects
$targets = @{
'1' = 'switch-to-projects'
'2' = 'switch-to-packages'
}
$key = ''
while ($null -eq $targets[$key])
{
$key = Read-Host '请选择1切换到项目引用 2切换到Nuget包引用'
}
$files = Get-ChildItem Switcher.*.json
$file = 9999
while ($null -eq $files[[int]$file - 1])
{
$i = 0
Write-Host '请选择要切换的配置文件文件'
foreach ($file in $files)
{
$i++
Write-Host $i $file.Name
}
$file = Read-Host
}
$file = [int]$file - 1
Copy-Item $files[$file] 'switcher.json' -Force
dnt $targets[$key] ../NetAdmin.sln
Remove-Item switcher.json

View File

@ -17,6 +17,20 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "meta", "meta", "{5198A03D-0
"""
);
content = Regex.Replace(
content,
"Project\\(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\"\\) = \"docker\", \"docker\", \"{E80A1018-C354-4A26-9029-8847BB9DA864}\"(?:.|\n)*?EndProject",
$$"""
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docker", "docker", "{E80A1018-C354-4A26-9029-8847BB9DA864}"
ProjectSection(SolutionItems) = preProject
{{string.Join('\n',
Directory.GetFiles(@"../docker", "*")
.Select(x=>$" {Path.GetFileName(x)} = docker/{Path.GetFileName(x)}")
)}}
EndProject
"""
);
content = Regex.Replace(
content,
"Project\\(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\"\\) = \"workflows\", \"workflows\", \"{3C6F049E-3EE8-4D66-9AFF-E8A369032487}\"(?:.|\n)*?EndProject",

View File

@ -0,0 +1,39 @@
#!/bin/bash
# 检查是否提供了 URL 参数
if [ -z "$1" ]; then
echo "Usage: $0 <url>"
exit 1
fi
# 获取外部传入的 URL 参数
URL="$1"
# 初始化返回值和时间限制
response=""
start_time=$(date +%s)
time_limit=600 # 10分钟的秒数
# 循环检查 API 返回值
while [ "$response" != "1" ]; do
# 等待一段时间再进行下一次检查,避免频繁请求
sleep 1
# 使用 curl 请求 URL并捕获返回值忽略 SSL 证书错误
response=$(curl -sk "$URL")
# 打印返回值 (可选)
echo "$1: $response"
# 检查时间是否超过限制
current_time=$(date +%s)
elapsed_time=$((current_time - start_time))
if [ "$elapsed_time" -ge "$time_limit" ]; then
echo "Time limit exceeded. Continuing with the script..."
break
fi
done
# 无论是因为返回值为 "1" 还是超时,继续执行后续脚本
echo "Continuing with the script..."

View File

@ -25,16 +25,16 @@ global using FreeSql;
global using FreeSql.Aop;
global using FreeSql.DataAnnotations;
global using FreeSql.Internal.Model;
global using Furion;
global using Furion.Authorization;
global using Furion.ConfigurableOptions;
global using Furion.DataEncryption;
global using Furion.DataValidation;
global using Furion.DependencyInjection;
global using Furion.DynamicApiController;
global using Furion.EventBus;
global using Furion.SpecificationDocument;
global using Furion.UnifyResult;
global using Gurion;
global using Gurion.Authorization;
global using Gurion.ConfigurableOptions;
global using Gurion.DataEncryption;
global using Gurion.DataValidation;
global using Gurion.DependencyInjection;
global using Gurion.DynamicApiController;
global using Gurion.EventBus;
global using Gurion.SpecificationDocument;
global using Gurion.UnifyResult;
global using Mapster;
global using Microsoft.AspNetCore.Authorization;
global using Microsoft.AspNetCore.Builder;
@ -64,7 +64,3 @@ global using NetAdmin.Infrastructure.Languages;
global using NetAdmin.Infrastructure.Utils;
global using NSExt.Attributes;
global using NSExt.Extensions;
#if !INFRAS
global using DynamicFilterInfo = NetAdmin.Domain.Dto.Dependency.DynamicFilterInfo;
global using DynamicFilterOperators = NetAdmin.Domain.Enums.DynamicFilterOperators;
#endif

View File

@ -1,6 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="$(SolutionDir)/build/code.quality.props"/>
<ItemGroup>
<ProjectReference Include="../NetAdmin.SysComponent.Application/NetAdmin.SysComponent.Application.csproj"/>
</ItemGroup>
</Project>

View File

@ -1,7 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="$(SolutionDir)/build/code.quality.props"/>
<ItemGroup>
<ProjectReference Include="../NetAdmin.SysComponent.Cache/NetAdmin.SysComponent.Cache.csproj"/>
<ProjectReference Include="../NetAdmin.AdmServer.Application/NetAdmin.AdmServer.Application.csproj"/>
</ItemGroup>
</Project>

View File

@ -1,19 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Import Project="$(SolutionDir)/build/code.quality.props"/>
<ItemGroup>
<EmbeddedResource Include="$(SolutionDir)/assets/captcha/**" LinkBase="Assets/Captcha"/>
<EmbeddedResource Include="$(SolutionDir)/CHANGELOG.md" LogicalName="CHANGELOG.md"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../NetAdmin.SysComponent.Host/NetAdmin.SysComponent.Host.csproj"/>
<ProjectReference Include="../NetAdmin.AdmServer.Cache/NetAdmin.AdmServer.Cache.csproj"/>
</ItemGroup>
<ItemGroup>
<None Update="*.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup Condition="'$(Configuration)' != 'Debug'">
<EmbeddedResource Include="../../../dist/frontend/admin/**/*" LinkBase="UI"/>
</ItemGroup>
</Project>

View File

@ -1,45 +0,0 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
"SpecificationDocumentSettings": {
"GroupOpenApiInfos": [
{
"Group": "Sys",
"Title": "系统组件",
"Description": "NetAdmin - 系统组件",
},
{
"Group": "Adm",
"Title": "管理服务",
"Description": "NetAdmin - 管理服务",
},
{
"Group": "Tpl",
"Visible": false,
},
{
"Group": "Probe",
"Visible": false,
}
],
"SecurityDefinitions": [
{
"Id": "Bearer",
"Type": "ApiKey",
"Name": "Authorization",
"Description": "JWT Authorization header using the Bearer scheme.",
"BearerFormat": "JWT",
"Scheme": "bearer",
"In": "Header",
"Requirement": {
"Scheme": {
"Reference": {
"Id": "Bearer",
"Type": "SecurityScheme"
},
"Accesses": []
}
}
}
]
}
}

View File

@ -1,186 +0,0 @@
using System.Diagnostics.CodeAnalysis;
using System.Net.Http.Json;
using Microsoft.AspNetCore.Mvc.Testing;
using NetAdmin.AdmServer.Host;
using NetAdmin.Application.Modules;
using NetAdmin.Domain.Dto.Dependency;
using NetAdmin.Domain.Dto.Sys.Api;
using NetAdmin.Domain.Dto.Sys.Cache;
using NetAdmin.Domain.Dto.Sys.Config;
using NetAdmin.Domain.Dto.Sys.Tool;
using NetAdmin.SysComponent.Application.Modules.Sys;
using NetAdmin.Tests;
using Xunit;
using Xunit.Abstractions;
namespace NetAdmin.AdmServer.Tests;
/// <summary>
/// 所有测试
/// </summary>
[SuppressMessage("Usage", "xUnit1028:Test method must have valid return type")]
public class AllTests(WebApplicationFactory<Startup> factory, ITestOutputHelper testOutputHelper)
: WebApiTestBase<Startup>(factory, testOutputHelper), IToolsModule, ICacheModule, IApiModule, IConfigModule
{
/// <inheritdoc cref="ICrudModule{TCreateReq,TCreateRsp,TQueryReq,TQueryRsp,TUpdateReq,TUpdateRsp,TDelReq}.BulkDeleteAsync" />
public Task<int> BulkDeleteAsync(BulkReq<DelReq> req)
{
throw new NotImplementedException();
}
/// <inheritdoc />
[Fact]
public async Task<CacheStatisticsRsp> CacheStatisticsAsync()
{
var rsp = await PostAsync("/api/sys/cache/cache.statistics", null).ConfigureAwait(true);
Assert.Equal(HttpStatusCode.OK, rsp.StatusCode);
return default;
}
/// <inheritdoc />
public Task<long> CountAsync(QueryReq<QueryConfigReq> req)
{
throw new NotImplementedException();
}
/// <inheritdoc />
public Task<long> CountAsync(QueryReq<QueryApiReq> req)
{
throw new NotImplementedException();
}
/// <inheritdoc />
public Task<QueryConfigRsp> CreateAsync(CreateConfigReq req)
{
throw new NotImplementedException();
}
/// <inheritdoc />
public Task<QueryApiRsp> CreateAsync(CreateApiReq req)
{
throw new NotImplementedException();
}
/// <inheritdoc cref="ICrudModule{TCreateReq,TCreateRsp,TQueryReq,TQueryRsp,TUpdateReq,TUpdateRsp,TDelReq}.DeleteAsync" />
public Task<int> DeleteAsync(DelReq req)
{
throw new NotImplementedException();
}
/// <inheritdoc />
public Task<bool> ExistAsync(QueryReq<QueryConfigReq> req)
{
throw new NotImplementedException();
}
/// <inheritdoc />
public Task<bool> ExistAsync(QueryReq<QueryApiReq> req)
{
throw new NotImplementedException();
}
/// <inheritdoc />
[InlineData(default)]
[Theory]
public async Task<PagedQueryRsp<GetAllEntriesRsp>> GetAllEntriesAsync(PagedQueryReq<GetAllEntriesReq> req)
{
var rsp = await PostAsync("/api/sys/cache/get.all.entries"
, JsonContent.Create(new PagedQueryReq<GetAllEntriesReq>()))
.ConfigureAwait(true);
Assert.Equal(HttpStatusCode.OK, rsp.StatusCode);
return default;
}
/// <inheritdoc />
public Task<QueryConfigRsp> GetAsync(QueryConfigReq req)
{
throw new NotImplementedException();
}
/// <inheritdoc />
public Task<QueryApiRsp> GetAsync(QueryApiReq req)
{
throw new NotImplementedException();
}
/// <inheritdoc />
public Task<string> GetChangeLogAsync()
{
throw new NotImplementedException();
}
/// <inheritdoc />
public Task<QueryConfigRsp> GetLatestConfigAsync()
{
throw new NotImplementedException();
}
/// <inheritdoc />
public Task<IEnumerable<GetModulesRsp>> GetModulesAsync()
{
throw new NotImplementedException();
}
/// <inheritdoc />
[Fact]
public async Task<DateTime> GetServerUtcTimeAsync()
{
var response = await PostAsync("/api/sys/tools/get.server.utc.time", null).ConfigureAwait(true);
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
return default;
}
/// <inheritdoc />
[Fact]
public async Task<string> GetVersionAsync()
{
var response = await PostAsync("/api/sys/tools/version", null).ConfigureAwait(true);
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
return default;
}
/// <inheritdoc />
public Task<PagedQueryRsp<QueryConfigRsp>> PagedQueryAsync(PagedQueryReq<QueryConfigReq> req)
{
throw new NotImplementedException();
}
/// <inheritdoc />
public Task<PagedQueryRsp<QueryApiRsp>> PagedQueryAsync(PagedQueryReq<QueryApiReq> req)
{
throw new NotImplementedException();
}
/// <inheritdoc />
public Task<IEnumerable<QueryConfigRsp>> QueryAsync(QueryReq<QueryConfigReq> req)
{
throw new NotImplementedException();
}
/// <inheritdoc />
public Task<IEnumerable<QueryApiRsp>> QueryAsync(QueryReq<QueryApiReq> req)
{
throw new NotImplementedException();
}
/// <inheritdoc />
[Fact]
public async Task SyncAsync()
{
var response = await PostAsync("/api/sys/api/sync", null).ConfigureAwait(true);
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
}
/// <inheritdoc />
public Task<QueryConfigRsp> UpdateAsync(UpdateConfigReq req)
{
throw new NotImplementedException();
}
/// <inheritdoc />
public Task<NopReq> UpdateAsync(NopReq req)
{
throw new NotImplementedException();
}
}

View File

@ -1,9 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="../NetAdmin.Tests/NetAdmin.Tests.csproj"/>
<ProjectReference Include="../NetAdmin.AdmServer.Host/NetAdmin.AdmServer.Host.csproj"/>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.10.0-release-24177-07"/>
</ItemGroup>
</Project>

View File

@ -1,17 +0,0 @@
using NetAdmin.Domain.Contexts;
using NetAdmin.Domain.DbMaps.Dependency;
namespace NetAdmin.Application.Repositories;
/// <summary>
/// 默认仓储
/// </summary>
public sealed class DefaultRepository<TEntity>(IFreeSql fSql, UnitOfWorkManager uowManger, ContextUserToken userToken)
: DefaultRepository<TEntity, long>(fSql, uowManger)
where TEntity : EntityBase
{
/// <summary>
/// 当前上下文关联的用户令牌
/// </summary>
public ContextUserToken UserToken => userToken;
}

View File

@ -1,34 +0,0 @@
using NetAdmin.Application.Repositories;
using NetAdmin.Domain.DbMaps.Dependency;
namespace NetAdmin.Application.Services;
/// <summary>
/// 仓储服务基类
/// </summary>
/// <typeparam name="TEntity">实体类型</typeparam>
/// <typeparam name="TLogger">日志类型</typeparam>
public abstract class RepositoryService<TEntity, TLogger>(DefaultRepository<TEntity> rpo) : ServiceBase<TLogger>
where TEntity : EntityBase
{
/// <summary>
/// 默认仓储
/// </summary>
protected DefaultRepository<TEntity> Rpo => rpo;
/// <summary>
/// 启用级联保存
/// </summary>
protected bool EnableCascadeSave {
get => Rpo.DbContextOptions.EnableCascadeSave;
set => Rpo.DbContextOptions.EnableCascadeSave = value;
}
/// <summary>
/// 针对 Sqlite 数据的更新操作
/// </summary>
/// <returns>
/// 非 Sqlite 数据库请删除
/// </returns>
protected abstract Task<TEntity> UpdateForSqliteAsync(TEntity req);
}

View File

@ -1,6 +0,0 @@
namespace NetAdmin.Domain.DbMaps.Dependency;
/// <summary>
/// 数据库实体基类
/// </summary>
public abstract record EntityBase : DataAbstraction;

View File

@ -1,22 +0,0 @@
namespace NetAdmin.Domain.DbMaps.Dependency.Fields;
/// <summary>
/// 创建者客户端字段接口
/// </summary>
public interface IFieldCreatedClient
{
/// <summary>
/// 创建者客户端IP
/// </summary>
int? CreatedClientIp { get; init; }
/// <summary>
/// 创建者来源地址
/// </summary>
string CreatedReferer { get; init; }
/// <summary>
/// 创建者客户端用户代理
/// </summary>
string CreatedUserAgent { get; init; }
}

View File

@ -1,12 +0,0 @@
namespace NetAdmin.Domain.DbMaps.Dependency.Fields;
/// <summary>
/// 主键字段接口
/// </summary>
public interface IFieldPrimary<T>
{
/// <summary>
/// 唯一编码
/// </summary>
T Id { get; init; }
}

View File

@ -1,33 +0,0 @@
using NetAdmin.Domain.Attributes;
using NetAdmin.Domain.DbMaps.Dependency.Fields;
namespace NetAdmin.Domain.DbMaps.Dependency;
/// <inheritdoc />
public abstract record MutableEntity : MutableEntity<long>
{
/// <inheritdoc cref="IFieldPrimary{T}.Id" />
[Column(IsIdentity = false, IsPrimary = true, Position = 1)]
[Snowflake]
public override long Id { get; init; }
}
/// <summary>
/// 可变实体
/// </summary>
public abstract record MutableEntity<T> : LiteMutableEntity<T>, IFieldModifiedUser
{
/// <inheritdoc cref="IFieldPrimary{T}.Id" />
[Column(IsIdentity = false, IsPrimary = true, Position = 1)]
public override T Id { get; init; }
/// <inheritdoc cref="IFieldModifiedUser.ModifiedUserId" />
[Column(CanInsert = false, Position = -1)]
[JsonIgnore]
public long? ModifiedUserId { get; init; }
/// <inheritdoc cref="IFieldModifiedUser.ModifiedUserName" />
[Column(DbType = Chars.FLG_DB_FIELD_TYPE_VARCHAR_31, CanInsert = false, Position = -1)]
[JsonIgnore]
public string ModifiedUserName { get; init; }
}

View File

@ -1,6 +0,0 @@
namespace NetAdmin.Domain.DbMaps.Dependency;
/// <summary>
/// 简单实体
/// </summary>
public abstract record SimpleEntity : EntityBase;

View File

@ -1,42 +0,0 @@
using NetAdmin.Domain.Enums;
namespace NetAdmin.Domain.Dto.Dependency;
/// <summary>
/// 动态过滤条件
/// </summary>
public sealed record DynamicFilterInfo : DataAbstraction
{
/// <summary>
/// 字段名
/// </summary>
public string Field { get; init; }
/// <summary>
/// 子过滤条件
/// </summary>
public List<DynamicFilterInfo> Filters { get; init; }
/// <summary>
/// 子过滤条件逻辑关系
/// </summary>
public DynamicFilterLogics Logic { get; init; }
/// <summary>
/// 操作符
/// </summary>
public DynamicFilterOperators Operator { get; init; }
/// <summary>
/// 值
/// </summary>
public object Value { get; init; }
/// <summary>
/// 隐式转换为 FreeSql 的 DynamicFilterInfo 对象
/// </summary>
public static implicit operator FreeSql.Internal.Model.DynamicFilterInfo(DynamicFilterInfo d)
{
return d.Adapt<FreeSql.Internal.Model.DynamicFilterInfo>();
}
}

View File

@ -1,39 +0,0 @@
namespace NetAdmin.Domain.Dto.Dependency;
/// <summary>
/// 请求:查询
/// </summary>
public record QueryReq<T> : DataAbstraction
where T : DataAbstraction, new()
{
/// <summary>
/// 取前n条
/// </summary>
[Range(1, Numbers.MAX_LIMIT_QUERY)]
public int Count { get; init; } = Numbers.MAX_LIMIT_QUERY;
/// <summary>
/// 动态查询条件
/// </summary>
public DynamicFilterInfo DynamicFilter { get; init; }
/// <summary>
/// 查询条件
/// </summary>
public T Filter { get; init; }
/// <summary>
/// 查询关键字
/// </summary>
public string Keywords { get; init; }
/// <summary>
/// 排序方式
/// </summary>
public Orders? Order { get; init; }
/// <summary>
/// 排序字段
/// </summary>
public string Prop { get; init; }
}

View File

@ -1,53 +0,0 @@
namespace NetAdmin.Domain.Dto.Sys.Cache;
/// <summary>
/// 响应:获取所有缓存项
/// </summary>
public sealed record GetAllEntriesRsp : DataAbstraction
{
/// <summary>
/// Initializes a new instance of the <see cref="GetAllEntriesRsp" /> class.
/// </summary>
public GetAllEntriesRsp() { }
/// <summary>
/// Initializes a new instance of the <see cref="GetAllEntriesRsp" /> class.
/// </summary>
public GetAllEntriesRsp(long absExp, string key, long sldExp, string data)
{
AbsExp = absExp;
Key = key;
SldExp = sldExp;
Data = data;
}
/// <summary>
/// 绝对过期时间
/// </summary>
public DateTime? AbsExpTime => AbsExp == -1 ? null : DateTime.FromBinary(AbsExp).ToLocalTime();
/// <summary>
/// 滑动过期时间
/// </summary>
public DateTime? SldExpTime => SldExp == -1 ? null : DateTime.FromBinary(SldExp).ToLocalTime();
/// <summary>
/// 绝对过期时间
/// </summary>
public long AbsExp { get; init; }
/// <summary>
/// 缓存值
/// </summary>
public string Data { get; init; }
/// <summary>
/// 缓存键
/// </summary>
public string Key { get; init; }
/// <summary>
/// 滑动过期时间
/// </summary>
public long SldExp { get; init; }
}

View File

@ -1,13 +0,0 @@
using NetAdmin.Domain.DbMaps.Dependency.Fields;
namespace NetAdmin.Domain.Dto.Sys.Dic.Catalog;
/// <summary>
/// 请求:更新字典目录
/// </summary>
public sealed record UpdateDicCatalogReq : CreateDicCatalogReq
{
/// <inheritdoc cref="IFieldVersion.Version" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override long Version { get; init; }
}

View File

@ -1,13 +0,0 @@
using NetAdmin.Domain.DbMaps.Dependency.Fields;
namespace NetAdmin.Domain.Dto.Sys.Dic.Content;
/// <summary>
/// 请求:更新字典内容
/// </summary>
public sealed record UpdateDicContentReq : CreateDicContentReq
{
/// <inheritdoc cref="IFieldVersion.Version" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override long Version { get; init; }
}

View File

@ -1,8 +0,0 @@
using NetAdmin.Domain.DbMaps.Sys;
namespace NetAdmin.Domain.Dto.Sys.JobRecord;
/// <summary>
/// 请求:创建计划作业执行记录
/// </summary>
public record CreateJobRecordReq : Sys_JobRecord;

View File

@ -1,6 +0,0 @@
namespace NetAdmin.Domain.Dto.Sys.JobRecord;
/// <summary>
/// 请求:更新计划作业执行记录
/// </summary>
public sealed record UpdateJobRecordReq : CreateJobRecordReq;

View File

@ -1,8 +0,0 @@
using NetAdmin.Domain.DbMaps.Sys;
namespace NetAdmin.Domain.Dto.Sys.RequestLog;
/// <summary>
/// 请求:创建请求日志
/// </summary>
public sealed record CreateRequestLogReq : Sys_RequestLog;

View File

@ -1,8 +0,0 @@
using NetAdmin.Domain.DbMaps.Sys;
namespace NetAdmin.Domain.Dto.Sys.RequestLog;
/// <summary>
/// 请求:查询请求日志
/// </summary>
public sealed record QueryRequestLogReq : Sys_RequestLog;

View File

@ -1,107 +0,0 @@
using NetAdmin.Domain.DbMaps.Dependency.Fields;
using NetAdmin.Domain.DbMaps.Sys;
namespace NetAdmin.Domain.Dto.Sys.RequestLog;
/// <summary>
/// 响应:查询请求日志
/// </summary>
public sealed record QueryRequestLogRsp : Sys_RequestLog, IRegister
{
/// <summary>
/// 创建者客户端IP
/// </summary>
public new string CreatedClientIp => base.CreatedClientIp?.ToIpV4();
/// <summary>
/// 操作系统
/// </summary>
public string Os => UserAgentParser.Create(CreatedUserAgent)?.Platform;
/// <inheritdoc cref="Sys_RequestLog.ApiId" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string ApiId { get; init; }
/// <summary>
/// 接口描述
/// </summary>
public string ApiSummary { get; init; }
/// <inheritdoc cref="IFieldCreatedTime.CreatedTime" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override DateTime CreatedTime { get; init; }
/// <inheritdoc cref="Sys_RequestLog.CreatedUserAgent" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string CreatedUserAgent { get; init; }
/// <inheritdoc cref="IFieldCreatedUser.CreatedUserName" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string CreatedUserName { get; init; }
/// <inheritdoc cref="Sys_RequestLog.Duration" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override long Duration { get; init; }
/// <inheritdoc cref="Sys_RequestLog.ErrorCode" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override ErrorCodes ErrorCode { get; init; }
/// <inheritdoc cref="Sys_RequestLog.Exception" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Exception { get; init; }
/// <inheritdoc cref="Sys_RequestLog.ExtraData" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string ExtraData { get; init; }
/// <inheritdoc cref="Sys_RequestLog.HttpStatusCode" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override int HttpStatusCode { get; init; }
/// <inheritdoc cref="Sys_RequestLog.Method" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string Method { get; init; }
/// <inheritdoc cref="Sys_RequestLog.ReferUrl" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string ReferUrl { get; init; }
/// <inheritdoc cref="Sys_RequestLog.RequestBody" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string RequestBody { get; init; }
/// <inheritdoc cref="Sys_RequestLog.RequestContentType" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string RequestContentType { get; init; }
/// <inheritdoc cref="Sys_RequestLog.RequestHeaders" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string RequestHeaders { get; init; }
/// <inheritdoc cref="Sys_RequestLog.RequestUrl" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string RequestUrl { get; init; }
/// <inheritdoc cref="Sys_RequestLog.ResponseBody" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string ResponseBody { get; init; }
/// <inheritdoc cref="Sys_RequestLog.ResponseContentType" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string ResponseContentType { get; init; }
/// <inheritdoc cref="Sys_RequestLog.ResponseHeaders" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override string ResponseHeaders { get; init; }
/// <inheritdoc cref="Sys_RequestLog.ServerIp" />
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
public override int? ServerIp { get; init; }
/// <inheritdoc />
public void Register(TypeAdapterConfig config)
{
_ = config.ForType<Sys_RequestLog, QueryRequestLogRsp>().Map(d => d.ApiSummary, s => s.Api.Summary);
}
}

View File

@ -1,19 +0,0 @@
using NetAdmin.Domain.DbMaps.Dependency.Fields;
namespace NetAdmin.Domain.Dto.Sys.Role;
/// <summary>
/// 请求:修改角色
/// </summary>
public sealed record UpdateRoleReq : CreateRoleReq
{
/// <inheritdoc cref="IFieldPrimary{T}.Id" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
[Required(ErrorMessageResourceType = typeof(Ln), ErrorMessageResourceName = nameof(Ln.唯一编码不能为空))]
public override long Id { get; init; }
/// <inheritdoc cref="IFieldVersion.Version" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
[Required(ErrorMessageResourceType = typeof(Ln), ErrorMessageResourceName = nameof(Ln.数据版本不能为空))]
public override long Version { get; init; }
}

View File

@ -1,8 +0,0 @@
using NetAdmin.Domain.DbMaps.Sys;
namespace NetAdmin.Domain.Dto.Sys.SiteMsgDept;
/// <summary>
/// 请求:创建站内信-部门映射
/// </summary>
public record CreateSiteMsgDeptReq : Sys_SiteMsgDept;

View File

@ -1,6 +0,0 @@
namespace NetAdmin.Domain.Dto.Sys.SiteMsgDept;
/// <summary>
/// 请求:更新站内信-部门映射
/// </summary>
public sealed record UpdateSiteMsgDeptReq : CreateSiteMsgDeptReq;

View File

@ -1,6 +0,0 @@
namespace NetAdmin.Domain.Dto.Sys.SiteMsgFlag;
/// <summary>
/// 请求:更新站内信标记
/// </summary>
public sealed record UpdateSiteMsgFlagReq : CreateSiteMsgFlagReq;

View File

@ -1,8 +0,0 @@
using NetAdmin.Domain.DbMaps.Sys;
namespace NetAdmin.Domain.Dto.Sys.SiteMsgRole;
/// <summary>
/// 请求:创建站内信-角色映射
/// </summary>
public record CreateSiteMsgRoleReq : Sys_SiteMsgRole;

View File

@ -1,6 +0,0 @@
namespace NetAdmin.Domain.Dto.Sys.SiteMsgRole;
/// <summary>
/// 请求:更新站内信-角色映射
/// </summary>
public sealed record UpdateSiteMsgRoleReq : CreateSiteMsgRoleReq;

View File

@ -1,8 +0,0 @@
using NetAdmin.Domain.DbMaps.Sys;
namespace NetAdmin.Domain.Dto.Sys.SiteMsgUser;
/// <summary>
/// 请求:创建站内信-用户映射
/// </summary>
public record CreateSiteMsgUserReq : Sys_SiteMsgUser;

View File

@ -1,6 +0,0 @@
namespace NetAdmin.Domain.Dto.Sys.SiteMsgUser;
/// <summary>
/// 请求:更新站内信-用户映射
/// </summary>
public sealed record UpdateSiteMsgUserReq : CreateSiteMsgUserReq;

View File

@ -1,22 +0,0 @@
using NetAdmin.Domain.DbMaps.Dependency.Fields;
using NetAdmin.Domain.DbMaps.Sys;
using NetAdmin.Domain.Dto.Sys.UserProfile;
namespace NetAdmin.Domain.Dto.Sys.User;
/// <summary>
/// 请求:更新用户
/// </summary>
public sealed record UpdateUserReq : CreateUpdateUserReq
{
/// <inheritdoc cref="IFieldPrimary{T}.Id" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override long Id { get; init; }
/// <inheritdoc cref="Sys_User.Profile" />
public new UpdateUserProfileReq Profile { get; init; }
/// <inheritdoc cref="IFieldVersion.Version" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override long Version { get; init; }
}

View File

@ -1,13 +0,0 @@
using NetAdmin.Domain.DbMaps.Dependency.Fields;
namespace NetAdmin.Domain.Dto.Sys.UserProfile;
/// <summary>
/// 请求:更新用户档案
/// </summary>
public sealed record UpdateUserProfileReq : CreateUserProfileReq
{
/// <inheritdoc cref="IFieldVersion.Version" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override long Version { get; init; }
}

View File

@ -1,13 +0,0 @@
using NetAdmin.Domain.DbMaps.Dependency.Fields;
namespace NetAdmin.Domain.Dto.Sys.VerifyCode;
/// <summary>
/// 请求:更新验证码
/// </summary>
public sealed record UpdateVerifyCodeReq : CreateVerifyCodeReq
{
/// <inheritdoc cref="IFieldVersion.Version" />
[JsonIgnore(Condition = JsonIgnoreCondition.Never)]
public override long Version { get; init; }
}

View File

@ -1,9 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="$(SolutionDir)/build/code.quality.props"/>
<ItemGroup>
<Content Include="$(SolutionDir)/assets/seed-data/**" LinkBase="SeedData" CopyToOutputDirectory="PreserveNewest"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="../NetAdmin.Infrastructure/NetAdmin.Infrastructure.csproj"/>
</ItemGroup>
</Project>

View File

@ -1,28 +0,0 @@
using NetAdmin.Application.Services;
using NetAdmin.Cache;
using NetAdmin.Host.Middlewares;
namespace NetAdmin.Host.Controllers;
/// <summary>
/// 探针组件
/// </summary>
[ApiDescriptionSettings("Probe")]
public sealed class ProbeController : ControllerBase<ICache<IDistributedCache, IService>, IService>
{
/// <summary>
/// 健康检查
/// </summary>
[AllowAnonymous]
[HttpGet]
#pragma warning disable CA1822, S3400
public object HealthCheck()
#pragma warning restore S3400, CA1822
{
return new {
HostName = Environment.MachineName
, CurrentConnections = SafetyShopHostMiddleware.Connections
, GlobalStatic.ProductVersion
};
}
}

View File

@ -1,8 +0,0 @@
using NetAdmin.Domain.Dto;
namespace NetAdmin.Host.Filters;
/// <inheritdoc cref="NetAdmin.Host.Filters.ApiResultHandler{T}" />
[SuppressSniffer]
[UnifyModel(typeof(RestfulInfo<>))]
public sealed class DefaultApiResultHandler : ApiResultHandler<RestfulInfo<object>>, IUnifyResultProvider;

View File

@ -1,44 +0,0 @@
namespace NetAdmin.Host.Middlewares;
/// <summary>
/// 安全停机中间件
/// </summary>
/// <remarks>
/// 放在所有中间件最前面
/// </remarks>
public sealed class SafetyShopHostMiddleware(RequestDelegate next)
{
private static long _connections;
private static bool _hostStopping;
/// <summary>
/// 当前连接数
/// </summary>
public static long Connections => Interlocked.Read(ref _connections);
/// <summary>
/// 停机处理
/// </summary>
public static void OnStopping()
{
Volatile.Write(ref _hostStopping, true);
while (Interlocked.Read(ref _connections) > 0) {
Thread.Sleep(10);
}
}
/// <summary>
/// 主函数
/// </summary>
public async Task InvokeAsync(HttpContext context)
{
if (Volatile.Read(ref _hostStopping)) {
context.Response.StatusCode = (int)HttpStatusCode.ServiceUnavailable;
return;
}
_ = Interlocked.Increment(ref _connections);
await next(context).ConfigureAwait(false);
_ = Interlocked.Decrement(ref _connections);
}
}

View File

@ -1,90 +0,0 @@
using NetAdmin.Domain.Contexts;
using NetAdmin.Domain.Dto.Sys.RequestLog;
using NetAdmin.Domain.Events.Sys;
namespace NetAdmin.Host.Utils;
/// <summary>
/// 请求日志记录器
/// </summary>
public sealed class RequestLogger(
ILogger<RequestLogger> logger
, IOptions<SpecificationDocumentSettingsOptions> specificationDocumentSettingsOptions
, IEventPublisher eventPublisher) : ISingleton
{
private static readonly string[] _textContentTypes = ["text", "json", "xml", "urlencoded"];
private readonly int _tokenPrefixLength
= specificationDocumentSettingsOptions?.Value.SecurityDefinitions?[0]?.Scheme?.Length + 1 ??
0; // eg. "Bearer ";
/// <summary>
/// 生成审计数据
/// </summary>
public async Task<CreateRequestLogReq> LogAsync(HttpContext context, long duration, string responseBody
, ErrorCodes errorCode, IExceptionHandlerFeature exception)
{
// 从请求头中读取用户信息
var associatedUser = GetAssociatedUser(context);
var auditData = new CreateRequestLogReq {
Duration = duration
, Method = context.Request.Method
, ReferUrl = context.Request.GetRefererUrlAddress()
, RequestContentType = context.Request.ContentType
, RequestBody = Array.Exists( //
_textContentTypes
, x => context.Request.ContentType?.Contains(
x, StringComparison.OrdinalIgnoreCase) ?? false)
? (await context.ReadBodyContentAsync().ConfigureAwait(false))
?.Sub(0, Numbers.MAX_LIMIT_PRINT_LEN_CONTENT)
: string.Empty
, RequestUrl = context.Request.GetRequestUrlAddress()
, ResponseBody
= responseBody?.Sub(0, Numbers.MAX_LIMIT_PRINT_LEN_CONTENT)
, ServerIp = context.GetLocalIpAddressToIPv4()?.IpV4ToInt32()
, ApiId = context.Request.Path.Value?.TrimStart('/')
, RequestHeaders = context.Request.Headers.Json()
, ResponseContentType = context.Response.ContentType
, ResponseHeaders = context.Response.Headers.Json()
, HttpStatusCode = context.Response.StatusCode
, ErrorCode = errorCode
, Exception = exception?.Error.ToString()
, CreatedUserId = associatedUser?.UserId
, CreatedUserName = associatedUser?.UserName
, CreatedUserAgent = context.Request.Headers.UserAgent.ToString()
, CreatedClientIp = context.GetRealIpAddress()
?.MapToIPv4()
.ToString()
.IpV4ToInt32()
};
// 打印日志
logger.Info(auditData);
// 发布请求日志事件
await eventPublisher.PublishAsync(new RequestLogEvent(auditData)).ConfigureAwait(false);
return auditData;
}
private (long UserId, string UserName)? GetAssociatedUser(HttpContext context)
{
var token = context.Request.Headers.Authorization.FirstOrDefault();
if (token == null) {
return null;
}
ContextUserToken userToken = null;
try {
var jsonWebToken = JWTEncryption.ReadJwtToken(token[_tokenPrefixLength..]);
var claim = jsonWebToken?.Claims.FirstOrDefault(y => y.Type == nameof(ContextUserToken));
userToken = claim?.Value.ToObject<ContextUserToken>();
}
catch (Exception ex) {
logger.Warn($"{Ln.读取用户令牌出错}: {ex}");
}
return userToken == null ? null : (userToken.Id, userToken.UserName);
}
}

View File

@ -1,32 +0,0 @@
#pragma warning disable CS1591
namespace NetAdmin.Infrastructure.Constant;
/// <summary>
/// 数字常量表
/// </summary>
/// <remarks>
/// public类型会通过接口暴露给前端
/// </remarks>
public static class Numbers
{
public const int DEF_PAGE_SIZE_QUERY = 20; // 分页查询默认的页容量
public const long DEF_SORT_VAL = 100; // 排序默认值
public const int HTTP_STATUS_BIZ_FAIL = 900; // Http状态码-业务异常
public const long ID_DIC_CATALOG_GEO_AREA = 379794295185413; // 唯一编号:字典目录-行政区划字典
public const int MAX_LIMIT_BULK_REQ = 100; // 最大限制:批量请求数
public const int MAX_LIMIT_PRINT_LEN_CONTENT = 4096; // 最大限制打印长度HTTP 内容)
public const int MAX_LIMIT_PRINT_LEN_SQL = 4096; // 最大限制打印长度SQL 语句)
public const int MAX_LIMIT_QUERY = 1000; // 最大限制:非分页查询条数
public const int MAX_LIMIT_QUERY_PAGE_NO = 10000; // 最大限制:分页查询页码
public const int MAX_LIMIT_QUERY_PAGE_SIZE = 100; // 最大限制:分页查询页容量
public const int SECS_CACHE_CHART = 300; // 秒:缓存时间-仪表
public const int SECS_CACHE_DEFAULT = 60; // 秒:缓存时间-默认
public const int SECS_RED_LOCK_EXPIRY = 30; // 秒RedLock-锁过期时间,锁区域内的逻辑执行如果超过过期时间,锁将被释放
public const int SECS_RED_LOCK_RETRY = 1; // 秒RedLock-锁等待时间内,多久尝试获取一次
public const int SECS_RED_LOCK_WAIT = 10; // 秒RedLock-锁等待时间,相同的 resource 如果当前的锁被其他线程占用,最多等待时间
public const int SECS_TIMEOUT_JOB = 600; // 秒:超时时间-作业
}

View File

@ -1,8 +0,0 @@
namespace NetAdmin.Infrastructure.Exceptions;
/// <summary>
/// 加锁失败异常
/// </summary>
#pragma warning disable RCS1194
public sealed class NetAdminGetLockerException : NetAdminException;
#pragma warning restore RCS1194

View File

@ -1,24 +0,0 @@
namespace NetAdmin.Infrastructure.Exceptions;
/// <summary>
/// 无效操作异常
/// </summary>
/// <remarks>
/// 非正常的业务流程或逻辑
/// </remarks>
#pragma warning disable RCS1194, DesignedForInheritance
public class NetAdminInvalidOperationException : NetAdminException
#pragma warning restore DesignedForInheritance, RCS1194
{
/// <summary>
/// Initializes a new instance of the <see cref="NetAdminInvalidOperationException" /> class.
/// </summary>
public NetAdminInvalidOperationException(string message, Exception innerException = null) //
: this(ErrorCodes.InvalidOperation, message, innerException) { }
/// <summary>
/// Initializes a new instance of the <see cref="NetAdminInvalidOperationException" /> class.
/// </summary>
protected NetAdminInvalidOperationException(ErrorCodes errorCode, string message, Exception innerException) //
: base(errorCode, message, innerException) { }
}

View File

@ -1,30 +0,0 @@
namespace NetAdmin.Infrastructure.Exceptions;
/// <summary>
/// 非预期结果异常
/// </summary>
/// <remarks>
/// 运行结果是非预期的,例如事务失败回滚
/// </remarks>
#pragma warning disable RCS1194, DesignedForInheritance
public class NetAdminUnexpectedException : NetAdminException
#pragma warning restore DesignedForInheritance, RCS1194
{
/// <summary>
/// Initializes a new instance of the <see cref="NetAdminUnexpectedException" /> class.
/// </summary>
public NetAdminUnexpectedException(string message) //
: this(ErrorCodes.Unexpected, message) { }
/// <summary>
/// Initializes a new instance of the <see cref="NetAdminUnexpectedException" /> class.
/// </summary>
public NetAdminUnexpectedException() //
: this(string.Empty) { }
/// <summary>
/// Initializes a new instance of the <see cref="NetAdminUnexpectedException" /> class.
/// </summary>
protected NetAdminUnexpectedException(ErrorCodes errorCode, string message) //
: base(errorCode, message) { }
}

View File

@ -1,38 +0,0 @@
namespace NetAdmin.Infrastructure.Extensions;
/// <summary>
/// HttpResponseMessage 扩展方法
/// </summary>
public static class HttpResponseMessageExtensions
{
/// <summary>
/// 记录日志
/// </summary>
public static async Task LogAsync<T>(this HttpResponseMessage me, ILogger<T> logger
, Func<string, string> bodyPreHandle = null)
{
logger.Info(
(await me.BuildJsonAsync(bodyPreHandle).ConfigureAwait(false))?.Sub(
0, Numbers.MAX_LIMIT_PRINT_LEN_CONTENT));
}
/// <summary>
/// 记录异常日志
/// </summary>
public static async Task LogExceptionAsync<T>(this HttpResponseMessage me, string errors, ILogger<T> logger
, Func<string, string> bodyHandle = null)
{
logger.Warn(
$"{errors}: {(await me.BuildJsonAsync(bodyHandle).ConfigureAwait(false))?.Sub(0, Numbers.MAX_LIMIT_PRINT_LEN_CONTENT)}");
}
/// <summary>
/// 将Http请求的Uri、Header、Body打包成Json字符串
/// </summary>
private static async Task<string> BuildJsonAsync( //
this HttpResponseMessage me, Func<string, string> bodyHandle = null)
{
var body = me?.Content is null ? null : await me.Content!.ReadAsStringAsync().ConfigureAwait(false);
return new { Header = me?.ToString(), Body = bodyHandle is null ? body : bodyHandle(body) }.ToJson();
}
}

View File

@ -1,52 +0,0 @@
namespace NetAdmin.Infrastructure.Extensions;
/// <summary>
/// String 扩展方法
/// </summary>
public static class StringExtensions
{
private static readonly Regex _regex = new("Options$");
private static readonly Regex _regex2 = new("Async$");
/// <summary>
/// object -> json
/// </summary>
public static T ToObject<T>(this string me)
{
return me.Object<T>(GlobalStatic.JsonSerializerOptions);
}
/// <summary>
/// object -> json
/// </summary>
public static object ToObject(this string me, Type toType)
{
return me.Object(toType, GlobalStatic.JsonSerializerOptions);
}
/// <summary>
/// 去掉尾部字符串“Async”
/// </summary>
#pragma warning disable RCS1047, ASA002, VSTHRD200
public static string TrimEndAsync(this string me)
#pragma warning restore VSTHRD200, ASA002, RCS1047
{
return _regex2.Replace(me, string.Empty);
}
/// <summary>
/// 去掉尾部字符串“Options”
/// </summary>
public static string TrimEndOptions(this string me)
{
return _regex.Replace(me, string.Empty);
}
/// <summary>
/// 去掉前部字符串
/// </summary>
public static string TrimStart(this string me, string clearStr)
{
return Regex.Replace(me, $"^{clearStr}", string.Empty);
}
}

View File

@ -1,27 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<DefineConstants>INFRAS</DefineConstants>
</PropertyGroup>
<Import Project="$(SolutionDir)/build/code.quality.props"/>
<Import Project="$(SolutionDir)/build/copy.pkg.xml.comment.files.targets"/>
<Import Project="$(SolutionDir)/build/prebuild.targets"/>
<ItemGroup>
<PackageReference Include="Cronos" Version="0.8.4"/>
<PackageReference Include="FreeSql.DbContext.NS" Version="3.2.821-ns1"/>
<PackageReference Include="FreeSql.Provider.Sqlite.NS" Version="3.2.821-ns1"/>
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.9.2.31"/>
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster.NS" Version="4.9.2.31-ns1"/>
<PackageReference Include="Furion.Pure.NS" Version="4.9.2.31-ns1"/>
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="9.0.0-preview.3.24172.13"/>
<PackageReference Include="Minio" Version="6.0.2"/>
<PackageReference Include="NSExt" Version="2.1.0"/>
<PackageReference Include="RedLock.net" Version="2.3.2"/>
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0"/>
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14"/>
</ItemGroup>
<ItemGroup>
<None Update="*.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@ -1,98 +0,0 @@
using RedLockNet.SERedis;
using RedLockNet.SERedis.Configuration;
using StackExchange.Redis;
namespace NetAdmin.Infrastructure.Utils;
/// <summary>
/// Redis 分布锁
/// </summary>
#pragma warning disable DesignedForInheritance
public class RedLocker : IDisposable, ISingleton
#pragma warning restore DesignedForInheritance
{
// Track whether Dispose has been called.
private bool _disposed;
/// <summary>
/// Initializes a new instance of the <see cref="RedLocker" /> class.
/// </summary>
public RedLocker(IOptions<RedisOptions> redisOptions)
{
RedLockFactory = RedLockFactory.Create( //
new List<RedLockMultiplexer> //
{
ConnectionMultiplexer.Connect( //
redisOptions.Value.Instances.First(x => x.Name == Chars.FLG_REDIS_INSTANCE_DATA_CACHE).ConnStr)
});
}
/// <summary>
/// Finalizes an instance of the <see cref="RedLocker" /> class.
/// Use C# finalizer syntax for finalization code.
/// This finalizer will run only if the Dispose method
/// does not get called.
/// It gives your base class the opportunity to finalize.
/// Do not provide finalizer in types derived from this class.
/// </summary>
~RedLocker()
{
// Do not re-create Dispose clean-up code here.
// Calling Dispose(disposing: false) is optimal in terms of
// readability and maintainability.
Dispose(false);
}
/// <summary>
/// RedLockFactory
/// </summary>
public RedLockFactory RedLockFactory { get; }
/// <summary>
/// Implement IDisposable.
/// Do not make this method virtual.
/// A derived class should not be able to override this method.
/// </summary>
public void Dispose()
{
Dispose(true);
// This object will be cleaned up by the Dispose method.
// Therefore, you should call GC.SuppressFinalize to
// take this object off the finalization queue
// and prevent finalization code for this object
// from executing a second time.
GC.SuppressFinalize(this);
}
/// <summary>
/// Dispose(bool disposing) executes in two distinct scenarios.
/// If disposing equals true, the method has been called directly
/// or indirectly by a user's code. Managed and unmanaged resources
/// can be disposed.
/// If disposing equals false, the method has been called by the
/// runtime from inside the finalizer and you should not reference
/// other objects. Only unmanaged resources can be disposed.
/// </summary>
protected virtual void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if (_disposed) {
return;
}
// If disposing equals true, dispose all managed
// and unmanaged resources.
if (disposing) {
RedLockFactory.Dispose();
}
// Call the appropriate methods to clean up
// unmanaged resources here.
// If disposing is false,
// only the following code is executed.
// Note disposing has been done.
_disposed = true;
}
}

View File

@ -1,15 +0,0 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
"AppSettings": {
"InjectSpecificationDocument": true,
"InjectMiniProfiler": true
},
"JWTSettings": {
"ExpiredTime": 20000
},
"Logging": {
"LogLevel": {
"Default": "Debug",
},
},
}

View File

@ -1,15 +0,0 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
"AppSettings": {
"InjectSpecificationDocument": true,
"InjectMiniProfiler": true
},
"JWTSettings": {
"ExpiredTime": 20000
},
"Logging": {
"LogLevel": {
"Default": "Debug",
},
}
}

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