101 Commits

Author SHA1 Message Date
tk
06b7aa4ae8 chore(release): 2.3.1 2024-12-13 16:15:37 +08:00
tk
b1678e2537 refactor: ♻️ 前端体验优化
[skip ci]
2024-12-13 16:15:02 +08:00
442a69f90d fix: 🐛 修复一些样式问题 2024-12-12 23:23:39 +08:00
f1fd53f72b build: 📦 git.config
[skip ci]
2024-12-12 20:12:04 +08:00
tk
ae4ed8b3ef chore(release): 2.3.0 2024-12-12 18:16:03 +08:00
tk
4e4a1d0dff fix: 🐛 个性主题色冲突 2024-12-12 18:04:08 +08:00
tk
098cfc135e feat: 框架代码同步 2024-12-12 10:05:58 +08:00
tk
0285eea352 refactor: ♻️ 框架代码同步 2024-12-11 09:36:10 +08:00
tk
725662693b feat: 框架代码同步 2024-12-10 14:50:16 +08:00
tk
9504c96f40 style: 💄 code format
[skip ci]
2024-12-09 20:07:13 +08:00
tk
d1e4704adc revert: appConfig.js 2024-12-09 20:05:05 +08:00
tk
0b036e9d67 feat: 分组统计功能 2024-12-09 19:37:18 +08:00
tk
89846d9783 refactor: ♻️ enum 扩展方法 2024-12-07 15:27:07 +08:00
194eb89d31 chore: 🔨 移动端样式调整
[skip ci]
2024-12-06 21:46:07 +08:00
tk
d622111f53 refactor: ♻️ 生成前端apijs 2024-12-06 17:19:30 +08:00
tk
c2a2b27afd refactor: ♻️ curdModule 新增Edit方案
[skip ci]
2024-12-06 17:14:17 +08:00
tk
4228bd5c32 refactor: ♻️ 国家代码表重构
[skip ci]
2024-12-06 10:27:24 +08:00
tk
b24642e5c9 chore(release): 2.2.1 2024-12-04 16:36:31 +08:00
tk
4eecc0b4ce fix: 🐛 version lock
[skip ci]
2024-12-04 16:35:20 +08:00
tk
01058ba728 fix: 🐛 version 条件重复指定 2024-12-03 11:05:27 +08:00
a6f6a8f0a3 perf: nuget update 2024-11-29 22:42:47 +08:00
4f12b5064d Update README.md 2024-11-29 22:21:30 +08:00
2acf88cad1 style: 💄 code format 2024-11-29 22:13:01 +08:00
tk
180119019c chore: 🔨 sys_Menu.json
[skip ci]
2024-11-29 18:22:07 +08:00
tk
f5203782aa chore: 🔨 iSelect 扩展方法增强
[skip ci]
2024-11-29 17:44:13 +08:00
tk
4874a58eee perf: nuget update 2024-11-29 17:40:19 +08:00
tk
b4ca6d5626 style: 💄 解决方案文件段落整理
[skip ci]
2024-11-29 11:16:26 +08:00
tk
63d7a3ed4a refactor: ♻️ iSelect 扩展方法
[skip ci]
2024-11-29 11:08:37 +08:00
ef2a0c3280 fix: 🐛 editUser 2024-11-29 09:28:05 +08:00
c69655e353 build: 📦 refs update
[skip ci]
2024-11-29 00:35:42 +08:00
f0e1155ee8 build: 📦 修复项目引用路径问题
[skip ci]
2024-11-29 00:30:10 +08:00
03745ff767 build: 📦 更新子模块
[skip ci]
2024-11-28 23:24:03 +08:00
ee94d47551 refactor: ♻️ freeSql 重编译版本
[skip ci]
2024-11-28 23:18:25 +08:00
155deedd15 refactor: ♻️ 减少一些条件编译语句 (#229)
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-28 15:51:09 +08:00
a0a04590c9 build: 📦 rename.csx (#228)
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-28 10:27:47 +08:00
c88c8d293d fix: 🐛 按钮文字提示 (#227)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-27 18:38:52 +08:00
7501138e31 chore: 🔨 界面优化 (#226)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-27 17:58:38 +08:00
cb75d19202 Merge pull request #225 from nsnail/release
chore(release): 2.2.0
2024-11-27 16:54:46 +08:00
tk
e8a2d27c00 chore(release): 2.2.0 2024-11-27 16:54:27 +08:00
440c7ffcb9 chore: 🔨 分享文档链接按钮 (#224)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-27 16:54:15 +08:00
e8b568426b chore: 🔨 增加一个图标 (#223)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-27 16:20:17 +08:00
37b45c9f36 perf: npm update (#222)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-27 16:04:12 +08:00
7ed30406c9 feat: 文档管理 (#221)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-27 15:52:23 +08:00
71bfdaafa8 fix: 🐛 用户选择器报错 (#220)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-26 10:10:25 +08:00
cec96390a5 refactor: ♻️ 精简前端组件 (#219) 2024-11-25 22:30:45 +08:00
0e412db6ce perf: nuget update (#218)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-25 17:57:19 +08:00
4d857f1861 feat: select-filter badge icon (#217)
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-25 10:53:57 +08:00
d74a7e13ef perf: npm update (#216)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-22 18:13:17 +08:00
2f16efd291 refactor: ♻️ 样式优化 (#215)
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-22 18:12:03 +08:00
81d9b0b3bb feat: 菜单复制 (#214)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-22 14:04:33 +08:00
ef2f0de095 fix: 🐛 导出界面报错 (#213)
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-22 13:23:32 +08:00
6d87d8e9cd chore: 🔨 用户管理-角色排序 (#212)
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-22 12:11:10 +08:00
69dc407002 chore: 🔨 userbar下拉菜单弹出方式 (#211)
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-22 11:52:55 +08:00
6c71c74a27 fix: 🐛 请求日志批量插入,漏写了登录日志 (#210)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-22 11:16:18 +08:00
4e9f605ea2 fix: 🐛 idd (#208) 2024-11-16 14:40:21 +08:00
d28d7e9a18 chore: 🔨 导出文件时,如勾选,只导出勾选项 (#207) 2024-11-16 12:44:32 +08:00
a6018edb87 style: 💄 code format (#206)
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-15 19:22:06 +08:00
841a4195e7 fix: 🐛 导出文件的responseType (#205)
Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-15 18:34:45 +08:00
5e9b67bca8 refactor: ♻️ 精简框架分层 (#204)
[skip ci]

Co-authored-by: tk <fiyne1a@dingtalk.com>
2024-11-15 18:27:21 +08:00
76e5fdcd94 Merge pull request #203 from nsnail/release
chore(release): 2.1.0

[skip ci]
2024-11-15 16:48:47 +08:00
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
866 changed files with 20328 additions and 8813 deletions

View File

@ -0,0 +1 @@
drone workflows

View File

@ -10,6 +10,7 @@ ij_xml_text_wrap = off # IntelliJ IDEA 中 XML 文本不换行
indent_size = 4 # 缩进大小为 4 个空格 indent_size = 4 # 缩进大小为 4 个空格
indent_style = space # 使用空格进行缩进 indent_style = space # 使用空格进行缩进
insert_final_newline = false # 不在文件末尾插入空行 insert_final_newline = false # 不在文件末尾插入空行
max_line_length = 150 # 行长度限制为 150 个字符
trim_trailing_whitespace = true # 删除行尾的空格 trim_trailing_whitespace = true # 删除行尾的空格
[{*.json,*.yml}] [{*.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 runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
node-version: [ 20.x ] node-version: [ 22.x ]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
with: with:
@ -37,8 +37,8 @@ jobs:
path: ~/.nuget/packages path: ~/.nuget/packages
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }} key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
restore-keys: ${{ runner.os }}-nuget restore-keys: ${{ runner.os }}-nuget
- working-directory: ./src/backend/NetAdmin.AdmServer.Host - working-directory: ./src/backend/YourSolution.AdmServer.Host
run: dotnet publish NetAdmin.AdmServer.Host.csproj -c Release run: dotnet publish YourSolution.AdmServer.Host.csproj -c Release
- run: docker build -t nsnail/netadmin:nightly . - run: docker build -t nsnail/netadmin:nightly .
- uses: docker/login-action@v3 - uses: docker/login-action@v3
with: with:

View File

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

2
.gitignore vendored
View File

@ -402,4 +402,4 @@ FodyWeavers.xsd
dist/ dist/
*.[Dd]esigner.cs *.[Dd]esigner.cs
*.db *.db
/assets/res/Ln.resx /assets/res/Ln.resx

12
.gitmodules vendored
View File

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

View File

@ -2,6 +2,143 @@
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. 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.
### [2.3.1](https://github.com/nsnail/NetAdmin/compare/v2.1.0...v2.3.1) (2024-12-13)
### Features
* ✨ 菜单复制 ([#214](https://github.com/nsnail/NetAdmin/issues/214)) ([81d9b0b](https://github.com/nsnail/NetAdmin/commit/81d9b0b3bb280661ceffa61aa6e9d612fb7ec52c))
* ✨ 分组统计功能 ([0b036e9](https://github.com/nsnail/NetAdmin/commit/0b036e9d67ffdf7a07c772606009f02744e6a3c3))
* ✨ 框架代码同步 ([098cfc1](https://github.com/nsnail/NetAdmin/commit/098cfc135e781a0cf172cd1289e5e871c7a76419))
* ✨ 框架代码同步 ([7256626](https://github.com/nsnail/NetAdmin/commit/725662693b7b47f6fae4c1917dd8d80220c7640a))
* ✨ 文档管理 ([#221](https://github.com/nsnail/NetAdmin/issues/221)) ([7ed3040](https://github.com/nsnail/NetAdmin/commit/7ed30406c9f721a12f0b756ec8884a1882242b93))
* ✨ select-filter badge icon ([#217](https://github.com/nsnail/NetAdmin/issues/217)) ([4d857f1](https://github.com/nsnail/NetAdmin/commit/4d857f1861b1256980e7cc59e2ab6a5f7d966da2))
### Bug Fixes
* 🐛 按钮文字提示 ([#227](https://github.com/nsnail/NetAdmin/issues/227)) ([c88c8d2](https://github.com/nsnail/NetAdmin/commit/c88c8d293d44f2707f3b5232e6a40a141af9981c))
* 🐛 导出界面报错 ([#213](https://github.com/nsnail/NetAdmin/issues/213)) ([ef2f0de](https://github.com/nsnail/NetAdmin/commit/ef2f0de095e314f34bec21c0a2ccdb51423a163b))
* 🐛 导出文件的responseType ([#205](https://github.com/nsnail/NetAdmin/issues/205)) ([841a419](https://github.com/nsnail/NetAdmin/commit/841a4195e77aa96e3c6c72626c1add3f71a310aa))
* 🐛 个性主题色冲突 ([4e4a1d0](https://github.com/nsnail/NetAdmin/commit/4e4a1d0dff7f3698e9a9cfcf46368260cfd70cbd))
* 🐛 请求日志批量插入,漏写了登录日志 ([#210](https://github.com/nsnail/NetAdmin/issues/210)) ([6c71c74](https://github.com/nsnail/NetAdmin/commit/6c71c74a27617c7d0530a5f6eaff650ecfd4eaec))
* 🐛 修复一些样式问题 ([442a69f](https://github.com/nsnail/NetAdmin/commit/442a69f90de179539f78c01d967572f83bd2eff8))
* 🐛 用户选择器报错 ([#220](https://github.com/nsnail/NetAdmin/issues/220)) ([71bfdaa](https://github.com/nsnail/NetAdmin/commit/71bfdaafa8176cf686b03244ee758de058080a71))
* 🐛 editUser ([ef2a0c3](https://github.com/nsnail/NetAdmin/commit/ef2a0c3280532ac24889279e4780a1b1a2561a6b))
* 🐛 idd ([#208](https://github.com/nsnail/NetAdmin/issues/208)) ([4e9f605](https://github.com/nsnail/NetAdmin/commit/4e9f605ea2cc6fe394068cfea5638e51920b9096))
* 🐛 version 条件重复指定 ([01058ba](https://github.com/nsnail/NetAdmin/commit/01058ba7288bcc645f66de2f78e1d659d55333cf))
* 🐛 version lock ([4eecc0b](https://github.com/nsnail/NetAdmin/commit/4eecc0b4ce09f620f83109949e4c2b67b7f8ba90))
## [2.3.0](https://github.com/nsnail/NetAdmin/compare/v2.1.0...v2.3.0) (2024-12-12)
### Features
* ✨ 菜单复制 ([#214](https://github.com/nsnail/NetAdmin/issues/214)) ([81d9b0b](https://github.com/nsnail/NetAdmin/commit/81d9b0b3bb280661ceffa61aa6e9d612fb7ec52c))
* ✨ 分组统计功能 ([0b036e9](https://github.com/nsnail/NetAdmin/commit/0b036e9d67ffdf7a07c772606009f02744e6a3c3))
* ✨ 框架代码同步 ([098cfc1](https://github.com/nsnail/NetAdmin/commit/098cfc135e781a0cf172cd1289e5e871c7a76419))
* ✨ 框架代码同步 ([7256626](https://github.com/nsnail/NetAdmin/commit/725662693b7b47f6fae4c1917dd8d80220c7640a))
* ✨ 文档管理 ([#221](https://github.com/nsnail/NetAdmin/issues/221)) ([7ed3040](https://github.com/nsnail/NetAdmin/commit/7ed30406c9f721a12f0b756ec8884a1882242b93))
* ✨ select-filter badge icon ([#217](https://github.com/nsnail/NetAdmin/issues/217)) ([4d857f1](https://github.com/nsnail/NetAdmin/commit/4d857f1861b1256980e7cc59e2ab6a5f7d966da2))
### Bug Fixes
* 🐛 按钮文字提示 ([#227](https://github.com/nsnail/NetAdmin/issues/227)) ([c88c8d2](https://github.com/nsnail/NetAdmin/commit/c88c8d293d44f2707f3b5232e6a40a141af9981c))
* 🐛 导出界面报错 ([#213](https://github.com/nsnail/NetAdmin/issues/213)) ([ef2f0de](https://github.com/nsnail/NetAdmin/commit/ef2f0de095e314f34bec21c0a2ccdb51423a163b))
* 🐛 导出文件的responseType ([#205](https://github.com/nsnail/NetAdmin/issues/205)) ([841a419](https://github.com/nsnail/NetAdmin/commit/841a4195e77aa96e3c6c72626c1add3f71a310aa))
* 🐛 个性主题色冲突 ([4e4a1d0](https://github.com/nsnail/NetAdmin/commit/4e4a1d0dff7f3698e9a9cfcf46368260cfd70cbd))
* 🐛 请求日志批量插入,漏写了登录日志 ([#210](https://github.com/nsnail/NetAdmin/issues/210)) ([6c71c74](https://github.com/nsnail/NetAdmin/commit/6c71c74a27617c7d0530a5f6eaff650ecfd4eaec))
* 🐛 用户选择器报错 ([#220](https://github.com/nsnail/NetAdmin/issues/220)) ([71bfdaa](https://github.com/nsnail/NetAdmin/commit/71bfdaafa8176cf686b03244ee758de058080a71))
* 🐛 editUser ([ef2a0c3](https://github.com/nsnail/NetAdmin/commit/ef2a0c3280532ac24889279e4780a1b1a2561a6b))
* 🐛 idd ([#208](https://github.com/nsnail/NetAdmin/issues/208)) ([4e9f605](https://github.com/nsnail/NetAdmin/commit/4e9f605ea2cc6fe394068cfea5638e51920b9096))
* 🐛 version 条件重复指定 ([01058ba](https://github.com/nsnail/NetAdmin/commit/01058ba7288bcc645f66de2f78e1d659d55333cf))
* 🐛 version lock ([4eecc0b](https://github.com/nsnail/NetAdmin/commit/4eecc0b4ce09f620f83109949e4c2b67b7f8ba90))
### [2.2.1](https://github.com/nsnail/NetAdmin/compare/v2.1.0...v2.2.1) (2024-12-04)
### Features
* ✨ 菜单复制 ([#214](https://github.com/nsnail/NetAdmin/issues/214)) ([81d9b0b](https://github.com/nsnail/NetAdmin/commit/81d9b0b3bb280661ceffa61aa6e9d612fb7ec52c))
* ✨ 文档管理 ([#221](https://github.com/nsnail/NetAdmin/issues/221)) ([7ed3040](https://github.com/nsnail/NetAdmin/commit/7ed30406c9f721a12f0b756ec8884a1882242b93))
* ✨ select-filter badge icon ([#217](https://github.com/nsnail/NetAdmin/issues/217)) ([4d857f1](https://github.com/nsnail/NetAdmin/commit/4d857f1861b1256980e7cc59e2ab6a5f7d966da2))
### Bug Fixes
* 🐛 按钮文字提示 ([#227](https://github.com/nsnail/NetAdmin/issues/227)) ([c88c8d2](https://github.com/nsnail/NetAdmin/commit/c88c8d293d44f2707f3b5232e6a40a141af9981c))
* 🐛 导出界面报错 ([#213](https://github.com/nsnail/NetAdmin/issues/213)) ([ef2f0de](https://github.com/nsnail/NetAdmin/commit/ef2f0de095e314f34bec21c0a2ccdb51423a163b))
* 🐛 导出文件的responseType ([#205](https://github.com/nsnail/NetAdmin/issues/205)) ([841a419](https://github.com/nsnail/NetAdmin/commit/841a4195e77aa96e3c6c72626c1add3f71a310aa))
* 🐛 请求日志批量插入,漏写了登录日志 ([#210](https://github.com/nsnail/NetAdmin/issues/210)) ([6c71c74](https://github.com/nsnail/NetAdmin/commit/6c71c74a27617c7d0530a5f6eaff650ecfd4eaec))
* 🐛 用户选择器报错 ([#220](https://github.com/nsnail/NetAdmin/issues/220)) ([71bfdaa](https://github.com/nsnail/NetAdmin/commit/71bfdaafa8176cf686b03244ee758de058080a71))
* 🐛 editUser ([ef2a0c3](https://github.com/nsnail/NetAdmin/commit/ef2a0c3280532ac24889279e4780a1b1a2561a6b))
* 🐛 idd ([#208](https://github.com/nsnail/NetAdmin/issues/208)) ([4e9f605](https://github.com/nsnail/NetAdmin/commit/4e9f605ea2cc6fe394068cfea5638e51920b9096))
* 🐛 version 条件重复指定 ([01058ba](https://github.com/nsnail/NetAdmin/commit/01058ba7288bcc645f66de2f78e1d659d55333cf))
* 🐛 version lock ([4eecc0b](https://github.com/nsnail/NetAdmin/commit/4eecc0b4ce09f620f83109949e4c2b67b7f8ba90))
## [2.2.0](https://github.com/nsnail/NetAdmin/compare/v2.1.0...v2.2.0) (2024-11-27)
### Features
* ✨ 菜单复制 ([#214](https://github.com/nsnail/NetAdmin/issues/214)) ([81d9b0b](https://github.com/nsnail/NetAdmin/commit/81d9b0b3bb280661ceffa61aa6e9d612fb7ec52c))
* ✨ 文档管理 ([#221](https://github.com/nsnail/NetAdmin/issues/221)) ([7ed3040](https://github.com/nsnail/NetAdmin/commit/7ed30406c9f721a12f0b756ec8884a1882242b93))
* ✨ select-filter badge icon ([#217](https://github.com/nsnail/NetAdmin/issues/217)) ([4d857f1](https://github.com/nsnail/NetAdmin/commit/4d857f1861b1256980e7cc59e2ab6a5f7d966da2))
### Bug Fixes
* 🐛 导出界面报错 ([#213](https://github.com/nsnail/NetAdmin/issues/213)) ([ef2f0de](https://github.com/nsnail/NetAdmin/commit/ef2f0de095e314f34bec21c0a2ccdb51423a163b))
* 🐛 导出文件的responseType ([#205](https://github.com/nsnail/NetAdmin/issues/205)) ([841a419](https://github.com/nsnail/NetAdmin/commit/841a4195e77aa96e3c6c72626c1add3f71a310aa))
* 🐛 请求日志批量插入,漏写了登录日志 ([#210](https://github.com/nsnail/NetAdmin/issues/210)) ([6c71c74](https://github.com/nsnail/NetAdmin/commit/6c71c74a27617c7d0530a5f6eaff650ecfd4eaec))
* 🐛 用户选择器报错 ([#220](https://github.com/nsnail/NetAdmin/issues/220)) ([71bfdaa](https://github.com/nsnail/NetAdmin/commit/71bfdaafa8176cf686b03244ee758de058080a71))
* 🐛 idd ([#208](https://github.com/nsnail/NetAdmin/issues/208)) ([4e9f605](https://github.com/nsnail/NetAdmin/commit/4e9f605ea2cc6fe394068cfea5638e51920b9096))
## [2.1.0](https://github.com/nsnail/NetAdmin/compare/v2.0.0...v2.1.0) (2024-11-15)
### Features
* ✨ 首页仪表板自定义布局 ([#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
* 🐛 --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) ## [1.5.0](https://github.com/nsnail/NetAdmin/compare/v1.4.0...v1.5.0) (2024-07-26)

View File

@ -1,6 +1,7 @@
<!-- 注意此文件名大小写不可变更 --> <!-- 注意此文件名大小写不可变更 -->
<Project> <Project>
<PropertyGroup> <PropertyGroup>
<DefineConstants>DBTYPE_SQLITE</DefineConstants>
<SolutionDir>$(MSBuildThisFileDirectory)</SolutionDir> <SolutionDir>$(MSBuildThisFileDirectory)</SolutionDir>
</PropertyGroup> </PropertyGroup>
<Import Project="$(SolutionDir)/build/minver.targets" /> <Import Project="$(SolutionDir)/build/minver.targets" />
@ -9,8 +10,8 @@
<Authors>nsnail</Authors> <Authors>nsnail</Authors>
<BaseIntermediateOutputPath>$(SolutionDir)/dist/backend/$(MSBuildProjectName)/obj</BaseIntermediateOutputPath> <BaseIntermediateOutputPath>$(SolutionDir)/dist/backend/$(MSBuildProjectName)/obj</BaseIntermediateOutputPath>
<BaseOutputPath>$(SolutionDir)/dist/backend/$(MSBuildProjectName)/bin</BaseOutputPath> <BaseOutputPath>$(SolutionDir)/dist/backend/$(MSBuildProjectName)/bin</BaseOutputPath>
<Copyright>© 2006-2023 nsnail</Copyright> <Copyright>© 2006-2024 nsnail</Copyright>
<Description>通用后台权限管理系统、快速开发框架基于C#12/.NET9、Vue3/Vite、Element Plus等现代技术构建具有十分整洁、优雅的编码规范</Description> <Description>通用后台权限管理系统、快速开发框架基于C#13/.NET9、Vue3/Vite、ElementPlus等现代技术构建具有十分整洁、优雅的编码规范</Description>
<EnableBaseIntermediateOutputPathMismatchWarning>false</EnableBaseIntermediateOutputPathMismatchWarning> <EnableBaseIntermediateOutputPathMismatchWarning>false</EnableBaseIntermediateOutputPathMismatchWarning>
<GenerateDocumentationFile>true</GenerateDocumentationFile> <GenerateDocumentationFile>true</GenerateDocumentationFile>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
@ -25,12 +26,12 @@
<Title>$(AssemblyName)</Title> <Title>$(AssemblyName)</Title>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="MinVer" Version="5.0.0"> <PackageReference Include="MinVer" Version="6.0.0">
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="../GlobalUsings.cs" Link="GlobalUsings.cs" /> <Compile Include="$(SolutionDir)/src/backend/GlobalUsings.cs" Link="GlobalUsings.cs" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

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

View File

@ -1,12 +1,42 @@
Microsoft Visual Studio Solution File, Format Version 12.00 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17 # Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59 VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{C84EB5A0-37AD-4B17-A51E-E36888C4441E}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".drone", ".drone", "{3E408077-E73E-45CE-A53A-EF5F9DAE4B46}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "backend", "backend", "{4DAF9366-855F-46BB-AE4C-660C92FA0697}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{BB5BB244-E7D2-4368-8C18-C1C0ED1E12D1}"
ProjectSection(SolutionItems) = preProject
README.md = .drone/workflows/README.md
EndProjectSection
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{1129FE25-466B-4F4F-85FC-3752664245E1}"
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
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{8E4C93BA-9493-4892-80C4-5E174C504829}"
ProjectSection(SolutionItems) = preProject
code.quality.props = build/code.quality.props
copy.pkg.xml.comment.files.targets = build/copy.pkg.xml.comment.files.targets
minver.targets = build/minver.targets
prebuild.targets = build/prebuild.targets
stylecop.analyzers.ruleset = build/stylecop.analyzers.ruleset
EndProjectSection
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("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "meta", "meta", "{5198A03D-0CAC-4828-A807-34A693F73859}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "meta", "meta", "{5198A03D-0CAC-4828-A807-34A693F73859}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
.commitlintrc.js = .commitlintrc.js .commitlintrc.js = .commitlintrc.js
@ -26,11 +56,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "meta", "meta", "{5198A03D-0
README.md = README.md README.md = README.md
EndProjectSection EndProjectSection
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{BB0B25C9-0901-4923-913F-00F9A6B352A5}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{BB0B25C9-0901-4923-913F-00F9A6B352A5}"
ProjectSection(SolutionItems) = preProject ProjectSection(SolutionItems) = preProject
1.git.pull.request.ps1 = scripts/1.git.pull.request.ps1 1.git.pull.request.ps1 = scripts/1.git.pull.request.ps1
2.git.release.ps1 = scripts/2.git.release.ps1 2.git.release.ps1 = scripts/2.git.release.ps1
3.git.recreate.branch.ps1 = scripts/3.git.recreate.branch.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
5.git.update.submodule.ps1 = scripts/5.git.update.submodule.ps1
clean.ln.csx = scripts/clean.ln.csx clean.ln.csx = scripts/clean.ln.csx
code.clean.csx = scripts/code.clean.csx code.clean.csx = scripts/code.clean.csx
code.clean.ps1 = scripts/code.clean.ps1 code.clean.ps1 = scripts/code.clean.ps1
@ -43,53 +76,39 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{BB0B
install.as.tpl.ps1 = scripts/install.as.tpl.ps1 install.as.tpl.ps1 = scripts/install.as.tpl.ps1
rename.csx = scripts/rename.csx rename.csx = scripts/rename.csx
resharper.full.ps1 = scripts/resharper.full.ps1 resharper.full.ps1 = scripts/resharper.full.ps1
switcher.freesql.json = scripts/switcher.freesql.json switch.nuget.or.project.csx = scripts/switch.nuget.or.project.csx
switcher.furion.json = scripts/switcher.furion.json
switcher.nsext.json = scripts/switcher.nsext.json
switcher.ps1 = scripts/switcher.ps1
sync.sln.files.csx = scripts/sync.sln.files.csx sync.sln.files.csx = scripts/sync.sln.files.csx
wait.server.stop.sh = scripts/wait.server.stop.sh
EndProjectSection EndProjectSection
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{1129FE25-466B-4F4F-85FC-3752664245E1}"
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{C84EB5A0-37AD-4B17-A51E-E36888C4441E}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{3C6F049E-3EE8-4D66-9AFF-E8A369032487}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "backend", "backend", "{4DAF9366-855F-46BB-AE4C-660C92FA0697}"
ProjectSection(SolutionItems) = preProject
nightly-build.yml = .github/workflows/nightly-build.yml
release.yml = .github/workflows/release.yml
EndProjectSection
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "build", "build", "{8E4C93BA-9493-4892-80C4-5E174C504829}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetAdmin.Infrastructure", "src\backend\NetAdmin\NetAdmin.Infrastructure\NetAdmin.Infrastructure.csproj", "{1E62C322-EE42-4699-A6F1-791C53EFA62D}"
ProjectSection(SolutionItems) = preProject
code.quality.props = build/code.quality.props
copy.pkg.xml.comment.files.targets = build/copy.pkg.xml.comment.files.targets
minver.targets = build/minver.targets
prebuild.targets = build/prebuild.targets
stylecop.analyzers.ruleset = build/stylecop.analyzers.ruleset
EndProjectSection
EndProject 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}") = "YourSolution.AdmServer.Application", "src\backend\YourSolution.AdmServer.Application\YourSolution.AdmServer.Application.csproj", "{E38B2EB4-D7A5-4777-9236-3B348919DF23}"
EndProject 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.Host", "src\backend\YourSolution.AdmServer.Host\YourSolution.AdmServer.Host.csproj", "{CE895E44-EEC3-4ECE-A56A-8A82E7D863E3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetAdmin.AdmServer.Host", "src\backend\NetAdmin.AdmServer.Host\NetAdmin.AdmServer.Host.csproj", "{CE895E44-EEC3-4ECE-A56A-8A82E7D863E3}"
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "03.hosted-servers", "03.hosted-servers", "{12AE5B4B-CB1A-498E-83B8-04E201E31D86}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "03.hosted-servers", "03.hosted-servers", "{12AE5B4B-CB1A-498E-83B8-04E201E31D86}"
EndProject 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 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 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 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 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 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 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 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 EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "02.components", "02.components", "{3F23258D-8299-4992-9F51-2EE9B52CF9D2}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "02.components", "02.components", "{3F23258D-8299-4992-9F51-2EE9B52CF9D2}"
EndProject EndProject
@ -97,10 +116,25 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "01.frameworks", "01.framewo
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "04.tests", "04.tests", "{89260294-80FC-49F1-8D73-AECD39AFF2B7}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "04.tests", "04.tests", "{89260294-80FC-49F1-8D73-AECD39AFF2B7}"
EndProject 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 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 EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetAdmin.Tests", "src\backend\NetAdmin\NetAdmin.Tests\NetAdmin.Tests.csproj", "{00604162-C444-478B-B773-3AB23C856CA7}"
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}") = "Gurion", "refs\Gurion\src\Gurion\Gurion.csproj", "{CCD098FE-4F95-4FA4-8CC0-9A6DE921FBAE}"#refs
##EndProject#refs
##Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSql", "refs\NetAdmin.FreeSql\src\FreeSql\FreeSql.csproj", "{3C65DA42-877D-46FF-B754-C12214302A29}"#refs
##EndProject#refs
##Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSql.Provider.Sqlite", "refs\NetAdmin.FreeSql\src\FreeSql.Provider.Sqlite\FreeSql.Provider.Sqlite.csproj", "{CF5EFA63-4631-4A64-B4F3-98A7DD532F68}"#refs
##EndProject#refs
##Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSql.DbContext", "refs\NetAdmin.FreeSql\src\FreeSql.DbContext\FreeSql.DbContext.csproj", "{FE03DF27-EC56-48DB-81B0-F99947259A7C}"#refs
##EndProject#refs
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
@ -162,6 +196,30 @@ Global
{00604162-C444-478B-B773-3AB23C856CA7}.Debug|Any CPU.Build.0 = Debug|Any CPU {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.ActiveCfg = Release|Any CPU
{00604162-C444-478B-B773-3AB23C856CA7}.Release|Any CPU.Build.0 = Release|Any CPU {00604162-C444-478B-B773-3AB23C856CA7}.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
##{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 EndGlobalSection
GlobalSection(NestedProjects) = preSolution GlobalSection(NestedProjects) = preSolution
{4DAF9366-855F-46BB-AE4C-660C92FA0697} = {C84EB5A0-37AD-4B17-A51E-E36888C4441E} {4DAF9366-855F-46BB-AE4C-660C92FA0697} = {C84EB5A0-37AD-4B17-A51E-E36888C4441E}
@ -178,10 +236,14 @@ Global
{CE895E44-EEC3-4ECE-A56A-8A82E7D863E3} = {12AE5B4B-CB1A-498E-83B8-04E201E31D86} {CE895E44-EEC3-4ECE-A56A-8A82E7D863E3} = {12AE5B4B-CB1A-498E-83B8-04E201E31D86}
{89260294-80FC-49F1-8D73-AECD39AFF2B7} = {4DAF9366-855F-46BB-AE4C-660C92FA0697} {89260294-80FC-49F1-8D73-AECD39AFF2B7} = {4DAF9366-855F-46BB-AE4C-660C92FA0697}
{C7F27698-DA05-4ACD-B0D7-4791B3972002} = {89260294-80FC-49F1-8D73-AECD39AFF2B7} {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} {00604162-C444-478B-B773-3AB23C856CA7} = {D9C3EF66-2757-473D-A26B-54FD08DA203F}
{34650E82-D257-46DA-BD6B-DE307113347B} = {3F23258D-8299-4992-9F51-2EE9B52CF9D2} {34650E82-D257-46DA-BD6B-DE307113347B} = {3F23258D-8299-4992-9F51-2EE9B52CF9D2}
{19872A4C-3C9A-4C62-A33B-74F5B8D6F77C} = {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} {C2CC1596-3BEE-43EA-A9BE-4EDE5716296C} = {3F23258D-8299-4992-9F51-2EE9B52CF9D2}
{79409163-5006-405D-AC96-406FA0AD77B7} = {4DAF9366-855F-46BB-AE4C-660C92FA0697}
{932520DF-D312-415A-A128-1117F8221D68} = {12AE5B4B-CB1A-498E-83B8-04E201E31D86}
{C3DE6F6A-D1FC-4B8E-9033-980FBEBBD2BA} = {12AE5B4B-CB1A-498E-83B8-04E201E31D86}
{3C6F049E-3EE8-4D66-9AFF-E8A369032487} = {1129FE25-466B-4F4F-85FC-3752664245E1}
{BB5BB244-E7D2-4368-8C18-C1C0ED1E12D1} = {3E408077-E73E-45CE-A53A-EF5F9DAE4B46}
EndGlobalSection EndGlobalSection
EndGlobal 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_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_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/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/=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/=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> <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_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_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_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_002EMigrateBlankLinesAroundFieldToBlankLinesAroundProperty/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EPredefinedNamingRulesToUserRulesUpgrade/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ESettingsUpgrade_002EPredefinedNamingRulesToUserRulesUpgrade/@EntryIndexedValue">True</s:Boolean>

View File

@ -1,21 +1,20 @@
# NetAdmin # NetAdmin
通用后台权限管理系统、快速开发框架基于C#12/.NET9、Vue3/Vite、Element Plus等现代技术构建具有十分整洁、优雅的编码规范 通用后台权限管理系统、快速开发框架基于C#13/.NET9、Vue3/Vite、ElementPlus等现代技术构建具有十分整洁、优雅的编码规范
[![.NET](https://github.com/nsnail/NetAdmin/actions/workflows/nightly-build.yml/badge.svg)](https://github.com/nsnail/NetAdmin/actions/workflows/nightly-build.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) [![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) [![FreeSql](https://img.shields.io/badge/FreeSql-3.x-orange.svg)](https://github.com/nsnail/NetAdmin/blob/main/LICENSE)
## 在线预览 ## 在线预览
http://47.110.248.163:12000 https://na.tools92.top
## 一键运行 ## 一键运行
```shell ```shell
docker run -p 8080:8080 nsnail/netadmin docker run -p 8080:8080 nsnail/netadmin
# 需翻墙 # 需魔法上网
``` ```
## 构建步骤 ## 构建步骤
@ -28,14 +27,16 @@ dotnet --list-sdks
# 2. 克隆代码仓库 # 2. 克隆代码仓库
git clone https://github.com/nsnail/NetAdmin.git && cd ./NetAdmin git clone https://github.com/nsnail/NetAdmin.git && cd ./NetAdmin
# 3. 检查本机 redis 运行状态 # 3. 确认本机 redis 处于运行状态
redis-cli dbsize redis-server # 启动服务器
redis-cli # 连接测试
# 下载 redis for windowshttps://github.com/redis-windows/redis-windows/releases # 下载 redis for windowshttps://github.com/redis-windows/redis-windows/releases
# 下载 redis for linux/machttps://redis.io/download # 下载 redis for linux/machttps://redis.io/download
# 4. 运行后端 WebApi # 4. 运行后端 WebApi
dotnet run --project ./src/backend/NetAdmin.AdmServer.Host/NetAdmin.AdmServer.Host.csproj --urls http://[::]:5010 -is dotnet run --project ./src/backend/YourSolution.AdmServer.Host/YourSolution.AdmServer.Host.csproj --urls http://[::]:5010 -is
# 浏览器打开 http://localhost:5010 将看到SwaggerKnife4jUI界面 # -i 插入种子数据;-s 同步数据库结构
# 浏览器访问 http://localhost:5010 将看到SwaggerKnife4jUI界面
# 5. 检查 nodejs 版本 >=20 # 5. 检查 nodejs 版本 >=20
node -v node -v
@ -46,51 +47,59 @@ cd ./src/frontend/admin && npm install
# 7. 运行前端项目 # 7. 运行前端项目
npm run dev npm run dev
# 浏览器打开 http://localhost:5020 将看到管理界面默认用户名root,密码:1234qwer # 浏览器访问 http://localhost:5020 ,将看到管理界面(默认用户名密码root 1234qwer
``` ```
## 文件目录 ## 文件目录
``` ```
+---.github # github 工程文件目录
+---.template.config # dotnet 项目模板配置目录 +---.template.config # dotnet 项目模板配置目录
+---assets # 项目资源文件目录 +---assets # 项目资源文件目录
+---build # 构建相关的工程文件目录 +---build # 构建相关的工程文件目录
+---dist # 编译生成的二进制文件目录 +---dist # 编译生成的二进制文件目录
+---docker # docker 镜像构建文件目录
+---docs # 项目开发文档目录 +---docs # 项目开发文档目录
+---refs # 引用的第三方包的仓库目录 +---refs # 引用的第三方包的仓库目录
+---scripts # 各种工具脚本文件目录 +---scripts # 各种工具脚本文件目录
+---src # 项目源码文件目录 +---src # 项目源码文件目录
``` ```
## 后端项目架构 ## 项目架构
```mermaid ```mermaid
flowchart TD flowchart TD
H["NetAdmin.Host\n公共主机层\n.Net自托管主机程序\n输入输出格式化\n数据校验、鉴权\n...所有HTTP管道过滤器中间件"] --> C["NetAdmin.Cache\n公共缓存层\n基于Redis或MemoryCache的缓存策略实现"] sys-host["NetAdmin.SysComponent.Host\n系统组件主机层"]
C --> A["NetAdmin.Application\n公共业务逻辑层\n内部服务增删改查\n外部服务增删改查\n...所有业务用例的计算与组合逻辑的模块化)"] sys-cache["NetAdmin.SysComponent.Cache\n系统组件缓存层"]
A --> D["NetAdmin.Domain\n数据实体层\n数据库关系实体映射\nDTO数据传输对象\n...所有数据模型的抽象与封装)"] sys-app["NetAdmin.SysComponent.Application\n系统组件应用层"]
D --> I["NetAdmin.Infrastructure\n基础设施层\n第三方组件和Nuget包引用\n公共构建和程序运行配置\n公共常量枚举异常定义\n全球化化和多语言\n...所有公共Utility工具"] host["<b>NetAdmin.Host</b>\n框架主机层\n.Net自托管主机程序\n输入输出格式化\n数据校验、鉴权\n...所有HTTP管道过滤器中间件"]
cache["<b>NetAdmin.Cache</b>\n框架缓存层\n基于Redis或MemoryCache的缓存策略实现"]
XH["NetAdmin.XXX.Host\nWebApi"]-->H app["<b>NetAdmin.Application</b>\n框架业务应用层\n内部服务增删改查\n外部服务增删改查\n...所有业务用例的计算与组合逻辑的模块化)"]
XS["NetAdmin.XXXService\n常驻内存服务"]-->H domain["<b>NetAdmin.Domain</b>\n框架数据实体层\n数据库关系实体映射\nDTO数据传输对象\n...所有数据模型的抽象与封装)"]
XS["NetAdmin.XXXService\n常驻内存服务"]-->XC infra["<b>NetAdmin.Infrastructure</b>\n框架基础设施层\n第三方组件和Nuget包引用\n公共构建和程序运行配置\n公共常量枚举异常定义\n全球化化和多语言\n...所有公共Utility工具"]
XC["NetAdmin.XXX.Cache\n缓存层实例"]-->C biz-host["YourSolution.XXX.Host\n业务实例主机层"]
XA["NetAdmin.XXX.Application\n业务逻辑层实例)"]-->A biz-cache["YourSolution.XXX.Cache\n业务实例:缓存层"]
biz-app["YourSolution.XXX.Application\n业务实例应用层"]
XH-->XC biz-domain["YourSolution.XXX.Domain\n业务实例数据实体层"]
XC-->XA biz-infra["YourSolution.XXX.Infrastructure\n业务实例基础设施层"]
biz-host-->biz-cache-->biz-app-->biz-domain-->biz-infra
sys-host-->sys-cache-->sys-app-->domain-->infra
host-->cache-->app-->domain-->infra
biz-host-->sys-host-->host
biz-cache-->sys-cache-->cache
biz-app-->sys-app-->app
biz-domain-->domain
biz-infra-->infra
``` ```
## 引用的开源代码 / 特别鸣谢 ## 特别鸣谢
| 语言 | 集成领域 | 开源库 | | 语言 | 集成领域 | 开源库 |
|------------|---------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| |------------|---------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| C# | Web基础框架 | [ASP.NET Core](https://github.com/dotnet/aspnetcore) | | 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# | 数据库关系映射 | [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# | 代码质量检查 | [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# | 单元测试框架 | [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# | 控制台终端界面库 | [Spectre.Console](https://github.com/spectreconsole/spectre.console) |
| C# | 扩展函数库 | [NSExt](https://github.com/nsnail/ns-ext.git) | | C# | 扩展函数库 | [NSExt](https://github.com/nsnail/ns-ext.git) |
| C# | 图形处理库 | [SixLabors.ImageSharp](https://github.com/SixLabors/ImageSharp) | | C# | 图形处理库 | [SixLabors.ImageSharp](https://github.com/SixLabors/ImageSharp) |
@ -98,11 +107,9 @@ XC-->XA
| C# | 性能监控采集 | [prometheus-net.AspNetCore](https://github.com/prometheus-net/prometheus-net) | | C# | 性能监控采集 | [prometheus-net.AspNetCore](https://github.com/prometheus-net/prometheus-net) |
| C# | 雪花ID生成器 | [Yitter.IdGenerator](https://github.com/yitter/idgenerator) | | C# | 雪花ID生成器 | [Yitter.IdGenerator](https://github.com/yitter/idgenerator) |
| C# | 自动化版本管理 | [MinVer](https://github.com/adamralph/minver) | | 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 | SPA基础框架 | [Vue](https://github.com/vuejs/core) |
| TypeScript | 前端构建工具 | [Vite](https://github.com/vitejs/vite) | | TypeScript | 前端构建工具 | [Vite](https://github.com/vitejs/vite) |
| TypeScript | UI控件库 | [Element Plus](https://github.com/element-plus/element-plus) | | TypeScript | UI控件库 | [ElementPlus](https://github.com/element-plus/element-plus) |
| TypeScript | CSS解析器 | [Sass](https://github.com/sass/sass) | | TypeScript | CSS解析器 | [Sass](https://github.com/sass/sass) |
| TypeScript | 图表和数据可视化 | [ECharts](https://github.com/apache/echarts) | | TypeScript | 图表和数据可视化 | [ECharts](https://github.com/apache/echarts) |
| JavaScript | 后台管理界面 | [SCUI](https://gitee.com/lolicode/scui) | | JavaScript | 后台管理界面 | [SCUI](https://gitee.com/lolicode/scui) |

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

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

View File

@ -72,12 +72,16 @@
插入种子数据 插入种子数据
操作系统 操作系统
数据范围 数据范围
文档内容
文档内容导出
文档标题
无效操作 无效操作
无效输入 无效输入
无限权限 无限权限
日期范围 日期范围
是否启用 是否启用
显示仪表板 显示仪表板
最后登录时间
未处理异常 未处理异常
未婚 未婚
未读 未读
@ -126,7 +130,6 @@
调试 调试
跟踪 跟踪
跟踪标识 跟踪标识
跟踪编号
身份证 身份证
运行 运行
通知 通知

View File

@ -21,6 +21,7 @@ XML注释文件不存在
字典目录编号不能为空 字典目录编号不能为空
字典编码不能为空 字典编码不能为空
学历不正确 学历不正确
完全公开
密码不能为空 密码不能为空
已处理完毕 已处理完毕
并发冲突_请稍后重试 并发冲突_请稍后重试
@ -35,6 +36,12 @@ XML注释文件不存在
数据库服务器时钟偏移 数据库服务器时钟偏移
数据库结构同步完成 数据库结构同步完成
文件不能为空 文件不能为空
文档内容不能为空
文档分类不存在
文档分类名称不能为空
文档分类编号不能为空
文档分类编码不能为空
文档标题不能为空
新密码不能为空 新密码不能为空
新手机号码验证码不正确 新手机号码验证码不正确
无效端口号 无效端口号
@ -47,8 +54,11 @@ XML注释文件不存在
时间计划不能为空 时间计划不能为空
未指定部门 未指定部门
未获取到待执行任务 未获取到待执行任务
档案可见性不正确
模块名称不能为空 模块名称不能为空
模块类型不能为空
模块说明不能为空 模块说明不能为空
此节点已下线
民族不正确 民族不正确
消息主题不能为空 消息主题不能为空
消息内容不能为空 消息内容不能为空
@ -60,12 +70,16 @@ XML注释文件不存在
用户名长度4位以上 用户名长度4位以上
用户头像不能为空 用户头像不能为空
用户编号不存在 用户编号不存在
登录用户
目标设备不能为空 目标设备不能为空
短信验证请求不能为空 短信验证请求不能为空
种子数据插入完成
站内信不存在 站内信不存在
站内信状态不正确 站内信状态不正确
站内信类型不正确 站内信类型不正确
缓存键不能为空
网络地址不正确 网络地址不正确
自己可见
菜单名称不能为空 菜单名称不能为空
菜单标题不能为空 菜单标题不能为空
菜单类型不正确 菜单类型不正确
@ -75,6 +89,7 @@ XML注释文件不存在
角色数据范围不正确 角色数据范围不正确
角色编号不能为空 角色编号不能为空
角色编号列表不能为空 角色编号列表不能为空
记录已存在
设备类型不能为空 设备类型不能为空
证件类型不正确 证件类型不正确
该角色下存在用户 该角色下存在用户
@ -83,12 +98,14 @@ XML注释文件不存在
请求地址不能为空 请求地址不能为空
请求对象不能为空 请求对象不能为空
请求方法不正确 请求方法不正确
请稍后重试
请联系管理员激活账号 请联系管理员激活账号
读取用户令牌出错 读取用户令牌出错
账号不能为空 账号不能为空
邀请码不正确 邀请码不正确
邮箱验证码不正确 邮箱验证码不正确
部门不存在 部门不存在
部门可见
部门名称不能为空 部门名称不能为空
配置文件初始化完毕 配置文件初始化完毕
键值不能为空 键值不能为空

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -140,13 +140,34 @@
"Title": "缓存管理", "Title": "缓存管理",
"Type": 1 "Type": 1
}, },
// ------------------------------ 档案管理 ------------------------------
{
"Icon": "sc-icon-Archive",
"Id": 616214756757512,
"Name": "archive",
"Path": "/archive",
"Sort": 98,
"Title": "档案管理",
"Type": 1
},
{
"Component": "sys/doc",
"Icon": "el-icon-document",
"Id": 616214756757516,
"Name": "archive/doc",
"ParentId": 616214756757512,
"Path": "/archive/doc",
"Sort": 100,
"Title": "文档管理",
"Type": 1
},
// ------------------------------ 日志管理 ------------------------------ // ------------------------------ 日志管理 ------------------------------
{ {
"Icon": "el-icon-tickets", "Icon": "el-icon-tickets",
"Id": 374792687640581, "Id": 374792687640581,
"Name": "log", "Name": "log",
"Path": "/log", "Path": "/log",
"Sort": 98, "Sort": 97,
"Title": "日志管理", "Title": "日志管理",
"Type": 1 "Type": 1
}, },
@ -178,7 +199,7 @@
"Id": 373838105399301, "Id": 373838105399301,
"Name": "dev", "Name": "dev",
"Path": "/dev", "Path": "/dev",
"Sort": 97, "Sort": 96,
"Title": "开发管理", "Title": "开发管理",
"Type": 1 "Type": 1
}, },
@ -198,7 +219,7 @@
"ParentId": 373838105399301, "ParentId": 373838105399301,
"Icon": "el-icon-eleme-filled", "Icon": "el-icon-eleme-filled",
"Name": "dev/element", "Name": "dev/element",
"Path": "http://element-plus.org/zh-CN/component/overview.html", "Path": "https://element-plus.org/zh-CN/component/overview.html",
"Sort": 99, "Sort": 99,
"Title": "Element", "Title": "Element",
"Type": 3, "Type": 3,

View File

@ -1,10 +1,10 @@
[ [
{ {
"Content": "<p>尊敬的用户:</p>\n<p style=\"padding-left: 40px;\">欢迎您使用 NetAdmin 后台管理系统NetAdmin 是一款通用后台权限管理系统和快速开发框架,它基于 C#12/.NET9、Vue3/Vite、Element Plus 等现代技术构建,具有十分整洁、优雅的编码规范。</p>\n<p style=\"padding-left: 40px;\">NetAdmin 致力于为企业提供高效、安全、易用的解决方案,帮助您快速构建出符合业务需求的应用程序。系统提供了丰富的功能模块,包括用户管理、权限管理、日志管理、文件上传等,可以满足您日常管理的需求。</p>\n<p style=\"padding-left: 40px;\">在使用 NetAdmin 的过程中,我们真诚地希望您能够遵守以下规定:</p>\n<p style=\"padding-left: 80px;\">1. 不得利用 NetAdmin 进行非法活动或者侵犯他人权益;</p>\n<p style=\"padding-left: 80px;\">2. 不得对 NetAdmin 系统进行恶意攻击或者破坏;</p>\n<p style=\"padding-left: 80px;\">3. 不得将 NetAdmin 系统的任何部分用于商业目的或者未经授权的访问。</p>\n<p style=\"padding-left: 80px;\">4. 为了更好地为您提供服务NetAdmin 将不断进行优化和升级,同时也欢迎您提出宝贵的意见和建议。如果您在使用过程中遇到任何问题,可以通过官方网站或者技术支持团队进行咨询和解决。</p>\n<p style=\"padding-left: 40px;\">再次感谢您对 NetAdmin 的信任和支持我们相信在您的使用过程中NetAdmin 一定会成为您的得力助手,为您的事业发展提供强有力的支持!</p>\n<p style=\"text-align: right;\">NetAdmin 开发团队</p>", "Content": "<p>尊敬的用户:</p>\n<p style=\"padding-left: 40px;\">欢迎您使用 NetAdmin 后台管理系统NetAdmin 是一款通用后台权限管理系统和快速开发框架,它基于 C#13/.NET9、Vue3/Vite、ElementPlus 等现代技术构建,具有十分整洁、优雅的编码规范。</p>\n<p style=\"padding-left: 40px;\">NetAdmin 致力于为企业提供高效、安全、易用的解决方案,帮助您快速构建出符合业务需求的应用程序。系统提供了丰富的功能模块,包括用户管理、权限管理、日志管理、文件上传等,可以满足您日常管理的需求。</p>\n<p style=\"padding-left: 40px;\">在使用 NetAdmin 的过程中,我们真诚地希望您能够遵守以下规定:</p>\n<p style=\"padding-left: 80px;\">1. 不得利用 NetAdmin 进行非法活动或者侵犯他人权益;</p>\n<p style=\"padding-left: 80px;\">2. 不得对 NetAdmin 系统进行恶意攻击或者破坏;</p>\n<p style=\"padding-left: 80px;\">3. 不得将 NetAdmin 系统的任何部分用于商业目的或者未经授权的访问。</p>\n<p style=\"padding-left: 80px;\">4. 为了更好地为您提供服务NetAdmin 将不断进行优化和升级,同时也欢迎您提出宝贵的意见和建议。如果您在使用过程中遇到任何问题,可以通过官方网站或者技术支持团队进行咨询和解决。</p>\n<p style=\"padding-left: 40px;\">再次感谢您对 NetAdmin 的信任和支持我们相信在您的使用过程中NetAdmin 一定会成为您的得力助手,为您的事业发展提供强有力的支持!</p>\n<p style=\"text-align: right;\">NetAdmin 开发团队</p>",
"CreatedUserId": 370942943322181, "CreatedUserId": 370942943322181,
"CreatedUserName": "root", "CreatedUserName": "root",
"MsgType": 2, "MsgType": 2,
"Summary": "尊敬的用户:\n欢迎您使用 NetAdmin 后台管理系统NetAdmin 是一款通用后台权限管理系统和快速开发框架,它基于 C#12/.NET9、Vue3/Vite、Element Plus 等现代", "Summary": "尊敬的用户:\n欢迎您使用 NetAdmin 后台管理系统NetAdmin 是一款通用后台权限管理系统和快速开发框架,它基于 C#13/.NET9、Vue3/Vite、ElementPlus 等现代",
"Title": "欢迎使用 NetAdmin 后台管理系统", "Title": "欢迎使用 NetAdmin 后台管理系统",
} }
] ]

View File

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

View File

@ -9,22 +9,4 @@
Command="dotnet t4 ./gen.cs.tt -o ../dist/backend/$(ProjectName)/Ln.cs" Command="dotnet t4 ./gen.cs.tt -o ../dist/backend/$(ProjectName)/Ln.cs"
StdOutEncoding="utf-8" /> StdOutEncoding="utf-8" />
</Target> </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/Fields.ln">
<Link>Languages/Fields.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> </Project>

1
docker/README.md Normal file
View File

@ -0,0 +1 @@
docker

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 207 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

View File

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

View File

@ -1,9 +1,9 @@
{ {
"version": "1.5.0", "version": "2.3.1",
"devDependencies": { "devDependencies": {
"cz-git": "^1.9.3", "cz-git": "^1.11.0",
"commitizen": "^4.3.0", "commitizen": "^4.3.1",
"prettier": "^3.3.3", "prettier": "^3.4.2",
"standard-version": "^9.5.0" "standard-version": "^9.5.0"
}, },
"config": { "config": {

Submodule refs/FreeSql deleted from 0f6c2b807d

Submodule refs/Furion deleted from d23c7cca55

1
refs/Gurion Submodule

Submodule refs/Gurion added at 89586fd0c6

1
refs/NetAdmin.FreeSql Submodule

Submodule refs/NetAdmin.FreeSql added at c851ae3da2

View File

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

@ -0,0 +1,3 @@
git submodule update --progress --init --recursive --force --remote -- "../refs/Gurion"
git submodule update --progress --init --recursive --force --remote -- "../refs/NetAdmin.FreeSql"
git submodule update --progress --init --recursive --force --remote -- "../refs/ns-ext"

View File

@ -1,6 +1,7 @@
<#@ template language="C#" #> <#@ template language="C#" #>
<#@ output encoding="utf-8" extension="resx" #> <#@ output encoding="utf-8" extension="resx" #>
<#@ import namespace="System.IO" #> <#@ import namespace="System.IO" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text.RegularExpressions" #> <#@ import namespace="System.Text.RegularExpressions" #>
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<root> <root>
@ -28,14 +29,11 @@
</resheader> </resheader>
<# <#
var regex = new Regex(@"^\d", RegexOptions.Compiled); 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> <data name="<#= regex.IsMatch(line) ? "_" : "" #><#= line #>" xml:space="preserve"><value><#= line #></value></data>
<# <#
}
} }
#> #>
</root> </root>

4
scripts/git.config.cmd Normal file
View File

@ -0,0 +1,4 @@
git config --local core.eol lf
git config --local core.autocrlf false
git config --local core.longpaths true
git config --local pull.rebase false

View File

@ -1,12 +1,11 @@
#r "nuget: NSExt, 2.2.0" #r "nuget: NSExt, 2.3.2"
using NSExt.Extensions; using NSExt.Extensions;
Console.WriteLine("请输入原始名称NetAdmin"); Console.WriteLine("请输入原始名称NetAdmin");
var oldName = Console.ReadLine().NullOrEmpty("NetAdmin"); var oldName = Console.ReadLine().NullOrEmpty("NetAdmin");
Console.WriteLine("请输入替换名称:"); Console.WriteLine("请输入替换名称:");
var newName = Console.ReadLine(); var newName = Console.ReadLine();
foreach (var path in Directory.EnumerateDirectories("../", $"*{oldName}*", foreach (var path in Directory.EnumerateDirectories("../", $"*{oldName}*", SearchOption.AllDirectories).Where(x => !x.Contains(".git")))
SearchOption.AllDirectories))
{ {
Console.Write($"{path} --> "); Console.Write($"{path} --> ");
var newPath = path.Replace(oldName, newName); var newPath = path.Replace(oldName, newName);
@ -16,7 +15,7 @@ foreach (var path in Directory.EnumerateDirectories("../", $"*{oldName}*",
Console.WriteLine(); Console.WriteLine();
foreach (var path in Directory.EnumerateFiles("../", $"*.*", SearchOption.AllDirectories)) foreach (var path in Directory.EnumerateFiles("../", $"*.*", SearchOption.AllDirectories).Where(x => !x.Contains(".git")))
{ {
File.WriteAllText(path, File.ReadAllText(path).Replace(oldName, newName)); File.WriteAllText(path, File.ReadAllText(path).Replace(oldName, newName));
var newPath = path.Replace(oldName, newName); var newPath = path.Replace(oldName, newName);

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.833-preview20260627-ns1"
},
{
"packageName": "FreeSql.DbContext.NS",
"version": "3.2.833-preview20260627-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.4.6-ns4"
}
]
}
]
}

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.2.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 = Regex.Replace(
content, content,
"Project\\(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\"\\) = \"workflows\", \"workflows\", \"{3C6F049E-3EE8-4D66-9AFF-E8A369032487}\"(?:.|\n)*?EndProject", "Project\\(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\"\\) = \"workflows\", \"workflows\", \"{3C6F049E-3EE8-4D66-9AFF-E8A369032487}\"(?:.|\n)*?EndProject",
@ -31,6 +45,20 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{
""" """
); );
content = Regex.Replace(
content,
"Project\\(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\"\\) = \"workflows\", \"workflows\", \"{BB5BB244-E7D2-4368-8C18-C1C0ED1E12D1}\"(?:.|\n)*?EndProject",
$$"""
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{BB5BB244-E7D2-4368-8C18-C1C0ED1E12D1}"
ProjectSection(SolutionItems) = preProject
{{string.Join('\n',
Directory.GetFiles(@"../.drone/workflows", "*")
.Select(x=>$" {Path.GetFileName(x)} = .drone/workflows/{Path.GetFileName(x)}")
)}}
EndProject
"""
);
content = Regex.Replace( content = Regex.Replace(
content, content,
"Project\\(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\"\\) = \"scripts\", \"scripts\", \"{BB0B25C9-0901-4923-913F-00F9A6B352A5}\"(?:.|\n)*?EndProject", "Project\\(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\"\\) = \"scripts\", \"scripts\", \"{BB0B25C9-0901-4923-913F-00F9A6B352A5}\"(?:.|\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.Aop;
global using FreeSql.DataAnnotations; global using FreeSql.DataAnnotations;
global using FreeSql.Internal.Model; global using FreeSql.Internal.Model;
global using Furion; global using Gurion;
global using Furion.Authorization; global using Gurion.Authorization;
global using Furion.ConfigurableOptions; global using Gurion.ConfigurableOptions;
global using Furion.DataEncryption; global using Gurion.DataEncryption;
global using Furion.DataValidation; global using Gurion.DataValidation;
global using Furion.DependencyInjection; global using Gurion.DependencyInjection;
global using Furion.DynamicApiController; global using Gurion.DynamicApiController;
global using Furion.EventBus; global using Gurion.EventBus;
global using Furion.SpecificationDocument; global using Gurion.SpecificationDocument;
global using Furion.UnifyResult; global using Gurion.UnifyResult;
global using Mapster; global using Mapster;
global using Microsoft.AspNetCore.Authorization; global using Microsoft.AspNetCore.Authorization;
global using Microsoft.AspNetCore.Builder; global using Microsoft.AspNetCore.Builder;
@ -63,18 +63,4 @@ global using NetAdmin.Infrastructure.Extensions;
global using NetAdmin.Infrastructure.Languages; global using NetAdmin.Infrastructure.Languages;
global using NetAdmin.Infrastructure.Utils; global using NetAdmin.Infrastructure.Utils;
global using NSExt.Attributes; global using NSExt.Attributes;
global using NSExt.Extensions; global using NSExt.Extensions;
#if !INFRAS
global using CsvHelper.Configuration.Attributes;
global using NetAdmin.Domain.Attributes;
global using NetAdmin.Domain.Attributes.DataValidation;
global using NetAdmin.Domain.DbMaps.Dependency;
global using NetAdmin.Domain.DbMaps.Dependency.Fields;
global using NetAdmin.Domain.DbMaps.Sys;
global using CsvIgnore = CsvHelper.Configuration.Attributes.IgnoreAttribute;
global using CsvIndex = CsvHelper.Configuration.Attributes.IndexAttribute;
global using CsvName = CsvHelper.Configuration.Attributes.NameAttribute;
global using DynamicFilterInfo = NetAdmin.Domain.Dto.Dependency.DynamicFilterInfo;
global using DynamicFilterOperators = NetAdmin.Domain.Enums.DynamicFilterOperators;
global using SqlIndex = FreeSql.DataAnnotations.IndexAttribute;
#endif

View File

@ -1,9 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<DefineConstants>DBTYPE_SQLITE</DefineConstants>
</PropertyGroup>
<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": []
}
}
}
]
}
}

File diff suppressed because it is too large Load Diff

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.11.0-release-24352-06"/>
</ItemGroup>
</Project>

View File

@ -1,50 +0,0 @@
using NetAdmin.Application.Repositories;
using RedLockNet;
namespace NetAdmin.Application.Services;
/// <summary>
/// RedLocker Service Base
/// </summary>
public abstract class RedLockerService<TEntity, TPrimary, TLogger>(
BasicRepository<TEntity, TPrimary> rpo
, RedLocker redLocker) : RepositoryService<TEntity, TPrimary, TLogger>(rpo)
where TEntity : EntityBase<TPrimary> //
where TPrimary : IEquatable<TPrimary>
{
/// <summary>
/// 获取锁
/// </summary>
protected Task<IRedLock> GetLockerAsync(string lockName)
{
return GetLockerAsync(lockName, TimeSpan.FromSeconds(Numbers.SECS_RED_LOCK_WAIT)
, TimeSpan.FromSeconds(Numbers.SECS_RED_LOCK_RETRY_INTERVAL));
}
/// <summary>
/// 获取锁
/// </summary>
/// <exception cref="NetAdminGetLockerException">NetAdminGetLockerException</exception>
protected async Task<IRedLock> GetLockerAsync(string lockName, TimeSpan waitTime, TimeSpan retryInterval)
{
// 加锁
var lockTask = waitTime == default || retryInterval == default
? redLocker.RedLockFactory.CreateLockAsync(lockName, TimeSpan.FromSeconds(Numbers.SECS_RED_LOCK_EXPIRY))
: redLocker.RedLockFactory.CreateLockAsync( //
lockName, TimeSpan.FromSeconds(Numbers.SECS_RED_LOCK_EXPIRY), waitTime, retryInterval);
var redLock = await lockTask.ConfigureAwait(false);
return redLock.IsAcquired ? redLock : throw new NetAdminGetLockerException();
}
/// <summary>
/// 获取锁
/// </summary>
/// <remarks>
/// 不重试,失败直接抛出异常
/// </remarks>
protected Task<IRedLock> GetLockerOnceAsync(string lockName)
{
return GetLockerAsync(lockName, default, default);
}
}

View File

@ -1,83 +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)
{
var ret = d.Adapt<FreeSql.Internal.Model.DynamicFilterInfo>();
ProcessDynamicFilter(ret);
return ret;
}
private static void ProcessDynamicFilter(FreeSql.Internal.Model.DynamicFilterInfo d)
{
if (d?.Filters != null) {
foreach (var filterInfo in d.Filters) {
ProcessDynamicFilter(filterInfo);
}
}
if (new[] { nameof(IFieldCreatedClientIp.CreatedClientIp), nameof(IFieldModifiedClientIp.ModifiedClientIp) }
.Contains(d?.Field, StringComparer.OrdinalIgnoreCase)) {
var val = d!.Value?.ToString();
if (val?.IsIpV4() == true) {
d.Value = val.IpV4ToInt32();
}
}
else if (d?.Operator == DynamicFilterOperator.DateRange) {
var values = ((JsonElement)d.Value).Deserialize<string[]>();
if (!DateTime.TryParse(values[0], CultureInfo.InvariantCulture, out _)) {
var result = values[0]
.ExecuteCSharpCodeAsync<DateTime>([typeof(DateTime).Assembly], nameof(System))
.ConfigureAwait(false)
.GetAwaiter()
.GetResult();
values[0] = $"{result:yyyy-MM-dd HH:mm:ss}";
}
if (!DateTime.TryParse(values[1], CultureInfo.InvariantCulture, out _)) {
var result = values[1]
.ExecuteCSharpCodeAsync<DateTime>([typeof(DateTime).Assembly], nameof(System))
.ConfigureAwait(false)
.GetAwaiter()
.GetResult();
values[1] = $"{result:yyyy-MM-dd HH:mm:ss}";
}
d.Value = values;
}
}
}

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,19 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<DefineConstants>DBTYPE_SQLITE</DefineConstants>
</PropertyGroup>
<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>
<ItemGroup>
<PackageReference Include="CronExpressionDescriptor" Version="2.36.0"/>
<PackageReference Include="Cronos" Version="0.8.4"/>
<PackageReference Include="CsvHelper.NS" Version="33.0.2-ns2"/>
<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="9.0.0-preview.6.24328.4"/>
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14"/>
</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,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,35 +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_EXPORT = 10000; // 最大限制导出为CSV文件的条数
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_CACHE_DIC_CATALOG_CODE = 300; // 秒:缓存时间-字典配置-目录代码
public const int SECS_RED_LOCK_EXPIRY = 30; // 秒RedLock-锁过期时间,假如持有锁的进程挂掉,最多在此时间内锁将被释放(如持有锁的进程正常,此值不会生效)
public const int SECS_RED_LOCK_RETRY_INTERVAL = 1; // 秒RedLock-锁等待时间内,多久尝试获取一次
public const int SECS_RED_LOCK_WAIT = 10; // 秒RedLock-锁等待时间,相同的 resource 如果当前的锁被其他线程占用,最多等待时间
public const int SECS_TIMEOUT_HTTP_CLIENT = 15; // 秒:超时时间-默认HTTP客户端
public const int SECS_TIMEOUT_JOB = 600; // 秒:超时时间-作业
}

View File

@ -1,89 +0,0 @@
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;
namespace NetAdmin.Infrastructure.Extensions;
/// <summary>
/// String 扩展方法
/// </summary>
public static class StringExtensions
{
private static readonly Regex _regexIpV4 = new(Chars.RGXL_IP_V4);
/// <summary>
/// 计算Crc32
/// </summary>
public static int Crc32(this string me)
{
return BitConverter.ToInt32(System.IO.Hashing.Crc32.Hash(Encoding.UTF8.GetBytes(me)));
}
/// <summary>
/// 执行C#代码
/// </summary>
public static Task<T> ExecuteCSharpCodeAsync<T>(this string me, Assembly[] assemblies
, params string[] importNamespaces)
{
// 使用 Roslyn 编译并执行代码
return CSharpScript.EvaluateAsync<T>(
me, ScriptOptions.Default.WithReferences(assemblies).WithImports(importNamespaces));
}
/// <summary>
/// 是否IPV4地址
/// </summary>
public static bool IsIpV4(this string me)
{
return _regexIpV4.IsMatch(me);
}
/// <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>
/// 去掉前部字符串
/// </summary>
public static string TrimPrefix(this string me, string clearStr)
{
return Regex.Replace(me, $"^{clearStr}", string.Empty);
}
/// <summary>
/// 去掉尾部字符串“Async”
/// </summary>
#pragma warning disable RCS1047, ASA002, VSTHRD200
public static string TrimPrefixAsync(this string me)
#pragma warning restore VSTHRD200, ASA002, RCS1047
{
return TrimPrefix(me, "Async");
}
/// <summary>
/// 去掉尾部字符串
/// </summary>
public static string TrimSuffix(this string me, string clearStr)
{
return Regex.Replace(me, $"{clearStr}$", string.Empty);
}
/// <summary>
/// 去掉尾部字符串“Options”
/// </summary>
public static string TrimSuffixOptions(this string me)
{
return TrimPrefix(me, "Options");
}
}

View File

@ -1,25 +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="FreeSql.DbContext.NS" Version="3.2.833-preview20260627-ns1"/>
<PackageReference Include="FreeSql.Provider.Sqlite.NS" Version="3.2.833-preview20260627-ns1"/>
<PackageReference Include="Furion.Extras.Authentication.JwtBearer" Version="4.9.4.6"/>
<PackageReference Include="Furion.Extras.ObjectMapper.Mapster.NS" Version="4.9.4.6-ns4"/>
<PackageReference Include="Furion.Pure.NS" Version="4.9.4.6-ns4"/>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.10.0"/>
<PackageReference Include="Minio" Version="6.0.3"/>
<PackageReference Include="NSExt" Version="2.2.0"/>
<PackageReference Include="RedLock.net" Version="2.3.2"/>
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.4"/>
</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",
},
}
}

View File

@ -1,332 +0,0 @@
{
"$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
// App基本配置
"AppSettings": {
// AppSettings配置根节点
// InjectMiniProfiler是否注入 MiniProfilerbool 类型,默认 true关闭 Swagger 左上角监听
// InjectSpecificationDocument是否启用 Swagger 文档bool 类型,默认 true生产环境可关闭
// EnabledReferenceAssemblyScan是否启用通过 dll 方式添加的引用程序集扫描bool 类型,默认 false
// ExternalAssemblies配置外部程序集完整路径支持动态加载string[] 类型,默认 []
// PrintDbConnectionInfo是否打印数据库连接信息到 MiniProfiler 中bool 类型,默认 true
// SupportPackageNamePrefixs配置支持的包前缀名string[] 类型,默认 []
// OutputOriginalSqlExecuteLog是否输出原始 Sql 执行日志ADO.NET默认 true
// VirtualPath配置虚拟目录必须以 / 开头
"InjectSpecificationDocument": false,
"InjectMiniProfiler": false
},
// Swagger文档配置 ------------------------------------------------------------------------------
"SpecificationDocumentSettings": {
// DocumentTitle文档标题string默认 Specification Api Document
// DefaultGroupName默认分组名string默认 Default
// EnableAuthorized是否启用权限控制bool默认 true
// FormatAsV2采用 Swagger 2.0 版本bool默认 false 已弃用
// RoutePrefix规范化文档地址string默认 api如果希望在首页改为空字符串即可。
// DocExpansionState文档显示方式DocExpansion默认 List取值
// List列表式展开子类默认值
// Full完全展开
// None列表式不展开子类
// XmlComments程序集注释描述文件名可带 .xmlstring默认 Furion.Application, Furion.Web.Entry, Furion.Web.Core
// GroupOpenApiInfos分组信息配置SpecificationOpenApiInfo[],默认 { 'Group': 'Default'}
// SecurityDefinitions安全策略定义配置SpecificationOpenApiSecurityScheme[],默认 []
// Servers配置 Server 下拉列表OpenApiServer[] 类型,默认 [],如:{Servers:[ { Url:"地址", Description:"描述"} ]}
// HideServers是否隐藏 Server 下拉列表bool 类型,默认 true
// RouteTemplate配置文档 swagger.json 路由模板默认模板swagger/{documentName}/swagger.json, {documentName} 代表分组名,必须保留原样
// PackagesGroups配置模块化内置分组名称string[] 类型,默认 []
// EnableEnumSchemaFilter启用枚举 Schema 筛选器bool 类型,默认 true
// EnableTagsOrderDocumentFilter启用标签排序筛选器bool 类型,默认 true
// ServerDir配置 IIS 添加 Application 部署名string 类型,默认空,仅在 Furion v3.2.0+` 有效
// LoginInfo配置 Swagger 是否需要登录才能访问SpecificationLoginInfo 类型,默认 null仅在 Furion v3.3.3+` 有效
// Enabled是否启用登录授权默认 false
// CheckUrl检查登录状态的 Url 地址,该地址必须是 POST 请求,已授权返回 200否则返回 401
// SubmitUrl提交登录的 Url 地址,该地址必须是 POST 请求且只有一个 SpecificationAuth 类型参数,成功登录返回 200否则返回 401支持相对地址以 / 开头
// EnableAllGroups启用 Swagger 总分组功能,自动将所有分组的接口合并到 All Groups 中bool 类型,默认 false仅在 Furion v3.3.4+` 有效
// 另外 SpecificationOpenApiInfo 内置配置如下:
//
// Group分组唯一标识string 类型,必填
// Order分组排序int 类型,数字越大排前面,默认 0
// Visible配置分组是否可见bool 类型,默认 true
// Title配置分组标题string 类型
// Description配置分组描述string 类型
// Version配置分组版本默认 1.0
// TermsOfService配置相关链接地址Uri 类型
// Contact配置联系方式OpenApiContact 类型
// License配置协议OpenApiLicense 类型
"EnableEnumSchemaFilter": false,
"EnableAuthorized": false,
"RoutePrefix": "swagger",
"XmlComments": [
"FreeSql.xml",
"NetAdmin.AdmServer.Application.xml",
"NetAdmin.AdmServer.Cache.xml",
"NetAdmin.AdmServer.Host.xml",
"NetAdmin.Application.xml",
"NetAdmin.Cache.xml",
"NetAdmin.Domain.xml",
"NetAdmin.Host.xml",
"NetAdmin.Infrastructure.xml",
"NetAdmin.ScheduledService.xml",
"NetAdmin.SysComponent.Application.xml",
"NetAdmin.SysComponent.Cache.xml",
"NetAdmin.SysComponent.Host.xml",
]
},
// 验证码配置 --------------------------------------------------------------------------------------------------------
"Captcha": {
"ImageRelativePath": ".data/captcha",
"SecretKey": "1Z?f(2)%v?:X5NYRl+]PSi.rDf7Ip#lB"
},
// 跨域配置 ----------------------------------------------------------------------------------------------------------
"CorsAccessorSettings": {
// CorsAccessorSettings
// PolicyName跨域策略名string 类型,必填,默认 App.Cors.Policy
// WithOrigins允许跨域的域名列表string[] 类型,默认 *
// WithHeaders请求表头没有配置则允许所有表头string[] 类型
// WithExposedHeaders设置客户端可获取的响应标头string[] 类型,默认 ["access-token", "x-access-token"]
// WithMethods设置跨域允许请求谓词没有配置则允许所有string[] 类型
// AllowCredentials是否允许跨域请求中的凭据bool 类型,默认值 true
// SetPreflightMaxAge设置预检过期时间int 类型,默认值 24小时
// FixedClientToken是否默认配置 WithExposedHeadersbool 类型,默认 true
// SignalRSupport是否启用 SignalR 跨域支持bool 类型,默认 false
"WithExposedHeaders": [
"access-token",
"x-access-token",
"content-disposition"
]
},
// 数据库配置 --------------------------------------------------------------------------------------------------------
"Database": {
"DbType": "Sqlite",
"ConnStr": "data source=NetAdmin.db",
"SeedDataRelativePath": "SeedData"
},
// 动态webapi配置 ----------------------------------------------------------------------------------------------------
"DynamicApiControllerSettings": {
// 5.1.10 DynamicApiControllerSettings 配置
// Furion 还提供动态 WebAPI 接口一些全局配置选项,如:
//
// DefaultRoutePrefix默认路由前缀string默认 api
// DefaultHttpMethod默认请求谓词string默认POST
// DefaultModule默认模块名称区域可用作接口版本string默认v1
// LowercaseRoute小写路由格式bool默认true
// AsLowerCamelCase启用小驼峰命名首字母小写默认 false
// KeepVerb是否保留动作谓词bool默认false
// KeepName是否保留默认名称bool默认fasle
// CamelCaseSeparator骆驼(驼峰)/帕斯卡命名分隔符string默认-
// VersionSeparator版本分隔符string默认@
// ModelToQueryGET/HEAD 请求将 类类型参数转查询参数bool默认 false
// SupportedMvcController是否支持 Mvc Controller 动态配置bool默认 false
// UrlParameterization路由参数采用 [FromQuery] 化,默认 false[FromRoute] 方式)
// DefaultArea配置默认区域默认 null
// ForceWithRoutePrefix配置是否强制添加 DefaultRoutePrefix当控制器自定义了 [Route] 有效,仅限 v3.4.1+版本有效
// AbandonControllerAffixes默认去除控制器名称前后缀列表名string[],默认:
// AppServices
// AppService
// ApiController
// Controller
// Services
// Service
// AbandonActionAffixes默认去除动作方法名称前后缀列表名string[],默认:
// Async
// VerbToHttpMethods复写默认方法名转 [HttpMethod] 规则string[][] 二维数组类型,内置匹配规则为:
// ["post"] = "POST",
// ["add"] = "POST",
// ["create"] = "POST",
// ["insert"] = "POST",
// ["submit"] = "POST",
// ["get"] = "GET",
// ["find"] = "GET",
// ["fetch"] = "GET",
// ["query"] = "GET",
// ["getlist"] = "GET",
// ["getall"] = "GET",
// ["put"] = "PUT",
// ["update"] = "PUT",
// ["delete"] = "DELETE",
// ["remove"] = "DELETE",
// ["clear"] = "DELETE",
// ["patch"] = "PATCH"
//
// 复写示例
// "DynamicApiControllerSettings": {
// "VerbToHttpMethods": [
// [ "getall", "HEAD" ], // => getall 会被复写为 `[HttpHead]`
// [ "other", "PUT" ] // => 新增一条新规则,比如,一 `[other]` 开头会转换为 `[HttpPut]` 请求
// ]
// }
// "DefaultRoutePrefix": "rest",
"VerbToHttpMethods": [
[
"post",
"POST"
],
[
"add",
"POST"
],
[
"create",
"POST"
],
[
"insert",
"POST"
],
[
"submit",
"POST"
],
[
"get",
"POST"
],
[
"find",
"POST"
],
[
"fetch",
"POST"
],
[
"query",
"POST"
],
[
"getlist",
"POST"
],
[
"getall",
"POST"
],
[
"put",
"POST"
],
[
"update",
"POST"
],
[
"delete",
"POST"
],
[
"remove",
"POST"
],
[
"clear",
"POST"
],
[
"patch",
"POST"
]
],
"CamelCaseSeparator": ".",
"UrlParameterization": true,
"KeepVerb": true,
"AbandonControllerAffixes": [
"Controller"
],
},
// 友好异常配置 -------------------------------------------------------------------------------------------------------
"FriendlyExceptionSettings": {
// 7.15 FriendlyExceptionSettings 配置
// HideErrorCode隐藏错误码bool 类型,默认 false
// DefaultErrorCode默认错误码string 类型
// DefaultErrorMessage默认错误消息string 类型
// ThrowBah是否将 Oops.Oh 默认抛出为业务异常bool 类型,默认 false设置 true 之后 Oops.Oh 默认进入 OnValidateFailed 处理,而不是 OnException
// LogError是否输出异常日志bool 类型,默认 true
"LogError": false
},
// JWT鉴权配置 -------------------------------------------------------------------------------------------------------
"JWTSettings": {
"ValidateIssuerSigningKey": true,
// 是否验证密钥bool 类型默认true
"IssuerSigningKey": "bO0BCAGxpxYnm6AE4XpgO25T27NayFzjGgfDqBuzUzD6ROpFiZUi3KjVg93bdGek",
// 密钥string 类型必须是复杂密钥长度大于16
"ValidateIssuer": true,
// 是否验证签发方bool 类型默认true
"ValidIssuer": "签发方",
// 签发方string 类型
"ValidateAudience": true,
// 是否验证签收方bool 类型默认true
"ValidAudience": "签收方",
// 签收方string 类型
"ValidateLifetime": true,
// 是否验证过期时间bool 类型默认true建议true
"ExpiredTime": 20,
// 过期时间long 类型单位分钟默认20分钟
"ClockSkew": 5,
// 过期时间容错值long 类型,单位秒,默认 5秒
"Algorithm": "HS256"
// 加密算法string 类型,默认 HS256
},
// 日志配置 ----------------------------------------------------------------------------------------------------------
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning",
"System.Logging.EventBusService": "Error"
},
"Monitor": {
"GlobalEnabled": false,
// 是否启用全局拦截,默认 `false`
// "IncludeOfMethods": [], // 是否指定拦截特定方法,当 GlobalEnabled: false 有效
// "ExcludeOfMethods": [], // 是否指定排除特定方法,当 GlobalEnabled: true 有效
// "BahLogLevel": "Information", // 配置 Oops.Oh 和 Oops.Bah 业务日志输出级别,默认 Information
// "WithReturnValue": true, // 配置是否包含返回值,默认 `true`Furion 4.3.9+ 有效
"ReturnValueThreshold": 1000
// 配置返回值字符串阈值,默认 0全量输出Furion 4.3.9+ 有效
// "JsonBehavior": "None", // 配置 LoggingMonitor Json 输出行为,默认 NoneFurion 4.5.2+ 有效
// "MethodsSettings": [
// // 配置被监视方法更多信息Furion 4.3.9+ 有效
// {
// "FullName": "Furion.Application.TestLoggerServices.MethodName", // 方法完全限定名
// "WithReturnValue": true, // 配置是否包含返回值,默认 `true`Furion 4.3.9+ 有效
// "ReturnValueThreshold": 0 // 配置返回值字符串阈值,默认 0全量输出Furion 4.3.9+ 有效
// }
// ]
}
},
// Redis配置 --------------------------------------------------------------------------------------------------------
"Redis": {
"Instances": [
// 数据缓存
{
"Name": "DataCache",
"ConnStr": "localhost:6379,abortConnect=false",
"DataBase": 0,
}
]
},
// UnifyResultSettings 规范化配置 ------------------------------------------------------------------------------------
"UnifyResultSettings": {
// Return200StatusCodes配置返回 200 状态码的请求int[] 类型,只支持 400+(404除外) 状态码篡改
// AdaptStatusCodes配置篡改状态码规则int[][] 类型,只支持 400+(404除外) 状态码篡改
// SupportMvcController是否支持 MVC 控制台规范化处理bool 类型,默认 false
"Return200StatusCodes": [
999
],
},
// 文件上传配置 -------------------------------------------------------------------------------------------------------
"Upload": {
"ContentTypes": [
"image/jpg",
"image/png",
"image/jpeg",
"image/gif"
],
"MaxSize": 1073741824,
"Minio": {
"ServerAddress": "vm-ubt-1:9000",
"AccessKey": "nVMM0gSqwyIjM8iZ",
"SecretKey": "F8OZngGrNsZSYn4MP9swwMSf5rfm61EC",
"BucketName": "net-admin",
"AccessUrl": "http://vm-ubt-1:9000",
"Secure": false,
}
},
}

View File

@ -1,16 +0,0 @@
using NetAdmin.Application.Services;
using NetAdmin.Domain.Dto.Sys.Dic.Catalog;
using NetAdmin.SysComponent.Application.Modules.Sys;
namespace NetAdmin.SysComponent.Application.Services.Sys.Dependency;
/// <summary>
/// 字典目录服务
/// </summary>
public interface IDicCatalogService : IService, IDicCatalogModule
{
/// <summary>
/// 编辑字典目录
/// </summary>
Task<int> EditAsync(EditDicCatalogReq req);
}

View File

@ -1,43 +0,0 @@
using NetAdmin.Application.Services;
using NetAdmin.Domain.Dto.Sys.Tool;
using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
namespace NetAdmin.SysComponent.Application.Services.Sys;
/// <inheritdoc cref="IToolsService" />
public sealed class ToolsService : ServiceBase<IToolsService>, IToolsService
{
/// <inheritdoc />
public async Task<string> GetChangeLogAsync()
{
await using var stream = Assembly.GetEntryAssembly()!.GetManifestResourceStream("CHANGELOG.md");
using var streamReader = new StreamReader(stream!);
return await streamReader.ReadToEndAsync().ConfigureAwait(false);
}
/// <inheritdoc />
public Task<IEnumerable<GetModulesRsp>> GetModulesAsync()
{
return Task.FromResult<IEnumerable<GetModulesRsp>>(AppDomain.CurrentDomain.GetAssemblies()
.Select(x => {
var asm = x.GetName();
return new GetModulesRsp {
Name = asm.Name
, Version = asm.Version?.ToString()
};
})
.OrderBy(x => x.Name));
}
/// <inheritdoc />
public Task<DateTime> GetServerUtcTimeAsync()
{
return Task.FromResult(DateTime.Now);
}
/// <inheritdoc />
public Task<string> GetVersionAsync()
{
return Task.FromResult(GlobalStatic.ProductVersion);
}
}

View File

@ -1,9 +0,0 @@
using NetAdmin.Application.Services;
using NetAdmin.SysComponent.Application.Modules.Tpl;
namespace NetAdmin.SysComponent.Application.Services.Tpl.Dependency;
/// <summary>
/// 示例服务
/// </summary>
public interface IExampleService : IService, IExampleModule;

View File

@ -1,10 +0,0 @@
using NetAdmin.Cache;
using NetAdmin.SysComponent.Application.Modules.Tpl;
using NetAdmin.SysComponent.Application.Services.Tpl.Dependency;
namespace NetAdmin.SysComponent.Cache.Tpl.Dependency;
/// <summary>
/// 示例缓存
/// </summary>
public interface IExampleCache : ICache<IDistributedCache, IExampleService>, IExampleModule;

View File

@ -1,22 +0,0 @@
using Furion.Schedule;
using NetAdmin.SysComponent.Host.Jobs;
namespace NetAdmin.SysComponent.Host.Extensions;
/// <summary>
/// ServiceCollection 扩展方法
/// </summary>
[SuppressSniffer]
public static class ServiceCollectionExtensions
{
/// <summary>
/// 添加定时任务
/// </summary>
public static IServiceCollection AddSchedules(this IServiceCollection me)
{
return me.AddSchedule( //
builder => builder //
.AddJob<ScheduledJob>(false, Triggers.PeriodSeconds(5).SetRunOnStart(true))
.AddJob<FreeScheduledJob>(false, Triggers.PeriodMinutes(1).SetRunOnStart(true)));
}
}

View File

@ -1,158 +0,0 @@
using FreeSql.Internal;
using Furion.RemoteRequest;
using Furion.RemoteRequest.Extensions;
using Furion.Schedule;
using NetAdmin.Domain.Dto.Sys.Job;
using NetAdmin.Domain.Dto.Sys.JobRecord;
using NetAdmin.Host.BackgroundRunning;
using NetAdmin.Host.Extensions;
using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
namespace NetAdmin.SysComponent.Host.Jobs;
/// <summary>
/// 计划作业
/// </summary>
public sealed class ScheduledJob : WorkBase<ScheduledJob>, IJob
{
private static string _accessToken;
private static string _refreshToken;
private readonly IJobRecordService _jobRecordService;
private readonly IJobService _jobService;
private readonly ILogger<ScheduledJob> _logger;
private readonly IUserService _userService;
private string _requestHeader;
/// <summary>
/// Initializes a new instance of the <see cref="ScheduledJob" /> class.
/// </summary>
public ScheduledJob()
{
_jobRecordService = ServiceProvider.GetService<IJobRecordService>();
_jobService = ServiceProvider.GetService<IJobService>();
_logger = ServiceProvider.GetService<ILogger<ScheduledJob>>();
_userService = ServiceProvider.GetService<IUserService>();
}
/// <summary>
/// 具体处理逻辑
/// </summary>
/// <param name="context">作业执行前上下文</param>
/// <param name="stoppingToken">取消任务 Token</param>
/// <exception cref="NetAdminGetLockerException">加锁失败异常</exception>
public async Task ExecuteAsync(JobExecutingContext context, CancellationToken stoppingToken)
{
await WorkflowAsync(stoppingToken).ConfigureAwait(false);
}
/// <summary>
/// 通用工作流
/// </summary>
/// <exception cref="NotImplementedException">NotImplementedException</exception>
/// <exception cref="ArgumentOutOfRangeException">ArgumentOutOfRangeException</exception>
protected override async ValueTask WorkflowAsync(CancellationToken cancelToken)
{
QueryJobRsp job = null;
try {
job = await _jobService.GetNextJobAsync().ConfigureAwait(false);
}
catch (DbUpdateVersionException) {
// ignore
}
if (job == null) {
_logger.Info(Ln.);
return;
}
var request = BuildRequest(job);
// 随机延时
if (job.RandomDelayBegin is > 0 && job.RandomDelayEnd is > 0) {
var (start, end) = (job.RandomDelayBegin.Value, job.RandomDelayEnd.Value);
if (start > end) {
(start, end) = (end, start);
}
await Task.Delay(new[] { start, end }.Rand(), CancellationToken.None).ConfigureAwait(false);
}
var sw = new Stopwatch();
sw.Start();
var rsp = await request.SendAsync(CancellationToken.None).ConfigureAwait(false);
if (rsp.StatusCode is HttpStatusCode.Unauthorized or HttpStatusCode.Forbidden) {
var loginRsp = await _userService.LoginByUserIdAsync(job.UserId).ConfigureAwait(false);
#pragma warning disable S2696
_accessToken = loginRsp.AccessToken;
_refreshToken = loginRsp.RefreshToken;
#pragma warning restore S2696
request = BuildRequest(job);
rsp = await request.SendAsync(CancellationToken.None).ConfigureAwait(false);
}
sw.Stop();
await UowManager.AtomicOperateAsync(async () => {
var rspBody = await rsp.Content.ReadAsStringAsync(CancellationToken.None)
.ConfigureAwait(false);
var jobRecord = new CreateJobRecordReq //
{
Duration = sw.ElapsedMilliseconds
, HttpMethod = job.HttpMethod
, HttpStatusCode = (int)rsp.StatusCode
, JobId = job.Id
, RequestBody = job.RequestBody
, RequestHeader = _requestHeader
, RequestUrl = job.RequestUrl
, ResponseBody = rspBody
, ResponseHeader = rsp.Headers.Json()
, TimeId = job.NextTimeId!.Value
};
_ = await _jobRecordService.CreateAsync(jobRecord).ConfigureAwait(false);
await _jobService
.FinishJobAsync(job.Adapt<FinishJobReq>() with {
LastStatusCode = rsp.StatusCode
, LastDuration = jobRecord.Duration
})
.ConfigureAwait(false);
})
.ConfigureAwait(false);
}
private HttpRequestPart BuildRequest(QueryJobRsp job)
{
var ret = job.RequestUrl.SetHttpMethod(new HttpMethod(job.HttpMethod.ToString()));
var headers = new Dictionary<string, string>();
if (!_accessToken.NullOrEmpty()) {
headers.Add( //
Chars.FLG_HTTP_HEADER_KEY_AUTHORIZATION, $"{Chars.FLG_HTTP_HEADER_VALUE_AUTH_SCHEMA} {_accessToken}");
}
if (!_refreshToken.NullOrEmpty()) {
headers.Add( //
Chars.FLG_HTTP_HEADER_KEY_X_ACCESS_TOKEN_HEADER_KEY
, $"{Chars.FLG_HTTP_HEADER_VALUE_AUTH_SCHEMA} {_refreshToken}");
}
if (!job.RequestHeader.NullOrEmpty()) {
ret = ret.SetHeaders(headers.Union(job.RequestHeader.Object<Dictionary<string, string>>())
.ToDictionary(x => x.Key, x => x.Value));
}
if (!job.RequestBody.NullOrEmpty()) {
ret = ret.SetBody(job.RequestBody);
}
return ret.SetLog(_logger).OnResponsing(GetRequestHeader).OnException(GetRequestHeader);
}
private void GetRequestHeader(HttpClient _, HttpResponseMessage rsp, string __)
{
_requestHeader = rsp!.RequestMessage!.Headers.Json();
}
private void GetRequestHeader(HttpClient _, HttpResponseMessage rsp)
{
GetRequestHeader(_, rsp, null);
}
}

View File

@ -1,24 +0,0 @@
using NetAdmin.Domain.Events.Sys;
using NetAdmin.SysComponent.Application.Services.Sys.Dependency;
namespace NetAdmin.SysComponent.Host.Subscribers;
/// <summary>
/// 操作日志记录
/// </summary>
public sealed class OperationLogger : IEventSubscriber
{
/// <summary>
/// 保存请求日志到数据库
/// </summary>
[EventSubscribe(nameof(RequestLogEvent))]
public async Task OperationEventDbRecordAsync(EventHandlerExecutingContext context)
{
if (context.Source is not RequestLogEvent operationEvent) {
return;
}
operationEvent.Data.TruncateStrings();
_ = await App.GetService<IRequestLogService>().CreateAsync(operationEvent.Data).ConfigureAwait(false);
}
}

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