mirror of
https://gitee.com/ccnetcore/Yi
synced 2026-04-24 02:16:36 +08:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d919e07096 |
139
.gitignore
vendored
139
.gitignore
vendored
@@ -1,7 +1,20 @@
|
|||||||
## Ignore Visual Studio temporary files, build results, and
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
## files generated by popular Visual Studio add-ons.
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
##
|
||||||
|
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||||
|
WebFirst/SoEasyPlatform.exe
|
||||||
|
WebFirst/excel
|
||||||
|
WebFirst/wwwroot
|
||||||
|
WebFirst/SoEasyPlatform.exe
|
||||||
|
WebFirst/appsettings.Development.json
|
||||||
|
WebFirst/appsettings.json
|
||||||
|
WebFirst/SoEasyPlatform.pdb
|
||||||
|
WebFirst/SoEasyPlatform.Views.pdb
|
||||||
|
WebFirst/web.config
|
||||||
|
WebFirst/WebFirst.exe
|
||||||
|
|
||||||
# User-specific files
|
# User-specific files
|
||||||
|
*.rsuser
|
||||||
*.suo
|
*.suo
|
||||||
*.user
|
*.user
|
||||||
*.userosscache
|
*.userosscache
|
||||||
@@ -17,16 +30,21 @@
|
|||||||
[Rr]eleases/
|
[Rr]eleases/
|
||||||
x64/
|
x64/
|
||||||
x86/
|
x86/
|
||||||
|
[Aa][Rr][Mm]/
|
||||||
|
[Aa][Rr][Mm]64/
|
||||||
bld/
|
bld/
|
||||||
[Bb]in/
|
[Bb]in/
|
||||||
[Oo]bj/
|
[Oo]bj/
|
||||||
[Ll]og/
|
[Ll]og/
|
||||||
|
|
||||||
# Visual Studio 2015 cache/options directory
|
# Visual Studio 2015/2017 cache/options directory
|
||||||
.vs/
|
.vs/
|
||||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||||
#wwwroot/
|
#wwwroot/
|
||||||
|
|
||||||
|
# Visual Studio 2017 auto generated files
|
||||||
|
Generated\ Files/
|
||||||
|
|
||||||
# MSTest test Results
|
# MSTest test Results
|
||||||
[Tt]est[Rr]esult*/
|
[Tt]est[Rr]esult*/
|
||||||
[Bb]uild[Ll]og.*
|
[Bb]uild[Ll]og.*
|
||||||
@@ -40,18 +58,28 @@ TestResult.xml
|
|||||||
[Rr]eleasePS/
|
[Rr]eleasePS/
|
||||||
dlldata.c
|
dlldata.c
|
||||||
|
|
||||||
# DNX
|
# Benchmark Results
|
||||||
|
BenchmarkDotNet.Artifacts/
|
||||||
|
|
||||||
|
# .NET Core
|
||||||
project.lock.json
|
project.lock.json
|
||||||
|
project.fragment.lock.json
|
||||||
artifacts/
|
artifacts/
|
||||||
|
|
||||||
|
# StyleCop
|
||||||
|
StyleCopReport.xml
|
||||||
|
|
||||||
|
# Files built by Visual Studio
|
||||||
*_i.c
|
*_i.c
|
||||||
*_p.c
|
*_p.c
|
||||||
*_i.h
|
*_h.h
|
||||||
*.ilk
|
*.ilk
|
||||||
*.meta
|
*.meta
|
||||||
*.obj
|
*.obj
|
||||||
|
*.iobj
|
||||||
*.pch
|
*.pch
|
||||||
*.pdb
|
*.pdb
|
||||||
|
*.ipdb
|
||||||
*.pgc
|
*.pgc
|
||||||
*.pgd
|
*.pgd
|
||||||
*.rsp
|
*.rsp
|
||||||
@@ -61,6 +89,7 @@ artifacts/
|
|||||||
*.tlh
|
*.tlh
|
||||||
*.tmp
|
*.tmp
|
||||||
*.tmp_proj
|
*.tmp_proj
|
||||||
|
*_wpftmp.csproj
|
||||||
*.log
|
*.log
|
||||||
*.vspscc
|
*.vspscc
|
||||||
*.vssscc
|
*.vssscc
|
||||||
@@ -89,6 +118,9 @@ ipch/
|
|||||||
*.vspx
|
*.vspx
|
||||||
*.sap
|
*.sap
|
||||||
|
|
||||||
|
# Visual Studio Trace Files
|
||||||
|
*.e2e
|
||||||
|
|
||||||
# TFS 2012 Local Workspace
|
# TFS 2012 Local Workspace
|
||||||
$tf/
|
$tf/
|
||||||
|
|
||||||
@@ -109,6 +141,14 @@ _TeamCity*
|
|||||||
# DotCover is a Code Coverage Tool
|
# DotCover is a Code Coverage Tool
|
||||||
*.dotCover
|
*.dotCover
|
||||||
|
|
||||||
|
# AxoCover is a Code Coverage Tool
|
||||||
|
.axoCover/*
|
||||||
|
!.axoCover/settings.json
|
||||||
|
|
||||||
|
# Visual Studio code coverage results
|
||||||
|
*.coverage
|
||||||
|
*.coveragexml
|
||||||
|
|
||||||
# NCrunch
|
# NCrunch
|
||||||
_NCrunch_*
|
_NCrunch_*
|
||||||
.*crunch*.local.xml
|
.*crunch*.local.xml
|
||||||
@@ -140,7 +180,7 @@ publish/
|
|||||||
# Publish Web Output
|
# Publish Web Output
|
||||||
*.[Pp]ublish.xml
|
*.[Pp]ublish.xml
|
||||||
*.azurePubxml
|
*.azurePubxml
|
||||||
# TODO: Comment the next line if you want to checkin your web deploy settings
|
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||||
# but database connection strings (with potential passwords) will be unencrypted
|
# but database connection strings (with potential passwords) will be unencrypted
|
||||||
*.pubxml
|
*.pubxml
|
||||||
*.publishproj
|
*.publishproj
|
||||||
@@ -153,12 +193,12 @@ PublishScripts/
|
|||||||
# NuGet Packages
|
# NuGet Packages
|
||||||
*.nupkg
|
*.nupkg
|
||||||
# The packages folder can be ignored because of Package Restore
|
# The packages folder can be ignored because of Package Restore
|
||||||
**/packages/*
|
**/[Pp]ackages/*
|
||||||
# except build/, which is used as an MSBuild target.
|
# except build/, which is used as an MSBuild target.
|
||||||
!**/packages/build/
|
!**/[Pp]ackages/build/
|
||||||
# Uncomment if necessary however generally it will be regenerated when needed
|
# Uncomment if necessary however generally it will be regenerated when needed
|
||||||
#!**/packages/repositories.config
|
#!**/[Pp]ackages/repositories.config
|
||||||
# NuGet v3's project.json files produces more ignoreable files
|
# NuGet v3's project.json files produces more ignorable files
|
||||||
*.nuget.props
|
*.nuget.props
|
||||||
*.nuget.targets
|
*.nuget.targets
|
||||||
|
|
||||||
@@ -175,12 +215,13 @@ AppPackages/
|
|||||||
BundleArtifacts/
|
BundleArtifacts/
|
||||||
Package.StoreAssociation.xml
|
Package.StoreAssociation.xml
|
||||||
_pkginfo.txt
|
_pkginfo.txt
|
||||||
|
*.appx
|
||||||
|
|
||||||
# Visual Studio cache files
|
# Visual Studio cache files
|
||||||
# files ending in .cache can be ignored
|
# files ending in .cache can be ignored
|
||||||
*.[Cc]ache
|
*.[Cc]ache
|
||||||
# but keep track of directories ending in .cache
|
# but keep track of directories ending in .cache
|
||||||
!*.[Cc]ache/
|
!?*.[Cc]ache/
|
||||||
|
|
||||||
# Others
|
# Others
|
||||||
ClientBin/
|
ClientBin/
|
||||||
@@ -188,11 +229,15 @@ ClientBin/
|
|||||||
*~
|
*~
|
||||||
*.dbmdl
|
*.dbmdl
|
||||||
*.dbproj.schemaview
|
*.dbproj.schemaview
|
||||||
|
*.jfm
|
||||||
*.pfx
|
*.pfx
|
||||||
*.publishsettings
|
*.publishsettings
|
||||||
node_modules/
|
|
||||||
orleans.codegen.cs
|
orleans.codegen.cs
|
||||||
|
|
||||||
|
# Including strong name files can present a security risk
|
||||||
|
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||||
|
#*.snk
|
||||||
|
|
||||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||||
#bower_components/
|
#bower_components/
|
||||||
@@ -207,15 +252,20 @@ _UpgradeReport_Files/
|
|||||||
Backup*/
|
Backup*/
|
||||||
UpgradeLog*.XML
|
UpgradeLog*.XML
|
||||||
UpgradeLog*.htm
|
UpgradeLog*.htm
|
||||||
|
ServiceFabricBackup/
|
||||||
|
*.rptproj.bak
|
||||||
|
|
||||||
# SQL Server files
|
# SQL Server files
|
||||||
*.mdf
|
*.mdf
|
||||||
*.ldf
|
*.ldf
|
||||||
|
*.ndf
|
||||||
|
|
||||||
# Business Intelligence projects
|
# Business Intelligence projects
|
||||||
*.rdl.data
|
*.rdl.data
|
||||||
*.bim.layout
|
*.bim.layout
|
||||||
*.bim_*.settings
|
*.bim_*.settings
|
||||||
|
*.rptproj.rsuser
|
||||||
|
*- Backup*.rdl
|
||||||
|
|
||||||
# Microsoft Fakes
|
# Microsoft Fakes
|
||||||
FakesAssemblies/
|
FakesAssemblies/
|
||||||
@@ -225,6 +275,7 @@ FakesAssemblies/
|
|||||||
|
|
||||||
# Node.js Tools for Visual Studio
|
# Node.js Tools for Visual Studio
|
||||||
.ntvs_analysis.dat
|
.ntvs_analysis.dat
|
||||||
|
node_modules/
|
||||||
|
|
||||||
# Visual Studio 6 build log
|
# Visual Studio 6 build log
|
||||||
*.plg
|
*.plg
|
||||||
@@ -232,6 +283,9 @@ FakesAssemblies/
|
|||||||
# Visual Studio 6 workspace options file
|
# Visual Studio 6 workspace options file
|
||||||
*.opt
|
*.opt
|
||||||
|
|
||||||
|
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||||
|
*.vbw
|
||||||
|
|
||||||
# Visual Studio LightSwitch build output
|
# Visual Studio LightSwitch build output
|
||||||
**/*.HTMLClient/GeneratedArtifacts
|
**/*.HTMLClient/GeneratedArtifacts
|
||||||
**/*.DesktopClient/GeneratedArtifacts
|
**/*.DesktopClient/GeneratedArtifacts
|
||||||
@@ -251,25 +305,48 @@ paket-files/
|
|||||||
.idea/
|
.idea/
|
||||||
*.sln.iml
|
*.sln.iml
|
||||||
|
|
||||||
# BookStore
|
# CodeRush personal settings
|
||||||
src/Acme.BookStore.Web/Logs/*
|
.cr/personal
|
||||||
src/Acme.BookStore.Web.Host/Logs/*
|
|
||||||
src/Acme.BookStore.AuthServer/Logs/*
|
|
||||||
src/Acme.BookStore.HttpApi.Host/Logs/*
|
|
||||||
src/Acme.BookStore.HttpApi.HostWithIds/Logs/*
|
|
||||||
src/Acme.BookStore.DbMigrator/Logs/*
|
|
||||||
src/Acme.BookStore.Blazor.Server/Logs/*
|
|
||||||
src/Acme.BookStore.Blazor.Server.Tiered/Logs/*
|
|
||||||
|
|
||||||
# Use abp install-libs to restore.
|
# Python Tools for Visual Studio (PTVS)
|
||||||
**/wwwroot/libs/*
|
__pycache__/
|
||||||
dist
|
*.pyc
|
||||||
.vscode
|
|
||||||
/Yi.Abp.Net8/src/Yi.Abp.Web/appsettings.Development.json
|
# Cake - Uncomment if you are using it
|
||||||
/Yi.Abp.Net8/src/Yi.Abp.Web/appsettings.Production.json
|
# tools/**
|
||||||
Logs
|
# !tools/packages.config
|
||||||
logs
|
|
||||||
/Yi.Abp.Net8/test/Yi.Abp.Test/appsettings.Development.json
|
# Tabs Studio
|
||||||
/Yi.Abp.Net8/test/Yi.Abp.Test/appsettings.Production.json
|
*.tss
|
||||||
database_backup
|
|
||||||
/Yi.Abp.Net8/src/Yi.Abp.Web/appsettings.Staging.json
|
# Telerik's JustMock configuration file
|
||||||
|
*.jmconfig
|
||||||
|
|
||||||
|
# BizTalk build output
|
||||||
|
*.btp.cs
|
||||||
|
*.btm.cs
|
||||||
|
*.odx.cs
|
||||||
|
*.xsd.cs
|
||||||
|
|
||||||
|
# OpenCover UI analysis results
|
||||||
|
OpenCover/
|
||||||
|
|
||||||
|
# Azure Stream Analytics local run output
|
||||||
|
ASALocalRun/
|
||||||
|
|
||||||
|
# MSBuild Binary and Structured Log
|
||||||
|
*.binlog
|
||||||
|
|
||||||
|
# NVidia Nsight GPU debugger configuration file
|
||||||
|
*.nvuser
|
||||||
|
|
||||||
|
# MFractors (Xamarin productivity tool) working folder
|
||||||
|
.mfractor/
|
||||||
|
|
||||||
|
# Local History for Visual Studio
|
||||||
|
.localhistory/
|
||||||
|
|
||||||
|
# BeatPulse healthcheck temp database
|
||||||
|
healthchecksdb
|
||||||
|
|
||||||
|
appsettings.Development.json
|
||||||
|
|||||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2023 橙子
|
Copyright (c) 2022 jacktang
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|||||||
387
README.md
387
README.md
@@ -1,144 +1,100 @@
|
|||||||
<h1 align="center"><img align="left" height="150px" src="https://ccnetcore.com/prod-api/wwwroot/logo.png"> Yi框架</h1>
|
|
||||||
<h4 align="center">一套以用户体验出发的.Net8 Web开源框架</h4>
|
|
||||||
<h5 align="center">支持Abp.vNext 版本原生版本、Furion版本,前端后台接入Ruoyi Vue3.0</h5>
|
<h1 align="center"><img align="left" height="100px" src="https://user-images.githubusercontent.com/68722157/138828506-f58b7c57-5e10-4178-8f7d-5d5e12050113.png"> Yi框架</h1>
|
||||||
|
<h4 align="center">一套与SqlSugar一样爽的.Net6开源框架</h4>
|
||||||
<h2 align="center">集大成者,终究轮子</h2>
|
<h2 align="center">集大成者,终究轮子</h2>
|
||||||
|
|
||||||
[](https://gitee.com/ccnetcore/Yi)
|
|
||||||
[](https://gitee.com/ccnetcore/Yi)
|
|
||||||
[](https://gitee.com/ccnetcore/Yi)
|
|
||||||
|
|
||||||
[English](README-en.md) | 简体中文
|
[English](README-en.md) | 简体中文
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
****
|
****
|
||||||
## :tw-1f34e: 简介:
|
### 简介:
|
||||||
YiFramework是一个基于.Net8+Abp.vNext+SqlSugar的DDD领域驱动设计后端开源框架
|
|
||||||
|
|
||||||
谁说Abp复杂?谁说DDD难?`打破常规,化繁为简`,新人入门,项目二开,最佳方式之一
|
|
||||||
|
|
||||||
**中文:意框架**(和他的名字一样“简易”,同时接入Java的Ruoyi Vue3.0前端)
|
**中文:意框架**(和他的名字一样“简易”,同时接入Java的Ruoyi Vue3.0前端)
|
||||||
|
|
||||||
模块化,可根据业务自行引用或抛弃,集大成者,大而全乎,也许你能从中学习到一些独特见解
|
模块分化较多,可根据业务自行引用或抛弃,集大成者,大而全乎,也许你能从中学习到一些独特见解
|
||||||
|
|
||||||
|
正在持续更进业务模块,已接入ruoyi
|
||||||
|
|
||||||
**英文:YiFramework**
|
**英文:YiFramework**
|
||||||
|
|
||||||
Yi框架-一套与SqlSugar一样爽的.Net8开源框架。
|
Yi框架-一套与SqlSugar一样爽的.Net6低代码开源框架。
|
||||||
与Sqlsugar理念一致,以用户体验出发。
|
与Sqlsugar理念一致,以用户体验出发。
|
||||||
适合.Net8学习、Sqlsugar学习 、项目二次开发。
|
架构干净整洁、无业务代码、采用微软风格原生框架封装、CodeFrist+配套自研文件模板代码生成器 开发。
|
||||||
|
适合.Net6学习、Sqlsugar学习 、项目二次开发。
|
||||||
集大成者,终究轮子
|
集大成者,终究轮子
|
||||||
|
|
||||||
(更新频繁,可watching持续关注。)
|
Yi框架最新版本标签:`v1.2.1`,具体版本可以查看标签迭代
|
||||||
|
|
||||||
|
(项目与Sqlsugar同步更新,但这作者老杰哥代码天天爆肝到凌晨两点,我们也尽量会跟上他的脚步。更新频繁,所以可watching持续关注。)
|
||||||
|
|
||||||
————这不仅仅是一个程序,更是一个艺术品,面向艺术的开发!
|
————这不仅仅是一个程序,更是一个艺术品,面向艺术的开发!
|
||||||
|
|
||||||
> 核心特点:简单好用,框架不以打包形式引用,而是直接以项目附带源码给出,自由度拉满,遵循Mit协议,允许随意修改(请注明来源即可)
|
**分支**:
|
||||||
|
|
||||||
**分支:**
|
(本项目由EFCore版本历经3年不断迭代至Sqlsugar版本,现EFcore版本已弃用,目前sqlsugar已带业务功能)
|
||||||
|
|
||||||
- (推荐) **Abp**: 基于Abp.vNext分支,DDD领域驱动设计,回归开发本质,极度简单,用起来贼爽
|
**SqlSugar**:.Net6 DDD领域驱动设计 简单分层微服务架构
|
||||||
|
|
||||||
- **Furion**: 基于Furion分支
|
- Yi.Framework.Net6:.NetCore 6 意框架 (后端)
|
||||||
|
|
||||||
|
- Yi.Vue3.X.RuoYi:Vue3 RuoYi前端框架 (前端后台)
|
||||||
|
|
||||||
|
(你没有听错,已经接入java流行指数最高最火爆的框架之一,与其他框架不同,Yi框架后端为完全重制版,并非为ruoyi java模仿版)
|
||||||
|
|
||||||
|
- Yi.Vue3.x.Vant:Vue3 移动端前端框架 (前端前台)持续迭代
|
||||||
|
|
||||||
|
**SqlSugar-Dev**:为sqlsugar分支的实时开发版本
|
||||||
|
|
||||||
|
~~**ec**: EFcore完整电商项目~~
|
||||||
|
|
||||||
****
|
****
|
||||||
|
|
||||||
## :tw-1f350: 官网及演示地址:
|
### 演示地址:
|
||||||
|
|
||||||
废话少说直接上地址
|
废话少说直接上地址,**请不要**更改里面的数据
|
||||||
|
|
||||||
Yi社区官网网址:[ccnetcore.com](https://ccnetcore.com) (已上线,欢迎加入)
|
API服务:[yi.ccnetcore.com](http://yi.ccnetcore.com) 管理员账号:cc 、 123456
|
||||||
|
|
||||||
Rbac后台管理系统:已上线,暂不提供演示地址,可本地部署访问
|
网关地址:~~[gate.ccnetcore.com/swagger](http://gate.ccnetcore.com/swagger)~~
|
||||||
|
|
||||||
App移动端系统:已上线,暂不提供演示地址,可本地部署访问
|
~~WebFirst开发:所有代码生成器已经配置完成,无需任何操作数据库及任何代码,只需要网页表格上点点点即可~~
|
||||||
|
|
||||||
Rbac演示地址:https://ccnetcore.com:1000 (用户cc、密码123456)
|
代码自动生成:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
## :tw-1f351: 支持:
|
### 支持:
|
||||||
|
|
||||||
- [x] 完全支持单体应用架构
|
- [x] 完全支持单体应用架构
|
||||||
- [x] 完全支持分布式应用架构
|
- [x] 完全支持分布式应用架构
|
||||||
- [x] 完全支持微服务架构
|
- [x] 完全支持微服务架构
|
||||||
|
- [ ] 即将支持网格服务架构(我们将在后续版本加入dapr)
|
||||||
|
|
||||||
****
|
****
|
||||||
## :tw-1f352: 详细到爆炸的Yi框架教程导航:
|
### 软件架构:
|
||||||
|
|
||||||
1. [框架快速开始教程](https://ccnetcore.com/article/aaa00329-7f35-d3fe-d258-3a0f8380b742)(已完成)
|
**架构**:后端.NET6(Asp.NetCore 6)、WebFirst代码生成器~~与.NET5(Asp.NetCore 5)、前端Vue(2.0)~~
|
||||||
2. [框架功能模块教程](https://ccnetcore.com/article/8c464ab3-8ba5-2761-a4b0-3a0f83a9f312)(已完成)
|
|
||||||
3. [实战演练开发教程](https://ccnetcore.com/article/e89c9593-f337-ada7-d108-3a0f83ae48e6)
|
**关系型数据库**:mysql、sql server、sqlite、oracle(正在兼容中)
|
||||||
4. [橙子运维CICD教程](https://ccnetcore.com/article/6b80ed42-50cd-db15-c073-3a0fa8f7fd77)(已完成)
|
|
||||||
5. [版本更新日志](https://ccnetcore.com/article/e9e69a38-ce1e-06f5-7944-3a0fdc942ef3)(已完成)
|
**操作系统**:Windows、Linux
|
||||||
|
|
||||||
|
**身份验证**:JWT、IdentityServer4
|
||||||
|
|
||||||
|
**组件**:SqlSugar、Autofac、Castle、Swagger、Log4Net、Redis、RabbitMq、ES、Quartz.net、~~T4~~
|
||||||
|
|
||||||
|
**分布式**:CAP、Lock
|
||||||
|
|
||||||
|
**微服务**:Consul、Ocelot、IdentityService、Apollo、Docker、Jenkins、Nginx、K8s、ELK、Polly
|
||||||
|
|
||||||
|
**封装**:Json处理模块,滑动验证码模块,base64图片处理模块,异常捕捉模块、邮件处理模块、linq封装模块、随机数模块、统一接口模块、基于策略的jwt验证、过滤器、数据库连接、跨域、初始化种子数据、Base32、Console输出、日期处理、文件传输、html筛选、http请求、ip过滤、md5加密、Rsa加密、序列化、雪花算法、字符串处理、编码处理、地址处理、xml处理、心跳检查。。。
|
||||||
|
|
||||||
****
|
****
|
||||||
## :tw-1f353: 它的理念:
|
<h3>业务支持模块</h3>
|
||||||
谁说Abp复杂?谁说DDD难?打破常规,化繁为简,新人入门,项目二开,最佳方式之一
|
|
||||||
|
|
||||||
> 一百个人,就有一百种DDD,Yi框架不一定是极度严格的DDD,而是站在巨人的肩膀上,经过极多项目的提炼,摸索出一种最佳实践
|
RABC权限管理系统(正在更新)
|
||||||
|
(大部分ruoyi功能,采用ruoyi前端)
|
||||||
|
|
||||||
优雅的进行快速开发,通常,简单程度与优雅程度不可兼得,Yi框架并不一昧的追求极致的解耦,会站在用户使用角度上,在使用难易度进行考虑衡量
|
|
||||||
|
|
||||||
> 一个面向用户的快速开发后端框架
|
|
||||||
|
|
||||||
在真正的使用这,你会明白这一点,极致的简单,也是优雅的一种体现。
|
|
||||||
****
|
|
||||||
|
|
||||||
## :tw-1f354: 特点
|
|
||||||
- 面向用户的后端框架,使用简单,适合小型、中型、企业级项目
|
|
||||||
- 项目直接内置源码,不打包,非常适合进行二开改造
|
|
||||||
- 内置包含大量通用场景模块
|
|
||||||
- 优雅支持分布式及微服务架构
|
|
||||||
- 等等
|
|
||||||
|
|
||||||
## :tw-1f340: 基础设施简介
|
|
||||||
|
|
||||||
以下全部功能可直接使用:
|
|
||||||
|
|
||||||
- [Abp.vNext官网](https://docs.abp.io/zh-Hans/abp/latest/)
|
|
||||||
|
|
||||||
- [SqlSugar官网](https://www.donet5.com/home/doc)
|
|
||||||
|
|
||||||
## :tw-1f341: 内置模块简介
|
|
||||||
- Rbac权限管理系统(已上线)
|
|
||||||
- Bbs论坛社区系统(已上线)
|
|
||||||
|
|
||||||
> 重复的东西,无需再写一遍,这也是优雅的体现之一
|
|
||||||
|
|
||||||
****
|
|
||||||
## :tw-1f31e: 核心技术
|
|
||||||
#### 后端
|
|
||||||
C# Asp.NetCore 8.0
|
|
||||||
- [x] 动态Api:Abp.vNext
|
|
||||||
- [x] 鉴权授权:Jwt
|
|
||||||
- [x] 日志:Serilog
|
|
||||||
- [x] 模块化:Abp.vNext
|
|
||||||
- [x] 依赖注入:Autofac
|
|
||||||
- [x] 对象映射:Mapster
|
|
||||||
- [x] ORM: SqlsugarCore
|
|
||||||
- [x] 多租户:Abp.vNext
|
|
||||||
- [x] 后台任务:Quartz.Net
|
|
||||||
- [x] 本地缓存:Abp.vNext
|
|
||||||
- [x] 分布式缓存:Abp.vNext
|
|
||||||
- [x] 事件总线:Abp.vNext
|
|
||||||
|
|
||||||
#### 前端
|
|
||||||
js Vue3.2
|
|
||||||
- [x] 异步请求:axios
|
|
||||||
- [x] 图表:echarts
|
|
||||||
- [x] ui:element-plus
|
|
||||||
- [x] 存储:pinia
|
|
||||||
- [x] 路由:vue-router
|
|
||||||
- [x] 打包:vite
|
|
||||||
|
|
||||||
#### 运维
|
|
||||||
- [x] 部署:nginx
|
|
||||||
- [x] CICD:gitlab+Jenkins
|
|
||||||
- [x] Docker:harbor
|
|
||||||
|
|
||||||
|
|
||||||
****
|
|
||||||
## :tw-1f366: 业务支持模块:
|
|
||||||
|
|
||||||
#### :tw-1f42f: RABC权限管理系统(持续更新)
|
|
||||||
(采用ruoyi前端)
|
|
||||||
- 用户管理
|
- 用户管理
|
||||||
- 角色管理
|
- 角色管理
|
||||||
- 菜单管理
|
- 菜单管理
|
||||||
@@ -149,100 +105,177 @@ js Vue3.2
|
|||||||
- 用户在线
|
- 用户在线
|
||||||
- 操作日志
|
- 操作日志
|
||||||
- 登录日志
|
- 登录日志
|
||||||
- 定时任务
|
- 等等
|
||||||
- 缓存列表
|
|
||||||
- 服务监控
|
|
||||||
- WebFirst代码生成工具
|
|
||||||
|
|
||||||
#### :tw-1f431: BBS社区论坛系统(持续更新)
|
ERP进销存系统(正在更新)
|
||||||
(采用vue3前端)
|
- 供货商管理
|
||||||
- 文章功能
|
- 等等
|
||||||
- 板块功能
|
|
||||||
- 主题功能
|
|
||||||
- 个人中心
|
|
||||||
- 授权中心
|
|
||||||
- 权限管理
|
|
||||||
|
|
||||||
#### :star: 演示截图:
|
BBS论坛系统(持续迭代)
|
||||||
<table>
|
- 文章管理
|
||||||
<tr>
|
- 评论管理
|
||||||
<td><img src="readme/101.png"/></td>
|
- 等等
|
||||||
<td><img src="readme/102.png"/></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><img src="readme/103.png"/></td>
|
|
||||||
<td><img src="readme/104.png"/></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
<table>
|
|
||||||
<tr>
|
|
||||||
<td><img src="readme/1.png"/></td>
|
|
||||||
<td><img src="readme/2.png"/></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><img src="readme/3.png"/></td>
|
|
||||||
<td><img src="readme/4.png"/></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><img src="readme/3.png"/></td>
|
|
||||||
<td><img src="readme/4.png"/></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><img src="readme/5.png"/></td>
|
|
||||||
<td><img src="readme/6.png"/></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><img src="readme/7.png"/></td>
|
|
||||||
<td><img src="readme/8.png"/></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><img src="readme/9.png"/></td>
|
|
||||||
<td><img src="readme/10.png"/></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td><img src="readme/11.png"/></td>
|
|
||||||
<td><img src="readme/12.png"/></td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
## :tw-1f44f: 感谢:
|
SHOP电商系统(持续迭代)
|
||||||
|
- SPU管理
|
||||||
|
- SKU管理
|
||||||
|
- 商品规格
|
||||||
|
- 商品分类
|
||||||
|
- 等等
|
||||||
|
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 框架支持模块:
|
||||||
|
|
||||||
|
大致如图:
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
(删除线代表已实现功能还未迁移过来)
|
||||||
|
- [x] 支持大致`DDD领域驱动设计`进行分层,支持微服务扩展
|
||||||
|
- [x] 支持采用`异步`开发awit/async
|
||||||
|
- [x] 支持数据库主从`读写分离`
|
||||||
|
- [x] 支持功能替换,无需改动代码,只需配置`json文件`进行装配即可
|
||||||
|
- [x] 支持`Aop封装`,FilterAop、IocAop、LogAop、SqlAop
|
||||||
|
- [x] 支持`Log4Net日志`记录,自动生成至bin目录下的logs文件夹
|
||||||
|
- [x] 支持`DbSeed数据库种子数据`接入
|
||||||
|
- [x] 支持主流`数据库随意切换`,Mysql/Sqlite/Sqlserver/Oracle
|
||||||
|
- [x] 支持上海杰哥官方`SqlSugar ORM`封装
|
||||||
|
- [x] 支持新版`SwaggerWebAPI`,jwt身份认证接入
|
||||||
|
- [x] 支持`Cors`跨域
|
||||||
|
- [x] 支持`AutoFac`自动映射依赖注入
|
||||||
|
- [x] 支持`consul`服务器注册与发现
|
||||||
|
- [x] 支持`健康检查`
|
||||||
|
- [x] 支持`RabbitMQ`消息队列
|
||||||
|
- [x] 支持`Redis`多级缓存
|
||||||
|
- [x] 支持`MemoryCache`多级缓存
|
||||||
|
- [x] 支持`Ocelot`网关,路由、服务聚合、服务发现、认证、鉴权、限流、熔断、缓存、Header头传递
|
||||||
|
- [x] 支持`Apollo`全局配置中心;
|
||||||
|
- [x] 支持`docker`镜像制作
|
||||||
|
- [x] 支持`Quartz.net`任务调度,实现任意接口被调度
|
||||||
|
- [x] 支持`ThumbnailSharp`缩略图封装
|
||||||
|
- [x] 支持`ELK`,log4net+kafka+es+logstach+kibana
|
||||||
|
- [x] 支持`IdentityService4`授权中心
|
||||||
|
- [x] 支持`Es`分词查询
|
||||||
|
- [x] 支持多级`缓存`
|
||||||
|
- [x] 支持`CAP`分布式事务,mysql+rabbitMq
|
||||||
|
- [x] 支持`Docker+k8s`部署
|
||||||
|
- [x] 支持`Jenkins+CI/CD`
|
||||||
|
- [x] 支持`AutoMapper`模块映射
|
||||||
|
- [x] 支持`微信支付`模块
|
||||||
|
- [x] 支持`单表多租户`常用功能
|
||||||
|
- [x] 支持`逻辑删除`常用功能
|
||||||
|
- [x] 支持`操作日志`常用功能
|
||||||
|
- [x] 支持`自动分表`
|
||||||
|
- [x] 支持`数据权限`
|
||||||
|
- [x] 支持`CodeFrist`快速构建数据库
|
||||||
|
- [x] 支持自研文件版`代码生成器`快速构建通用代码
|
||||||
|
- [x] 支持完整`Dto`模式
|
||||||
|
- [x] 支持 太多了忘了
|
||||||
|
|
||||||
|
|
||||||
|
****
|
||||||
|
### 目录结构:
|
||||||
|
|
||||||
|

|
||||||
|

|
||||||
|

|
||||||
|
|
||||||
|
我们大致依照DDD领域驱动设计分层
|
||||||
|
|
||||||
|
分层如此清晰!什么?还感觉太复杂了?用户只需关注Api、Service其他都是轮子啊!
|
||||||
|
|
||||||
|
- BackGround:后台进程(通常使用消息队列进行消费任务)
|
||||||
|
- Test:测试(单元测试)
|
||||||
|
- Domain:领域层(Dto、服务接口层、模型层、仓储层、服务层)
|
||||||
|
- Infrastructure:基础实例层(通用工具层、核心层、定时任务Job、国际化、Web扩展层)
|
||||||
|
- Module:模块层(其他模块,可按需进行引入,例如微信支付、代码生成)
|
||||||
|
- MicroServiceInstance:服务层(微服务)
|
||||||
|
|
||||||
|
****
|
||||||
|
### 安装教程:
|
||||||
|
|
||||||
|
我们将在之后更新教程手册!
|
||||||
|
|
||||||
|
后端
|
||||||
|
1. 下载全部源码,默认使用sqlite数据库,已经生成
|
||||||
|
2. 直接点击sln文件运行即可,没有任何其他依赖
|
||||||
|
|
||||||
|
前端
|
||||||
|
1. 下载全部源码,npm i 安装依赖
|
||||||
|
2. 使用npm run dev进行运行
|
||||||
|
|
||||||
|
|
||||||
|
****
|
||||||
|
### 使用说明:
|
||||||
|
|
||||||
|
~~1. 导入使用仓库中的WebFirst数据库~~
|
||||||
|
~~2. 使用WebFirst添加实体、同步实体、修改模板生成路径并生成方案~~
|
||||||
|
|
||||||
|
没了,恭喜你已经成功完成了项目,并且已经具备大部分通用场景业务
|
||||||
|
是不是一个字?爽!
|
||||||
|
到此为止,你无需写任何一个代码!
|
||||||
|
|
||||||
|
**爽点**:
|
||||||
|
|
||||||
|
新人,看这里,项目下载之后直接可以启动,无任何依赖,之后你可以查看`Test控制器`,迫不及待的快来爽一爽!
|
||||||
|
|
||||||
|
我们将使用说明转移至我们的官方论坛中,正在制作中,尽情期待!
|
||||||
|
|
||||||
|
****
|
||||||
|
### 感谢:
|
||||||
|
|
||||||
|
**大力支持**: Eleven神、Sqlsugar上海杰哥、Gerry、哲学的老张
|
||||||
|
|
||||||
[橙子]https://ccnetcore.com
|
[橙子]https://ccnetcore.com
|
||||||
|
|
||||||
[XWen]https://gitee.com/on-wensil
|
[lzw]https://github.com/yeslode
|
||||||
|
|
||||||
[朝夕教育]https://www.zhaoxiedu.net
|
[朝夕教育]https://www.zhaoxiedu.net
|
||||||
|
|
||||||
[Sqlsugar老杰哥]https://www.donet5.com/Home/Doc
|
[Sqlsugar]https://www.donet5.com/Home/Doc
|
||||||
|
|
||||||
[车神]微信公众号搜索Dotnet技术进阶
|
[RuYiAdmin]https://gitee.com/pang-mingjun/RuYiAdmin
|
||||||
|
|
||||||
[RuYiAdmin如意老兄]https://gitee.com/pang-mingjun/RuYiAdmin
|
[ZrAdminNetCore]https://gitee.com/izory/ZrAdminNetCore
|
||||||
|
|
||||||
[ZrAdminNetCore字母老哥]https://gitee.com/izory/ZrAdminNetCore
|
|
||||||
|
|
||||||
[Admin.NET]https://gitee.com/zuohuaijun/Admin.NET
|
|
||||||
|
|
||||||
[Furion百小僧]https://furion.baiqian.ltd/
|
|
||||||
|
|
||||||
****
|
****
|
||||||
## :tw-1f438: 联系我们:
|
### 联系我们:
|
||||||
|
|
||||||
作者QQ:`454313500`,2029年之前作者24小时在线,时刻保持活跃更新。
|
作者QQ:`454313500`,2029年之前作者24小时在线,时刻保持活跃更新。
|
||||||
|
|
||||||
QQ交流群:官方一群(已满)、官方二群(已满)、官方三群:`786308927`(已满)、官方四群:`498310311`(基本已满)、官方五群:`981136525`(新群)
|
QQ交流群:官方一群(已满)、官方二群(已满)、官方三群:`786308927`(加作者QQ后同意)
|
||||||
|
|
||||||
微信交流群:加作者微信 chengzilaoge520 (橙子老哥520),备注拉群
|
|
||||||
|
|
||||||
联系作者,这里人人都是顾问
|
联系作者,这里人人都是顾问
|
||||||
|
|
||||||
官方网址留言区:[ccnetcore.com](https://ccnetcore.com)
|
官方网址:正在建设
|
||||||
|
|
||||||
****
|
****
|
||||||
## :tw-1f41e: FQA:
|
### FQA:
|
||||||
|
|
||||||
前往官网查看留言区
|
问1:为什么不采用EFcore?
|
||||||
|
|
||||||
[留言区](https://ccnetcore.com/discuss/1641030787056930818)
|
答1:别问,问就是Sqlsugar,和本框架一样爽!
|
||||||
|
|
||||||
|
问2:以后会持续更新下去吗?
|
||||||
|
|
||||||
|
答2:一定会的,我们的标题是 一个和Sqlsugar一样爽的.Net6开源框架 ,只要Sqlsugar在,我们将一直更新下去。
|
||||||
|
|
||||||
|
问3:这个框架的针对人群是哪些人?适合所有人吗?
|
||||||
|
|
||||||
|
答3:并不是适合所有人,应该算适合需要有一定基础的开发人员,当然,如果你是大神,你完全可以将这个框架二次开发!
|
||||||
|
|
||||||
|
问4:花如此多的精力制作这个框架,是为了什么?是为了赚钱吗?和目前主流的abp等框架比,又有什么意义呢?
|
||||||
|
|
||||||
|
答4:我们与Sqlsugar作者理念一致,我们是从用户角度出发,框架是为用户服务,与ABP复杂上手理念完全是相反的。
|
||||||
|
|
||||||
|
问5:为何不出版一个详细的说明书呢?
|
||||||
|
|
||||||
|
答5:暂时不会了,之后可能会,代码都是基于Asp.NetCore框架,适用于新手不用造轮子,整个框架较为简单,阅读源码后,基本能自定义改造使用了,过难也已经封装完毕,别忘了,其意义是为了开发更加简易!建议添加作者好友,这里人人都是顾问。
|
||||||
|
|
||||||
|
我大抵要厌倦了负重前行。
|
||||||
|
|||||||
BIN
Readme/代码生成.gif
Normal file
BIN
Readme/代码生成.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.5 MiB |
BIN
Readme/用户管理.png
Normal file
BIN
Readme/用户管理.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 79 KiB |
BIN
Readme/菜单管理.png
Normal file
BIN
Readme/菜单管理.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 153 KiB |
@@ -1,509 +0,0 @@
|
|||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
|
||||||
# Visual Studio Version 17
|
|
||||||
VisualStudioVersion = 17.7.34202.233
|
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Abp.Web", "src\Yi.Abp.Web\Yi.Abp.Web.csproj", "{15913E44-DA92-44B9-9AC5-E9457EA34BF5}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.SqlSugarCore", "framework\Yi.Framework.SqlSugarCore\Yi.Framework.SqlSugarCore.csproj", "{DC431ECC-C75D-4B01-8B79-4861948179BB}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{B782C78B-6C17-49E6-A237-3383BA720766}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{0D10EEF2-FBAE-4C72-B816-A52823FC299B}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "framework", "framework", "{77B949E9-530E-45A5-9657-20F7D5C6875C}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "module", "module", "{2317227D-7796-4E7B-BEDB-7CD1CAE7B853}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Abp.SqlSugarCore", "src\Yi.Abp.SqlSugarCore\Yi.Abp.SqlSugarCore.csproj", "{9A7BBA40-28D6-4900-9E1D-D627A516EE72}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Abp.Application", "src\Yi.Abp.Application\Yi.Abp.Application.csproj", "{746DBBD6-23E8-4D5D-9D23-E2902BE338BD}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Abp.Application.Contracts", "src\Yi.Abp.Application.Contracts\Yi.Abp.Application.Contracts.csproj", "{51EEBF59-3D37-4681-981D-56F8D8F8968D}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Abp.Domain", "src\Yi.Abp.Domain\Yi.Abp.Domain.csproj", "{7B15C198-538A-44ED-A6AA-3A0FEAA1D2BD}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Abp.Domain.Shared", "src\Yi.Abp.Domain.Shared\Yi.Abp.Domain.Shared.csproj", "{F4D5A496-BFBE-470B-A05B-CB5823B47E72}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{6A5375C6-1D55-4E93-9B19-736F1C68CBC3}"
|
|
||||||
ProjectSection(SolutionItems) = preProject
|
|
||||||
common.props = common.props
|
|
||||||
end.sh = end.sh
|
|
||||||
logo.png = logo.png
|
|
||||||
start.sh = start.sh
|
|
||||||
tool.bat = tool.bat
|
|
||||||
usings.props = usings.props
|
|
||||||
version.props = version.props
|
|
||||||
publish.bat = publish.bat
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.SqlSugarCore.Abstractions", "framework\Yi.Framework.SqlSugarCore.Abstractions\Yi.Framework.SqlSugarCore.Abstractions.csproj", "{FD6D6860-3753-4747-8A26-977E4A3001F9}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.Core", "framework\Yi.Framework.Core\Yi.Framework.Core.csproj", "{ECE874D4-F882-4EF4-84A6-A842D9B8FBC5}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.Mapster", "framework\Yi.Framework.Mapster\Yi.Framework.Mapster.csproj", "{1995A019-C8AE-467E-B427-ED57D6CBF44F}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.AspNetCore", "framework\Yi.Framework.AspNetCore\Yi.Framework.AspNetCore.csproj", "{F5011C0D-209B-4A98-BBE3-68157503EEF8}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.Ddd.Application.Contracts", "framework\Yi.Framework.Ddd.Application.Contracts\Yi.Framework.Ddd.Application.Contracts.csproj", "{0A8296A3-C11F-4F13-8E49-6BC8188D4804}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.Ddd.Application", "framework\Yi.Framework.Ddd.Application\Yi.Framework.Ddd.Application.csproj", "{F0141C17-0EBD-4261-98D5-1C5B7BC1DFEE}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "rbac", "rbac", "{9CC7A457-1236-40BA-B47B-E7B710A3F061}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.Rbac.Application.Contracts", "module\rbac\Yi.Framework.Rbac.Application.Contracts\Yi.Framework.Rbac.Application.Contracts.csproj", "{1C360956-8CD8-407E-B87F-D0BD57068EB9}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.Rbac.Application", "module\rbac\Yi.Framework.Rbac.Application\Yi.Framework.Rbac.Application.csproj", "{4F02B08D-5FE2-460D-BCA5-DA565151AE30}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.Rbac.Domain", "module\rbac\Yi.Framework.Rbac.Domain\Yi.Framework.Rbac.Domain.csproj", "{C04D3F71-1557-46D0-B810-97B1FBB6AB73}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.Rbac.Domain.Shared", "module\rbac\Yi.Framework.Rbac.Domain.Shared\Yi.Framework.Rbac.Domain.Shared.csproj", "{A2BB899D-4F9A-4184-81BD-94B938E2AB03}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.Rbac.SqlSugarCore", "module\rbac\Yi.Framework.Rbac.SqlSugarCore\Yi.Framework.Rbac.SqlSugarCore.csproj", "{4503A2F9-139D-4CBC-AF11-689C34F0D77B}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "bbs", "bbs", "{E902A945-4F41-4E96-A0DA-9F66CDA22261}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.Bbs.Domain.Shared", "module\bbs\Yi.Framework.Bbs.Domain.Shared\Yi.Framework.Bbs.Domain.Shared.csproj", "{EB9349E2-256D-41EB-A345-21635A1361B3}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.Bbs.Domain", "module\bbs\Yi.Framework.Bbs.Domain\Yi.Framework.Bbs.Domain.csproj", "{4EABBC84-BCED-46C1-8CF1-62A7B8081ED7}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.Bbs.Application.Contracts", "module\bbs\Yi.Framework.Bbs.Application.Contracts\Yi.Framework.Bbs.Application.Contracts.csproj", "{7E569FD9-B1AB-4848-8AB7-FD9EFA1DBA20}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.Bbs.Application", "module\bbs\Yi.Framework.Bbs.Application\Yi.Framework.Bbs.Application.csproj", "{AD4EE9E6-F4A3-4139-AF05-71388167DE5B}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.Bbs.SqlSugarCore", "module\bbs\Yi.Framework.Bbs.SqlSugarCore\Yi.Framework.Bbs.SqlSugarCore.csproj", "{6C86BA71-9F87-4E2C-B467-2950D77DCDFA}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "audit-logging", "audit-logging", "{73CCF2C4-B9FD-44AB-8D4B-0A421805B094}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.AuditLogging.SqlSugarCore", "module\audit-logging\Yi.Framework.AuditLogging.SqlSugarCore\Yi.Framework.AuditLogging.SqlSugarCore.csproj", "{48806510-8E18-4E1E-9BAF-5B97E88C5FC3}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.AspNetCore.Authentication.OAuth", "framework\Yi.Framework.AspNetCore.Authentication.OAuth\Yi.Framework.AspNetCore.Authentication.OAuth.csproj", "{791AC2FA-50D3-4408-8D68-31DA72F608BE}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "sample", "sample", "{01300F0F-686E-47B3-821D-12424177867B}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Acme.BookStore.Web", "sample\Acme.BookStore.Web\Acme.BookStore.Web.csproj", "{576DBC97-4E5D-4444-B65C-F41649A5F8E0}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Acme.BookStore.Domain.Shared", "sample\Acme.BookStore.Domain.Shared\Acme.BookStore.Domain.Shared.csproj", "{D7F8BD42-F6A2-4F0A-9212-391B5185A99D}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Acme.BookStore.Domain", "sample\Acme.BookStore.Domain\Acme.BookStore.Domain.csproj", "{B615847F-8568-41D1-8B7E-63D61AE69F3D}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Acme.BookStore.Application.Contracts", "sample\Acme.BookStore.Application.Contracts\Acme.BookStore.Application.Contracts.csproj", "{20827DB5-5CDE-491A-82E8-3CAB82618C1E}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Acme.BookStore.Application", "sample\Acme.BookStore.Application\Acme.BookStore.Application.csproj", "{320273B6-7AE3-42DA-9675-D9AD4928A289}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Acme.BookStore.SqlSugarCore", "sample\Acme.BookStore.SqlSugarCore\Acme.BookStore.SqlSugarCore.csproj", "{70CCBD89-C0A1-4AC8-9AFA-C86C356DFDD7}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Abp.Test", "test\Yi.Abp.Test\Yi.Abp.Test.csproj", "{68627BC2-F049-4C69-AD17-81DF9478E8CE}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tenant-management", "tenant-management", "{499A8C71-7892-42D0-A77E-48756E1EFF16}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.TenantManagement.SqlSugarCore", "module\tenant-management\Yi.Framework.TenantManagement.SqlSugarCore\Yi.Framework.TenantManagement.SqlSugarCore.csproj", "{FA5BBAA1-08DC-472F-BB2C-5314E59D1556}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.TenantManagement.Domain", "module\tenant-management\Yi.Framework.TenantManagement.Domain\Yi.Framework.TenantManagement.Domain.csproj", "{54D8E2BC-591C-4344-A58E-874D49C00B41}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.AuditLogging.Domain", "module\audit-logging\Yi.Framework.AuditLogging.Domain\Yi.Framework.AuditLogging.Domain.csproj", "{EFD13211-17B5-400A-B99A-9F6F4E520C1E}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.AuditLogging.Domain.Shared", "module\audit-logging\Yi.Framework.AuditLogging.Domain.Shared\Yi.Framework.AuditLogging.Domain.Shared.csproj", "{9C8C3C53-3DCE-4516-867E-228858E61B26}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.TenantManagement.Application", "module\tenant-management\Yi.Framework.TenantManagement.Application\Yi.Framework.TenantManagement.Application.csproj", "{17816837-E53B-486B-B796-53C601FE6CD9}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.TenantManagement.Application.Contracts", "module\tenant-management\Yi.Framework.TenantManagement.Application.Contracts\Yi.Framework.TenantManagement.Application.Contracts.csproj", "{FA735055-CBDD-4EFD-B84B-85810DA1425E}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "code-gen", "code-gen", "{4FFE7212-21F2-476D-B628-3C65E6C5075E}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.CodeGen.Application", "module\code-gen\Yi.Framework.CodeGen.Application\Yi.Framework.CodeGen.Application.csproj", "{97EC40D7-DBFA-467A-98CB-221AF27B14F2}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.CodeGen.Application.Contracts", "module\code-gen\Yi.Framework.CodeGen.Application.Contracts\Yi.Framework.CodeGen.Application.Contracts.csproj", "{882BC563-2F75-4B95-AC96-F4BF23F5E69D}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.CodeGen.Domain", "module\code-gen\Yi.Framework.CodeGen.Domain\Yi.Framework.CodeGen.Domain.csproj", "{85CB8517-2B80-42D8-B954-081079AC9BA0}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.CodeGen.Domain.Shared", "module\code-gen\Yi.Framework.CodeGen.Domain.Shared\Yi.Framework.CodeGen.Domain.Shared.csproj", "{EEFF0F05-2709-4151-A8CE-667935CEAE0B}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.Caching.FreeRedis", "framework\Yi.Framework.Caching.FreeRedis\Yi.Framework.Caching.FreeRedis.csproj", "{862BB0EF-3D4E-44FF-AB15-0EB74CE553D3}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.CodeGen.SqlSugarCore", "module\code-gen\Yi.Framework.CodeGen.SqlSugarCore\Yi.Framework.CodeGen.SqlSugarCore.csproj", "{FB09ACC2-A27D-4D87-8D85-1435FDED4D04}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "client", "client", "{8B27846A-043D-4F2F-8140-5CEC9D1863B5}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Abp.HttpApi.Client", "client\Yi.Abp.HttpApi.Client\Yi.Abp.HttpApi.Client.csproj", "{6B554DCC-3A81-4624-9141-4E39365ADA35}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Abp.Client.Console", "client\Yi.Abp.Client.Console\Yi.Abp.Client.Console.csproj", "{2D23B44A-DFA3-4C36-8516-4F5AE442403C}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Abp.Client.WebApi", "client\Yi.Abp.Client.WebApi\Yi.Abp.Client.WebApi.csproj", "{00E49781-C6A0-491C-86A1-46F685C90915}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "setting-management", "setting-management", "{8C68059E-F3B1-4D28-A1C9-A5830F53E5D3}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.SettingManagement.Domain", "module\setting-management\Yi.Framework.SettingManagement.Domain\Yi.Framework.SettingManagement.Domain.csproj", "{6FEE0EB3-EAD2-47F8-B6FC-3D0FD3CCABFF}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.SettingManagement.SqlSugarCore", "module\setting-management\Yi.Framework.SettingManagement.SqlSugarCore\Yi.Framework.SettingManagement.SqlSugarCore.csproj", "{495C4643-39D4-46E7-BDC8-237589627BE4}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "chat-hub", "chat-hub", "{D8CDDE99-3684-4EED-A5E5-87F2AF4C78AB}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.ChatHub.Application.Contracts", "module\chat-hub\Yi.Framework.ChatHub.Application.Contracts\Yi.Framework.ChatHub.Application.Contracts.csproj", "{65D4D033-5504-44B9-B152-0172ACD64CE6}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.ChatHub.Domain.Shared", "module\chat-hub\Yi.Framework.ChatHub.Domain.Shared\Yi.Framework.ChatHub.Domain.Shared.csproj", "{DEEC0B15-190C-4464-B469-C45C6563C592}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.ChatHub.SqlSugarCore", "module\chat-hub\Yi.Framework.ChatHub.SqlSugarCore\Yi.Framework.ChatHub.SqlSugarCore.csproj", "{E476D266-8FB2-4D6B-AE2B-F0D279D4264E}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.ChatHub.Domain", "module\chat-hub\Yi.Framework.ChatHub.Domain\Yi.Framework.ChatHub.Domain.csproj", "{C2DCA2FD-BFB4-4E76-967B-0AF8CC4F4D47}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.ChatHub.Application", "module\chat-hub\Yi.Framework.ChatHub.Application\Yi.Framework.ChatHub.Application.csproj", "{B7A1A8F3-CFA6-4ECF-A707-0F33FE0A6F1D}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Framework.Rbac.Test", "test\Yi.Framework.Rbac.Test\Yi.Framework.Rbac.Test.csproj", "{9ECF0841-53BE-4FD8-95D1-A7223C7F3A07}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tool", "tool", "{084CBEEC-5D37-4716-B9C7-D80D6960DFF4}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Abp.Tool", "tool\Yi.Abp.Tool\Yi.Abp.Tool.csproj", "{4FEBBDD9-E4F4-4BAF-8599-E2D57C08A74F}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Abp.Tool.Web", "tool\Yi.Abp.Tool.Web\Yi.Abp.Tool.Web.csproj", "{2CE51D4C-1EF9-462B-BA14-7EA01A7E4AF1}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Abp.Tool.Application", "tool\Yi.Abp.Tool.Application\Yi.Abp.Tool.Application.csproj", "{776590BA-B900-4C8B-986A-5B721FA4B306}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Abp.Tool.Application.Contracts", "tool\Yi.Abp.Tool.Application.Contracts\Yi.Abp.Tool.Application.Contracts.csproj", "{3A3AF1ED-FC7F-48CF-8ACE-9D50426B4675}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Abp.Tool.Domain", "tool\Yi.Abp.Tool.Domain\Yi.Abp.Tool.Domain.csproj", "{68F73B7B-0F8A-41C1-8092-6D6FFAED32F8}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Abp.Tool.Domain.Shared", "tool\Yi.Abp.Tool.Domain.Shared\Yi.Abp.Tool.Domain.Shared.csproj", "{4AE84CDE-2A47-4D68-8E93-86193F72E4E8}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Yi.Abp.Tool.HttpApi.Client", "tool\Yi.Abp.Tool.HttpApi.Client\Yi.Abp.Tool.HttpApi.Client.csproj", "{C8F97775-D903-4365-A4FF-3DA97E318CD2}"
|
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Yi.Framework.SettingManagement.Application", "module\setting-management\Yi.Framework.SettingManagement.Application\Yi.Framework.SettingManagement.Application.csproj", "{2A31D7CB-BDCC-4253-BA73-273B6B5E1956}"
|
|
||||||
EndProject
|
|
||||||
Global
|
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
||||||
Debug|Any CPU = Debug|Any CPU
|
|
||||||
Release|Any CPU = Release|Any CPU
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
|
||||||
{15913E44-DA92-44B9-9AC5-E9457EA34BF5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{15913E44-DA92-44B9-9AC5-E9457EA34BF5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{15913E44-DA92-44B9-9AC5-E9457EA34BF5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{15913E44-DA92-44B9-9AC5-E9457EA34BF5}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{DC431ECC-C75D-4B01-8B79-4861948179BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{DC431ECC-C75D-4B01-8B79-4861948179BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{DC431ECC-C75D-4B01-8B79-4861948179BB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{DC431ECC-C75D-4B01-8B79-4861948179BB}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{9A7BBA40-28D6-4900-9E1D-D627A516EE72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{9A7BBA40-28D6-4900-9E1D-D627A516EE72}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{9A7BBA40-28D6-4900-9E1D-D627A516EE72}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{9A7BBA40-28D6-4900-9E1D-D627A516EE72}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{746DBBD6-23E8-4D5D-9D23-E2902BE338BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{746DBBD6-23E8-4D5D-9D23-E2902BE338BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{746DBBD6-23E8-4D5D-9D23-E2902BE338BD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{746DBBD6-23E8-4D5D-9D23-E2902BE338BD}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{51EEBF59-3D37-4681-981D-56F8D8F8968D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{51EEBF59-3D37-4681-981D-56F8D8F8968D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{51EEBF59-3D37-4681-981D-56F8D8F8968D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{51EEBF59-3D37-4681-981D-56F8D8F8968D}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{7B15C198-538A-44ED-A6AA-3A0FEAA1D2BD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{7B15C198-538A-44ED-A6AA-3A0FEAA1D2BD}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{7B15C198-538A-44ED-A6AA-3A0FEAA1D2BD}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{7B15C198-538A-44ED-A6AA-3A0FEAA1D2BD}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{F4D5A496-BFBE-470B-A05B-CB5823B47E72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{F4D5A496-BFBE-470B-A05B-CB5823B47E72}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{F4D5A496-BFBE-470B-A05B-CB5823B47E72}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{F4D5A496-BFBE-470B-A05B-CB5823B47E72}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{FD6D6860-3753-4747-8A26-977E4A3001F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{FD6D6860-3753-4747-8A26-977E4A3001F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{FD6D6860-3753-4747-8A26-977E4A3001F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{FD6D6860-3753-4747-8A26-977E4A3001F9}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{ECE874D4-F882-4EF4-84A6-A842D9B8FBC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{ECE874D4-F882-4EF4-84A6-A842D9B8FBC5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{ECE874D4-F882-4EF4-84A6-A842D9B8FBC5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{ECE874D4-F882-4EF4-84A6-A842D9B8FBC5}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{1995A019-C8AE-467E-B427-ED57D6CBF44F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{1995A019-C8AE-467E-B427-ED57D6CBF44F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{1995A019-C8AE-467E-B427-ED57D6CBF44F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{1995A019-C8AE-467E-B427-ED57D6CBF44F}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{F5011C0D-209B-4A98-BBE3-68157503EEF8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{F5011C0D-209B-4A98-BBE3-68157503EEF8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{F5011C0D-209B-4A98-BBE3-68157503EEF8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{F5011C0D-209B-4A98-BBE3-68157503EEF8}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{0A8296A3-C11F-4F13-8E49-6BC8188D4804}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{0A8296A3-C11F-4F13-8E49-6BC8188D4804}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{0A8296A3-C11F-4F13-8E49-6BC8188D4804}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{0A8296A3-C11F-4F13-8E49-6BC8188D4804}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{F0141C17-0EBD-4261-98D5-1C5B7BC1DFEE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{F0141C17-0EBD-4261-98D5-1C5B7BC1DFEE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{F0141C17-0EBD-4261-98D5-1C5B7BC1DFEE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{F0141C17-0EBD-4261-98D5-1C5B7BC1DFEE}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{1C360956-8CD8-407E-B87F-D0BD57068EB9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{1C360956-8CD8-407E-B87F-D0BD57068EB9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{1C360956-8CD8-407E-B87F-D0BD57068EB9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{1C360956-8CD8-407E-B87F-D0BD57068EB9}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{4F02B08D-5FE2-460D-BCA5-DA565151AE30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{4F02B08D-5FE2-460D-BCA5-DA565151AE30}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{4F02B08D-5FE2-460D-BCA5-DA565151AE30}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{4F02B08D-5FE2-460D-BCA5-DA565151AE30}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{C04D3F71-1557-46D0-B810-97B1FBB6AB73}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{C04D3F71-1557-46D0-B810-97B1FBB6AB73}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{C04D3F71-1557-46D0-B810-97B1FBB6AB73}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{C04D3F71-1557-46D0-B810-97B1FBB6AB73}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{A2BB899D-4F9A-4184-81BD-94B938E2AB03}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{A2BB899D-4F9A-4184-81BD-94B938E2AB03}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{A2BB899D-4F9A-4184-81BD-94B938E2AB03}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{A2BB899D-4F9A-4184-81BD-94B938E2AB03}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{4503A2F9-139D-4CBC-AF11-689C34F0D77B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{4503A2F9-139D-4CBC-AF11-689C34F0D77B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{4503A2F9-139D-4CBC-AF11-689C34F0D77B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{4503A2F9-139D-4CBC-AF11-689C34F0D77B}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{EB9349E2-256D-41EB-A345-21635A1361B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{EB9349E2-256D-41EB-A345-21635A1361B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{EB9349E2-256D-41EB-A345-21635A1361B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{EB9349E2-256D-41EB-A345-21635A1361B3}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{4EABBC84-BCED-46C1-8CF1-62A7B8081ED7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{4EABBC84-BCED-46C1-8CF1-62A7B8081ED7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{4EABBC84-BCED-46C1-8CF1-62A7B8081ED7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{4EABBC84-BCED-46C1-8CF1-62A7B8081ED7}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{7E569FD9-B1AB-4848-8AB7-FD9EFA1DBA20}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{7E569FD9-B1AB-4848-8AB7-FD9EFA1DBA20}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{7E569FD9-B1AB-4848-8AB7-FD9EFA1DBA20}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{7E569FD9-B1AB-4848-8AB7-FD9EFA1DBA20}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{AD4EE9E6-F4A3-4139-AF05-71388167DE5B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{AD4EE9E6-F4A3-4139-AF05-71388167DE5B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{AD4EE9E6-F4A3-4139-AF05-71388167DE5B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{AD4EE9E6-F4A3-4139-AF05-71388167DE5B}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{6C86BA71-9F87-4E2C-B467-2950D77DCDFA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{6C86BA71-9F87-4E2C-B467-2950D77DCDFA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{6C86BA71-9F87-4E2C-B467-2950D77DCDFA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{6C86BA71-9F87-4E2C-B467-2950D77DCDFA}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{48806510-8E18-4E1E-9BAF-5B97E88C5FC3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{48806510-8E18-4E1E-9BAF-5B97E88C5FC3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{48806510-8E18-4E1E-9BAF-5B97E88C5FC3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{48806510-8E18-4E1E-9BAF-5B97E88C5FC3}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{791AC2FA-50D3-4408-8D68-31DA72F608BE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{791AC2FA-50D3-4408-8D68-31DA72F608BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{791AC2FA-50D3-4408-8D68-31DA72F608BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{791AC2FA-50D3-4408-8D68-31DA72F608BE}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{576DBC97-4E5D-4444-B65C-F41649A5F8E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{576DBC97-4E5D-4444-B65C-F41649A5F8E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{576DBC97-4E5D-4444-B65C-F41649A5F8E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{576DBC97-4E5D-4444-B65C-F41649A5F8E0}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{D7F8BD42-F6A2-4F0A-9212-391B5185A99D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{D7F8BD42-F6A2-4F0A-9212-391B5185A99D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{D7F8BD42-F6A2-4F0A-9212-391B5185A99D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{D7F8BD42-F6A2-4F0A-9212-391B5185A99D}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{B615847F-8568-41D1-8B7E-63D61AE69F3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{B615847F-8568-41D1-8B7E-63D61AE69F3D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{B615847F-8568-41D1-8B7E-63D61AE69F3D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{B615847F-8568-41D1-8B7E-63D61AE69F3D}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{20827DB5-5CDE-491A-82E8-3CAB82618C1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{20827DB5-5CDE-491A-82E8-3CAB82618C1E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{20827DB5-5CDE-491A-82E8-3CAB82618C1E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{20827DB5-5CDE-491A-82E8-3CAB82618C1E}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{320273B6-7AE3-42DA-9675-D9AD4928A289}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{320273B6-7AE3-42DA-9675-D9AD4928A289}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{320273B6-7AE3-42DA-9675-D9AD4928A289}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{320273B6-7AE3-42DA-9675-D9AD4928A289}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{70CCBD89-C0A1-4AC8-9AFA-C86C356DFDD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{70CCBD89-C0A1-4AC8-9AFA-C86C356DFDD7}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{70CCBD89-C0A1-4AC8-9AFA-C86C356DFDD7}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{70CCBD89-C0A1-4AC8-9AFA-C86C356DFDD7}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{68627BC2-F049-4C69-AD17-81DF9478E8CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{68627BC2-F049-4C69-AD17-81DF9478E8CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{68627BC2-F049-4C69-AD17-81DF9478E8CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{68627BC2-F049-4C69-AD17-81DF9478E8CE}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{FA5BBAA1-08DC-472F-BB2C-5314E59D1556}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{FA5BBAA1-08DC-472F-BB2C-5314E59D1556}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{FA5BBAA1-08DC-472F-BB2C-5314E59D1556}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{FA5BBAA1-08DC-472F-BB2C-5314E59D1556}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{54D8E2BC-591C-4344-A58E-874D49C00B41}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{54D8E2BC-591C-4344-A58E-874D49C00B41}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{54D8E2BC-591C-4344-A58E-874D49C00B41}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{54D8E2BC-591C-4344-A58E-874D49C00B41}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{EFD13211-17B5-400A-B99A-9F6F4E520C1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{EFD13211-17B5-400A-B99A-9F6F4E520C1E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{EFD13211-17B5-400A-B99A-9F6F4E520C1E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{EFD13211-17B5-400A-B99A-9F6F4E520C1E}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{9C8C3C53-3DCE-4516-867E-228858E61B26}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{9C8C3C53-3DCE-4516-867E-228858E61B26}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{9C8C3C53-3DCE-4516-867E-228858E61B26}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{9C8C3C53-3DCE-4516-867E-228858E61B26}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{17816837-E53B-486B-B796-53C601FE6CD9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{17816837-E53B-486B-B796-53C601FE6CD9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{17816837-E53B-486B-B796-53C601FE6CD9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{17816837-E53B-486B-B796-53C601FE6CD9}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{FA735055-CBDD-4EFD-B84B-85810DA1425E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{FA735055-CBDD-4EFD-B84B-85810DA1425E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{FA735055-CBDD-4EFD-B84B-85810DA1425E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{FA735055-CBDD-4EFD-B84B-85810DA1425E}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{97EC40D7-DBFA-467A-98CB-221AF27B14F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{97EC40D7-DBFA-467A-98CB-221AF27B14F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{97EC40D7-DBFA-467A-98CB-221AF27B14F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{97EC40D7-DBFA-467A-98CB-221AF27B14F2}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{882BC563-2F75-4B95-AC96-F4BF23F5E69D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{882BC563-2F75-4B95-AC96-F4BF23F5E69D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{882BC563-2F75-4B95-AC96-F4BF23F5E69D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{882BC563-2F75-4B95-AC96-F4BF23F5E69D}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{85CB8517-2B80-42D8-B954-081079AC9BA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{85CB8517-2B80-42D8-B954-081079AC9BA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{85CB8517-2B80-42D8-B954-081079AC9BA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{85CB8517-2B80-42D8-B954-081079AC9BA0}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{EEFF0F05-2709-4151-A8CE-667935CEAE0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{EEFF0F05-2709-4151-A8CE-667935CEAE0B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{EEFF0F05-2709-4151-A8CE-667935CEAE0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{EEFF0F05-2709-4151-A8CE-667935CEAE0B}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{862BB0EF-3D4E-44FF-AB15-0EB74CE553D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{862BB0EF-3D4E-44FF-AB15-0EB74CE553D3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{862BB0EF-3D4E-44FF-AB15-0EB74CE553D3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{862BB0EF-3D4E-44FF-AB15-0EB74CE553D3}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{FB09ACC2-A27D-4D87-8D85-1435FDED4D04}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{FB09ACC2-A27D-4D87-8D85-1435FDED4D04}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{FB09ACC2-A27D-4D87-8D85-1435FDED4D04}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{FB09ACC2-A27D-4D87-8D85-1435FDED4D04}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{6B554DCC-3A81-4624-9141-4E39365ADA35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{6B554DCC-3A81-4624-9141-4E39365ADA35}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{6B554DCC-3A81-4624-9141-4E39365ADA35}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{6B554DCC-3A81-4624-9141-4E39365ADA35}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{2D23B44A-DFA3-4C36-8516-4F5AE442403C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{2D23B44A-DFA3-4C36-8516-4F5AE442403C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{2D23B44A-DFA3-4C36-8516-4F5AE442403C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{2D23B44A-DFA3-4C36-8516-4F5AE442403C}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{00E49781-C6A0-491C-86A1-46F685C90915}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{00E49781-C6A0-491C-86A1-46F685C90915}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{00E49781-C6A0-491C-86A1-46F685C90915}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{00E49781-C6A0-491C-86A1-46F685C90915}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{6FEE0EB3-EAD2-47F8-B6FC-3D0FD3CCABFF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{6FEE0EB3-EAD2-47F8-B6FC-3D0FD3CCABFF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{6FEE0EB3-EAD2-47F8-B6FC-3D0FD3CCABFF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{6FEE0EB3-EAD2-47F8-B6FC-3D0FD3CCABFF}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{495C4643-39D4-46E7-BDC8-237589627BE4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{495C4643-39D4-46E7-BDC8-237589627BE4}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{495C4643-39D4-46E7-BDC8-237589627BE4}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{495C4643-39D4-46E7-BDC8-237589627BE4}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{65D4D033-5504-44B9-B152-0172ACD64CE6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{65D4D033-5504-44B9-B152-0172ACD64CE6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{65D4D033-5504-44B9-B152-0172ACD64CE6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{65D4D033-5504-44B9-B152-0172ACD64CE6}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{DEEC0B15-190C-4464-B469-C45C6563C592}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{DEEC0B15-190C-4464-B469-C45C6563C592}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{DEEC0B15-190C-4464-B469-C45C6563C592}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{DEEC0B15-190C-4464-B469-C45C6563C592}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{E476D266-8FB2-4D6B-AE2B-F0D279D4264E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{E476D266-8FB2-4D6B-AE2B-F0D279D4264E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{E476D266-8FB2-4D6B-AE2B-F0D279D4264E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{E476D266-8FB2-4D6B-AE2B-F0D279D4264E}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{C2DCA2FD-BFB4-4E76-967B-0AF8CC4F4D47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{C2DCA2FD-BFB4-4E76-967B-0AF8CC4F4D47}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{C2DCA2FD-BFB4-4E76-967B-0AF8CC4F4D47}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{C2DCA2FD-BFB4-4E76-967B-0AF8CC4F4D47}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{B7A1A8F3-CFA6-4ECF-A707-0F33FE0A6F1D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{B7A1A8F3-CFA6-4ECF-A707-0F33FE0A6F1D}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{B7A1A8F3-CFA6-4ECF-A707-0F33FE0A6F1D}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{B7A1A8F3-CFA6-4ECF-A707-0F33FE0A6F1D}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{9ECF0841-53BE-4FD8-95D1-A7223C7F3A07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{9ECF0841-53BE-4FD8-95D1-A7223C7F3A07}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{9ECF0841-53BE-4FD8-95D1-A7223C7F3A07}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{9ECF0841-53BE-4FD8-95D1-A7223C7F3A07}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{4FEBBDD9-E4F4-4BAF-8599-E2D57C08A74F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{4FEBBDD9-E4F4-4BAF-8599-E2D57C08A74F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{4FEBBDD9-E4F4-4BAF-8599-E2D57C08A74F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{4FEBBDD9-E4F4-4BAF-8599-E2D57C08A74F}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{2CE51D4C-1EF9-462B-BA14-7EA01A7E4AF1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{2CE51D4C-1EF9-462B-BA14-7EA01A7E4AF1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{2CE51D4C-1EF9-462B-BA14-7EA01A7E4AF1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{2CE51D4C-1EF9-462B-BA14-7EA01A7E4AF1}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{776590BA-B900-4C8B-986A-5B721FA4B306}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{776590BA-B900-4C8B-986A-5B721FA4B306}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{776590BA-B900-4C8B-986A-5B721FA4B306}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{776590BA-B900-4C8B-986A-5B721FA4B306}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{3A3AF1ED-FC7F-48CF-8ACE-9D50426B4675}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{3A3AF1ED-FC7F-48CF-8ACE-9D50426B4675}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{3A3AF1ED-FC7F-48CF-8ACE-9D50426B4675}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{3A3AF1ED-FC7F-48CF-8ACE-9D50426B4675}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{68F73B7B-0F8A-41C1-8092-6D6FFAED32F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{68F73B7B-0F8A-41C1-8092-6D6FFAED32F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{68F73B7B-0F8A-41C1-8092-6D6FFAED32F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{68F73B7B-0F8A-41C1-8092-6D6FFAED32F8}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{4AE84CDE-2A47-4D68-8E93-86193F72E4E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{4AE84CDE-2A47-4D68-8E93-86193F72E4E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{4AE84CDE-2A47-4D68-8E93-86193F72E4E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{4AE84CDE-2A47-4D68-8E93-86193F72E4E8}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{C8F97775-D903-4365-A4FF-3DA97E318CD2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{C8F97775-D903-4365-A4FF-3DA97E318CD2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{C8F97775-D903-4365-A4FF-3DA97E318CD2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{C8F97775-D903-4365-A4FF-3DA97E318CD2}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{2A31D7CB-BDCC-4253-BA73-273B6B5E1956}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{2A31D7CB-BDCC-4253-BA73-273B6B5E1956}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{2A31D7CB-BDCC-4253-BA73-273B6B5E1956}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{2A31D7CB-BDCC-4253-BA73-273B6B5E1956}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
|
||||||
HideSolutionNode = FALSE
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(NestedProjects) = preSolution
|
|
||||||
{15913E44-DA92-44B9-9AC5-E9457EA34BF5} = {B782C78B-6C17-49E6-A237-3383BA720766}
|
|
||||||
{DC431ECC-C75D-4B01-8B79-4861948179BB} = {77B949E9-530E-45A5-9657-20F7D5C6875C}
|
|
||||||
{9A7BBA40-28D6-4900-9E1D-D627A516EE72} = {B782C78B-6C17-49E6-A237-3383BA720766}
|
|
||||||
{746DBBD6-23E8-4D5D-9D23-E2902BE338BD} = {B782C78B-6C17-49E6-A237-3383BA720766}
|
|
||||||
{51EEBF59-3D37-4681-981D-56F8D8F8968D} = {B782C78B-6C17-49E6-A237-3383BA720766}
|
|
||||||
{7B15C198-538A-44ED-A6AA-3A0FEAA1D2BD} = {B782C78B-6C17-49E6-A237-3383BA720766}
|
|
||||||
{F4D5A496-BFBE-470B-A05B-CB5823B47E72} = {B782C78B-6C17-49E6-A237-3383BA720766}
|
|
||||||
{FD6D6860-3753-4747-8A26-977E4A3001F9} = {77B949E9-530E-45A5-9657-20F7D5C6875C}
|
|
||||||
{ECE874D4-F882-4EF4-84A6-A842D9B8FBC5} = {77B949E9-530E-45A5-9657-20F7D5C6875C}
|
|
||||||
{1995A019-C8AE-467E-B427-ED57D6CBF44F} = {77B949E9-530E-45A5-9657-20F7D5C6875C}
|
|
||||||
{F5011C0D-209B-4A98-BBE3-68157503EEF8} = {77B949E9-530E-45A5-9657-20F7D5C6875C}
|
|
||||||
{0A8296A3-C11F-4F13-8E49-6BC8188D4804} = {77B949E9-530E-45A5-9657-20F7D5C6875C}
|
|
||||||
{F0141C17-0EBD-4261-98D5-1C5B7BC1DFEE} = {77B949E9-530E-45A5-9657-20F7D5C6875C}
|
|
||||||
{9CC7A457-1236-40BA-B47B-E7B710A3F061} = {2317227D-7796-4E7B-BEDB-7CD1CAE7B853}
|
|
||||||
{1C360956-8CD8-407E-B87F-D0BD57068EB9} = {9CC7A457-1236-40BA-B47B-E7B710A3F061}
|
|
||||||
{4F02B08D-5FE2-460D-BCA5-DA565151AE30} = {9CC7A457-1236-40BA-B47B-E7B710A3F061}
|
|
||||||
{C04D3F71-1557-46D0-B810-97B1FBB6AB73} = {9CC7A457-1236-40BA-B47B-E7B710A3F061}
|
|
||||||
{A2BB899D-4F9A-4184-81BD-94B938E2AB03} = {9CC7A457-1236-40BA-B47B-E7B710A3F061}
|
|
||||||
{4503A2F9-139D-4CBC-AF11-689C34F0D77B} = {9CC7A457-1236-40BA-B47B-E7B710A3F061}
|
|
||||||
{E902A945-4F41-4E96-A0DA-9F66CDA22261} = {2317227D-7796-4E7B-BEDB-7CD1CAE7B853}
|
|
||||||
{EB9349E2-256D-41EB-A345-21635A1361B3} = {E902A945-4F41-4E96-A0DA-9F66CDA22261}
|
|
||||||
{4EABBC84-BCED-46C1-8CF1-62A7B8081ED7} = {E902A945-4F41-4E96-A0DA-9F66CDA22261}
|
|
||||||
{7E569FD9-B1AB-4848-8AB7-FD9EFA1DBA20} = {E902A945-4F41-4E96-A0DA-9F66CDA22261}
|
|
||||||
{AD4EE9E6-F4A3-4139-AF05-71388167DE5B} = {E902A945-4F41-4E96-A0DA-9F66CDA22261}
|
|
||||||
{6C86BA71-9F87-4E2C-B467-2950D77DCDFA} = {E902A945-4F41-4E96-A0DA-9F66CDA22261}
|
|
||||||
{73CCF2C4-B9FD-44AB-8D4B-0A421805B094} = {2317227D-7796-4E7B-BEDB-7CD1CAE7B853}
|
|
||||||
{48806510-8E18-4E1E-9BAF-5B97E88C5FC3} = {73CCF2C4-B9FD-44AB-8D4B-0A421805B094}
|
|
||||||
{791AC2FA-50D3-4408-8D68-31DA72F608BE} = {77B949E9-530E-45A5-9657-20F7D5C6875C}
|
|
||||||
{576DBC97-4E5D-4444-B65C-F41649A5F8E0} = {01300F0F-686E-47B3-821D-12424177867B}
|
|
||||||
{D7F8BD42-F6A2-4F0A-9212-391B5185A99D} = {01300F0F-686E-47B3-821D-12424177867B}
|
|
||||||
{B615847F-8568-41D1-8B7E-63D61AE69F3D} = {01300F0F-686E-47B3-821D-12424177867B}
|
|
||||||
{20827DB5-5CDE-491A-82E8-3CAB82618C1E} = {01300F0F-686E-47B3-821D-12424177867B}
|
|
||||||
{320273B6-7AE3-42DA-9675-D9AD4928A289} = {01300F0F-686E-47B3-821D-12424177867B}
|
|
||||||
{70CCBD89-C0A1-4AC8-9AFA-C86C356DFDD7} = {01300F0F-686E-47B3-821D-12424177867B}
|
|
||||||
{68627BC2-F049-4C69-AD17-81DF9478E8CE} = {0D10EEF2-FBAE-4C72-B816-A52823FC299B}
|
|
||||||
{499A8C71-7892-42D0-A77E-48756E1EFF16} = {2317227D-7796-4E7B-BEDB-7CD1CAE7B853}
|
|
||||||
{FA5BBAA1-08DC-472F-BB2C-5314E59D1556} = {499A8C71-7892-42D0-A77E-48756E1EFF16}
|
|
||||||
{54D8E2BC-591C-4344-A58E-874D49C00B41} = {499A8C71-7892-42D0-A77E-48756E1EFF16}
|
|
||||||
{EFD13211-17B5-400A-B99A-9F6F4E520C1E} = {73CCF2C4-B9FD-44AB-8D4B-0A421805B094}
|
|
||||||
{9C8C3C53-3DCE-4516-867E-228858E61B26} = {73CCF2C4-B9FD-44AB-8D4B-0A421805B094}
|
|
||||||
{17816837-E53B-486B-B796-53C601FE6CD9} = {499A8C71-7892-42D0-A77E-48756E1EFF16}
|
|
||||||
{FA735055-CBDD-4EFD-B84B-85810DA1425E} = {499A8C71-7892-42D0-A77E-48756E1EFF16}
|
|
||||||
{4FFE7212-21F2-476D-B628-3C65E6C5075E} = {2317227D-7796-4E7B-BEDB-7CD1CAE7B853}
|
|
||||||
{97EC40D7-DBFA-467A-98CB-221AF27B14F2} = {4FFE7212-21F2-476D-B628-3C65E6C5075E}
|
|
||||||
{882BC563-2F75-4B95-AC96-F4BF23F5E69D} = {4FFE7212-21F2-476D-B628-3C65E6C5075E}
|
|
||||||
{85CB8517-2B80-42D8-B954-081079AC9BA0} = {4FFE7212-21F2-476D-B628-3C65E6C5075E}
|
|
||||||
{EEFF0F05-2709-4151-A8CE-667935CEAE0B} = {4FFE7212-21F2-476D-B628-3C65E6C5075E}
|
|
||||||
{862BB0EF-3D4E-44FF-AB15-0EB74CE553D3} = {77B949E9-530E-45A5-9657-20F7D5C6875C}
|
|
||||||
{FB09ACC2-A27D-4D87-8D85-1435FDED4D04} = {4FFE7212-21F2-476D-B628-3C65E6C5075E}
|
|
||||||
{6B554DCC-3A81-4624-9141-4E39365ADA35} = {8B27846A-043D-4F2F-8140-5CEC9D1863B5}
|
|
||||||
{2D23B44A-DFA3-4C36-8516-4F5AE442403C} = {8B27846A-043D-4F2F-8140-5CEC9D1863B5}
|
|
||||||
{00E49781-C6A0-491C-86A1-46F685C90915} = {8B27846A-043D-4F2F-8140-5CEC9D1863B5}
|
|
||||||
{8C68059E-F3B1-4D28-A1C9-A5830F53E5D3} = {2317227D-7796-4E7B-BEDB-7CD1CAE7B853}
|
|
||||||
{6FEE0EB3-EAD2-47F8-B6FC-3D0FD3CCABFF} = {8C68059E-F3B1-4D28-A1C9-A5830F53E5D3}
|
|
||||||
{495C4643-39D4-46E7-BDC8-237589627BE4} = {8C68059E-F3B1-4D28-A1C9-A5830F53E5D3}
|
|
||||||
{D8CDDE99-3684-4EED-A5E5-87F2AF4C78AB} = {2317227D-7796-4E7B-BEDB-7CD1CAE7B853}
|
|
||||||
{65D4D033-5504-44B9-B152-0172ACD64CE6} = {D8CDDE99-3684-4EED-A5E5-87F2AF4C78AB}
|
|
||||||
{DEEC0B15-190C-4464-B469-C45C6563C592} = {D8CDDE99-3684-4EED-A5E5-87F2AF4C78AB}
|
|
||||||
{E476D266-8FB2-4D6B-AE2B-F0D279D4264E} = {D8CDDE99-3684-4EED-A5E5-87F2AF4C78AB}
|
|
||||||
{C2DCA2FD-BFB4-4E76-967B-0AF8CC4F4D47} = {D8CDDE99-3684-4EED-A5E5-87F2AF4C78AB}
|
|
||||||
{B7A1A8F3-CFA6-4ECF-A707-0F33FE0A6F1D} = {D8CDDE99-3684-4EED-A5E5-87F2AF4C78AB}
|
|
||||||
{9ECF0841-53BE-4FD8-95D1-A7223C7F3A07} = {0D10EEF2-FBAE-4C72-B816-A52823FC299B}
|
|
||||||
{4FEBBDD9-E4F4-4BAF-8599-E2D57C08A74F} = {084CBEEC-5D37-4716-B9C7-D80D6960DFF4}
|
|
||||||
{2CE51D4C-1EF9-462B-BA14-7EA01A7E4AF1} = {084CBEEC-5D37-4716-B9C7-D80D6960DFF4}
|
|
||||||
{776590BA-B900-4C8B-986A-5B721FA4B306} = {084CBEEC-5D37-4716-B9C7-D80D6960DFF4}
|
|
||||||
{3A3AF1ED-FC7F-48CF-8ACE-9D50426B4675} = {084CBEEC-5D37-4716-B9C7-D80D6960DFF4}
|
|
||||||
{68F73B7B-0F8A-41C1-8092-6D6FFAED32F8} = {084CBEEC-5D37-4716-B9C7-D80D6960DFF4}
|
|
||||||
{4AE84CDE-2A47-4D68-8E93-86193F72E4E8} = {084CBEEC-5D37-4716-B9C7-D80D6960DFF4}
|
|
||||||
{C8F97775-D903-4365-A4FF-3DA97E318CD2} = {084CBEEC-5D37-4716-B9C7-D80D6960DFF4}
|
|
||||||
{2A31D7CB-BDCC-4253-BA73-273B6B5E1956} = {8C68059E-F3B1-4D28-A1C9-A5830F53E5D3}
|
|
||||||
EndGlobalSection
|
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
|
||||||
SolutionGuid = {23D6FBC9-C970-4641-BC1E-2AEA59F51C18}
|
|
||||||
EndGlobalSection
|
|
||||||
EndGlobal
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.Hosting;
|
|
||||||
using Yi.Abp.Client.Console;
|
|
||||||
using Yi.Framework.Rbac.Application.Contracts.IServices;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
IHost host = Host.CreateDefaultBuilder()
|
|
||||||
.ConfigureServices(async (host, service) =>
|
|
||||||
{
|
|
||||||
await service.AddApplicationAsync<YiAbpClientConsoleModule>();
|
|
||||||
})
|
|
||||||
.UseAutofac()
|
|
||||||
.Build();
|
|
||||||
|
|
||||||
//控制台直接调用
|
|
||||||
var account = host.Services.GetRequiredService<IAccountService>();
|
|
||||||
|
|
||||||
//获取验证码
|
|
||||||
var data1 = await account.GetCaptchaImageAsync();
|
|
||||||
|
|
||||||
//登录
|
|
||||||
var data2 = await account.PostLoginAsync(new Yi.Framework.Rbac.Application.Contracts.Dtos.Account.LoginInputVo { UserName = "cc", Password = "123456", Code = string.Empty, Uuid = string.Empty });
|
|
||||||
|
|
||||||
|
|
||||||
host.Run();
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine(ex.Message);
|
|
||||||
Console.WriteLine(ex.StackTrace);
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
<Import Project="..\..\common.props" />
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutputType>Exe</OutputType>
|
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
|
|
||||||
<PackageReference Include="Volo.Abp.Autofac" Version="$(AbpVersion)" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\Yi.Abp.HttpApi.Client\Yi.Abp.HttpApi.Client.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Volo.Abp.Modularity;
|
|
||||||
using Yi.Abp.HttpApi.Client;
|
|
||||||
|
|
||||||
namespace Yi.Abp.Client.Console
|
|
||||||
{
|
|
||||||
[DependsOn(typeof(YiAbpHttpApiClientModule))]
|
|
||||||
public class YiAbpClientConsoleModule:AbpModule
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Yi.Framework.Rbac.Application.Contracts.Dtos.Account;
|
|
||||||
using Yi.Framework.Rbac.Application.Contracts.IServices;
|
|
||||||
|
|
||||||
namespace Yi.Abp.Client.WebApi.Controllers
|
|
||||||
{
|
|
||||||
[ApiController]
|
|
||||||
[Route("[controller]")]
|
|
||||||
public class AccountController : ControllerBase
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
private readonly ILogger<AccountController> _logger;
|
|
||||||
private IAccountService _accountService;
|
|
||||||
public AccountController(ILogger<AccountController> logger, IAccountService accountService)
|
|
||||||
{
|
|
||||||
_logger = logger;
|
|
||||||
_accountService = accountService;
|
|
||||||
}
|
|
||||||
|
|
||||||
[HttpPost("my-login")]
|
|
||||||
public async Task<IActionResult> Login(LoginInputVo input)
|
|
||||||
{
|
|
||||||
await _accountService.PostLoginAsync(input);
|
|
||||||
return Ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[HttpGet("my-captcha-image")]
|
|
||||||
public async Task<IActionResult> CaptchaImageAsync()
|
|
||||||
{
|
|
||||||
var output = await _accountService.GetCaptchaImageAsync();
|
|
||||||
return Ok(output);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
using Autofac.Core;
|
|
||||||
using Yi.Abp.Client.WebApi;
|
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
|
||||||
|
|
||||||
// Add services to the container.
|
|
||||||
builder.Host.UseAutofac();
|
|
||||||
builder.Services.AddControllers();
|
|
||||||
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
|
|
||||||
builder.Services.AddEndpointsApiExplorer();
|
|
||||||
builder.Services.AddSwaggerGen();
|
|
||||||
await builder.Services.AddApplicationAsync<YiAbpClientWebApiModule>();
|
|
||||||
var app = builder.Build();
|
|
||||||
|
|
||||||
// Configure the HTTP request pipeline.
|
|
||||||
if (app.Environment.IsDevelopment())
|
|
||||||
{
|
|
||||||
app.UseSwagger();
|
|
||||||
app.UseSwaggerUI();
|
|
||||||
}
|
|
||||||
|
|
||||||
app.UseHttpsRedirection();
|
|
||||||
|
|
||||||
app.UseAuthorization();
|
|
||||||
|
|
||||||
app.MapControllers();
|
|
||||||
|
|
||||||
app.Run();
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
{
|
|
||||||
"$schema": "http://json.schemastore.org/launchsettings.json",
|
|
||||||
"iisSettings": {
|
|
||||||
"windowsAuthentication": false,
|
|
||||||
"anonymousAuthentication": true,
|
|
||||||
"iisExpress": {
|
|
||||||
"applicationUrl": "http://localhost:35597",
|
|
||||||
"sslPort": 44322
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"profiles": {
|
|
||||||
"http": {
|
|
||||||
"commandName": "Project",
|
|
||||||
"dotnetRunMessages": true,
|
|
||||||
"launchBrowser": true,
|
|
||||||
"launchUrl": "swagger",
|
|
||||||
"applicationUrl": "http://localhost:5002",
|
|
||||||
"environmentVariables": {
|
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"https": {
|
|
||||||
"commandName": "Project",
|
|
||||||
"dotnetRunMessages": true,
|
|
||||||
"launchBrowser": true,
|
|
||||||
"launchUrl": "swagger",
|
|
||||||
"applicationUrl": "https://localhost:7108;http://localhost:5002",
|
|
||||||
"environmentVariables": {
|
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"IIS Express": {
|
|
||||||
"commandName": "IISExpress",
|
|
||||||
"launchBrowser": true,
|
|
||||||
"launchUrl": "swagger",
|
|
||||||
"environmentVariables": {
|
|
||||||
"ASPNETCORE_ENVIRONMENT": "Development"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
|
||||||
<Import Project="..\..\common.props" />
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\Yi.Abp.HttpApi.Client\Yi.Abp.HttpApi.Client.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
@Yi.Abp.Client.WebApi_HostAddress = http://localhost:5002
|
|
||||||
|
|
||||||
GET {{Yi.Abp.Client.WebApi_HostAddress}}/weatherforecast/
|
|
||||||
Accept: application/json
|
|
||||||
|
|
||||||
###
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
using Volo.Abp.Modularity;
|
|
||||||
using Yi.Abp.HttpApi.Client;
|
|
||||||
|
|
||||||
namespace Yi.Abp.Client.WebApi
|
|
||||||
{
|
|
||||||
[DependsOn(typeof(YiAbpHttpApiClientModule))]
|
|
||||||
public class YiAbpClientWebApiModule:AbpModule
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
{
|
|
||||||
"Logging": {
|
|
||||||
"LogLevel": {
|
|
||||||
"Default": "Information",
|
|
||||||
"Microsoft.AspNetCore": "Warning"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
<Import Project="..\..\common.props" />
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
<OutputType>Library</OutputType>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
|
|
||||||
<PackageReference Include="Volo.Abp.Http.Client" Version="$(AbpVersion)" />
|
|
||||||
<PackageReference Include="Volo.Abp.Autofac" Version="$(AbpVersion)" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\..\src\Yi.Abp.Application.Contracts\Yi.Abp.Application.Contracts.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Volo.Abp.Autofac;
|
|
||||||
using Volo.Abp.Http.Client;
|
|
||||||
using Volo.Abp.Modularity;
|
|
||||||
using Yi.Framework.Rbac.Application.Contracts;
|
|
||||||
|
|
||||||
namespace Yi.Abp.HttpApi.Client
|
|
||||||
{
|
|
||||||
[DependsOn(typeof(AbpHttpClientModule),
|
|
||||||
typeof(AbpAutofacModule),
|
|
||||||
|
|
||||||
|
|
||||||
typeof(YiFrameworkRbacApplicationContractsModule))]
|
|
||||||
public class YiAbpHttpApiClientModule : AbpModule
|
|
||||||
{
|
|
||||||
public override void ConfigureServices(ServiceConfigurationContext context)
|
|
||||||
{
|
|
||||||
//创建动态客户端代理
|
|
||||||
context.Services.AddHttpClientProxies(
|
|
||||||
typeof(YiFrameworkRbacApplicationContractsModule).Assembly
|
|
||||||
|
|
||||||
);
|
|
||||||
Configure<AbpRemoteServiceOptions>(options =>
|
|
||||||
{
|
|
||||||
options.RemoteServices.Default =
|
|
||||||
new RemoteServiceConfiguration("http://localhost:19001");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
<Project>
|
|
||||||
<Import Project="usings.props" />
|
|
||||||
<Import Project="version.props" />
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<LangVersion>latest</LangVersion>
|
|
||||||
<Version>1.0.0</Version>
|
|
||||||
<NoWarn>$(NoWarn);CS1591;CS8618;CS1998;CS8604;CS8620;CS8600;CS8602</NoWarn>
|
|
||||||
<AbpProjectType>app</AbpProjectType>
|
|
||||||
|
|
||||||
<PublishDocumentationFiles>true</PublishDocumentationFiles>
|
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
|
||||||
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<Target Name="NoWarnOnRazorViewImportedTypeConflicts" BeforeTargets="RazorCoreCompile">
|
|
||||||
<PropertyGroup>
|
|
||||||
<NoWarn>$(NoWarn);0436</NoWarn>
|
|
||||||
</PropertyGroup>
|
|
||||||
</Target>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Content Remove="$(UserProfile)\.nuget\packages\*\*\contentFiles\any\*\*.abppkg*.json" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
kill -9 $(lsof -t -i:19001)
|
|
||||||
echo "Yi-进程已关闭"
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Yi.Framework.AspNetCore.Authentication.OAuth
|
|
||||||
{
|
|
||||||
public class AuthenticationConstants
|
|
||||||
{
|
|
||||||
public const string OpenId = "urn:openid";
|
|
||||||
public const string AccessToken = "urn:access_token";
|
|
||||||
public const string Name = "urn:name";
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.AspNetCore.Authentication.OAuth;
|
|
||||||
|
|
||||||
namespace Yi.Framework.AspNetCore.Authentication.OAuth
|
|
||||||
{
|
|
||||||
public class AuthenticationOAuthOptions:OAuthOptions
|
|
||||||
{
|
|
||||||
|
|
||||||
public string RedirectUri { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Yi.Framework.AspNetCore.Authentication.OAuth.Gitee;
|
|
||||||
|
|
||||||
namespace Yi.Framework.AspNetCore.Authentication.OAuth
|
|
||||||
{
|
|
||||||
public class AuthticationErrCodeModel
|
|
||||||
{
|
|
||||||
public string error { get; set; }
|
|
||||||
|
|
||||||
public string error_description { get; set; }
|
|
||||||
|
|
||||||
public static void VerifyErrResponse(string content)
|
|
||||||
{
|
|
||||||
|
|
||||||
var model = Newtonsoft.Json.JsonConvert.DeserializeObject<AuthticationErrCodeModel>(content);
|
|
||||||
if (model.error != null)
|
|
||||||
{
|
|
||||||
|
|
||||||
throw new Exception($"第三方授权返回错误,错误码:【{model.error}】,错误详情:【{model.error_description}】");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
|
|
||||||
* See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers
|
|
||||||
* for more information concerning the license and the contributors participating to this project.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Yi.Framework.AspNetCore.Authentication.OAuth.Gitee;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Contains constants specific to the <see cref="GiteeAuthenticationHandler"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static class GiteeAuthenticationConstants
|
|
||||||
{
|
|
||||||
public static class Claims
|
|
||||||
{
|
|
||||||
public const string Url = "urn:gitee:url";
|
|
||||||
public const string AvatarUrl = "urn:gitee:avatarUrl";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
|
|
||||||
* See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers
|
|
||||||
* for more information concerning the license and the contributors participating to this project.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Yi.Framework.AspNetCore.Authentication.OAuth.Gitee;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Default values used by the Gitee authentication middleware.
|
|
||||||
/// </summary>
|
|
||||||
public static class GiteeAuthenticationDefaults
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Default value for <see cref="AuthenticationScheme.Name"/>.
|
|
||||||
/// </summary>
|
|
||||||
public const string AuthenticationScheme = "Gitee";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Default value for <see cref="AuthenticationScheme.DisplayName"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly string DisplayName = "Gitee";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Default value for <see cref="AuthenticationSchemeOptions.ClaimsIssuer"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly string Issuer = "Gitee";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Default value for <see cref="RemoteAuthenticationOptions.CallbackPath"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly string CallbackPath = "/signin-gitee";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Default value for <see cref="OAuthOptions.AuthorizationEndpoint"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly string AuthorizationEndpoint = "https://gitee.com/oauth/authorize";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Default value for <see cref="OAuthOptions.TokenEndpoint"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly string TokenEndpoint = "https://gitee.com/oauth/token";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Default value for <see cref="OAuthOptions.UserInformationEndpoint"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly string UserInformationEndpoint = "https://gitee.com/api/v5/user";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Default value for <see cref="GiteeAuthenticationOptions.UserEmailsEndpoint"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly string UserEmailsEndpoint = "https://gitee.com/api/v5/emails";
|
|
||||||
}
|
|
||||||
@@ -1,75 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
|
|
||||||
* See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers
|
|
||||||
* for more information concerning the license and the contributors participating to this project.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Microsoft.AspNetCore.Authentication;
|
|
||||||
|
|
||||||
namespace Yi.Framework.AspNetCore.Authentication.OAuth.Gitee;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Extension methods to add Gitee authentication capabilities to an HTTP application pipeline.
|
|
||||||
/// </summary>
|
|
||||||
public static class GiteeAuthenticationExtensions
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Adds <see cref="GiteeAuthenticationHandler"/> to the specified
|
|
||||||
/// <see cref="AuthenticationBuilder"/>, which enables Gitee authentication capabilities.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="builder">The authentication builder.</param>
|
|
||||||
/// <returns>The <see cref="AuthenticationBuilder"/>.</returns>
|
|
||||||
public static AuthenticationBuilder AddGitee([NotNull] this AuthenticationBuilder builder)
|
|
||||||
{
|
|
||||||
return builder.AddGitee(GiteeAuthenticationDefaults.AuthenticationScheme, options => { });
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds <see cref="GiteeAuthenticationHandler"/> to the specified
|
|
||||||
/// <see cref="AuthenticationBuilder"/>, which enables Gitee authentication capabilities.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="builder">The authentication builder.</param>
|
|
||||||
/// <param name="configuration">The delegate used to configure the OpenID 2.0 options.</param>
|
|
||||||
/// <returns>The <see cref="AuthenticationBuilder"/>.</returns>
|
|
||||||
public static AuthenticationBuilder AddGitee(
|
|
||||||
[NotNull] this AuthenticationBuilder builder,
|
|
||||||
[NotNull] Action<GiteeAuthenticationOptions> configuration)
|
|
||||||
{
|
|
||||||
return builder.AddGitee(GiteeAuthenticationDefaults.AuthenticationScheme, configuration);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds <see cref="GiteeAuthenticationHandler"/> to the specified
|
|
||||||
/// <see cref="AuthenticationBuilder"/>, which enables Gitee authentication capabilities.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="builder">The authentication builder.</param>
|
|
||||||
/// <param name="scheme">The authentication scheme associated with this instance.</param>
|
|
||||||
/// <param name="configuration">The delegate used to configure the Gitee options.</param>
|
|
||||||
/// <returns>The <see cref="AuthenticationBuilder"/>.</returns>
|
|
||||||
public static AuthenticationBuilder AddGitee(
|
|
||||||
[NotNull] this AuthenticationBuilder builder,
|
|
||||||
[NotNull] string scheme,
|
|
||||||
[NotNull] Action<GiteeAuthenticationOptions> configuration)
|
|
||||||
{
|
|
||||||
return builder.AddGitee(scheme, GiteeAuthenticationDefaults.DisplayName, configuration);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds <see cref="GiteeAuthenticationHandler"/> to the specified
|
|
||||||
/// <see cref="AuthenticationBuilder"/>, which enables Gitee authentication capabilities.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="builder">The authentication builder.</param>
|
|
||||||
/// <param name="scheme">The authentication scheme associated with this instance.</param>
|
|
||||||
/// <param name="caption">The optional display name associated with this instance.</param>
|
|
||||||
/// <param name="configuration">The delegate used to configure the Gitee options.</param>
|
|
||||||
/// <returns>The <see cref="AuthenticationBuilder"/>.</returns>
|
|
||||||
public static AuthenticationBuilder AddGitee(
|
|
||||||
[NotNull] this AuthenticationBuilder builder,
|
|
||||||
[NotNull] string scheme,
|
|
||||||
[CanBeNull] string caption,
|
|
||||||
[NotNull] Action<GiteeAuthenticationOptions> configuration)
|
|
||||||
{
|
|
||||||
return builder.AddScheme<GiteeAuthenticationOptions, GiteeAuthenticationHandler>(scheme, caption, configuration);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
using System.Security.Claims;
|
|
||||||
using System.Text.Encodings.Web;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using static Yi.Framework.AspNetCore.Authentication.OAuth.Gitee.GiteeAuthenticationConstants;
|
|
||||||
|
|
||||||
namespace Yi.Framework.AspNetCore.Authentication.OAuth.Gitee
|
|
||||||
{
|
|
||||||
public class GiteeAuthenticationHandler : OauthAuthenticationHandler<GiteeAuthenticationOptions>
|
|
||||||
{
|
|
||||||
public GiteeAuthenticationHandler(IOptionsMonitor<GiteeAuthenticationOptions> options, ILoggerFactory logger, UrlEncoder encoder, IHttpClientFactory httpClientFactory) : base(options, logger, encoder, httpClientFactory)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string AuthenticationSchemeNmae => GiteeAuthenticationDefaults.AuthenticationScheme;
|
|
||||||
|
|
||||||
protected override async Task<List<Claim>> GetAuthTicketAsync(string code)
|
|
||||||
{
|
|
||||||
//获取 accessToken
|
|
||||||
var tokenQueryKv = new List<KeyValuePair<string, string?>>()
|
|
||||||
{
|
|
||||||
new KeyValuePair<string, string?>("grant_type","authorization_code"),
|
|
||||||
new KeyValuePair<string, string?>("client_id",Options.ClientId),
|
|
||||||
new KeyValuePair<string, string?>("client_secret",Options.ClientSecret),
|
|
||||||
new KeyValuePair<string, string?>("redirect_uri",Options.RedirectUri),
|
|
||||||
new KeyValuePair<string, string?>("code",code)
|
|
||||||
};
|
|
||||||
var tokenModel = await SendHttpRequestAsync<GiteeAuthticationcationTokenResponse>(GiteeAuthenticationDefaults.TokenEndpoint, tokenQueryKv,HttpMethod.Post);
|
|
||||||
|
|
||||||
//获取 userInfo
|
|
||||||
var userInfoQueryKv = new List<KeyValuePair<string, string?>>()
|
|
||||||
{
|
|
||||||
new KeyValuePair<string, string?>("access_token",tokenModel.access_token),
|
|
||||||
};
|
|
||||||
var userInfoMdoel = await SendHttpRequestAsync<GiteeAuthticationcationUserInfoResponse>(GiteeAuthenticationDefaults.UserInformationEndpoint, userInfoQueryKv);
|
|
||||||
|
|
||||||
List<Claim> claims = new List<Claim>()
|
|
||||||
{
|
|
||||||
new Claim(Claims.AvatarUrl, userInfoMdoel.avatar_url),
|
|
||||||
new Claim(Claims.Url, userInfoMdoel.url),
|
|
||||||
|
|
||||||
new Claim(AuthenticationConstants.OpenId,userInfoMdoel.id.ToString()),
|
|
||||||
new Claim(AuthenticationConstants.Name, userInfoMdoel.name),
|
|
||||||
new Claim(AuthenticationConstants.AccessToken, tokenModel.access_token)
|
|
||||||
};
|
|
||||||
return claims;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
|
|
||||||
* See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers
|
|
||||||
* for more information concerning the license and the contributors participating to this project.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System.Security.Claims;
|
|
||||||
using Microsoft.AspNetCore.Authentication;
|
|
||||||
using static Yi.Framework.AspNetCore.Authentication.OAuth.Gitee.GiteeAuthenticationConstants;
|
|
||||||
|
|
||||||
namespace Yi.Framework.AspNetCore.Authentication.OAuth.Gitee;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Defines a set of options used by <see cref="GiteeAuthenticationHandler"/>.
|
|
||||||
/// </summary>
|
|
||||||
public class GiteeAuthenticationOptions : AuthenticationOAuthOptions
|
|
||||||
{
|
|
||||||
public GiteeAuthenticationOptions()
|
|
||||||
{
|
|
||||||
ClaimsIssuer = GiteeAuthenticationDefaults.Issuer;
|
|
||||||
|
|
||||||
CallbackPath = GiteeAuthenticationDefaults.CallbackPath;
|
|
||||||
|
|
||||||
AuthorizationEndpoint = GiteeAuthenticationDefaults.AuthorizationEndpoint;
|
|
||||||
TokenEndpoint = GiteeAuthenticationDefaults.TokenEndpoint;
|
|
||||||
UserInformationEndpoint = GiteeAuthenticationDefaults.UserInformationEndpoint;
|
|
||||||
UserEmailsEndpoint = GiteeAuthenticationDefaults.UserEmailsEndpoint;
|
|
||||||
|
|
||||||
Scope.Add("user_info");
|
|
||||||
Scope.Add("emails");
|
|
||||||
|
|
||||||
ClaimActions.MapJsonKey(ClaimTypes.NameIdentifier, "id");
|
|
||||||
ClaimActions.MapJsonKey(ClaimTypes.Name, "login");
|
|
||||||
ClaimActions.MapJsonKey(ClaimTypes.Email, "email");
|
|
||||||
ClaimActions.MapJsonKey(ClaimTypes.Name, "name");
|
|
||||||
ClaimActions.MapJsonKey(Claims.Url, "url");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the address of the endpoint exposing
|
|
||||||
/// the email addresses associated with the logged in user.
|
|
||||||
/// </summary>
|
|
||||||
public string UserEmailsEndpoint { get; set; }
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Yi.Framework.AspNetCore.Authentication.OAuth.Gitee
|
|
||||||
{
|
|
||||||
public class GiteeAuthticationcationTokenResponse
|
|
||||||
{
|
|
||||||
public string access_token { get; set; }
|
|
||||||
public string token_type { get; set; }
|
|
||||||
public int expires_in { get; set; }
|
|
||||||
public string refresh_token { get; set; }
|
|
||||||
public string scope { get; set; }
|
|
||||||
public long created_at { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public class GiteeAuthticationcationOpenIdResponse
|
|
||||||
{
|
|
||||||
public string client_id { get; set; }
|
|
||||||
|
|
||||||
public string openid { get; set; }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class GiteeAuthticationcationUserInfoResponse
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 也可以等于openId
|
|
||||||
/// </summary>
|
|
||||||
public int id { get; set; }
|
|
||||||
public string login { get; set; }
|
|
||||||
public string name { get; set; }
|
|
||||||
public string avatar_url { get; set; }
|
|
||||||
public string url { get; set; }
|
|
||||||
public string html_url { get; set; }
|
|
||||||
public string remark { get; set; }
|
|
||||||
public string followers_url { get; set; }
|
|
||||||
public string following_url { get; set; }
|
|
||||||
public string gists_url { get; set; }
|
|
||||||
public string starred_url { get; set; }
|
|
||||||
public string subscriptions_url { get; set; }
|
|
||||||
public string organizations_url { get; set; }
|
|
||||||
public string repos_url { get; set; }
|
|
||||||
public string events_url { get; set; }
|
|
||||||
public string received_events_url { get; set; }
|
|
||||||
public string type { get; set; }
|
|
||||||
public string blog { get; set; }
|
|
||||||
public string weibo { get; set; }
|
|
||||||
public string bio { get; set; }
|
|
||||||
public int public_repos { get; set; }
|
|
||||||
public int public_gists { get; set; }
|
|
||||||
public int followers { get; set; }
|
|
||||||
public int following { get; set; }
|
|
||||||
public int stared { get; set; }
|
|
||||||
public int watched { get; set; }
|
|
||||||
public DateTime created_at { get; set; }
|
|
||||||
public DateTime updated_at { get; set; }
|
|
||||||
public string email { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
using System.Security.Claims;
|
|
||||||
using System.Text.Encodings.Web;
|
|
||||||
using Microsoft.AspNetCore.Authentication;
|
|
||||||
using Microsoft.AspNetCore.WebUtilities;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
|
|
||||||
namespace Yi.Framework.AspNetCore.Authentication.OAuth
|
|
||||||
{
|
|
||||||
public abstract class OauthAuthenticationHandler<TOptions> : AuthenticationHandler<TOptions> where TOptions : AuthenticationSchemeOptions, new()
|
|
||||||
{
|
|
||||||
public abstract string AuthenticationSchemeNmae { get; }
|
|
||||||
private AuthenticationScheme _scheme;
|
|
||||||
|
|
||||||
public OauthAuthenticationHandler(IOptionsMonitor<TOptions> options, ILoggerFactory logger, UrlEncoder encoder, IHttpClientFactory httpClientFactory) : base(options, logger, encoder)
|
|
||||||
{
|
|
||||||
HttpClientFactory = httpClientFactory;
|
|
||||||
HttpClient = HttpClientFactory.CreateClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected IHttpClientFactory HttpClientFactory { get; }
|
|
||||||
|
|
||||||
protected HttpClient HttpClient { get; }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 生成认证票据
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
private AuthenticationTicket TicketConver(List<Claim> claims)
|
|
||||||
{
|
|
||||||
var claimsIdentity = new ClaimsIdentity(claims.ToArray(), AuthenticationSchemeNmae);
|
|
||||||
var principal = new ClaimsPrincipal(claimsIdentity);
|
|
||||||
return new AuthenticationTicket(principal, AuthenticationSchemeNmae);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected async Task<HttpModel> SendHttpRequestAsync<HttpModel>(string url, IEnumerable<KeyValuePair<string, string?>> query, HttpMethod? httpMethod = null)
|
|
||||||
{
|
|
||||||
httpMethod = httpMethod ?? HttpMethod.Get;
|
|
||||||
|
|
||||||
var queryUrl = QueryHelpers.AddQueryString(url, query);
|
|
||||||
HttpResponseMessage response = null;
|
|
||||||
if (httpMethod == HttpMethod.Get)
|
|
||||||
{
|
|
||||||
response = await HttpClient.GetAsync(queryUrl);
|
|
||||||
}
|
|
||||||
else if (httpMethod == HttpMethod.Post)
|
|
||||||
{
|
|
||||||
response = await HttpClient.PostAsync(queryUrl, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
var content = await response.Content.ReadAsStringAsync();
|
|
||||||
if (!response.IsSuccessStatusCode)
|
|
||||||
{
|
|
||||||
throw new Exception($"授权服务器请求错误,请求地址:{queryUrl},错误信息:{content}");
|
|
||||||
}
|
|
||||||
VerifyErrResponse(content);
|
|
||||||
var model = Newtonsoft.Json.JsonConvert.DeserializeObject<HttpModel>(content);
|
|
||||||
return model!;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void VerifyErrResponse(string content)
|
|
||||||
{
|
|
||||||
AuthticationErrCodeModel.VerifyErrResponse(content);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract Task<List<Claim>> GetAuthTicketAsync(string code);
|
|
||||||
|
|
||||||
|
|
||||||
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
|
|
||||||
{
|
|
||||||
if (!Context.Request.Query.ContainsKey("code"))
|
|
||||||
{
|
|
||||||
return AuthenticateResult.Fail("回调未包含code参数");
|
|
||||||
}
|
|
||||||
var code = Context.Request.Query["code"].ToString();
|
|
||||||
|
|
||||||
List<Claim> authTicket = null;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
authTicket = await GetAuthTicketAsync(code);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
return AuthenticateResult.Fail(ex.Message ?? "未知错误");
|
|
||||||
}
|
|
||||||
//成功
|
|
||||||
var result = AuthenticateResult.Success(TicketConver(authTicket));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
|
|
||||||
* See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers
|
|
||||||
* for more information concerning the license and the contributors participating to this project.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Yi.Framework.AspNetCore.Authentication.OAuth.QQ;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Contains constants specific to the <see cref="QQAuthenticationHandler"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static class QQAuthenticationConstants
|
|
||||||
{
|
|
||||||
public static class Claims
|
|
||||||
{
|
|
||||||
public const string AvatarFullUrl = "urn:qq:avatar_full";
|
|
||||||
public const string AvatarUrl = "urn:qq:avatar";
|
|
||||||
public const string PictureFullUrl = "urn:qq:picture_full";
|
|
||||||
public const string PictureMediumUrl = "urn:qq:picture_medium";
|
|
||||||
public const string PictureUrl = "urn:qq:picture";
|
|
||||||
public const string UnionId = "urn:qq:unionid";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
|
|
||||||
* See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers
|
|
||||||
* for more information concerning the license and the contributors participating to this project.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Yi.Framework.AspNetCore.Authentication.OAuth.QQ;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Default values for QQ authentication.
|
|
||||||
/// </summary>
|
|
||||||
public static class QQAuthenticationDefaults
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Default value for <see cref="AuthenticationScheme.Name"/>.
|
|
||||||
/// </summary>
|
|
||||||
public const string AuthenticationScheme = "QQ";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Default value for <see cref="AuthenticationScheme.DisplayName"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly string DisplayName = "QQ";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Default value for <see cref="AuthenticationSchemeOptions.ClaimsIssuer"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly string Issuer = "QQ";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Default value for <see cref="RemoteAuthenticationOptions.CallbackPath"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly string CallbackPath = "/signin-qq";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Default value for <see cref="OAuthOptions.AuthorizationEndpoint"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly string AuthorizationEndpoint = "https://graph.qq.com/oauth2.0/authorize";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Default value for <see cref="OAuthOptions.TokenEndpoint"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly string TokenEndpoint = "https://graph.qq.com/oauth2.0/token";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Default value for <see cref="QQAuthenticationOptions.UserIdentificationEndpoint"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly string UserIdentificationEndpoint = "https://graph.qq.com/oauth2.0/me";
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Default value for <see cref="OAuthOptions.UserInformationEndpoint"/>.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly string UserInformationEndpoint = "https://graph.qq.com/user/get_user_info";
|
|
||||||
}
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
|
|
||||||
* See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers
|
|
||||||
* for more information concerning the license and the contributors participating to this project.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using JetBrains.Annotations;
|
|
||||||
using Microsoft.AspNetCore.Authentication;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
|
|
||||||
namespace Yi.Framework.AspNetCore.Authentication.OAuth.QQ;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Extension methods to add QQ authentication capabilities to an HTTP application pipeline.
|
|
||||||
/// </summary>
|
|
||||||
public static class QQAuthenticationExtensions
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Adds <see cref="QQAuthenticationHandler"/> to the specified
|
|
||||||
/// <see cref="AuthenticationBuilder"/>, which enables QQ authentication capabilities.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="builder">The authentication builder.</param>
|
|
||||||
/// <returns>The <see cref="AuthenticationBuilder"/>.</returns>
|
|
||||||
public static AuthenticationBuilder AddQQ([NotNull] this AuthenticationBuilder builder)
|
|
||||||
{
|
|
||||||
return builder.AddQQ(QQAuthenticationDefaults.AuthenticationScheme, options => { });
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds <see cref="QQAuthenticationHandler"/> to the specified
|
|
||||||
/// <see cref="AuthenticationBuilder"/>, which enables QQ authentication capabilities.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="builder">The authentication builder.</param>
|
|
||||||
/// <param name="configuration">The delegate used to configure the OpenID 2.0 options.</param>
|
|
||||||
/// <returns>The <see cref="AuthenticationBuilder"/>.</returns>
|
|
||||||
public static AuthenticationBuilder AddQQ(
|
|
||||||
[NotNull] this AuthenticationBuilder builder,
|
|
||||||
[NotNull] Action<QQAuthenticationOptions> configuration)
|
|
||||||
{
|
|
||||||
return builder.AddQQ(QQAuthenticationDefaults.AuthenticationScheme, configuration);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds <see cref="QQAuthenticationHandler"/> to the specified
|
|
||||||
/// <see cref="AuthenticationBuilder"/>, which enables QQ authentication capabilities.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="builder">The authentication builder.</param>
|
|
||||||
/// <param name="scheme">The authentication scheme associated with this instance.</param>
|
|
||||||
/// <param name="configuration">The delegate used to configure the QQ options.</param>
|
|
||||||
/// <returns>The <see cref="AuthenticationBuilder"/>.</returns>
|
|
||||||
public static AuthenticationBuilder AddQQ(
|
|
||||||
[NotNull] this AuthenticationBuilder builder,
|
|
||||||
[NotNull] string scheme,
|
|
||||||
[NotNull] Action<QQAuthenticationOptions> configuration)
|
|
||||||
{
|
|
||||||
return builder.AddQQ(scheme, QQAuthenticationDefaults.DisplayName, configuration);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Adds <see cref="QQAuthenticationHandler"/> to the specified
|
|
||||||
/// <see cref="AuthenticationBuilder"/>, which enables QQ authentication capabilities.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="builder">The authentication builder.</param>
|
|
||||||
/// <param name="scheme">The authentication scheme associated with this instance.</param>
|
|
||||||
/// <param name="caption">The optional display name associated with this instance.</param>
|
|
||||||
/// <param name="configuration">The delegate used to configure the QQ options.</param>
|
|
||||||
/// <returns>The <see cref="AuthenticationBuilder"/>.</returns>
|
|
||||||
public static AuthenticationBuilder AddQQ(
|
|
||||||
[NotNull] this AuthenticationBuilder builder,
|
|
||||||
[NotNull] string scheme,
|
|
||||||
[CanBeNull] string caption,
|
|
||||||
[NotNull] Action<QQAuthenticationOptions> configuration)
|
|
||||||
{
|
|
||||||
return builder.AddScheme<QQAuthenticationOptions, QQAuthenticationHandler>(scheme, caption, configuration);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
using System.Security.Claims;
|
|
||||||
using System.Text.Encodings.Web;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using static Yi.Framework.AspNetCore.Authentication.OAuth.QQ.QQAuthenticationConstants;
|
|
||||||
|
|
||||||
namespace Yi.Framework.AspNetCore.Authentication.OAuth.QQ
|
|
||||||
{
|
|
||||||
public class QQAuthenticationHandler : OauthAuthenticationHandler<QQAuthenticationOptions>
|
|
||||||
{
|
|
||||||
public QQAuthenticationHandler(IOptionsMonitor<QQAuthenticationOptions> options, ILoggerFactory logger, UrlEncoder encoder, IHttpClientFactory httpClientFactory) : base(options, logger, encoder, httpClientFactory)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string AuthenticationSchemeNmae => QQAuthenticationDefaults.AuthenticationScheme;
|
|
||||||
|
|
||||||
protected override async Task<List<Claim>> GetAuthTicketAsync(string code)
|
|
||||||
{
|
|
||||||
|
|
||||||
//获取 accessToken
|
|
||||||
var tokenQueryKv = new List<KeyValuePair<string, string?>>()
|
|
||||||
{
|
|
||||||
new KeyValuePair<string, string?>("grant_type","authorization_code"),
|
|
||||||
new KeyValuePair<string, string?>("client_id",Options.ClientId),
|
|
||||||
new KeyValuePair<string, string?>("client_secret",Options.ClientSecret),
|
|
||||||
new KeyValuePair<string, string?>("redirect_uri",Options.RedirectUri),
|
|
||||||
new KeyValuePair<string, string?>("fmt","json"),
|
|
||||||
new KeyValuePair<string, string?>("need_openid","1"),
|
|
||||||
new KeyValuePair<string, string?>("code",code)
|
|
||||||
};
|
|
||||||
var tokenModel = await SendHttpRequestAsync<QQAuthticationcationTokenResponse>(QQAuthenticationDefaults.TokenEndpoint, tokenQueryKv);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//获取 userInfo
|
|
||||||
var userInfoQueryKv = new List<KeyValuePair<string, string?>>()
|
|
||||||
{
|
|
||||||
new KeyValuePair<string, string?>("access_token",tokenModel.access_token),
|
|
||||||
new KeyValuePair<string, string?>("oauth_consumer_key",Options.ClientId),
|
|
||||||
new KeyValuePair<string, string?>("openid",tokenModel.openid),
|
|
||||||
};
|
|
||||||
|
|
||||||
var userInfoMdoel = await SendHttpRequestAsync<QQAuthticationcationUserInfoResponse>(QQAuthenticationDefaults.UserInformationEndpoint, userInfoQueryKv);
|
|
||||||
|
|
||||||
|
|
||||||
List<Claim> claims = new List<Claim>()
|
|
||||||
{
|
|
||||||
|
|
||||||
new Claim(Claims.AvatarFullUrl, userInfoMdoel.figureurl_qq_2),
|
|
||||||
new Claim(Claims.AvatarUrl, userInfoMdoel.figureurl_qq_1),
|
|
||||||
new Claim(Claims.PictureFullUrl, userInfoMdoel.figureurl_2),
|
|
||||||
new Claim(Claims.PictureMediumUrl, userInfoMdoel.figureurl_qq_1),
|
|
||||||
new Claim(Claims.PictureUrl, userInfoMdoel.figureurl),
|
|
||||||
|
|
||||||
new Claim(AuthenticationConstants.OpenId, tokenModel.openid),
|
|
||||||
new Claim(AuthenticationConstants.Name, userInfoMdoel.nickname),
|
|
||||||
new Claim(AuthenticationConstants.AccessToken, tokenModel.access_token),
|
|
||||||
|
|
||||||
};
|
|
||||||
return claims;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
/*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
|
|
||||||
* See https://github.com/aspnet-contrib/AspNet.Security.OAuth.Providers
|
|
||||||
* for more information concerning the license and the contributors participating to this project.
|
|
||||||
*/
|
|
||||||
|
|
||||||
using System.Security.Claims;
|
|
||||||
using Microsoft.AspNetCore.Authentication;
|
|
||||||
using static Yi.Framework.AspNetCore.Authentication.OAuth.QQ.QQAuthenticationConstants;
|
|
||||||
|
|
||||||
namespace Yi.Framework.AspNetCore.Authentication.OAuth.QQ;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Defines a set of options used by <see cref="QQAuthenticationHandler"/>.
|
|
||||||
/// </summary>
|
|
||||||
public class QQAuthenticationOptions : AuthenticationOAuthOptions
|
|
||||||
{
|
|
||||||
public QQAuthenticationOptions()
|
|
||||||
{
|
|
||||||
ClaimsIssuer = QQAuthenticationDefaults.Issuer;
|
|
||||||
CallbackPath = QQAuthenticationDefaults.CallbackPath;
|
|
||||||
|
|
||||||
AuthorizationEndpoint = QQAuthenticationDefaults.AuthorizationEndpoint;
|
|
||||||
TokenEndpoint = QQAuthenticationDefaults.TokenEndpoint;
|
|
||||||
UserIdentificationEndpoint = QQAuthenticationDefaults.UserIdentificationEndpoint;
|
|
||||||
UserInformationEndpoint = QQAuthenticationDefaults.UserInformationEndpoint;
|
|
||||||
|
|
||||||
Scope.Add("get_user_info");
|
|
||||||
|
|
||||||
ClaimActions.MapJsonKey(ClaimTypes.Name, "nickname");
|
|
||||||
ClaimActions.MapJsonKey(ClaimTypes.Gender, "gender");
|
|
||||||
ClaimActions.MapJsonKey(Claims.PictureUrl, "figureurl");
|
|
||||||
ClaimActions.MapJsonKey(Claims.PictureMediumUrl, "figureurl_1");
|
|
||||||
ClaimActions.MapJsonKey(Claims.PictureFullUrl, "figureurl_2");
|
|
||||||
ClaimActions.MapJsonKey(Claims.AvatarUrl, "figureurl_qq_1");
|
|
||||||
ClaimActions.MapJsonKey(Claims.AvatarFullUrl, "figureurl_qq_2");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets if the union Id (the primary key of an owner for different apps of the QQ platform) should be put into the user claims.
|
|
||||||
/// </summary>
|
|
||||||
public bool ApplyForUnionId { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the URL of the user identification endpoint (a.k.a. the "OpenID endpoint").
|
|
||||||
/// </summary>
|
|
||||||
public string UserIdentificationEndpoint { get; set; }
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Yi.Framework.AspNetCore.Authentication.OAuth.QQ
|
|
||||||
{
|
|
||||||
public class QQAuthticationcationTokenResponse
|
|
||||||
{
|
|
||||||
public string access_token { get; set; }
|
|
||||||
|
|
||||||
public string expires_in { get; set; }
|
|
||||||
|
|
||||||
public string refresh_token { get; set; }
|
|
||||||
|
|
||||||
public string openid { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public class QQAuthticationcationOpenIdResponse
|
|
||||||
{
|
|
||||||
public string client_id { get; set; }
|
|
||||||
|
|
||||||
public string openid { get; set; }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public class QQAuthticationcationUserInfoResponse
|
|
||||||
{
|
|
||||||
// 返回码
|
|
||||||
public int ret { get; set; }
|
|
||||||
|
|
||||||
// 如果ret<0,会有相应的错误信息提示
|
|
||||||
// 返回数据全部用UTF-8编码
|
|
||||||
public string msg { get; set; }
|
|
||||||
|
|
||||||
// 判断是否有数据丢失
|
|
||||||
// 0或者不返回:没有数据丢失,可以缓存
|
|
||||||
// 1:有部分数据丢失或错误,不要缓存
|
|
||||||
public int is_lost { get; set; }
|
|
||||||
|
|
||||||
// 用户在QQ空间的昵称
|
|
||||||
public string nickname { get; set; }
|
|
||||||
|
|
||||||
// 大小为30x30像素的QQ空间头像URL
|
|
||||||
public string figureurl { get; set; }
|
|
||||||
|
|
||||||
// 大小为50x50像素的QQ空间头像URL
|
|
||||||
public string figureurl_1 { get; set; }
|
|
||||||
|
|
||||||
// 大小为100x100像素的QQ空间头像URL
|
|
||||||
public string figureurl_2 { get; set; }
|
|
||||||
|
|
||||||
// 大小为40x40像素的QQ头像URL
|
|
||||||
public string figureurl_qq_1 { get; set; }
|
|
||||||
|
|
||||||
// 大小为100x100像素的QQ头像URL
|
|
||||||
// 需要注意,不是所有的用户都拥有QQ的100x100的头像,但40x40像素则是一定会有
|
|
||||||
public string figureurl_qq_2 { get; set; }
|
|
||||||
|
|
||||||
// 性别。如果获取不到则默认返回"男"
|
|
||||||
public string gender { get; set; }
|
|
||||||
|
|
||||||
// 性别类型。默认返回2
|
|
||||||
public int gender_type { get; set; }
|
|
||||||
|
|
||||||
// 省
|
|
||||||
public string province { get; set; }
|
|
||||||
|
|
||||||
// 市
|
|
||||||
public string city { get; set; }
|
|
||||||
|
|
||||||
// 年
|
|
||||||
public int year { get; set; }
|
|
||||||
|
|
||||||
// 星座
|
|
||||||
public string constellation { get; set; }
|
|
||||||
|
|
||||||
// 标识用户是否为黄钻用户
|
|
||||||
public int is_yellow_vip { get; set; }
|
|
||||||
|
|
||||||
// 黄钻等级
|
|
||||||
public int yellow_vip_level { get; set; }
|
|
||||||
|
|
||||||
// 是否为年费黄钻用户
|
|
||||||
public int is_yellow_year_vip { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
<Import Project="..\..\common.props" />
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\Yi.Framework.AspNetCore\Yi.Framework.AspNetCore.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Volo.Abp.Modularity;
|
|
||||||
using Yi.Framework.Core;
|
|
||||||
|
|
||||||
|
|
||||||
namespace Yi.Framework.AspNetCore.Authentication.OAuth
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 本模块轮子来自 AspNet.Security.OAuth.QQ;
|
|
||||||
/// </summary>
|
|
||||||
[DependsOn(typeof(YiFrameworkAspNetCoreModule))]
|
|
||||||
public class YiFrameworkAspNetCoreAuthenticationOAuthModule:AbpModule
|
|
||||||
{
|
|
||||||
public override void ConfigureServices(ServiceConfigurationContext context)
|
|
||||||
{
|
|
||||||
var service = context.Services;
|
|
||||||
service.AddHttpClient();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
using JetBrains.Annotations;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Yi.Framework.AspNetCore.Microsoft.AspNetCore.Middlewares;
|
|
||||||
|
|
||||||
namespace Yi.Framework.AspNetCore.Microsoft.AspNetCore.Builder
|
|
||||||
{
|
|
||||||
public static class ApiInfoBuilderExtensions
|
|
||||||
{
|
|
||||||
public static IApplicationBuilder UseYiApiHandlinge([NotNull] this IApplicationBuilder app)
|
|
||||||
{
|
|
||||||
app.UseMiddleware<ApiInfoMiddleware>();
|
|
||||||
return app;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using Volo.Abp.AspNetCore.Mvc;
|
|
||||||
|
|
||||||
namespace Yi.Framework.AspNetCore.Microsoft.AspNetCore.Builder
|
|
||||||
{
|
|
||||||
public static class SwaggerBuilderExtensons
|
|
||||||
{
|
|
||||||
public static IApplicationBuilder UseYiSwagger(this IApplicationBuilder app, params SwaggerModel[] swaggerModels)
|
|
||||||
{
|
|
||||||
var mvcOptions = app.ApplicationServices.GetRequiredService<IOptions<AbpAspNetCoreMvcOptions>>().Value;
|
|
||||||
|
|
||||||
app.UseSwagger();
|
|
||||||
app.UseSwaggerUI(c =>
|
|
||||||
{
|
|
||||||
foreach (var setting in mvcOptions.ConventionalControllers.ConventionalControllerSettings)
|
|
||||||
{
|
|
||||||
c.SwaggerEndpoint($"/swagger/{setting.RemoteServiceName}/swagger.json", setting.RemoteServiceName);
|
|
||||||
}
|
|
||||||
if (mvcOptions.ConventionalControllers.ConventionalControllerSettings.Count==0&&swaggerModels.Length == 0)
|
|
||||||
{
|
|
||||||
c.SwaggerEndpoint("/swagger/v1/swagger.json", "Yi.Framework");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foreach (var k in swaggerModels)
|
|
||||||
{
|
|
||||||
c.SwaggerEndpoint(k.Url, k.Name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
return app;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
public class SwaggerModel
|
|
||||||
{
|
|
||||||
public SwaggerModel(string name)
|
|
||||||
{
|
|
||||||
this.Name = name;
|
|
||||||
this.Url = "/swagger/v1/swagger.json";
|
|
||||||
}
|
|
||||||
public SwaggerModel(string url, string name)
|
|
||||||
{
|
|
||||||
this.Url = url;
|
|
||||||
this.Name = name;
|
|
||||||
}
|
|
||||||
public string Url { get; set; }
|
|
||||||
public string Name { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
using System.Diagnostics;
|
|
||||||
using System.Net.Http;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Volo.Abp.DependencyInjection;
|
|
||||||
using Volo.Abp.Json;
|
|
||||||
using Yi.Framework.Core.Extensions;
|
|
||||||
using static System.Net.WebRequestMethods;
|
|
||||||
|
|
||||||
namespace Yi.Framework.AspNetCore.Microsoft.AspNetCore.Middlewares
|
|
||||||
{
|
|
||||||
[DebuggerStepThrough]
|
|
||||||
public class ApiInfoMiddleware : IMiddleware, ITransientDependency
|
|
||||||
{
|
|
||||||
|
|
||||||
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
|
|
||||||
{
|
|
||||||
context.Response.OnStarting([DebuggerStepThrough] () =>
|
|
||||||
{
|
|
||||||
if (context.Response.StatusCode == StatusCodes.Status200OK
|
|
||||||
&& context.Response.Headers["Content-Type"].ToString() == "application/vnd.ms-excel")
|
|
||||||
{
|
|
||||||
context.FileAttachmentHandle($"{DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss")}.xlsx");
|
|
||||||
}
|
|
||||||
if (context.Response.StatusCode == StatusCodes.Status200OK &&
|
|
||||||
context.Response.Headers["Content-Type"].ToString() == "application/x-zip-compressed")
|
|
||||||
{
|
|
||||||
context.FileAttachmentHandle($"{DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss")}.zip");
|
|
||||||
}
|
|
||||||
return Task.CompletedTask;
|
|
||||||
});
|
|
||||||
|
|
||||||
await next(context);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,157 +0,0 @@
|
|||||||
using System.ComponentModel;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Text;
|
|
||||||
using System.Xml.Linq;
|
|
||||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using Microsoft.OpenApi.Any;
|
|
||||||
using Microsoft.OpenApi.Models;
|
|
||||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
|
||||||
using Volo.Abp.AspNetCore.Mvc;
|
|
||||||
|
|
||||||
namespace Yi.Framework.AspNetCore.Microsoft.Extensions.DependencyInjection
|
|
||||||
{
|
|
||||||
public static class SwaggerAddExtensions
|
|
||||||
{
|
|
||||||
public static IServiceCollection AddYiSwaggerGen<Program>(this IServiceCollection services, Action<SwaggerGenOptions>? action=null)
|
|
||||||
{
|
|
||||||
|
|
||||||
var serviceProvider = services.BuildServiceProvider();
|
|
||||||
var mvcOptions = serviceProvider.GetRequiredService<IOptions<AbpAspNetCoreMvcOptions>>();
|
|
||||||
|
|
||||||
var mvcSettings = mvcOptions.Value.ConventionalControllers.ConventionalControllerSettings.DistinctBy(x => x.RemoteServiceName);
|
|
||||||
|
|
||||||
|
|
||||||
services.AddAbpSwaggerGen(
|
|
||||||
options =>
|
|
||||||
{
|
|
||||||
if (action is not null)
|
|
||||||
{
|
|
||||||
action.Invoke(options);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 配置分组,还需要去重,支持重写,如果外部传入后,将以外部为准
|
|
||||||
foreach (var setting in mvcSettings.OrderBy(x => x.RemoteServiceName))
|
|
||||||
{
|
|
||||||
if (!options.SwaggerGeneratorOptions.SwaggerDocs.ContainsKey(setting.RemoteServiceName))
|
|
||||||
{
|
|
||||||
options.SwaggerDoc(setting.RemoteServiceName, new OpenApiInfo { Title = setting.RemoteServiceName, Version = "v1" });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 根据分组名称过滤 API 文档
|
|
||||||
options.DocInclusionPredicate((docName, apiDesc) =>
|
|
||||||
{
|
|
||||||
if (apiDesc.ActionDescriptor is ControllerActionDescriptor controllerActionDescriptor)
|
|
||||||
{
|
|
||||||
var settingOrNull = mvcSettings.Where(x => x.Assembly == controllerActionDescriptor.ControllerTypeInfo.Assembly).FirstOrDefault();
|
|
||||||
if (settingOrNull is not null)
|
|
||||||
{
|
|
||||||
return docName == settingOrNull.RemoteServiceName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
options.CustomSchemaIds(type => type.FullName);
|
|
||||||
var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);
|
|
||||||
if (basePath is not null)
|
|
||||||
{
|
|
||||||
foreach (var item in Directory.GetFiles(basePath, "*.xml"))
|
|
||||||
{
|
|
||||||
options.IncludeXmlComments(item, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
options.AddSecurityDefinition("JwtBearer", new OpenApiSecurityScheme()
|
|
||||||
{
|
|
||||||
Description = "直接输入Token即可",
|
|
||||||
Name = "Authorization",
|
|
||||||
In = ParameterLocation.Header,
|
|
||||||
Type = SecuritySchemeType.Http,
|
|
||||||
Scheme = "bearer"
|
|
||||||
});
|
|
||||||
var scheme = new OpenApiSecurityScheme()
|
|
||||||
{
|
|
||||||
Reference = new OpenApiReference() { Type = ReferenceType.SecurityScheme, Id = "JwtBearer" }
|
|
||||||
};
|
|
||||||
options.AddSecurityRequirement(new OpenApiSecurityRequirement()
|
|
||||||
{
|
|
||||||
[scheme] = new string[0]
|
|
||||||
});
|
|
||||||
|
|
||||||
options.OperationFilter<AddRequiredHeaderParameter>();
|
|
||||||
options.SchemaFilter<EnumSchemaFilter>();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return services;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Swagger文档枚举字段显示枚举属性和枚举值,以及枚举描述
|
|
||||||
/// </summary>
|
|
||||||
public class EnumSchemaFilter : ISchemaFilter
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 实现接口
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="model"></param>
|
|
||||||
/// <param name="context"></param>
|
|
||||||
|
|
||||||
public void Apply(OpenApiSchema model, SchemaFilterContext context)
|
|
||||||
{
|
|
||||||
if (context.Type.IsEnum)
|
|
||||||
{
|
|
||||||
model.Enum.Clear();
|
|
||||||
model.Type = "string";
|
|
||||||
model.Format = null;
|
|
||||||
|
|
||||||
|
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
|
||||||
Enum.GetNames(context.Type)
|
|
||||||
.ToList()
|
|
||||||
.ForEach(name =>
|
|
||||||
{
|
|
||||||
Enum e = (Enum)Enum.Parse(context.Type, name);
|
|
||||||
var descrptionOrNull = GetEnumDescription(e);
|
|
||||||
model.Enum.Add(new OpenApiString(name));
|
|
||||||
stringBuilder.Append($"【枚举:{name}{(descrptionOrNull is null ? string.Empty : $"({descrptionOrNull})")}={Convert.ToInt64(Enum.Parse(context.Type, name))}】<br />");
|
|
||||||
});
|
|
||||||
model.Description= stringBuilder.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static string? GetEnumDescription(Enum value)
|
|
||||||
{
|
|
||||||
var fieldInfo = value.GetType().GetField(value.ToString());
|
|
||||||
var attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
|
|
||||||
return attributes.Length > 0 ? attributes[0].Description : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public class AddRequiredHeaderParameter : IOperationFilter
|
|
||||||
{
|
|
||||||
public static string HeaderKey { get; set; } = "__tenant";
|
|
||||||
public void Apply(OpenApiOperation operation, OperationFilterContext context)
|
|
||||||
{
|
|
||||||
if (operation.Parameters == null)
|
|
||||||
operation.Parameters = new List<OpenApiParameter>();
|
|
||||||
operation.Parameters.Add(new OpenApiParameter
|
|
||||||
{
|
|
||||||
Name = HeaderKey,
|
|
||||||
In = ParameterLocation.Header,
|
|
||||||
Required = false,
|
|
||||||
AllowEmptyValue = true,
|
|
||||||
Description="租户id或者租户名称(可空为默认租户)"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
using JetBrains.Annotations;
|
|
||||||
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
|
||||||
using System.Reflection;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using Volo.Abp.AspNetCore.Mvc.Conventions;
|
|
||||||
using Volo.Abp.DependencyInjection;
|
|
||||||
using Volo.Abp.Reflection;
|
|
||||||
|
|
||||||
namespace Yi.Framework.AspNetCore.Mvc
|
|
||||||
{
|
|
||||||
[Dependency(ServiceLifetime.Transient, ReplaceServices = true)]
|
|
||||||
[ExposeServices(typeof(IConventionalRouteBuilder))]
|
|
||||||
public class YiConventionalRouteBuilder : ConventionalRouteBuilder
|
|
||||||
{
|
|
||||||
public YiConventionalRouteBuilder(IOptions<AbpConventionalControllerOptions> options) : base(options)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
public override string Build(
|
|
||||||
string rootPath,
|
|
||||||
string controllerName,
|
|
||||||
ActionModel action,
|
|
||||||
string httpMethod,
|
|
||||||
[CanBeNull] ConventionalControllerSetting configuration)
|
|
||||||
{
|
|
||||||
|
|
||||||
var apiRoutePrefix = GetApiRoutePrefix(action, configuration);
|
|
||||||
var controllerNameInUrl =
|
|
||||||
NormalizeUrlControllerName(rootPath, controllerName, action, httpMethod, configuration);
|
|
||||||
|
|
||||||
var url = $"{rootPath}/{NormalizeControllerNameCase(controllerNameInUrl, configuration)}";
|
|
||||||
|
|
||||||
//Add {id} path if needed
|
|
||||||
var idParameterModel = action.Parameters.FirstOrDefault(p => p.ParameterName == "id");
|
|
||||||
if (idParameterModel != null)
|
|
||||||
{
|
|
||||||
if (TypeHelper.IsPrimitiveExtended(idParameterModel.ParameterType, includeEnums: true))
|
|
||||||
{
|
|
||||||
url += "/{id}";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var properties = idParameterModel
|
|
||||||
.ParameterType
|
|
||||||
.GetProperties(BindingFlags.Instance | BindingFlags.Public);
|
|
||||||
|
|
||||||
foreach (var property in properties)
|
|
||||||
{
|
|
||||||
url += "/{" + NormalizeIdPropertyNameCase(property, configuration) + "}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Add action name if needed
|
|
||||||
var actionNameInUrl = NormalizeUrlActionName(rootPath, controllerName, action, httpMethod, configuration);
|
|
||||||
if (!actionNameInUrl.IsNullOrEmpty())
|
|
||||||
{
|
|
||||||
url += $"/{NormalizeActionNameCase(actionNameInUrl, configuration)}";
|
|
||||||
|
|
||||||
//Add secondary Id
|
|
||||||
var secondaryIds = action.Parameters
|
|
||||||
.Where(p => p.ParameterName.EndsWith("Id", StringComparison.Ordinal)).ToList();
|
|
||||||
if (secondaryIds.Count == 1)
|
|
||||||
{
|
|
||||||
url += $"/{{{NormalizeSecondaryIdNameCase(secondaryIds[0], configuration)}}}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
using JetBrains.Annotations;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.AspNetCore.Mvc.ActionConstraints;
|
|
||||||
using Microsoft.AspNetCore.Mvc.ApplicationModels;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using Volo.Abp;
|
|
||||||
using Volo.Abp.AspNetCore;
|
|
||||||
using Volo.Abp.AspNetCore.Mvc;
|
|
||||||
using Volo.Abp.AspNetCore.Mvc.Conventions;
|
|
||||||
using Volo.Abp.DependencyInjection;
|
|
||||||
using Volo.Abp.Reflection;
|
|
||||||
|
|
||||||
namespace Yi.Framework.AspNetCore.Mvc
|
|
||||||
{
|
|
||||||
[Dependency(ServiceLifetime.Transient, ReplaceServices = true)]
|
|
||||||
[ExposeServices(typeof(IAbpServiceConvention))]
|
|
||||||
public class YiServiceConvention : AbpServiceConvention
|
|
||||||
{
|
|
||||||
public YiServiceConvention(IOptions<AbpAspNetCoreMvcOptions> options, IConventionalRouteBuilder conventionalRouteBuilder) : base(options, conventionalRouteBuilder)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void ConfigureSelector(string rootPath, string controllerName, ActionModel action, ConventionalControllerSetting? configuration)
|
|
||||||
{
|
|
||||||
RemoveEmptySelectors(action.Selectors);
|
|
||||||
|
|
||||||
var remoteServiceAtt = ReflectionHelper.GetSingleAttributeOrDefault<RemoteServiceAttribute>(action.ActionMethod);
|
|
||||||
if (remoteServiceAtt != null && !remoteServiceAtt.IsEnabledFor(action.ActionMethod))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!action.Selectors.Any())
|
|
||||||
{
|
|
||||||
AddAbpServiceSelector(rootPath, controllerName, action, configuration);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
NormalizeSelectorRoutes(rootPath, controllerName, action, configuration);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected override void AddAbpServiceSelector(string rootPath, string controllerName, ActionModel action, ConventionalControllerSetting? configuration)
|
|
||||||
{
|
|
||||||
base.AddAbpServiceSelector(rootPath, controllerName, action, configuration);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void NormalizeSelectorRoutes(string rootPath, string controllerName, ActionModel action, ConventionalControllerSetting? configuration)
|
|
||||||
{
|
|
||||||
foreach (var selector in action.Selectors)
|
|
||||||
{
|
|
||||||
var httpMethod = selector.ActionConstraints
|
|
||||||
.OfType<HttpMethodActionConstraint>()
|
|
||||||
.FirstOrDefault()?
|
|
||||||
.HttpMethods?
|
|
||||||
.FirstOrDefault();
|
|
||||||
|
|
||||||
if (httpMethod == null)
|
|
||||||
{
|
|
||||||
httpMethod = SelectHttpMethod(action, configuration);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selector.AttributeRouteModel == null)
|
|
||||||
{
|
|
||||||
selector.AttributeRouteModel = CreateAbpServiceAttributeRouteModel(rootPath, controllerName, action, httpMethod, configuration);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
|
|
||||||
var template = selector.AttributeRouteModel.Template;
|
|
||||||
if (!template.StartsWith("/"))
|
|
||||||
{
|
|
||||||
var route = $"{rootPath}/{template}";
|
|
||||||
selector.AttributeRouteModel.Template = route;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (!selector.ActionConstraints.OfType<HttpMethodActionConstraint>().Any())
|
|
||||||
{
|
|
||||||
selector.ActionConstraints.Add(new HttpMethodActionConstraint(new[] { httpMethod }));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
namespace Yi.Framework.AspNetCore
|
|
||||||
{
|
|
||||||
[Serializable]
|
|
||||||
public class RemoteServiceSuccessInfo
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a new instance of <see cref="RemoteServiceSuccessInfo"/>.
|
|
||||||
/// </summary>
|
|
||||||
public RemoteServiceSuccessInfo()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a new instance of <see cref="RemoteServiceSuccessInfo"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="code">Error code</param>
|
|
||||||
/// <param name="details">Error details</param>
|
|
||||||
/// <param name="message">Error message</param>
|
|
||||||
/// <param name="data">Error data</param>
|
|
||||||
public RemoteServiceSuccessInfo(string message, string? details = null, string? code = null, object? data = null)
|
|
||||||
{
|
|
||||||
Message = message;
|
|
||||||
Details = details;
|
|
||||||
Code = code;
|
|
||||||
Data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// code.
|
|
||||||
/// </summary>
|
|
||||||
public string? Code { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// message.
|
|
||||||
/// </summary>
|
|
||||||
public string? Message { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// details.
|
|
||||||
/// </summary>
|
|
||||||
public string? Details { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// data.
|
|
||||||
/// </summary>
|
|
||||||
public object? Data { get; set; }
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
<Import Project="..\..\common.props" />
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<Compile Remove="Cors\**" />
|
|
||||||
<EmbeddedResource Remove="Cors\**" />
|
|
||||||
<None Remove="Cors\**" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Volo.Abp.Json" Version="$(AbpVersion)" />
|
|
||||||
<PackageReference Include="Volo.Abp.Swashbuckle" Version="$(AbpVersion)" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\Yi.Framework.Core\Yi.Framework.Core.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
using System.Reflection;
|
|
||||||
using Microsoft.AspNetCore.Builder;
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using Microsoft.AspNetCore.Mvc.ApiExplorer;
|
|
||||||
using Microsoft.AspNetCore.Mvc.Controllers;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using Microsoft.OpenApi.Models;
|
|
||||||
using Newtonsoft.Json.Linq;
|
|
||||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
|
||||||
using Volo.Abp;
|
|
||||||
using Volo.Abp.AspNetCore.Mvc;
|
|
||||||
using Volo.Abp.DependencyInjection;
|
|
||||||
using Volo.Abp.Modularity;
|
|
||||||
using Yi.Framework.AspNetCore.Mvc;
|
|
||||||
using Yi.Framework.Core;
|
|
||||||
|
|
||||||
namespace Yi.Framework.AspNetCore
|
|
||||||
{
|
|
||||||
[DependsOn(typeof(YiFrameworkCoreModule)
|
|
||||||
)]
|
|
||||||
public class YiFrameworkAspNetCoreModule : AbpModule
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using FreeRedis;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Caching.FreeRedis
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 便于转到定义
|
|
||||||
/// </summary>
|
|
||||||
public class FreeSqlOptions: ConnectionStringBuilder
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
<Import Project="..\..\common.props" />
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetFramework>net8.0</TargetFramework>
|
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
|
||||||
<Nullable>enable</Nullable>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="FreeRedis" Version="1.2.14" />
|
|
||||||
<PackageReference Include="FreeRedis.DistributedCache" Version="1.2.5" />
|
|
||||||
<PackageReference Include="Volo.Abp.Caching" Version="$(AbpVersion)" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using Volo.Abp.Caching;
|
|
||||||
using Volo.Abp.DependencyInjection;
|
|
||||||
using Volo.Abp.MultiTenancy;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Caching.FreeRedis
|
|
||||||
{
|
|
||||||
[Dependency(ReplaceServices =true)]
|
|
||||||
public class YiDistributedCacheKeyNormalizer : IDistributedCacheKeyNormalizer, ITransientDependency
|
|
||||||
{
|
|
||||||
protected ICurrentTenant CurrentTenant { get; }
|
|
||||||
|
|
||||||
protected AbpDistributedCacheOptions DistributedCacheOptions { get; }
|
|
||||||
|
|
||||||
public YiDistributedCacheKeyNormalizer(
|
|
||||||
ICurrentTenant currentTenant,
|
|
||||||
IOptions<AbpDistributedCacheOptions> distributedCacheOptions)
|
|
||||||
{
|
|
||||||
CurrentTenant = currentTenant;
|
|
||||||
DistributedCacheOptions = distributedCacheOptions.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual string NormalizeKey(DistributedCacheKeyNormalizeArgs args)
|
|
||||||
{
|
|
||||||
var normalizedKey = $"{DistributedCacheOptions.KeyPrefix}{args.Key}";
|
|
||||||
|
|
||||||
//if (!args.IgnoreMultiTenancy && CurrentTenant.Id.HasValue)
|
|
||||||
//{
|
|
||||||
// normalizedKey = $"t:{CurrentTenant.Id.Value},{normalizedKey}";
|
|
||||||
//}
|
|
||||||
|
|
||||||
return normalizedKey;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
using FreeRedis;
|
|
||||||
using Microsoft.Extensions.Caching.Distributed;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
|
||||||
using Volo.Abp.Caching;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Caching.FreeRedis
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 此模块得益于FreeRedis作者支持IDistributedCache,使用湿滑
|
|
||||||
/// </summary>
|
|
||||||
[DependsOn(typeof(AbpCachingModule))]
|
|
||||||
public class YiFrameworkCachingFreeRedisModule : AbpModule
|
|
||||||
{
|
|
||||||
public override void ConfigureServices(ServiceConfigurationContext context)
|
|
||||||
{
|
|
||||||
|
|
||||||
var configuration = context.Services.GetConfiguration();
|
|
||||||
|
|
||||||
var redisEnabled = configuration["Redis:IsEnabled"];
|
|
||||||
if (redisEnabled.IsNullOrEmpty() || bool.Parse(redisEnabled))
|
|
||||||
{
|
|
||||||
var redisConfiguration = configuration["Redis:Configuration"];
|
|
||||||
RedisClient redisClient = new RedisClient(redisConfiguration);
|
|
||||||
|
|
||||||
context.Services.AddSingleton<IRedisClient>(redisClient);
|
|
||||||
context.Services.Replace(ServiceDescriptor.Singleton<IDistributedCache>(new
|
|
||||||
DistributedCache(redisClient)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Core.Enums
|
|
||||||
{
|
|
||||||
public enum QueryOperatorEnum
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 相等
|
|
||||||
/// </summary>
|
|
||||||
Equal,
|
|
||||||
/// <summary>
|
|
||||||
/// 匹配
|
|
||||||
/// </summary>
|
|
||||||
Like,
|
|
||||||
/// <summary>
|
|
||||||
/// 大于
|
|
||||||
/// </summary>
|
|
||||||
GreaterThan,
|
|
||||||
/// <summary>
|
|
||||||
/// 大于或等于
|
|
||||||
/// </summary>
|
|
||||||
GreaterThanOrEqual,
|
|
||||||
/// <summary>
|
|
||||||
/// 小于
|
|
||||||
/// </summary>
|
|
||||||
LessThan,
|
|
||||||
/// <summary>
|
|
||||||
/// 小于或等于
|
|
||||||
/// </summary>
|
|
||||||
LessThanOrEqual,
|
|
||||||
/// <summary>
|
|
||||||
/// 等于集合
|
|
||||||
/// </summary>
|
|
||||||
In,
|
|
||||||
/// <summary>
|
|
||||||
/// 不等于集合
|
|
||||||
/// </summary>
|
|
||||||
NotIn,
|
|
||||||
/// <summary>
|
|
||||||
/// 左边匹配
|
|
||||||
/// </summary>
|
|
||||||
LikeLeft,
|
|
||||||
/// <summary>
|
|
||||||
/// 右边匹配
|
|
||||||
/// </summary>
|
|
||||||
LikeRight,
|
|
||||||
/// <summary>
|
|
||||||
/// 不相等
|
|
||||||
/// </summary>
|
|
||||||
NoEqual,
|
|
||||||
/// <summary>
|
|
||||||
/// 为空或空
|
|
||||||
/// </summary>
|
|
||||||
IsNullOrEmpty,
|
|
||||||
/// <summary>
|
|
||||||
/// 不为空
|
|
||||||
/// </summary>
|
|
||||||
IsNot,
|
|
||||||
/// <summary>
|
|
||||||
/// 不匹配
|
|
||||||
/// </summary>
|
|
||||||
NoLike,
|
|
||||||
/// <summary>
|
|
||||||
/// 时间段 值用 "|" 隔开
|
|
||||||
/// </summary>
|
|
||||||
DateRange
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,100 +0,0 @@
|
|||||||
using System.Text;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Core.Extensions
|
|
||||||
{
|
|
||||||
public static class HttpContextExtensions
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 设置文件下载名称
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="httpContext"></param>
|
|
||||||
/// <param name="fileName"></param>
|
|
||||||
public static void FileInlineHandle(this HttpContext httpContext, string fileName)
|
|
||||||
{
|
|
||||||
string encodeFilename = System.Web.HttpUtility.UrlEncode(fileName, Encoding.GetEncoding("UTF-8"));
|
|
||||||
httpContext.Response.Headers.Add("Content-Disposition", "inline;filename=" + encodeFilename);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 设置文件附件名称
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="httpContext"></param>
|
|
||||||
/// <param name="fileName"></param>
|
|
||||||
public static void FileAttachmentHandle(this HttpContext httpContext, string fileName)
|
|
||||||
{
|
|
||||||
string encodeFilename = System.Web.HttpUtility.UrlEncode(fileName, Encoding.GetEncoding("UTF-8"));
|
|
||||||
httpContext.Response.Headers.Add("Content-Disposition", "attachment;filename=" + encodeFilename);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取语言种类
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="httpContext"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static string GetLanguage(this HttpContext httpContext)
|
|
||||||
{
|
|
||||||
string res = "zh-CN";
|
|
||||||
var str = httpContext.Request.Headers["Accept-Language"].FirstOrDefault();
|
|
||||||
if (str is not null)
|
|
||||||
{
|
|
||||||
res = str.Split(",")[0];
|
|
||||||
}
|
|
||||||
return res;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 判断是否为异步请求
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="request"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static bool IsAjaxRequest(this HttpRequest request)
|
|
||||||
{
|
|
||||||
string header = request.Headers["X-Requested-With"];
|
|
||||||
return "XMLHttpRequest".Equals(header);
|
|
||||||
}
|
|
||||||
/// <summary>
|
|
||||||
/// 获取客户端IP
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="context"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static string GetClientIp(this HttpContext context)
|
|
||||||
{
|
|
||||||
if (context == null) return "";
|
|
||||||
var result = context.Request.Headers["X-Forwarded-For"].FirstOrDefault();
|
|
||||||
if (string.IsNullOrEmpty(result))
|
|
||||||
{
|
|
||||||
result = context.Connection.RemoteIpAddress?.ToString();
|
|
||||||
}
|
|
||||||
if (string.IsNullOrEmpty(result) || result.Contains("::1"))
|
|
||||||
result = "127.0.0.1";
|
|
||||||
|
|
||||||
result = result.Replace("::ffff:", "127.0.0.1");
|
|
||||||
|
|
||||||
//Ip规则校验
|
|
||||||
var regResult = Regex.IsMatch(result, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$");
|
|
||||||
|
|
||||||
result = regResult ? result : "127.0.0.1";
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取浏览器标识
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="context"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static string GetUserAgent(this HttpContext context)
|
|
||||||
{
|
|
||||||
return context.Request.Headers["User-Agent"];
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string[]? GetUserPermissions(this HttpContext context, string permissionsName)
|
|
||||||
{
|
|
||||||
return context.User.Claims.Where(x => x.Type == permissionsName).Select(x => x.Value).ToArray();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,94 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Core.Helper
|
|
||||||
{
|
|
||||||
public static class AssemblyHelper
|
|
||||||
{
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 此处统一获取程序集,排除微软内部相关
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static Assembly[] GetAllLoadAssembly()
|
|
||||||
{
|
|
||||||
return AppDomain.CurrentDomain.GetAssemblies();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<Assembly> GetReferanceAssemblies(this AppDomain domain)
|
|
||||||
{
|
|
||||||
var list = new List<Assembly>();
|
|
||||||
domain.GetAssemblies().ToList().ForEach(i =>
|
|
||||||
{
|
|
||||||
GetReferanceAssemblies(i, list);
|
|
||||||
});
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
private static void GetReferanceAssemblies(Assembly assembly, List<Assembly> list)
|
|
||||||
{
|
|
||||||
assembly.GetReferencedAssemblies().ToList().ForEach(i =>
|
|
||||||
{
|
|
||||||
var ass = Assembly.Load(i);
|
|
||||||
if (!list.Contains(ass))
|
|
||||||
{
|
|
||||||
list.Add(ass);
|
|
||||||
GetReferanceAssemblies(ass, list);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<Type> GetClass(string assemblyFile, string? className = null, string? spaceName = null)
|
|
||||||
{
|
|
||||||
Assembly assembly = Assembly.Load(assemblyFile);
|
|
||||||
return assembly.GetTypes().Where(m => m.IsClass
|
|
||||||
&& className == null ? true : m.Name == className
|
|
||||||
&& spaceName == null ? true : m.Namespace == spaceName
|
|
||||||
&& !m.Name.StartsWith("<>")
|
|
||||||
).ToList();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<Type> GetClassByParentClass(string assemblyFile, Type type)
|
|
||||||
{
|
|
||||||
Assembly assembly = Assembly.Load(assemblyFile);
|
|
||||||
|
|
||||||
List<Type> resList = new List<Type>();
|
|
||||||
|
|
||||||
List<Type> typeList = assembly.GetTypes().Where(m => m.IsClass).ToList();
|
|
||||||
foreach (var t in typeList)
|
|
||||||
{
|
|
||||||
var data = t.BaseType;
|
|
||||||
if (data == type)
|
|
||||||
{
|
|
||||||
resList.Add(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return resList;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static List<Type> GetClassByInterfaces(string assemblyFile, Type type)
|
|
||||||
{
|
|
||||||
Assembly assembly = Assembly.Load(assemblyFile);
|
|
||||||
|
|
||||||
List<Type> resList = new List<Type>();
|
|
||||||
|
|
||||||
List<Type> typeList = assembly.GetTypes().Where(m => m.IsClass).ToList();
|
|
||||||
foreach (var t in typeList)
|
|
||||||
{
|
|
||||||
var data = t.GetInterfaces();
|
|
||||||
if (data.Contains(type))
|
|
||||||
{
|
|
||||||
resList.Add(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
return resList;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,329 +0,0 @@
|
|||||||
using System.Runtime.InteropServices;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Core.Helper
|
|
||||||
{
|
|
||||||
public class ComputerHelper
|
|
||||||
{
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 将object转换为long,若转换失败,则返回0。不抛出异常。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="str"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private static long ParseToLong( object obj)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return long.Parse(obj.ToString());
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return 0L;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 将string转换为DateTime,若转换失败,则返回日期最小值。不抛出异常。
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="str"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private static DateTime ParseToDateTime( string str)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(str))
|
|
||||||
{
|
|
||||||
return DateTime.MinValue;
|
|
||||||
}
|
|
||||||
if (str.Contains("-") || str.Contains("/"))
|
|
||||||
{
|
|
||||||
return DateTime.Parse(str);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int length = str.Length;
|
|
||||||
switch (length)
|
|
||||||
{
|
|
||||||
case 4:
|
|
||||||
return DateTime.ParseExact(str, "yyyy", System.Globalization.CultureInfo.CurrentCulture);
|
|
||||||
case 6:
|
|
||||||
return DateTime.ParseExact(str, "yyyyMM", System.Globalization.CultureInfo.CurrentCulture);
|
|
||||||
case 8:
|
|
||||||
return DateTime.ParseExact(str, "yyyyMMdd", System.Globalization.CultureInfo.CurrentCulture);
|
|
||||||
case 10:
|
|
||||||
return DateTime.ParseExact(str, "yyyyMMddHH", System.Globalization.CultureInfo.CurrentCulture);
|
|
||||||
case 12:
|
|
||||||
return DateTime.ParseExact(str, "yyyyMMddHHmm", System.Globalization.CultureInfo.CurrentCulture);
|
|
||||||
case 14:
|
|
||||||
return DateTime.ParseExact(str, "yyyyMMddHHmmss", System.Globalization.CultureInfo.CurrentCulture);
|
|
||||||
default:
|
|
||||||
return DateTime.ParseExact(str, "yyyyMMddHHmmss", System.Globalization.CultureInfo.CurrentCulture);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return DateTime.MinValue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private static double ParseToDouble(object obj)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
return double.Parse(obj.ToString());
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 内存使用情况
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static MemoryMetrics GetComputerInfo()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
MemoryMetricsClient client = new();
|
|
||||||
MemoryMetrics memoryMetrics = IsUnix() ? client.GetUnixMetrics() : client.GetWindowsMetrics();
|
|
||||||
|
|
||||||
memoryMetrics.FreeRam = Math.Round(memoryMetrics.Free / 1024, 2) + "GB";
|
|
||||||
memoryMetrics.UsedRam = Math.Round(memoryMetrics.Used / 1024, 2) + "GB";
|
|
||||||
memoryMetrics.TotalRAM = Math.Round(memoryMetrics.Total / 1024, 2) + "GB";
|
|
||||||
memoryMetrics.RAMRate = Math.Ceiling(100 * memoryMetrics.Used / memoryMetrics.Total).ToString() + "%";
|
|
||||||
memoryMetrics.CPURate = Math.Ceiling(ParseToDouble(GetCPURate())) + "%";
|
|
||||||
return memoryMetrics;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine("获取内存使用出错,msg=" + ex.Message + "," + ex.StackTrace);
|
|
||||||
}
|
|
||||||
return new MemoryMetrics();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取内存大小
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static List<DiskInfo> GetDiskInfos()
|
|
||||||
{
|
|
||||||
List<DiskInfo> diskInfos = new();
|
|
||||||
|
|
||||||
if (IsUnix())
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
string output = ShellHelper.Bash("df -m / | awk '{print $2,$3,$4,$5,$6}'");
|
|
||||||
var arr = output.Split('\n', StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
if (arr.Length == 0) return diskInfos;
|
|
||||||
|
|
||||||
var rootDisk = arr[1].Split(' ', (char)StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
if (rootDisk == null || rootDisk.Length == 0)
|
|
||||||
{
|
|
||||||
return diskInfos;
|
|
||||||
}
|
|
||||||
DiskInfo diskInfo = new()
|
|
||||||
{
|
|
||||||
DiskName = "/",
|
|
||||||
TotalSize = long.Parse(rootDisk[0]) / 1024,
|
|
||||||
Used = long.Parse(rootDisk[1]) / 1024,
|
|
||||||
AvailableFreeSpace = long.Parse(rootDisk[2]) / 1024,
|
|
||||||
AvailablePercent = decimal.Parse(rootDisk[3].Replace("%", ""))
|
|
||||||
};
|
|
||||||
diskInfos.Add(diskInfo);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine("获取磁盘信息出错了" + ex.Message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var driv = DriveInfo.GetDrives();
|
|
||||||
foreach (var item in driv)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
var obj = new DiskInfo()
|
|
||||||
{
|
|
||||||
DiskName = item.Name,
|
|
||||||
TypeName = item.DriveType.ToString(),
|
|
||||||
TotalSize = item.TotalSize / 1024 / 1024 / 1024,
|
|
||||||
AvailableFreeSpace = item.AvailableFreeSpace / 1024 / 1024 / 1024,
|
|
||||||
};
|
|
||||||
obj.Used = obj.TotalSize - obj.AvailableFreeSpace;
|
|
||||||
obj.AvailablePercent = decimal.Ceiling(obj.Used / (decimal)obj.TotalSize * 100);
|
|
||||||
diskInfos.Add(obj);
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine("获取磁盘信息出错了" + ex.Message);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return diskInfos;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static bool IsUnix()
|
|
||||||
{
|
|
||||||
var isUnix = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
|
|
||||||
return isUnix;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetCPURate()
|
|
||||||
{
|
|
||||||
string cpuRate;
|
|
||||||
if (IsUnix())
|
|
||||||
{
|
|
||||||
string output = ShellHelper.Bash("top -b -n1 | grep \"Cpu(s)\" | awk '{print $2 + $4}'");
|
|
||||||
cpuRate = output.Trim();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string output = ShellHelper.Cmd("wmic", "cpu get LoadPercentage");
|
|
||||||
cpuRate = output.Replace("LoadPercentage", string.Empty).Trim();
|
|
||||||
}
|
|
||||||
return cpuRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取系统运行时间
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static string GetRunTime()
|
|
||||||
{
|
|
||||||
string runTime = string.Empty;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (IsUnix())
|
|
||||||
{
|
|
||||||
string output = ShellHelper.Bash("uptime -s").Trim();
|
|
||||||
runTime = DateTimeHelper.FormatTime(ParseToLong((DateTime.Now - ParseToDateTime(output)).TotalMilliseconds.ToString().Split('.')[0]));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string output = ShellHelper.Cmd("wmic", "OS get LastBootUpTime/Value");
|
|
||||||
string[] outputArr = output.Split('=', (char)StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
if (outputArr.Length == 2)
|
|
||||||
{
|
|
||||||
runTime = DateTimeHelper.FormatTime(ParseToLong((DateTime.Now - ParseToDateTime( outputArr[1].Split('.')[0])).TotalMilliseconds.ToString().Split('.')[0]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
Console.WriteLine("获取runTime出错" + ex.Message);
|
|
||||||
}
|
|
||||||
return runTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 内存信息
|
|
||||||
/// </summary>
|
|
||||||
public class MemoryMetrics
|
|
||||||
{
|
|
||||||
[JsonIgnore]
|
|
||||||
public double Total { get; set; }
|
|
||||||
[JsonIgnore]
|
|
||||||
public double Used { get; set; }
|
|
||||||
[JsonIgnore]
|
|
||||||
public double Free { get; set; }
|
|
||||||
|
|
||||||
public string UsedRam { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// CPU使用率%
|
|
||||||
/// </summary>
|
|
||||||
public string CPURate { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 总内存 GB
|
|
||||||
/// </summary>
|
|
||||||
public string TotalRAM { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 内存使用率 %
|
|
||||||
/// </summary>
|
|
||||||
public string RAMRate { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 空闲内存
|
|
||||||
/// </summary>
|
|
||||||
public string FreeRam { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class DiskInfo
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 磁盘名
|
|
||||||
/// </summary>
|
|
||||||
public string DiskName { get; set; }
|
|
||||||
public string TypeName { get; set; }
|
|
||||||
public long TotalFree { get; set; }
|
|
||||||
public long TotalSize { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 已使用
|
|
||||||
/// </summary>
|
|
||||||
public long Used { get; set; }
|
|
||||||
/// <summary>
|
|
||||||
/// 可使用
|
|
||||||
/// </summary>
|
|
||||||
public long AvailableFreeSpace { get; set; }
|
|
||||||
public decimal AvailablePercent { get; set; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public class MemoryMetricsClient
|
|
||||||
{
|
|
||||||
#region 获取内存信息
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// windows系统获取内存信息
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public MemoryMetrics GetWindowsMetrics()
|
|
||||||
{
|
|
||||||
string output = ShellHelper.Cmd("wmic", "OS get FreePhysicalMemory,TotalVisibleMemorySize /Value");
|
|
||||||
var metrics = new MemoryMetrics();
|
|
||||||
var lines = output.Trim().Split('\n', (char)StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
|
|
||||||
if (lines.Length <= 0) return metrics;
|
|
||||||
|
|
||||||
var freeMemoryParts = lines[0].Split('=', (char)StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
var totalMemoryParts = lines[1].Split('=', (char)StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
|
|
||||||
metrics.Total = Math.Round(double.Parse(totalMemoryParts[1]) / 1024, 0);
|
|
||||||
metrics.Free = Math.Round(double.Parse(freeMemoryParts[1]) / 1024, 0);//m
|
|
||||||
metrics.Used = metrics.Total - metrics.Free;
|
|
||||||
|
|
||||||
return metrics;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Unix系统获取
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public MemoryMetrics GetUnixMetrics()
|
|
||||||
{
|
|
||||||
string output = ShellHelper.Bash("free -m | awk '{print $2,$3,$4,$5,$6}'");
|
|
||||||
var metrics = new MemoryMetrics();
|
|
||||||
var lines = output.Split('\n', (char)StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
|
|
||||||
if (lines.Length <= 0) return metrics;
|
|
||||||
|
|
||||||
if (lines != null && lines.Length > 0)
|
|
||||||
{
|
|
||||||
var memory = lines[1].Split(' ', (char)StringSplitOptions.RemoveEmptyEntries);
|
|
||||||
if (memory.Length >= 3)
|
|
||||||
{
|
|
||||||
metrics.Total = double.Parse(memory[0]);
|
|
||||||
metrics.Used = double.Parse(memory[1]);
|
|
||||||
metrics.Free = double.Parse(memory[2]);//m
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return metrics;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,139 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Core.Helper
|
|
||||||
{
|
|
||||||
public class DateTimeHelper
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
///
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="dateTime"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static DateTime GetBeginTime(DateTime? dateTime, int days = 0)
|
|
||||||
{
|
|
||||||
if (dateTime == DateTime.MinValue || dateTime == null)
|
|
||||||
{
|
|
||||||
return DateTime.Now.AddDays(days);
|
|
||||||
}
|
|
||||||
return dateTime ?? DateTime.Now;
|
|
||||||
}
|
|
||||||
#region 时间戳转换
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 时间戳转本地时间-时间戳精确到秒
|
|
||||||
/// </summary>
|
|
||||||
public static DateTime ToLocalTimeDateBySeconds(long unix)
|
|
||||||
{
|
|
||||||
var dto = DateTimeOffset.FromUnixTimeSeconds(unix);
|
|
||||||
return dto.ToLocalTime().DateTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 时间转时间戳Unix-时间戳精确到秒
|
|
||||||
/// </summary>
|
|
||||||
public static long ToUnixTimestampBySeconds(DateTime dt)
|
|
||||||
{
|
|
||||||
DateTimeOffset dto = new DateTimeOffset(dt);
|
|
||||||
return dto.ToUnixTimeSeconds();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 时间戳转本地时间-时间戳精确到毫秒
|
|
||||||
/// </summary>
|
|
||||||
public static DateTime ToLocalTimeDateByMilliseconds(long unix)
|
|
||||||
{
|
|
||||||
var dto = DateTimeOffset.FromUnixTimeMilliseconds(unix);
|
|
||||||
return dto.ToLocalTime().DateTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 时间转时间戳Unix-时间戳精确到毫秒
|
|
||||||
/// </summary>
|
|
||||||
public static long ToUnixTimestampByMilliseconds(DateTime dt)
|
|
||||||
{
|
|
||||||
DateTimeOffset dto = new DateTimeOffset(dt);
|
|
||||||
return dto.ToUnixTimeMilliseconds();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 毫秒转天时分秒
|
|
||||||
/// <summary>
|
|
||||||
/// 毫秒转天时分秒
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="ms"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static string FormatTime(long ms)
|
|
||||||
{
|
|
||||||
int ss = 1000;
|
|
||||||
int mi = ss * 60;
|
|
||||||
int hh = mi * 60;
|
|
||||||
int dd = hh * 24;
|
|
||||||
|
|
||||||
long day = ms / dd;
|
|
||||||
long hour = (ms - day * dd) / hh;
|
|
||||||
long minute = (ms - day * dd - hour * hh) / mi;
|
|
||||||
long second = (ms - day * dd - hour * hh - minute * mi) / ss;
|
|
||||||
long milliSecond = ms - day * dd - hour * hh - minute * mi - second * ss;
|
|
||||||
|
|
||||||
string sDay = day < 10 ? "0" + day : "" + day; //天
|
|
||||||
string sHour = hour < 10 ? "0" + hour : "" + hour;//小时
|
|
||||||
string sMinute = minute < 10 ? "0" + minute : "" + minute;//分钟
|
|
||||||
string sSecond = second < 10 ? "0" + second : "" + second;//秒
|
|
||||||
string sMilliSecond = milliSecond < 10 ? "0" + milliSecond : "" + milliSecond;//毫秒
|
|
||||||
sMilliSecond = milliSecond < 100 ? "0" + sMilliSecond : "" + sMilliSecond;
|
|
||||||
|
|
||||||
return string.Format("{0} 天 {1} 小时 {2} 分 {3} 秒", sDay, sHour, sMinute, sSecond);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 获取unix时间戳
|
|
||||||
/// <summary>
|
|
||||||
/// 获取unix时间戳
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="dt"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static long GetUnixTimeStamp(DateTime dt)
|
|
||||||
{
|
|
||||||
long unixTime = ((DateTimeOffset)dt).ToUnixTimeMilliseconds();
|
|
||||||
return unixTime;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 获取日期天的最小时间
|
|
||||||
public static DateTime GetDayMinDate(DateTime dt)
|
|
||||||
{
|
|
||||||
DateTime min = new DateTime(dt.Year, dt.Month, dt.Day, 0, 0, 0);
|
|
||||||
return min;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 获取日期天的最大时间
|
|
||||||
public static DateTime GetDayMaxDate(DateTime dt)
|
|
||||||
{
|
|
||||||
DateTime max = new DateTime(dt.Year, dt.Month, dt.Day, 23, 59, 59);
|
|
||||||
return max;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 获取日期天的最大时间
|
|
||||||
public static string FormatDateTime(DateTime? dt)
|
|
||||||
{
|
|
||||||
if (dt != null)
|
|
||||||
{
|
|
||||||
if (dt.Value.Year == DateTime.Now.Year)
|
|
||||||
{
|
|
||||||
return dt.Value.ToString("MM-dd HH:mm");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return dt.Value.ToString("yyyy-MM-dd HH:mm");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return string.Empty;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Core.Helper
|
|
||||||
{
|
|
||||||
public static class EnumHelper
|
|
||||||
{
|
|
||||||
public static New EnumToEnum<New>(this object oldEnum)
|
|
||||||
{
|
|
||||||
if (oldEnum is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentNullException(nameof(oldEnum));
|
|
||||||
}
|
|
||||||
return (New)Enum.ToObject(typeof(New), oldEnum.GetHashCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static TEnum StringToEnum<TEnum>(this string str)
|
|
||||||
{
|
|
||||||
return (TEnum)Enum.Parse(typeof(TEnum), str);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Core.Helper
|
|
||||||
{
|
|
||||||
public static class ExpressionHelper
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Expression表达式树lambda参数拼接组合
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T"></typeparam>
|
|
||||||
/// <param name="first"></param>
|
|
||||||
/// <param name="second"></param>
|
|
||||||
/// <param name="merge"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static Expression<T> Compose<T>(this Expression<T> first, Expression<T> second, Func<Expression, Expression, Expression> merge)
|
|
||||||
{
|
|
||||||
var parameterMap = first.Parameters.Select((f, i) => new { f, s = second.Parameters[i] }).ToDictionary(p => p.s, p => p.f);
|
|
||||||
var secondBody = LambdaParameteRebinder.ReplaceParameter(parameterMap, second.Body);
|
|
||||||
return Expression.Lambda<T>(merge(first.Body, secondBody), first.Parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Expression表达式树lambda参数拼接--false
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T"></typeparam>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static Expression<Func<T, bool>> False<T>() => f => false;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Expression表达式树lambda参数拼接-true
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T"></typeparam>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static Expression<Func<T, bool>> True<T>() => f => true;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Expression表达式树lambda参数拼接--and
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T"></typeparam>
|
|
||||||
/// <param name="first"></param>
|
|
||||||
/// <param name="second"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second) => first.Compose(second, Expression.And);
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Expression表达式树lambda参数拼接--or
|
|
||||||
/// </summary>
|
|
||||||
/// <typeparam name="T"></typeparam>
|
|
||||||
/// <param name="first"></param>
|
|
||||||
/// <param name="second"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second) => first.Compose(second, Expression.Or);
|
|
||||||
}
|
|
||||||
|
|
||||||
public class LambdaParameteRebinder : ExpressionVisitor
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 存放表达式树的参数的字典
|
|
||||||
/// </summary>
|
|
||||||
private readonly Dictionary<ParameterExpression, ParameterExpression> map;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 构造函数
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="map"></param>
|
|
||||||
public LambdaParameteRebinder(Dictionary<ParameterExpression, ParameterExpression> map)
|
|
||||||
{
|
|
||||||
this.map = map ?? new Dictionary<ParameterExpression, ParameterExpression>();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 重载参数访问的方法,访问表达式树参数,如果字典中包含,则取出
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="node">表达式树参数</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
protected override Expression VisitParameter(ParameterExpression node)
|
|
||||||
{
|
|
||||||
if (map.TryGetValue(node, out ParameterExpression expression))
|
|
||||||
{
|
|
||||||
node = expression;
|
|
||||||
}
|
|
||||||
return base.VisitParameter(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Expression ReplaceParameter(Dictionary<ParameterExpression, ParameterExpression> map, Expression exp)
|
|
||||||
{
|
|
||||||
return new LambdaParameteRebinder(map).Visit(exp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Net;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Net.Mime;
|
|
||||||
using System.Text;
|
|
||||||
using System.Text.Json;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Core.Helper
|
|
||||||
{
|
|
||||||
public static class HttpHelper
|
|
||||||
{
|
|
||||||
|
|
||||||
public static HttpClient Client { get; set; } = new HttpClient();
|
|
||||||
|
|
||||||
public static async Task<string> Get(string url)
|
|
||||||
{
|
|
||||||
return await Client.GetStringAsync(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task<Stream> GetIO(string url)
|
|
||||||
{
|
|
||||||
return await Client.GetStreamAsync(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static async Task<string> Post(string url, object? item = null, Dictionary<string, string>? head = null)
|
|
||||||
{
|
|
||||||
|
|
||||||
using StringContent json = new(JsonSerializer.Serialize(item), Encoding.UTF8, MediaTypeNames.Application.Json);
|
|
||||||
|
|
||||||
|
|
||||||
if (head is not null)
|
|
||||||
{
|
|
||||||
foreach (var d in head)
|
|
||||||
{
|
|
||||||
json.Headers.Add(d.Key, d.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var httpResponse = await Client.PostAsync(url, json);
|
|
||||||
|
|
||||||
httpResponse.EnsureSuccessStatusCode();
|
|
||||||
|
|
||||||
var content = httpResponse.Content;
|
|
||||||
|
|
||||||
return await content.ReadAsStringAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// public static string HttpGet(string Url, string postDataStr="")
|
|
||||||
// {
|
|
||||||
//#pragma warning disable SYSLIB0014 // 类型或成员已过时
|
|
||||||
// HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url + (postDataStr == "" ? "" : "?") + postDataStr);
|
|
||||||
//#pragma warning restore SYSLIB0014 // 类型或成员已过时
|
|
||||||
// request.Method = "GET";
|
|
||||||
// request.ContentType = "text/html;charset=UTF-8";
|
|
||||||
|
|
||||||
// HttpWebResponse response = (HttpWebResponse)request.GetResponse();
|
|
||||||
// Stream myResponseStream = response.GetResponseStream();
|
|
||||||
// StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
|
|
||||||
// string retString = myStreamReader.ReadToEnd();
|
|
||||||
// myStreamReader.Close();
|
|
||||||
// myResponseStream.Close();
|
|
||||||
|
|
||||||
// return retString;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// public static bool HttpIOGet(string Url, string file, string postDataStr="")
|
|
||||||
// {
|
|
||||||
// HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url + (postDataStr == "" ? "" : "?") + postDataStr);
|
|
||||||
// request.Method = "GET";
|
|
||||||
// request.ContentType = "text/html;charset=UTF-8";
|
|
||||||
|
|
||||||
// HttpWebResponse response = (HttpWebResponse)request.GetResponse();
|
|
||||||
// Stream myResponseStream = response.GetResponseStream();
|
|
||||||
// FileStream writer = new FileStream(file, FileMode.OpenOrCreate, FileAccess.Write);
|
|
||||||
// byte[] buffer = new byte[1024];
|
|
||||||
// int c;
|
|
||||||
// while ((c = myResponseStream.Read(buffer, 0, buffer.Length)) > 0)
|
|
||||||
// {
|
|
||||||
// writer.Write(buffer, 0, c);
|
|
||||||
// }
|
|
||||||
// writer.Close();
|
|
||||||
// myResponseStream.Close();
|
|
||||||
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// public static string HttpPost(string Url, string postDataStr="")
|
|
||||||
// {
|
|
||||||
// CookieContainer cookie = new CookieContainer();
|
|
||||||
//#pragma warning disable SYSLIB0014 // 类型或成员已过时
|
|
||||||
// HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
|
|
||||||
//#pragma warning restore SYSLIB0014 // 类型或成员已过时
|
|
||||||
// request.Method = "POST";
|
|
||||||
// request.ContentType = "application/x-www-form-urlencoded";
|
|
||||||
// request.ContentLength = Encoding.UTF8.GetByteCount(postDataStr);
|
|
||||||
// request.CookieContainer = cookie;
|
|
||||||
|
|
||||||
// Stream myRequestStream = request.GetRequestStream();
|
|
||||||
// StreamWriter myStreamWriter = new StreamWriter(myRequestStream, Encoding.GetEncoding("gb2312"));
|
|
||||||
// myStreamWriter.Write(postDataStr);
|
|
||||||
// myStreamWriter.Close();
|
|
||||||
|
|
||||||
// HttpWebResponse response = (HttpWebResponse)request.GetResponse();
|
|
||||||
|
|
||||||
// response.Cookies = cookie.GetCookies(response.ResponseUri);
|
|
||||||
// Stream myResponseStream = response.GetResponseStream();
|
|
||||||
// StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
|
|
||||||
// string retString = myStreamReader.ReadToEnd();
|
|
||||||
// myStreamReader.Close();
|
|
||||||
// myResponseStream.Close();
|
|
||||||
|
|
||||||
// return retString;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Core.Helper
|
|
||||||
{
|
|
||||||
public class MD5Helper
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 生成PasswordSalt
|
|
||||||
/// </summary>
|
|
||||||
/// <returns>返回string</returns>
|
|
||||||
public static string GenerateSalt()
|
|
||||||
{
|
|
||||||
byte[] buf = new byte[16];
|
|
||||||
#pragma warning disable SYSLIB0023 // 类型或成员已过时
|
|
||||||
new RNGCryptoServiceProvider().GetBytes(buf);
|
|
||||||
#pragma warning restore SYSLIB0023 // 类型或成员已过时
|
|
||||||
return Convert.ToBase64String(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 加密密码
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="pass">密码</param>
|
|
||||||
/// <param name="passwordFormat">加密类型</param>
|
|
||||||
/// <param name="salt">PasswordSalt</param>
|
|
||||||
/// <returns>加密后的密码</returns>
|
|
||||||
public static string SHA2Encode(string pass, string salt, int passwordFormat = 1)
|
|
||||||
{
|
|
||||||
if (passwordFormat == 0) // MembershipPasswordFormat.Clear
|
|
||||||
return pass;
|
|
||||||
|
|
||||||
byte[] bIn = Encoding.Unicode.GetBytes(pass);
|
|
||||||
byte[] bSalt = Convert.FromBase64String(salt);
|
|
||||||
byte[] bAll = new byte[bSalt.Length + bIn.Length];
|
|
||||||
byte[]? bRet = null;
|
|
||||||
|
|
||||||
Buffer.BlockCopy(bSalt, 0, bAll, 0, bSalt.Length);
|
|
||||||
Buffer.BlockCopy(bIn, 0, bAll, bSalt.Length, bIn.Length);
|
|
||||||
|
|
||||||
#pragma warning disable SYSLIB0021 // 类型或成员已过时
|
|
||||||
var s = SHA512.Create();
|
|
||||||
#pragma warning restore SYSLIB0021 // 类型或成员已过时
|
|
||||||
bRet = s.ComputeHash(bAll);
|
|
||||||
|
|
||||||
return ConvertEx.ToUrlBase64String(bRet);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 16位MD5加密
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="password"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static string MD5Encrypt16(string password)
|
|
||||||
{
|
|
||||||
var md5 = MD5.Create();
|
|
||||||
string t2 = BitConverter.ToString(md5.ComputeHash(Encoding.Default.GetBytes(password)), 4, 8);
|
|
||||||
t2 = t2.Replace("-", string.Empty);
|
|
||||||
return t2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 32位MD5加密
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="password"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static string MD5Encrypt32(string password = "")
|
|
||||||
{
|
|
||||||
string pwd = string.Empty;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!string.IsNullOrEmpty(password) && !string.IsNullOrWhiteSpace(password))
|
|
||||||
{
|
|
||||||
MD5 md5 = MD5.Create(); //实例化一个md5对像
|
|
||||||
// 加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择
|
|
||||||
byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(password));
|
|
||||||
// 通过使用循环,将字节类型的数组转换为字符串,此字符串是常规字符格式化所得
|
|
||||||
foreach (var item in s)
|
|
||||||
{
|
|
||||||
// 将得到的字符串使用十六进制类型格式。格式后的字符是小写的字母,如果使用大写(X)则格式后的字符是大写字符
|
|
||||||
pwd = string.Concat(pwd, item.ToString("X2"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
throw new Exception($"错误的 password 字符串:【{password}】");
|
|
||||||
}
|
|
||||||
return pwd;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 64位MD5加密
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="password"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static string MD5Encrypt64(string password)
|
|
||||||
{
|
|
||||||
// 实例化一个md5对像
|
|
||||||
// 加密后是一个字节类型的数组,这里要注意编码UTF8/Unicode等的选择
|
|
||||||
MD5 md5 = MD5.Create();
|
|
||||||
byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(password));
|
|
||||||
return Convert.ToBase64String(s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public class ConvertEx
|
|
||||||
{
|
|
||||||
static readonly char[] padding = { '=' };
|
|
||||||
public static string ToUrlBase64String(byte[] inArray)
|
|
||||||
{
|
|
||||||
var str = Convert.ToBase64String(inArray);
|
|
||||||
str = str.TrimEnd(padding).Replace('+', '-').Replace('/', '_');
|
|
||||||
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static byte[] FromUrlBase64String(string s)
|
|
||||||
{
|
|
||||||
string incoming = s.Replace('_', '/').Replace('-', '+');
|
|
||||||
switch (s.Length % 4)
|
|
||||||
{
|
|
||||||
case 2: incoming += "=="; break;
|
|
||||||
case 3: incoming += "="; break;
|
|
||||||
}
|
|
||||||
byte[] bytes = Convert.FromBase64String(incoming);
|
|
||||||
|
|
||||||
return bytes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,260 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Yi.Framework.Core.Enums;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Core.Helper
|
|
||||||
{
|
|
||||||
public static class MimeHelper
|
|
||||||
{
|
|
||||||
// 通过自己定义一个静态类
|
|
||||||
// 将所有的Content Type都扔进去吧
|
|
||||||
// 调用的时候直接调用静态方法即可。
|
|
||||||
|
|
||||||
public static List<string> ImageType { get; set; } = new List<string>
|
|
||||||
{
|
|
||||||
".jpg",".png",".jpeg"
|
|
||||||
};
|
|
||||||
|
|
||||||
private static Hashtable _mimeMappingTable;
|
|
||||||
|
|
||||||
private static void AddMimeMapping(string extension, string MimeType)
|
|
||||||
{
|
|
||||||
_mimeMappingTable.Add(extension, MimeType);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static string GetMimeMapping(string FileName)
|
|
||||||
{
|
|
||||||
string text = null!;
|
|
||||||
int num = FileName.LastIndexOf('.');
|
|
||||||
if (0 < num && num > FileName.LastIndexOf('\\'))
|
|
||||||
{
|
|
||||||
text = (string)_mimeMappingTable[FileName.Substring(num)]!;
|
|
||||||
}
|
|
||||||
if (text == null)
|
|
||||||
{
|
|
||||||
text = (string)_mimeMappingTable[".*"]!;
|
|
||||||
}
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static FileTypeEnum GetFileType(string fileName)
|
|
||||||
{
|
|
||||||
var extension = Path.GetExtension(fileName);
|
|
||||||
if (ImageType.Contains(extension.ToLower()))
|
|
||||||
return FileTypeEnum.Image;
|
|
||||||
return FileTypeEnum.File;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static MimeHelper()
|
|
||||||
{
|
|
||||||
_mimeMappingTable = new Hashtable(190, StringComparer.CurrentCultureIgnoreCase);
|
|
||||||
AddMimeMapping(".323", "text/h323");
|
|
||||||
AddMimeMapping(".asx", "video/x-ms-asf");
|
|
||||||
AddMimeMapping(".acx", "application/internet-property-stream");
|
|
||||||
AddMimeMapping(".ai", "application/postscript");
|
|
||||||
AddMimeMapping(".aif", "audio/x-aiff");
|
|
||||||
AddMimeMapping(".aiff", "audio/aiff");
|
|
||||||
AddMimeMapping(".axs", "application/olescript");
|
|
||||||
AddMimeMapping(".aifc", "audio/aiff");
|
|
||||||
AddMimeMapping(".asr", "video/x-ms-asf");
|
|
||||||
AddMimeMapping(".avi", "video/x-msvideo");
|
|
||||||
AddMimeMapping(".asf", "video/x-ms-asf");
|
|
||||||
AddMimeMapping(".au", "audio/basic");
|
|
||||||
AddMimeMapping(".application", "application/x-ms-application");
|
|
||||||
AddMimeMapping(".bin", "application/octet-stream");
|
|
||||||
AddMimeMapping(".bas", "text/plain");
|
|
||||||
AddMimeMapping(".bcpio", "application/x-bcpio");
|
|
||||||
AddMimeMapping(".bmp", "image/bmp");
|
|
||||||
AddMimeMapping(".cdf", "application/x-cdf");
|
|
||||||
AddMimeMapping(".cat", "application/vndms-pkiseccat");
|
|
||||||
AddMimeMapping(".crt", "application/x-x509-ca-cert");
|
|
||||||
AddMimeMapping(".c", "text/plain");
|
|
||||||
AddMimeMapping(".css", "text/css");
|
|
||||||
AddMimeMapping(".cer", "application/x-x509-ca-cert");
|
|
||||||
AddMimeMapping(".crl", "application/pkix-crl");
|
|
||||||
AddMimeMapping(".cmx", "image/x-cmx");
|
|
||||||
AddMimeMapping(".csh", "application/x-csh");
|
|
||||||
AddMimeMapping(".cod", "image/cis-cod");
|
|
||||||
AddMimeMapping(".cpio", "application/x-cpio");
|
|
||||||
AddMimeMapping(".clp", "application/x-msclip");
|
|
||||||
AddMimeMapping(".crd", "application/x-mscardfile");
|
|
||||||
AddMimeMapping(".deploy", "application/octet-stream");
|
|
||||||
AddMimeMapping(".dll", "application/x-msdownload");
|
|
||||||
AddMimeMapping(".dot", "application/msword");
|
|
||||||
AddMimeMapping(".doc", "application/msword");
|
|
||||||
AddMimeMapping(".dvi", "application/x-dvi");
|
|
||||||
AddMimeMapping(".dir", "application/x-director");
|
|
||||||
AddMimeMapping(".dxr", "application/x-director");
|
|
||||||
AddMimeMapping(".der", "application/x-x509-ca-cert");
|
|
||||||
AddMimeMapping(".dib", "image/bmp");
|
|
||||||
AddMimeMapping(".dcr", "application/x-director");
|
|
||||||
AddMimeMapping(".disco", "text/xml");
|
|
||||||
AddMimeMapping(".exe", "application/octet-stream");
|
|
||||||
AddMimeMapping(".etx", "text/x-setext");
|
|
||||||
AddMimeMapping(".evy", "application/envoy");
|
|
||||||
AddMimeMapping(".eml", "message/rfc822");
|
|
||||||
AddMimeMapping(".eps", "application/postscript");
|
|
||||||
AddMimeMapping(".flr", "x-world/x-vrml");
|
|
||||||
AddMimeMapping(".fif", "application/fractals");
|
|
||||||
AddMimeMapping(".gtar", "application/x-gtar");
|
|
||||||
AddMimeMapping(".gif", "image/gif");
|
|
||||||
AddMimeMapping(".gz", "application/x-gzip");
|
|
||||||
AddMimeMapping(".hta", "application/hta");
|
|
||||||
AddMimeMapping(".htc", "text/x-component");
|
|
||||||
AddMimeMapping(".htt", "text/webviewhtml");
|
|
||||||
AddMimeMapping(".h", "text/plain");
|
|
||||||
AddMimeMapping(".hdf", "application/x-hdf");
|
|
||||||
AddMimeMapping(".hlp", "application/winhlp");
|
|
||||||
AddMimeMapping(".html", "text/html");
|
|
||||||
AddMimeMapping(".htm", "text/html");
|
|
||||||
AddMimeMapping(".hqx", "application/mac-binhex40");
|
|
||||||
AddMimeMapping(".isp", "application/x-internet-signup");
|
|
||||||
AddMimeMapping(".iii", "application/x-iphone");
|
|
||||||
AddMimeMapping(".ief", "image/ief");
|
|
||||||
AddMimeMapping(".ivf", "video/x-ivf");
|
|
||||||
AddMimeMapping(".ins", "application/x-internet-signup");
|
|
||||||
AddMimeMapping(".ico", "image/x-icon");
|
|
||||||
AddMimeMapping(".jpg", "image/jpeg");
|
|
||||||
AddMimeMapping(".jfif", "image/pjpeg");
|
|
||||||
AddMimeMapping(".jpe", "image/jpeg");
|
|
||||||
AddMimeMapping(".jpeg", "image/jpeg");
|
|
||||||
AddMimeMapping(".js", "application/x-javascript");
|
|
||||||
AddMimeMapping(".lsx", "video/x-la-asf");
|
|
||||||
AddMimeMapping(".latex", "application/x-latex");
|
|
||||||
AddMimeMapping(".lsf", "video/x-la-asf");
|
|
||||||
AddMimeMapping(".manifest", "application/x-ms-manifest");
|
|
||||||
AddMimeMapping(".mhtml", "message/rfc822");
|
|
||||||
AddMimeMapping(".mny", "application/x-msmoney");
|
|
||||||
AddMimeMapping(".mht", "message/rfc822");
|
|
||||||
AddMimeMapping(".mid", "audio/mid");
|
|
||||||
AddMimeMapping(".mpv2", "video/mpeg");
|
|
||||||
AddMimeMapping(".man", "application/x-troff-man");
|
|
||||||
AddMimeMapping(".mvb", "application/x-msmediaview");
|
|
||||||
AddMimeMapping(".mpeg", "video/mpeg");
|
|
||||||
AddMimeMapping(".m3u", "audio/x-mpegurl");
|
|
||||||
AddMimeMapping(".mdb", "application/x-msaccess");
|
|
||||||
AddMimeMapping(".mpp", "application/vnd.ms-project");
|
|
||||||
AddMimeMapping(".m1v", "video/mpeg");
|
|
||||||
AddMimeMapping(".mpa", "video/mpeg");
|
|
||||||
AddMimeMapping(".me", "application/x-troff-me");
|
|
||||||
AddMimeMapping(".m13", "application/x-msmediaview");
|
|
||||||
AddMimeMapping(".movie", "video/x-sgi-movie");
|
|
||||||
AddMimeMapping(".m14", "application/x-msmediaview");
|
|
||||||
AddMimeMapping(".mpe", "video/mpeg");
|
|
||||||
AddMimeMapping(".mp2", "video/mpeg");
|
|
||||||
AddMimeMapping(".mov", "video/quicktime");
|
|
||||||
AddMimeMapping(".mp3", "audio/mpeg");
|
|
||||||
AddMimeMapping(".mpg", "video/mpeg");
|
|
||||||
AddMimeMapping(".ms", "application/x-troff-ms");
|
|
||||||
AddMimeMapping(".nc", "application/x-netcdf");
|
|
||||||
AddMimeMapping(".nws", "message/rfc822");
|
|
||||||
AddMimeMapping(".oda", "application/oda");
|
|
||||||
AddMimeMapping(".ods", "application/oleobject");
|
|
||||||
AddMimeMapping(".pmc", "application/x-perfmon");
|
|
||||||
AddMimeMapping(".p7r", "application/x-pkcs7-certreqresp");
|
|
||||||
AddMimeMapping(".p7b", "application/x-pkcs7-certificates");
|
|
||||||
AddMimeMapping(".p7s", "application/pkcs7-signature");
|
|
||||||
AddMimeMapping(".pmw", "application/x-perfmon");
|
|
||||||
AddMimeMapping(".ps", "application/postscript");
|
|
||||||
AddMimeMapping(".p7c", "application/pkcs7-mime");
|
|
||||||
AddMimeMapping(".pbm", "image/x-portable-bitmap");
|
|
||||||
AddMimeMapping(".ppm", "image/x-portable-pixmap");
|
|
||||||
AddMimeMapping(".pub", "application/x-mspublisher");
|
|
||||||
AddMimeMapping(".pnm", "image/x-portable-anymap");
|
|
||||||
AddMimeMapping(".png", "image/png");
|
|
||||||
AddMimeMapping(".pml", "application/x-perfmon");
|
|
||||||
AddMimeMapping(".p10", "application/pkcs10");
|
|
||||||
AddMimeMapping(".pfx", "application/x-pkcs12");
|
|
||||||
AddMimeMapping(".p12", "application/x-pkcs12");
|
|
||||||
AddMimeMapping(".pdf", "application/pdf");
|
|
||||||
AddMimeMapping(".pps", "application/vnd.ms-powerpoint");
|
|
||||||
AddMimeMapping(".p7m", "application/pkcs7-mime");
|
|
||||||
AddMimeMapping(".pko", "application/vndms-pkipko");
|
|
||||||
AddMimeMapping(".ppt", "application/vnd.ms-powerpoint");
|
|
||||||
AddMimeMapping(".pmr", "application/x-perfmon");
|
|
||||||
AddMimeMapping(".pma", "application/x-perfmon");
|
|
||||||
AddMimeMapping(".pot", "application/vnd.ms-powerpoint");
|
|
||||||
AddMimeMapping(".prf", "application/pics-rules");
|
|
||||||
AddMimeMapping(".pgm", "image/x-portable-graymap");
|
|
||||||
AddMimeMapping(".qt", "video/quicktime");
|
|
||||||
AddMimeMapping(".ra", "audio/x-pn-realaudio");
|
|
||||||
AddMimeMapping(".rgb", "image/x-rgb");
|
|
||||||
AddMimeMapping(".ram", "audio/x-pn-realaudio");
|
|
||||||
AddMimeMapping(".rmi", "audio/mid");
|
|
||||||
AddMimeMapping(".ras", "image/x-cmu-raster");
|
|
||||||
AddMimeMapping(".roff", "application/x-troff");
|
|
||||||
AddMimeMapping(".rtf", "application/rtf");
|
|
||||||
AddMimeMapping(".rtx", "text/richtext");
|
|
||||||
AddMimeMapping(".sv4crc", "application/x-sv4crc");
|
|
||||||
AddMimeMapping(".spc", "application/x-pkcs7-certificates");
|
|
||||||
AddMimeMapping(".setreg", "application/set-registration-initiation");
|
|
||||||
AddMimeMapping(".snd", "audio/basic");
|
|
||||||
AddMimeMapping(".stl", "application/vndms-pkistl");
|
|
||||||
AddMimeMapping(".setpay", "application/set-payment-initiation");
|
|
||||||
AddMimeMapping(".stm", "text/html");
|
|
||||||
AddMimeMapping(".shar", "application/x-shar");
|
|
||||||
AddMimeMapping(".sh", "application/x-sh");
|
|
||||||
AddMimeMapping(".sit", "application/x-stuffit");
|
|
||||||
AddMimeMapping(".spl", "application/futuresplash");
|
|
||||||
AddMimeMapping(".sct", "text/scriptlet");
|
|
||||||
AddMimeMapping(".scd", "application/x-msschedule");
|
|
||||||
AddMimeMapping(".sst", "application/vndms-pkicertstore");
|
|
||||||
AddMimeMapping(".src", "application/x-wais-source");
|
|
||||||
AddMimeMapping(".sv4cpio", "application/x-sv4cpio");
|
|
||||||
AddMimeMapping(".tex", "application/x-tex");
|
|
||||||
AddMimeMapping(".tgz", "application/x-compressed");
|
|
||||||
AddMimeMapping(".t", "application/x-troff");
|
|
||||||
AddMimeMapping(".tar", "application/x-tar");
|
|
||||||
AddMimeMapping(".tr", "application/x-troff");
|
|
||||||
AddMimeMapping(".tif", "image/tiff");
|
|
||||||
AddMimeMapping(".txt", "text/plain");
|
|
||||||
AddMimeMapping(".texinfo", "application/x-texinfo");
|
|
||||||
AddMimeMapping(".trm", "application/x-msterminal");
|
|
||||||
AddMimeMapping(".tiff", "image/tiff");
|
|
||||||
AddMimeMapping(".tcl", "application/x-tcl");
|
|
||||||
AddMimeMapping(".texi", "application/x-texinfo");
|
|
||||||
AddMimeMapping(".tsv", "text/tab-separated-values");
|
|
||||||
AddMimeMapping(".ustar", "application/x-ustar");
|
|
||||||
AddMimeMapping(".uls", "text/iuls");
|
|
||||||
AddMimeMapping(".vcf", "text/x-vcard");
|
|
||||||
AddMimeMapping(".wps", "application/vnd.ms-works");
|
|
||||||
AddMimeMapping(".wav", "audio/wav");
|
|
||||||
AddMimeMapping(".wrz", "x-world/x-vrml");
|
|
||||||
AddMimeMapping(".wri", "application/x-mswrite");
|
|
||||||
AddMimeMapping(".wks", "application/vnd.ms-works");
|
|
||||||
AddMimeMapping(".wmf", "application/x-msmetafile");
|
|
||||||
AddMimeMapping(".wcm", "application/vnd.ms-works");
|
|
||||||
AddMimeMapping(".wrl", "x-world/x-vrml");
|
|
||||||
AddMimeMapping(".wdb", "application/vnd.ms-works");
|
|
||||||
AddMimeMapping(".wsdl", "text/xml");
|
|
||||||
AddMimeMapping(".xap", "application/x-silverlight-app");
|
|
||||||
AddMimeMapping(".xml", "text/xml");
|
|
||||||
AddMimeMapping(".xlm", "application/vnd.ms-excel");
|
|
||||||
AddMimeMapping(".xaf", "x-world/x-vrml");
|
|
||||||
AddMimeMapping(".xla", "application/vnd.ms-excel");
|
|
||||||
AddMimeMapping(".xls", "application/vnd.ms-excel");
|
|
||||||
AddMimeMapping(".xlsx", "application/vnd.ms-excel");
|
|
||||||
AddMimeMapping(".xof", "x-world/x-vrml");
|
|
||||||
AddMimeMapping(".xlt", "application/vnd.ms-excel");
|
|
||||||
AddMimeMapping(".xlc", "application/vnd.ms-excel");
|
|
||||||
AddMimeMapping(".xsl", "text/xml");
|
|
||||||
AddMimeMapping(".xbm", "image/x-xbitmap");
|
|
||||||
AddMimeMapping(".xlw", "application/vnd.ms-excel");
|
|
||||||
AddMimeMapping(".xpm", "image/x-xpixmap");
|
|
||||||
AddMimeMapping(".xwd", "image/x-xwindowdump");
|
|
||||||
AddMimeMapping(".xsd", "text/xml");
|
|
||||||
AddMimeMapping(".z", "application/x-compress");
|
|
||||||
AddMimeMapping(".zip", "application/x-zip-compressed");
|
|
||||||
AddMimeMapping(".*", "application/octet-stream");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,390 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Core.Helper
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// RSA加解密 使用OpenSSL的公钥加密/私钥解密
|
|
||||||
/// 公私钥请使用openssl生成
|
|
||||||
/// </summary>
|
|
||||||
public class RSAHelper
|
|
||||||
{
|
|
||||||
public readonly RSA? _privateKeyRsaProvider;
|
|
||||||
public readonly RSA? _publicKeyRsaProvider;
|
|
||||||
private readonly HashAlgorithmName _hashAlgorithmName;
|
|
||||||
private readonly Encoding _encoding;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 实例化RSAHelper
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="rsaType">加密算法类型 RSA SHA1;RSA2 SHA256 密钥长度至少为2048</param>
|
|
||||||
/// <param name="encoding">编码类型</param>
|
|
||||||
/// <param name="privateKey">私钥</param>
|
|
||||||
/// <param name="publicKey">公钥</param>
|
|
||||||
public RSAHelper(RSAType rsaType, Encoding encoding, string privateKey, string? publicKey = null)
|
|
||||||
{
|
|
||||||
_encoding = encoding;
|
|
||||||
if (!string.IsNullOrEmpty(privateKey))
|
|
||||||
{
|
|
||||||
_privateKeyRsaProvider = CreateRsaProviderFromPrivateKey(privateKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(publicKey))
|
|
||||||
{
|
|
||||||
_publicKeyRsaProvider = CreateRsaProviderFromPublicKey(publicKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
_hashAlgorithmName = rsaType == RSAType.RSA ? HashAlgorithmName.SHA1 : HashAlgorithmName.SHA256;
|
|
||||||
}
|
|
||||||
|
|
||||||
#region 使用私钥签名
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 使用私钥签名
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="data">原始数据</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public string Sign(string data)
|
|
||||||
{
|
|
||||||
byte[] dataBytes = _encoding.GetBytes(data);
|
|
||||||
|
|
||||||
var signatureBytes = _privateKeyRsaProvider!.SignData(dataBytes, _hashAlgorithmName, RSASignaturePadding.Pkcs1);
|
|
||||||
|
|
||||||
return Convert.ToBase64String(signatureBytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 使用公钥验签
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 使用公钥验签
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="data">原始数据</param>
|
|
||||||
/// <param name="sign">签名</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public bool Verify(string data, string sign)
|
|
||||||
{
|
|
||||||
byte[] dataBytes = _encoding.GetBytes(data);
|
|
||||||
byte[] signBytes = Convert.FromBase64String(sign);
|
|
||||||
|
|
||||||
var verify = _publicKeyRsaProvider!.VerifyData(dataBytes, signBytes, _hashAlgorithmName, RSASignaturePadding.Pkcs1);
|
|
||||||
|
|
||||||
return verify;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 解密
|
|
||||||
/// <summary>
|
|
||||||
/// 私钥解密(原)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="cipherText">解密字符串(base64)</param>
|
|
||||||
/// <returns></returns>
|
|
||||||
|
|
||||||
//public string Decrypt(string cipherText)
|
|
||||||
//{
|
|
||||||
// if (_privateKeyRsaProvider == null)
|
|
||||||
// {
|
|
||||||
// throw new Exception("_privateKeyRsaProvider is null");
|
|
||||||
// }
|
|
||||||
// return _encoding.GetString(_privateKeyRsaProvider.Decrypt(Convert.FromBase64String(cipherText), RSAEncryptionPadding.Pkcs1));
|
|
||||||
//}
|
|
||||||
/// <summary>
|
|
||||||
/// 私钥解密(支持大量数据)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="cipherText"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public string Decrypt(string cipherText)
|
|
||||||
{
|
|
||||||
if (_privateKeyRsaProvider == null)
|
|
||||||
{
|
|
||||||
throw new Exception("_privateKeyRsaProvider is null");
|
|
||||||
}
|
|
||||||
var bufferSize = _privateKeyRsaProvider.KeySize / 8;
|
|
||||||
byte[] buffer = new byte[bufferSize];//待解密块
|
|
||||||
using (MemoryStream msInput = new MemoryStream(Convert.FromBase64String(cipherText)))
|
|
||||||
{
|
|
||||||
using (MemoryStream msOutput = new MemoryStream())
|
|
||||||
{
|
|
||||||
int readLen; while ((readLen = msInput.Read(buffer, 0, bufferSize)) > 0)
|
|
||||||
{
|
|
||||||
byte[] dataToEnc = new byte[readLen];
|
|
||||||
Array.Copy(buffer, 0, dataToEnc, 0, readLen); byte[] encData = _privateKeyRsaProvider.Decrypt(dataToEnc, RSAEncryptionPadding.Pkcs1);
|
|
||||||
msOutput.Write(encData, 0, encData.Length);
|
|
||||||
}
|
|
||||||
byte[] result = msOutput.ToArray();
|
|
||||||
return _encoding.GetString(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 加密
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 公钥加密(原)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="text"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
//public string Encrypt(string text)
|
|
||||||
//{
|
|
||||||
// if (_publicKeyRsaProvider == null)
|
|
||||||
// {
|
|
||||||
// throw new Exception("_publicKeyRsaProvider is null");
|
|
||||||
// }
|
|
||||||
// return Convert.ToBase64String(_publicKeyRsaProvider.Encrypt(Encoding.UTF8.GetBytes(text), RSAEncryptionPadding.Pkcs1));
|
|
||||||
//}
|
|
||||||
/// <summary>
|
|
||||||
/// 公钥加密(支持大量数据)
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="text"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public string Encrypt(string text)
|
|
||||||
{
|
|
||||||
if (_publicKeyRsaProvider == null)
|
|
||||||
{
|
|
||||||
throw new Exception("_publicKeyRsaProvider is null");
|
|
||||||
}
|
|
||||||
var bufferSize = _publicKeyRsaProvider.KeySize / 8 - 11;
|
|
||||||
byte[] buffer = new byte[bufferSize];//待加密块
|
|
||||||
|
|
||||||
using (MemoryStream msInput = new MemoryStream(_encoding.GetBytes(text)))
|
|
||||||
{
|
|
||||||
using (MemoryStream msOutput = new MemoryStream())
|
|
||||||
{
|
|
||||||
int readLen; while ((readLen = msInput.Read(buffer, 0, bufferSize)) > 0)
|
|
||||||
{
|
|
||||||
byte[] dataToEnc = new byte[readLen];
|
|
||||||
Array.Copy(buffer, 0, dataToEnc, 0, readLen); byte[] encData = _publicKeyRsaProvider.Encrypt(dataToEnc, RSAEncryptionPadding.Pkcs1);
|
|
||||||
msOutput.Write(encData, 0, encData.Length);
|
|
||||||
}
|
|
||||||
byte[] result = msOutput.ToArray();
|
|
||||||
return Convert.ToBase64String(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 使用私钥创建RSA实例
|
|
||||||
/// <summary>
|
|
||||||
/// 使用私钥创建RSA实例
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="privateKey"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
private RSA CreateRsaProviderFromPrivateKey(string privateKey)
|
|
||||||
{
|
|
||||||
var privateKeyBits = Convert.FromBase64String(privateKey);
|
|
||||||
|
|
||||||
var rsa = RSA.Create();
|
|
||||||
var rsaParameters = new RSAParameters();
|
|
||||||
|
|
||||||
using (BinaryReader binr = new BinaryReader(new MemoryStream(privateKeyBits)))
|
|
||||||
{
|
|
||||||
byte bt = 0;
|
|
||||||
ushort twobytes = 0;
|
|
||||||
twobytes = binr.ReadUInt16();
|
|
||||||
if (twobytes == 0x8130)
|
|
||||||
binr.ReadByte();
|
|
||||||
else if (twobytes == 0x8230)
|
|
||||||
binr.ReadInt16();
|
|
||||||
else
|
|
||||||
throw new Exception("Unexpected value read binr.ReadUInt16()");
|
|
||||||
|
|
||||||
twobytes = binr.ReadUInt16();
|
|
||||||
if (twobytes != 0x0102)
|
|
||||||
throw new Exception("Unexpected version");
|
|
||||||
|
|
||||||
bt = binr.ReadByte();
|
|
||||||
if (bt != 0x00)
|
|
||||||
throw new Exception("Unexpected value read binr.ReadByte()");
|
|
||||||
|
|
||||||
rsaParameters.Modulus = binr.ReadBytes(GetIntegerSize(binr));
|
|
||||||
rsaParameters.Exponent = binr.ReadBytes(GetIntegerSize(binr));
|
|
||||||
rsaParameters.D = binr.ReadBytes(GetIntegerSize(binr));
|
|
||||||
rsaParameters.P = binr.ReadBytes(GetIntegerSize(binr));
|
|
||||||
rsaParameters.Q = binr.ReadBytes(GetIntegerSize(binr));
|
|
||||||
rsaParameters.DP = binr.ReadBytes(GetIntegerSize(binr));
|
|
||||||
rsaParameters.DQ = binr.ReadBytes(GetIntegerSize(binr));
|
|
||||||
rsaParameters.InverseQ = binr.ReadBytes(GetIntegerSize(binr));
|
|
||||||
}
|
|
||||||
|
|
||||||
rsa.ImportParameters(rsaParameters);
|
|
||||||
return rsa;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 使用公钥创建RSA实例
|
|
||||||
/// <summary>
|
|
||||||
/// 使用公钥创建RSA实例
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="publicKeyString"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public RSA? CreateRsaProviderFromPublicKey(string publicKeyString)
|
|
||||||
{
|
|
||||||
// encoded OID sequence for PKCS #1 rsaEncryption szOID_RSA_RSA = "1.2.840.113549.1.1.1"
|
|
||||||
byte[] seqOid = { 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00 };
|
|
||||||
byte[] seq = new byte[15];
|
|
||||||
|
|
||||||
var x509Key = Convert.FromBase64String(publicKeyString);
|
|
||||||
|
|
||||||
// --------- Set up stream to read the asn.1 encoded SubjectPublicKeyInfo blob ------
|
|
||||||
using (MemoryStream mem = new MemoryStream(x509Key))
|
|
||||||
{
|
|
||||||
using (BinaryReader binr = new BinaryReader(mem)) //wrap Memory Stream with BinaryReader for easy reading
|
|
||||||
{
|
|
||||||
byte bt = 0;
|
|
||||||
ushort twobytes = 0;
|
|
||||||
|
|
||||||
twobytes = binr.ReadUInt16();
|
|
||||||
if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
|
|
||||||
binr.ReadByte(); //advance 1 byte
|
|
||||||
else if (twobytes == 0x8230)
|
|
||||||
binr.ReadInt16(); //advance 2 bytes
|
|
||||||
else
|
|
||||||
return null;
|
|
||||||
|
|
||||||
seq = binr.ReadBytes(15); //read the Sequence OID
|
|
||||||
if (!CompareBytearrays(seq, seqOid)) //make sure Sequence for OID is correct
|
|
||||||
return null;
|
|
||||||
|
|
||||||
twobytes = binr.ReadUInt16();
|
|
||||||
if (twobytes == 0x8103) //data read as little endian order (actual data order for Bit String is 03 81)
|
|
||||||
binr.ReadByte(); //advance 1 byte
|
|
||||||
else if (twobytes == 0x8203)
|
|
||||||
binr.ReadInt16(); //advance 2 bytes
|
|
||||||
else
|
|
||||||
return null;
|
|
||||||
|
|
||||||
bt = binr.ReadByte();
|
|
||||||
if (bt != 0x00) //expect null byte next
|
|
||||||
return null;
|
|
||||||
|
|
||||||
twobytes = binr.ReadUInt16();
|
|
||||||
if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
|
|
||||||
binr.ReadByte(); //advance 1 byte
|
|
||||||
else if (twobytes == 0x8230)
|
|
||||||
binr.ReadInt16(); //advance 2 bytes
|
|
||||||
else
|
|
||||||
return null;
|
|
||||||
|
|
||||||
twobytes = binr.ReadUInt16();
|
|
||||||
byte lowbyte = 0x00;
|
|
||||||
byte highbyte = 0x00;
|
|
||||||
|
|
||||||
if (twobytes == 0x8102) //data read as little endian order (actual data order for Integer is 02 81)
|
|
||||||
lowbyte = binr.ReadByte(); // read next bytes which is bytes in modulus
|
|
||||||
else if (twobytes == 0x8202)
|
|
||||||
{
|
|
||||||
highbyte = binr.ReadByte(); //advance 2 bytes
|
|
||||||
lowbyte = binr.ReadByte();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return null;
|
|
||||||
byte[] modint = { lowbyte, highbyte, 0x00, 0x00 }; //reverse byte order since asn.1 key uses big endian order
|
|
||||||
int modsize = BitConverter.ToInt32(modint, 0);
|
|
||||||
|
|
||||||
int firstbyte = binr.PeekChar();
|
|
||||||
if (firstbyte == 0x00)
|
|
||||||
{ //if first byte (highest order) of modulus is zero, don't include it
|
|
||||||
binr.ReadByte(); //skip this null byte
|
|
||||||
modsize -= 1; //reduce modulus buffer size by 1
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] modulus = binr.ReadBytes(modsize); //read the modulus bytes
|
|
||||||
|
|
||||||
if (binr.ReadByte() != 0x02) //expect an Integer for the exponent data
|
|
||||||
return null;
|
|
||||||
int expbytes = binr.ReadByte(); // should only need one byte for actual exponent data (for all useful values)
|
|
||||||
byte[] exponent = binr.ReadBytes(expbytes);
|
|
||||||
|
|
||||||
// ------- create RSACryptoServiceProvider instance and initialize with public key -----
|
|
||||||
var rsa = RSA.Create();
|
|
||||||
RSAParameters rsaKeyInfo = new RSAParameters
|
|
||||||
{
|
|
||||||
Modulus = modulus,
|
|
||||||
Exponent = exponent
|
|
||||||
};
|
|
||||||
rsa.ImportParameters(rsaKeyInfo);
|
|
||||||
|
|
||||||
return rsa;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 导入密钥算法
|
|
||||||
|
|
||||||
private int GetIntegerSize(BinaryReader binr)
|
|
||||||
{
|
|
||||||
byte bt = 0;
|
|
||||||
int count = 0;
|
|
||||||
bt = binr.ReadByte();
|
|
||||||
if (bt != 0x02)
|
|
||||||
return 0;
|
|
||||||
bt = binr.ReadByte();
|
|
||||||
|
|
||||||
if (bt == 0x81)
|
|
||||||
count = binr.ReadByte();
|
|
||||||
else
|
|
||||||
if (bt == 0x82)
|
|
||||||
{
|
|
||||||
var highbyte = binr.ReadByte();
|
|
||||||
var lowbyte = binr.ReadByte();
|
|
||||||
byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
|
|
||||||
count = BitConverter.ToInt32(modint, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
count = bt;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (binr.ReadByte() == 0x00)
|
|
||||||
{
|
|
||||||
count -= 1;
|
|
||||||
}
|
|
||||||
binr.BaseStream.Seek(-1, SeekOrigin.Current);
|
|
||||||
return count;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool CompareBytearrays(byte[] a, byte[] b)
|
|
||||||
{
|
|
||||||
if (a.Length != b.Length)
|
|
||||||
return false;
|
|
||||||
int i = 0;
|
|
||||||
foreach (byte c in a)
|
|
||||||
{
|
|
||||||
if (c != b[i])
|
|
||||||
return false;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// RSA算法类型
|
|
||||||
/// </summary>
|
|
||||||
public enum RSAType
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// SHA1
|
|
||||||
/// </summary>
|
|
||||||
RSA = 0,
|
|
||||||
/// <summary>
|
|
||||||
/// RSA2 密钥长度至少为2048
|
|
||||||
/// SHA256
|
|
||||||
/// </summary>
|
|
||||||
RSA2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Core.Helper
|
|
||||||
{
|
|
||||||
public static class ReflexHelper
|
|
||||||
{
|
|
||||||
|
|
||||||
#region 对象相关
|
|
||||||
/// <summary>
|
|
||||||
/// 取对象属性值
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="FieldName"></param>
|
|
||||||
/// <param name="obj"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static string GetModelValue(string FieldName, object obj)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Type Ts = obj.GetType();
|
|
||||||
object o = Ts.GetProperty(FieldName).GetValue(obj, null);
|
|
||||||
if (null == o)
|
|
||||||
return null;
|
|
||||||
string Value = Convert.ToString(o);
|
|
||||||
if (string.IsNullOrEmpty(Value))
|
|
||||||
return null;
|
|
||||||
return Value;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 设置对象属性值
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="FieldName"></param>
|
|
||||||
/// <param name="Value"></param>
|
|
||||||
/// <param name="obj"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static bool SetModelValue(string FieldName, object Value, object obj)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Type Ts = obj.GetType();
|
|
||||||
Ts.GetProperty(FieldName).SetValue(obj, Value, null);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Core.Helper
|
|
||||||
{
|
|
||||||
public class ShellHelper
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// linux 系统命令
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="command"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static string Bash(string command)
|
|
||||||
{
|
|
||||||
var escapedArgs = command.Replace("\"", "\\\"");
|
|
||||||
var process = new Process()
|
|
||||||
{
|
|
||||||
StartInfo = new ProcessStartInfo
|
|
||||||
{
|
|
||||||
FileName = "/bin/bash",
|
|
||||||
Arguments = $"-c \"{escapedArgs}\"",
|
|
||||||
RedirectStandardOutput = true,
|
|
||||||
UseShellExecute = false,
|
|
||||||
CreateNoWindow = true,
|
|
||||||
}
|
|
||||||
};
|
|
||||||
process.Start();
|
|
||||||
string result = process.StandardOutput.ReadToEnd();
|
|
||||||
process.WaitForExit();
|
|
||||||
process.Dispose();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// windows系统命令
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="fileName"></param>
|
|
||||||
/// <param name="args"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public static string Cmd(string fileName, string args)
|
|
||||||
{
|
|
||||||
string output = string.Empty;
|
|
||||||
|
|
||||||
var info = new ProcessStartInfo();
|
|
||||||
info.FileName = fileName;
|
|
||||||
info.Arguments = args;
|
|
||||||
info.RedirectStandardOutput = true;
|
|
||||||
|
|
||||||
using (var process = Process.Start(info))
|
|
||||||
{
|
|
||||||
output = process.StandardOutput.ReadToEnd();
|
|
||||||
}
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
using System.Diagnostics;
|
|
||||||
using System.Text;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using Volo.Abp.DependencyInjection;
|
|
||||||
using Volo.Abp.Modularity;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Core.Modularity;
|
|
||||||
|
|
||||||
[Dependency(ReplaceServices =true)]
|
|
||||||
public class YiModuleManager : ModuleManager, IModuleManager, ISingletonDependency
|
|
||||||
{
|
|
||||||
private readonly IModuleContainer _moduleContainer;
|
|
||||||
private readonly IEnumerable<IModuleLifecycleContributor> _lifecycleContributors;
|
|
||||||
private readonly ILogger<YiModuleManager> _logger;
|
|
||||||
|
|
||||||
public YiModuleManager(IModuleContainer moduleContainer, ILogger<YiModuleManager> logger, IOptions<AbpModuleLifecycleOptions> options, IServiceProvider serviceProvider) : base(moduleContainer, logger, options, serviceProvider)
|
|
||||||
{
|
|
||||||
_moduleContainer = moduleContainer;
|
|
||||||
_logger = logger;
|
|
||||||
_lifecycleContributors = options.Value.Contributors.Select(serviceProvider.GetRequiredService).Cast<IModuleLifecycleContributor>().ToArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task InitializeModulesAsync(ApplicationInitializationContext context)
|
|
||||||
{
|
|
||||||
|
|
||||||
_logger.LogDebug("==========模块Initialize初始化统计-跳过0ms模块==========");
|
|
||||||
var total = 0;
|
|
||||||
var watch =new Stopwatch();
|
|
||||||
long totalTime = 0;
|
|
||||||
foreach (var contributor in _lifecycleContributors)
|
|
||||||
{
|
|
||||||
foreach (var module in _moduleContainer.Modules)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
watch.Restart();
|
|
||||||
await contributor.InitializeAsync(context, module.Instance);
|
|
||||||
watch.Stop();
|
|
||||||
totalTime += watch.ElapsedMilliseconds;
|
|
||||||
total++;
|
|
||||||
if (watch.ElapsedMilliseconds > 1)
|
|
||||||
{
|
|
||||||
_logger.LogDebug($"耗时-{watch.ElapsedMilliseconds}ms,已加载模块-{module.Assembly.GetName().Name}");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
throw new AbpInitializationException($"An error occurred during the initialize {contributor.GetType().FullName} phase of the module {module.Type.AssemblyQualifiedName}: {ex.Message}. See the inner exception for details.", ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_logger.LogInformation($"==========【{total}】个模块初始化执行完毕,总耗时【{totalTime}ms】==========");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
<Import Project="..\..\common.props" />
|
|
||||||
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
|
||||||
<PackageReference Include="Volo.Abp.Core" Version="$(AbpVersion)" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
using Volo.Abp.Modularity;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Core
|
|
||||||
{
|
|
||||||
public class YiFrameworkCoreModule:AbpModule
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
using Volo.Abp;
|
|
||||||
using Volo.Abp.Application.Services;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Ddd.Application.Contracts
|
|
||||||
{
|
|
||||||
public interface IDeletesAppService<in TKey> : IDeleteAppService< TKey> , IApplicationService, IRemoteService
|
|
||||||
{
|
|
||||||
Task DeleteAsync(IEnumerable<TKey> ids);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
using Volo.Abp.Application.Dtos;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Ddd.Application.Contracts
|
|
||||||
{
|
|
||||||
public interface IPageTimeResultRequestDto : IPagedAndSortedResultRequest
|
|
||||||
{
|
|
||||||
DateTime? StartTime { get; set; }
|
|
||||||
DateTime? EndTime { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
using Volo.Abp.Application.Dtos;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Ddd.Application.Contracts
|
|
||||||
{
|
|
||||||
public interface IPagedAllResultRequestDto : IPageTimeResultRequestDto, IPagedAndSortedResultRequest
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Volo.Abp.Application.Services;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Ddd.Application.Contracts
|
|
||||||
{
|
|
||||||
public interface IYiCrudAppService<TEntityDto, in TKey> : ICrudAppService<TEntityDto, TKey>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IYiCrudAppService<TEntityDto, in TKey, in TGetListInput> : ICrudAppService<TEntityDto, TKey, TGetListInput>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IYiCrudAppService<TEntityDto, in TKey, in TGetListInput, in TCreateInput> : ICrudAppService<TEntityDto, TKey, TGetListInput, TCreateInput>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IYiCrudAppService<TEntityDto, in TKey, in TGetListInput, in TCreateInput, in TUpdateInput> : ICrudAppService<TEntityDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public interface IYiCrudAppService<TGetOutputDto, TGetListOutputDto, in TKey, in TGetListInput, in TCreateInput, in TUpdateInput> : ICrudAppService<TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TCreateInput, TUpdateInput>, IDeletesAppService<TKey>
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
using Volo.Abp.Application.Dtos;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Ddd.Application.Contracts
|
|
||||||
{
|
|
||||||
public class PagedAllResultRequestDto : PagedAndSortedResultRequestDto, IPagedAllResultRequestDto
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 查询开始时间条件
|
|
||||||
/// </summary>
|
|
||||||
public DateTime? StartTime { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 查询结束时间条件
|
|
||||||
/// </summary>
|
|
||||||
public DateTime? EndTime { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
<Import Project="..\..\common.props" />
|
|
||||||
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Volo.Abp.Ddd.Application.Contracts" Version="$(AbpVersion)" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\Yi.Framework.Core\Yi.Framework.Core.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
using Volo.Abp.Application;
|
|
||||||
using Volo.Abp.Modularity;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Ddd.Application.Contracts
|
|
||||||
{
|
|
||||||
[DependsOn(typeof(AbpDddApplicationContractsModule))]
|
|
||||||
public class YiFrameworkDddApplicationContractsModule : AbpModule
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
<Import Project="..\..\common.props" />
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="MiniExcel" Version="1.31.3" />
|
|
||||||
<PackageReference Include="Volo.Abp.Ddd.Application" Version="$(AbpVersion)" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\Yi.Framework.Ddd.Application.Contracts\Yi.Framework.Ddd.Application.Contracts.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
using Volo.Abp.Application.Dtos;
|
|
||||||
using Volo.Abp.Caching;
|
|
||||||
using Volo.Abp.Domain.Entities;
|
|
||||||
using Volo.Abp.Domain.Repositories;
|
|
||||||
using Volo.Abp.MultiTenancy;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Ddd.Application
|
|
||||||
{
|
|
||||||
public abstract class YiCacheCrudAppService<TEntity, TEntityDto, TKey> : YiCrudAppService<TEntity, TEntityDto, TKey, PagedAndSortedResultRequestDto>
|
|
||||||
where TEntity : class, IEntity<TKey>
|
|
||||||
where TEntityDto : IEntityDto<TKey>
|
|
||||||
{
|
|
||||||
protected YiCacheCrudAppService(IRepository<TEntity, TKey> repository) : base(repository)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class YiCacheCrudAppService<TEntity, TEntityDto, TKey, TGetListInput>
|
|
||||||
: YiCrudAppService<TEntity, TEntityDto, TKey, TGetListInput, TEntityDto>
|
|
||||||
where TEntity : class, IEntity<TKey>
|
|
||||||
where TEntityDto : IEntityDto<TKey>
|
|
||||||
{
|
|
||||||
protected YiCacheCrudAppService(IRepository<TEntity, TKey> repository) : base(repository)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public abstract class YiCacheCrudAppService<TEntity, TEntityDto, TKey, TGetListInput, TCreateInput>
|
|
||||||
: YiCrudAppService<TEntity, TEntityDto, TKey, TGetListInput, TCreateInput, TCreateInput>
|
|
||||||
where TEntity : class, IEntity<TKey>
|
|
||||||
where TEntityDto : IEntityDto<TKey>
|
|
||||||
{
|
|
||||||
protected YiCacheCrudAppService(IRepository<TEntity, TKey> repository) : base(repository)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class YiCacheCrudAppService<TEntity, TEntityDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
|
|
||||||
: YiCrudAppService<TEntity, TEntityDto, TEntityDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
|
|
||||||
where TEntity : class, IEntity<TKey>
|
|
||||||
where TEntityDto : IEntityDto<TKey>
|
|
||||||
{
|
|
||||||
protected YiCacheCrudAppService(IRepository<TEntity, TKey> repository) : base(repository)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public abstract class YiCacheCrudAppService<TEntity, TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
|
|
||||||
: YiCrudAppService<TEntity, TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
|
|
||||||
where TEntity : class, IEntity<TKey>
|
|
||||||
where TGetOutputDto : IEntityDto<TKey>
|
|
||||||
where TGetListOutputDto : IEntityDto<TKey>
|
|
||||||
{
|
|
||||||
protected IDistributedCache<TEntity> Cache => LazyServiceProvider.LazyGetRequiredService<IDistributedCache<TEntity>>();
|
|
||||||
|
|
||||||
protected string GetCacheKey(TKey id) => typeof(TEntity).Name + ":" + CurrentTenant.Id ?? Guid.Empty + ":" + id.ToString();
|
|
||||||
protected YiCacheCrudAppService(IRepository<TEntity, TKey> repository) : base(repository)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task<TGetOutputDto> UpdateAsync(TKey id, TUpdateInput input)
|
|
||||||
{
|
|
||||||
var output = await base.UpdateAsync(id, input);
|
|
||||||
await Cache.RemoveAsync(GetCacheKey(id));
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task<PagedResultDto<TGetListOutputDto>> GetListAsync(TGetListInput input)
|
|
||||||
{
|
|
||||||
//两种方式:
|
|
||||||
//1:全表缓存,使用缓存直接查询
|
|
||||||
//2:非全部缓存,查询到的数据直接添加到缓存
|
|
||||||
|
|
||||||
//判断是否该实体为全表缓存
|
|
||||||
throw new NotImplementedException();
|
|
||||||
|
|
||||||
//IDistributedCache 有局限性,条件查询无法进行缓存了
|
|
||||||
//if (true)
|
|
||||||
//{
|
|
||||||
// return await GetListByCacheAsync(input);
|
|
||||||
//}
|
|
||||||
//else
|
|
||||||
//{
|
|
||||||
// return await GetListByDbAsync(input);
|
|
||||||
//}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual async Task<PagedResultDto<TGetListOutputDto>> GetListByDbAsync(TGetListInput input)
|
|
||||||
{
|
|
||||||
//如果不是全表缓存,可以走这个啦
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
protected virtual async Task<PagedResultDto<TGetListOutputDto>> GetListByCacheAsync(TGetListInput input)
|
|
||||||
{
|
|
||||||
//如果是全表缓存,可以走这个啦
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected override async Task<TEntity> GetEntityByIdAsync(TKey id)
|
|
||||||
{
|
|
||||||
var output = await Cache.GetOrAddAsync(GetCacheKey(id), async () => await base.GetEntityByIdAsync(id));
|
|
||||||
return output!;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override async Task DeleteAsync(IEnumerable<TKey> id)
|
|
||||||
{
|
|
||||||
await base.DeleteAsync(id);
|
|
||||||
foreach (var itemId in id)
|
|
||||||
{
|
|
||||||
await Cache.RemoveAsync(GetCacheKey(itemId));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
|
||||||
using MiniExcelLibs;
|
|
||||||
using Volo.Abp;
|
|
||||||
using Volo.Abp.Application.Dtos;
|
|
||||||
using Volo.Abp.Application.Services;
|
|
||||||
using Volo.Abp.Domain.Entities;
|
|
||||||
using Volo.Abp.Domain.Repositories;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Ddd.Application
|
|
||||||
{
|
|
||||||
public abstract class YiCrudAppService<TEntity, TEntityDto, TKey> : YiCrudAppService<TEntity, TEntityDto, TKey, PagedAndSortedResultRequestDto>
|
|
||||||
where TEntity : class, IEntity<TKey>
|
|
||||||
where TEntityDto : IEntityDto<TKey>
|
|
||||||
{
|
|
||||||
protected YiCrudAppService(IRepository<TEntity, TKey> repository) : base(repository)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class YiCrudAppService<TEntity, TEntityDto, TKey, TGetListInput>
|
|
||||||
: YiCrudAppService<TEntity, TEntityDto, TKey, TGetListInput, TEntityDto>
|
|
||||||
where TEntity : class, IEntity<TKey>
|
|
||||||
where TEntityDto : IEntityDto<TKey>
|
|
||||||
{
|
|
||||||
protected YiCrudAppService(IRepository<TEntity, TKey> repository) : base(repository)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public abstract class YiCrudAppService<TEntity, TEntityDto, TKey, TGetListInput, TCreateInput>
|
|
||||||
: YiCrudAppService<TEntity, TEntityDto, TKey, TGetListInput, TCreateInput, TCreateInput>
|
|
||||||
where TEntity : class, IEntity<TKey>
|
|
||||||
where TEntityDto : IEntityDto<TKey>
|
|
||||||
{
|
|
||||||
protected YiCrudAppService(IRepository<TEntity, TKey> repository) : base(repository)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract class YiCrudAppService<TEntity, TEntityDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
|
|
||||||
: YiCrudAppService<TEntity, TEntityDto, TEntityDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
|
|
||||||
where TEntity : class, IEntity<TKey>
|
|
||||||
where TEntityDto : IEntityDto<TKey>
|
|
||||||
{
|
|
||||||
protected YiCrudAppService(IRepository<TEntity, TKey> repository) : base(repository)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public abstract class YiCrudAppService<TEntity, TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
|
|
||||||
: CrudAppService<TEntity, TGetOutputDto, TGetListOutputDto, TKey, TGetListInput, TCreateInput, TUpdateInput>
|
|
||||||
where TEntity : class, IEntity<TKey>
|
|
||||||
where TGetOutputDto : IEntityDto<TKey>
|
|
||||||
where TGetListOutputDto : IEntityDto<TKey>
|
|
||||||
{
|
|
||||||
protected YiCrudAppService(IRepository<TEntity, TKey> repository) : base(repository)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 多查
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public override async Task<PagedResultDto<TGetListOutputDto>> GetListAsync(TGetListInput input)
|
|
||||||
{
|
|
||||||
List<TEntity>? entites = null;
|
|
||||||
//区分多查还是批量查
|
|
||||||
if (input is IPagedResultRequest pagedInput)
|
|
||||||
{
|
|
||||||
entites = await Repository.GetPagedListAsync(pagedInput.SkipCount, pagedInput.MaxResultCount, string.Empty);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
entites = await Repository.GetListAsync();
|
|
||||||
}
|
|
||||||
var total = await Repository.GetCountAsync();
|
|
||||||
var output = await MapToGetListOutputDtosAsync(entites);
|
|
||||||
return new PagedResultDto<TGetListOutputDto>(total, output);
|
|
||||||
//throw new NotImplementedException($"【{typeof(TEntity)}】实体的CrudAppService,查询为具体业务,通用查询几乎无实际场景,请重写实现!");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 多删
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[RemoteService(isEnabled: true)]
|
|
||||||
public virtual async Task DeleteAsync(IEnumerable<TKey> id)
|
|
||||||
{
|
|
||||||
await Repository.DeleteManyAsync(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 偷梁换柱
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="id"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
[RemoteService(isEnabled: false)]
|
|
||||||
public override Task DeleteAsync(TKey id)
|
|
||||||
{
|
|
||||||
return base.DeleteAsync(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 导出excel
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public virtual async Task<IActionResult> GetExportExcelAsync(TGetListInput input)
|
|
||||||
{
|
|
||||||
if (input is IPagedResultRequest paged)
|
|
||||||
{
|
|
||||||
paged.SkipCount = 0;
|
|
||||||
paged.MaxResultCount = LimitedResultRequestDto.MaxMaxResultCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
var output = await this.GetListAsync(input);
|
|
||||||
var dirPath = $"/wwwroot/temp";
|
|
||||||
|
|
||||||
var fileName = $"{typeof(TEntity).Name}_{DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss")}_{Guid.NewGuid()}";
|
|
||||||
var filePath = $"{dirPath}/{fileName}.xlsx";
|
|
||||||
if (!Directory.Exists(dirPath))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(dirPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
MiniExcel.SaveAs(filePath, output.Items);
|
|
||||||
return new PhysicalFileResult(filePath, "application/vnd.ms-excel");
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 导入excle
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="input"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
public virtual async Task PostImportExcelAsync(List<TCreateInput> input)
|
|
||||||
{
|
|
||||||
var entities = input.Select(x => MapToEntity(x)).ToList();
|
|
||||||
//安全起见,该接口需要自己实现
|
|
||||||
throw new NotImplementedException();
|
|
||||||
//await Repository.DeleteManyAsync(entities.Select(x => x.Id));
|
|
||||||
//await Repository.InsertManyAsync(entities);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
using Volo.Abp;
|
|
||||||
using Volo.Abp.Application;
|
|
||||||
using Volo.Abp.Application.Dtos;
|
|
||||||
using Volo.Abp.Modularity;
|
|
||||||
using Yi.Framework.Ddd.Application.Contracts;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Ddd.Application
|
|
||||||
{
|
|
||||||
[DependsOn(typeof(AbpDddApplicationModule),
|
|
||||||
typeof(YiFrameworkDddApplicationContractsModule))]
|
|
||||||
public class YiFrameworkDddApplicationModule : AbpModule
|
|
||||||
{
|
|
||||||
public override void OnApplicationInitialization(ApplicationInitializationContext context)
|
|
||||||
{
|
|
||||||
//分页限制
|
|
||||||
LimitedResultRequestDto.DefaultMaxResultCount = 10;
|
|
||||||
LimitedResultRequestDto.MaxMaxResultCount = 10000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Mapster;
|
|
||||||
using Volo.Abp.ObjectMapping;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Mapster
|
|
||||||
{
|
|
||||||
public class MapsterAutoObjectMappingProvider : IAutoObjectMappingProvider
|
|
||||||
{
|
|
||||||
public TDestination Map<TSource, TDestination>(object source)
|
|
||||||
{
|
|
||||||
var sss = typeof(TDestination).Name;
|
|
||||||
return source.Adapt<TDestination>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public TDestination Map<TSource, TDestination>(TSource source, TDestination destination)
|
|
||||||
{
|
|
||||||
return source.Adapt<TSource, TDestination>(destination);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Volo.Abp.ObjectMapping;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Mapster
|
|
||||||
{
|
|
||||||
public class MapsterObjectMapper : IObjectMapper
|
|
||||||
{
|
|
||||||
public IAutoObjectMappingProvider AutoObjectMappingProvider => throw new NotImplementedException();
|
|
||||||
|
|
||||||
public TDestination Map<TSource, TDestination>(TSource source)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public TDestination Map<TSource, TDestination>(TSource source, TDestination destination)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
<Import Project="..\..\common.props" />
|
|
||||||
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="Mapster" Version="7.4.0" />
|
|
||||||
<PackageReference Include="Volo.Abp.ObjectMapping" Version="$(AbpVersion)" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\Yi.Framework.Core\Yi.Framework.Core.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
using MapsterMapper;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
|
||||||
using Volo.Abp.Modularity;
|
|
||||||
using Volo.Abp.ObjectMapping;
|
|
||||||
using Yi.Framework.Core;
|
|
||||||
|
|
||||||
namespace Yi.Framework.Mapster
|
|
||||||
{
|
|
||||||
[DependsOn(typeof(YiFrameworkCoreModule),
|
|
||||||
|
|
||||||
typeof(AbpObjectMappingModule)
|
|
||||||
)]
|
|
||||||
public class YiFrameworkMapsterModule : AbpModule
|
|
||||||
{
|
|
||||||
public override void ConfigureServices(ServiceConfigurationContext context)
|
|
||||||
{
|
|
||||||
context.Services.AddTransient<IAutoObjectMappingProvider, MapsterAutoObjectMappingProvider>();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
using SqlSugar;
|
|
||||||
|
|
||||||
namespace Yi.Framework.SqlSugarCore.Abstractions
|
|
||||||
{
|
|
||||||
public class DbConnOptions
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// 连接字符串(如果开启多租户,也就是默认库了),必填
|
|
||||||
/// </summary>
|
|
||||||
public string? Url { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 数据库类型
|
|
||||||
/// </summary>
|
|
||||||
public DbType? DbType { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 开启种子数据
|
|
||||||
/// </summary>
|
|
||||||
public bool EnabledDbSeed { get; set; } = false;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 开启codefirst
|
|
||||||
/// </summary>
|
|
||||||
public bool EnabledCodeFirst { get; set; } = false;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 开启sql日志
|
|
||||||
/// </summary>
|
|
||||||
public bool EnabledSqlLog { get; set; } = true;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 实体程序集
|
|
||||||
/// </summary>
|
|
||||||
public List<string>? EntityAssembly { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 开启读写分离
|
|
||||||
/// </summary>
|
|
||||||
public bool EnabledReadWrite { get; set; } = false;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 读写分离
|
|
||||||
/// </summary>
|
|
||||||
public List<string>? ReadUrl { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 开启Saas多租户
|
|
||||||
/// </summary>
|
|
||||||
public bool EnabledSaasMultiTenancy { get; set; } = false;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Yi.Framework.SqlSugarCore.Abstractions
|
|
||||||
{
|
|
||||||
[AttributeUsage(AttributeTargets.Class)]
|
|
||||||
public class DefaultTenantTableAttribute : Attribute
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using SqlSugar;
|
|
||||||
|
|
||||||
namespace Yi.Framework.SqlSugarCore.Abstractions
|
|
||||||
{
|
|
||||||
public interface ISqlSugarDbConnectionCreator
|
|
||||||
{
|
|
||||||
DbConnOptions Options { get; }
|
|
||||||
Action<ISqlSugarClient> OnSqlSugarClientConfig { get; set; }
|
|
||||||
Action<object, DataAfterModel> DataExecuted { get; set; }
|
|
||||||
Action<object, DataFilterModel> DataExecuting { get; set; }
|
|
||||||
Action<string, SugarParameter[]> OnLogExecuting { get; set; }
|
|
||||||
Action<string, SugarParameter[]> OnLogExecuted { get; set; }
|
|
||||||
Action<PropertyInfo, EntityColumnInfo> EntityService { get; set; }
|
|
||||||
|
|
||||||
ConnectionConfig Build(Action<ConnectionConfig>? action = null);
|
|
||||||
void SetDbAop(ISqlSugarClient currentDb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using SqlSugar;
|
|
||||||
using Volo.Abp.DependencyInjection;
|
|
||||||
|
|
||||||
namespace Yi.Framework.SqlSugarCore.Abstractions
|
|
||||||
{
|
|
||||||
public interface ISqlSugarDbContext
|
|
||||||
{
|
|
||||||
// IAbpLazyServiceProvider LazyServiceProvider { get; set; }
|
|
||||||
ISqlSugarClient SqlSugarClient { get; }
|
|
||||||
DbConnOptions Options { get; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 数据库备份
|
|
||||||
/// </summary>
|
|
||||||
void BackupDataBase();
|
|
||||||
void SetSqlSugarClient(ISqlSugarClient sqlSugarClient);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,88 +0,0 @@
|
|||||||
using System.Linq.Expressions;
|
|
||||||
using SqlSugar;
|
|
||||||
using Volo.Abp.Domain.Entities;
|
|
||||||
using Volo.Abp.Domain.Repositories;
|
|
||||||
|
|
||||||
namespace Yi.Framework.SqlSugarCore.Abstractions
|
|
||||||
{
|
|
||||||
|
|
||||||
public interface ISqlSugarRepository<TEntity>:IRepository<TEntity> where TEntity : class, IEntity,new ()
|
|
||||||
{
|
|
||||||
ISqlSugarClient _Db { get; }
|
|
||||||
ISugarQueryable<TEntity> _DbQueryable { get; }
|
|
||||||
|
|
||||||
Task<ISqlSugarClient> GetDbContextAsync();
|
|
||||||
Task<IDeleteable<TEntity>> AsDeleteable();
|
|
||||||
Task<IInsertable<TEntity>> AsInsertable(List<TEntity> insertObjs);
|
|
||||||
Task<IInsertable<TEntity>> AsInsertable(TEntity insertObj);
|
|
||||||
Task<IInsertable<TEntity>> AsInsertable(TEntity[] insertObjs);
|
|
||||||
Task<ISugarQueryable<TEntity>> AsQueryable();
|
|
||||||
Task<ISqlSugarClient> AsSugarClient();
|
|
||||||
Task<ITenant> AsTenant();
|
|
||||||
Task<IUpdateable<TEntity>> AsUpdateable(List<TEntity> updateObjs);
|
|
||||||
Task<IUpdateable<TEntity>> AsUpdateable(TEntity updateObj);
|
|
||||||
Task<IUpdateable<TEntity>> AsUpdateable();
|
|
||||||
Task<IUpdateable<TEntity>> AsUpdateable(TEntity[] updateObjs);
|
|
||||||
|
|
||||||
#region 单查
|
|
||||||
//单查
|
|
||||||
Task<TEntity> GetByIdAsync(dynamic id);
|
|
||||||
Task<TEntity> GetSingleAsync(Expression<Func<TEntity, bool>> whereExpression);
|
|
||||||
Task<TEntity> GetFirstAsync(Expression<Func<TEntity, bool>> whereExpression);
|
|
||||||
Task<bool> IsAnyAsync(Expression<Func<TEntity, bool>> whereExpression);
|
|
||||||
Task<int> CountAsync(Expression<Func<TEntity, bool>> whereExpression);
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region 多查
|
|
||||||
//多查
|
|
||||||
Task<List<TEntity>> GetListAsync();
|
|
||||||
Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> whereExpression);
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region 分页查
|
|
||||||
//分页查
|
|
||||||
Task<List<TEntity>> GetPageListAsync(Expression<Func<TEntity, bool>> whereExpression, int pageNum, int pageSize);
|
|
||||||
Task<List<TEntity>> GetPageListAsync(Expression<Func<TEntity, bool>> whereExpression, int pageNum, int pageSize, Expression<Func<TEntity, object>>? orderByExpression = null, OrderByType orderByType = OrderByType.Asc);
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 插入
|
|
||||||
//插入
|
|
||||||
Task<bool> InsertAsync(TEntity insertObj);
|
|
||||||
Task<bool> InsertOrUpdateAsync(TEntity data);
|
|
||||||
Task<bool> InsertOrUpdateAsync(List<TEntity> datas);
|
|
||||||
Task<int> InsertReturnIdentityAsync(TEntity insertObj);
|
|
||||||
Task<long> InsertReturnBigIdentityAsync(TEntity insertObj);
|
|
||||||
Task<long> InsertReturnSnowflakeIdAsync(TEntity insertObj);
|
|
||||||
Task<TEntity> InsertReturnEntityAsync(TEntity insertObj);
|
|
||||||
Task<bool> InsertRangeAsync(List<TEntity> insertObjs);
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region 更新
|
|
||||||
//更新
|
|
||||||
Task<bool> UpdateAsync(TEntity updateObj);
|
|
||||||
Task<bool> UpdateRangeAsync(List<TEntity> updateObjs);
|
|
||||||
Task<bool> UpdateAsync(Expression<Func<TEntity, TEntity>> columns, Expression<Func<TEntity, bool>> whereExpression);
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 删除
|
|
||||||
//删除
|
|
||||||
Task<bool> DeleteAsync(TEntity deleteObj);
|
|
||||||
Task<bool> DeleteAsync(List<TEntity> deleteObjs);
|
|
||||||
Task<bool> DeleteAsync(Expression<Func<TEntity, bool>> whereExpression);
|
|
||||||
Task<bool> DeleteByIdAsync(dynamic id);
|
|
||||||
Task<bool> DeleteByIdsAsync(dynamic[] ids);
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public interface ISqlSugarRepository<TEntity, TKey> : ISqlSugarRepository<TEntity>,IRepository<TEntity, TKey> where TEntity : class, IEntity<TKey>, new()
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Yi.Framework.SqlSugarCore.Abstractions
|
|
||||||
{
|
|
||||||
public interface ISugarDbContextProvider<TDbContext>
|
|
||||||
where TDbContext : ISqlSugarDbContext
|
|
||||||
{
|
|
||||||
|
|
||||||
Task<TDbContext> GetDbContextAsync();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace Yi.Framework.SqlSugarCore.Abstractions
|
|
||||||
{
|
|
||||||
[AttributeUsage(AttributeTargets.Class)]
|
|
||||||
public class IgnoreCodeFirstAttribute : Attribute
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
|
||||||
<Import Project="..\..\common.props" />
|
|
||||||
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<PackageReference Include="SqlSugarCoreNoDrive" Version="$(SqlSugarVersion)" />
|
|
||||||
<PackageReference Include="Volo.Abp.Ddd.Domain" Version="$(AbpVersion)" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\Yi.Framework.Core\Yi.Framework.Core.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
using Volo.Abp.Modularity;
|
|
||||||
using Yi.Framework.Core;
|
|
||||||
|
|
||||||
namespace Yi.Framework.SqlSugarCore.Abstractions
|
|
||||||
{
|
|
||||||
[DependsOn(typeof(YiFrameworkCoreModule))]
|
|
||||||
public class YiFrameworkSqlSugarCoreAbstractionsModule : AbpModule
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
|
||||||
|
|
||||||
namespace Yi.Framework.SqlSugarCore
|
|
||||||
{
|
|
||||||
public class AsyncLocalDbContextAccessor
|
|
||||||
{
|
|
||||||
public static AsyncLocalDbContextAccessor Instance { get; } = new();
|
|
||||||
public ISqlSugarDbContext? Current
|
|
||||||
{
|
|
||||||
get => _currentScope.Value;
|
|
||||||
set => _currentScope.Value = value;
|
|
||||||
}
|
|
||||||
public AsyncLocalDbContextAccessor()
|
|
||||||
{
|
|
||||||
_currentScope = new AsyncLocal<ISqlSugarDbContext?>();
|
|
||||||
}
|
|
||||||
private readonly AsyncLocal<ISqlSugarDbContext> _currentScope;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,154 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using SqlSugar;
|
|
||||||
using Volo.Abp.Domain.Entities;
|
|
||||||
using Volo.Abp.Domain.Repositories;
|
|
||||||
using Volo.Abp.Linq;
|
|
||||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
|
||||||
|
|
||||||
namespace Yi.Framework.SqlSugarCore.Repositories
|
|
||||||
{
|
|
||||||
public class SqlSugarObjectRepository<TEntity> : IRepository<TEntity> where TEntity : class, IEntity
|
|
||||||
{
|
|
||||||
public ISqlSugarClient _Db => GetDbContextAsync().Result;
|
|
||||||
private ISugarDbContextProvider<ISqlSugarDbContext> _sugarDbContextProvider;
|
|
||||||
/// <summary>
|
|
||||||
/// 获取DB
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public virtual async Task<ISqlSugarClient> GetDbContextAsync()
|
|
||||||
{
|
|
||||||
|
|
||||||
var db = (await _sugarDbContextProvider.GetDbContextAsync()).SqlSugarClient;
|
|
||||||
//await Console.Out.WriteLineAsync("获取的id:" + db.ContextID);
|
|
||||||
return db;
|
|
||||||
}
|
|
||||||
|
|
||||||
public IAsyncQueryableExecuter AsyncExecuter => throw new NotImplementedException();
|
|
||||||
|
|
||||||
public bool? IsChangeTrackingEnabled => throw new NotImplementedException();
|
|
||||||
|
|
||||||
public Task DeleteAsync(Expression<Func<TEntity, bool>> predicate, bool autoSave = false, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task DeleteAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task DeleteDirectAsync(Expression<Func<TEntity, bool>> predicate, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task DeleteManyAsync(IEnumerable<TEntity> entities, bool autoSave = false, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<TEntity?> FindAsync(Expression<Func<TEntity, bool>> predicate, bool includeDetails = true, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<TEntity> GetAsync(Expression<Func<TEntity, bool>> predicate, bool includeDetails = true, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<long> GetCountAsync(CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> predicate, bool includeDetails = false, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<List<TEntity>> GetListAsync(bool includeDetails = false, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<List<TEntity>> GetPagedListAsync(int skipCount, int maxResultCount, string sorting, bool includeDetails = false, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<IQueryable<TEntity>> GetQueryableAsync()
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task<TEntity> InsertAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
await (await GetDbContextAsync()).InsertableByObject(entity).ExecuteCommandAsync();
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task InsertManyAsync(IEnumerable<TEntity> entities, bool autoSave = false, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<TEntity> UpdateAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task UpdateManyAsync(IEnumerable<TEntity> entities, bool autoSave = false, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public IQueryable<TEntity> WithDetails()
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public IQueryable<TEntity> WithDetails(params Expression<Func<TEntity, object>>[] propertySelectors)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<IQueryable<TEntity>> WithDetailsAsync()
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<IQueryable<TEntity>> WithDetailsAsync(params Expression<Func<TEntity, object>>[] propertySelectors)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class SqlSugarObjectRepository<TEntity, TKey> : SqlSugarObjectRepository<TEntity>, IRepository<TEntity, TKey> where TEntity : class, IEntity<TKey>
|
|
||||||
{
|
|
||||||
public Task DeleteAsync(TKey id, bool autoSave = false, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task DeleteManyAsync(IEnumerable<TKey> ids, bool autoSave = false, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<TEntity?> FindAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<TEntity> GetAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,419 +0,0 @@
|
|||||||
using System.Linq;
|
|
||||||
using System.Linq.Expressions;
|
|
||||||
using SqlSugar;
|
|
||||||
using Volo.Abp;
|
|
||||||
using Volo.Abp.Auditing;
|
|
||||||
using Volo.Abp.Domain.Entities;
|
|
||||||
using Volo.Abp.Domain.Repositories;
|
|
||||||
using Volo.Abp.Linq;
|
|
||||||
using Yi.Framework.Core.Helper;
|
|
||||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
|
||||||
|
|
||||||
namespace Yi.Framework.SqlSugarCore.Repositories
|
|
||||||
{
|
|
||||||
public class SqlSugarRepository<TEntity> : ISqlSugarRepository<TEntity>, IRepository<TEntity> where TEntity : class, IEntity, new()
|
|
||||||
{
|
|
||||||
public ISqlSugarClient _Db => GetDbContextAsync().Result;
|
|
||||||
|
|
||||||
public ISugarQueryable<TEntity> _DbQueryable => GetDbContextAsync().Result.Queryable<TEntity>();
|
|
||||||
|
|
||||||
private ISugarDbContextProvider<ISqlSugarDbContext> _sugarDbContextProvider;
|
|
||||||
public IAsyncQueryableExecuter AsyncExecuter { get; }
|
|
||||||
|
|
||||||
public bool? IsChangeTrackingEnabled => false;
|
|
||||||
|
|
||||||
public SqlSugarRepository(ISugarDbContextProvider<ISqlSugarDbContext> sugarDbContextProvider)
|
|
||||||
{
|
|
||||||
_sugarDbContextProvider = sugarDbContextProvider;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取DB
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public virtual async Task<ISqlSugarClient> GetDbContextAsync()
|
|
||||||
{
|
|
||||||
|
|
||||||
var db = (await _sugarDbContextProvider.GetDbContextAsync()).SqlSugarClient;
|
|
||||||
//await Console.Out.WriteLineAsync("获取的id:" + db.ContextID);
|
|
||||||
return db;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 获取简单Db
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
public virtual async Task<SimpleClient<TEntity>> GetDbSimpleClientAsync()
|
|
||||||
{
|
|
||||||
var db = await GetDbContextAsync();
|
|
||||||
return new SimpleClient<TEntity>(db);
|
|
||||||
}
|
|
||||||
|
|
||||||
#region Abp模块
|
|
||||||
|
|
||||||
public virtual async Task<TEntity?> FindAsync(Expression<Func<TEntity, bool>> predicate, bool includeDetails = true, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
return await GetFirstAsync(predicate);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<TEntity> GetAsync(Expression<Func<TEntity, bool>> predicate, bool includeDetails = true, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
return await GetFirstAsync(predicate);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task DeleteAsync(Expression<Func<TEntity, bool>> predicate, bool autoSave = false, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
await this.DeleteAsync(predicate);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task DeleteDirectAsync(Expression<Func<TEntity, bool>> predicate, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
await this.DeleteAsync(predicate);
|
|
||||||
}
|
|
||||||
|
|
||||||
public IQueryable<TEntity> WithDetails()
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public IQueryable<TEntity> WithDetails(params Expression<Func<TEntity, object>>[] propertySelectors)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<IQueryable<TEntity>> WithDetailsAsync()
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<IQueryable<TEntity>> WithDetailsAsync(params Expression<Func<TEntity, object>>[] propertySelectors)
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<IQueryable<TEntity>> GetQueryableAsync()
|
|
||||||
{
|
|
||||||
throw new NotImplementedException();
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> predicate, bool includeDetails = false, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
return await GetListAsync(predicate);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<TEntity> InsertAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
return await InsertReturnEntityAsync(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task InsertManyAsync(IEnumerable<TEntity> entities, bool autoSave = false, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
await InsertRangeAsync(entities.ToList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<TEntity> UpdateAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
await UpdateAsync(entity);
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task UpdateManyAsync(IEnumerable<TEntity> entities, bool autoSave = false, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
await UpdateRangeAsync(entities.ToList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task DeleteAsync(TEntity entity, bool autoSave = false, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
await DeleteAsync(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task DeleteManyAsync(IEnumerable<TEntity> entities, bool autoSave = false, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
await DeleteAsync(entities.ToList());
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<List<TEntity>> GetListAsync(bool includeDetails = false, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
return await GetListAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<long> GetCountAsync(CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
return await this.CountAsync(_=>true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<List<TEntity>> GetPagedListAsync(int skipCount, int maxResultCount, string sorting, bool includeDetails = false, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
return await GetPageListAsync(_ => true, skipCount, maxResultCount);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
|
|
||||||
#region 内置DB快捷操作
|
|
||||||
public virtual async Task<IDeleteable<TEntity>> AsDeleteable()
|
|
||||||
{
|
|
||||||
return (await GetDbSimpleClientAsync()).AsDeleteable();
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<IInsertable<TEntity>> AsInsertable(List<TEntity> insertObjs)
|
|
||||||
{
|
|
||||||
return (await GetDbSimpleClientAsync()).AsInsertable(insertObjs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<IInsertable<TEntity>> AsInsertable(TEntity insertObj)
|
|
||||||
{
|
|
||||||
return (await GetDbSimpleClientAsync()).AsInsertable(insertObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<IInsertable<TEntity>> AsInsertable(TEntity[] insertObjs)
|
|
||||||
{
|
|
||||||
return (await GetDbSimpleClientAsync()).AsInsertable(insertObjs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<ISugarQueryable<TEntity>> AsQueryable()
|
|
||||||
{
|
|
||||||
return (await GetDbSimpleClientAsync()).AsQueryable();
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<ISqlSugarClient> AsSugarClient()
|
|
||||||
{
|
|
||||||
return (await GetDbSimpleClientAsync()).AsSugarClient();
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<ITenant> AsTenant()
|
|
||||||
{
|
|
||||||
return (await GetDbSimpleClientAsync()).AsTenant();
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<IUpdateable<TEntity>> AsUpdateable(List<TEntity> updateObjs)
|
|
||||||
{
|
|
||||||
return (await GetDbSimpleClientAsync()).AsUpdateable(updateObjs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<IUpdateable<TEntity>> AsUpdateable(TEntity updateObj)
|
|
||||||
{
|
|
||||||
return (await GetDbSimpleClientAsync()).AsUpdateable(updateObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<IUpdateable<TEntity>> AsUpdateable()
|
|
||||||
{
|
|
||||||
return (await GetDbSimpleClientAsync()).AsUpdateable();
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<IUpdateable<TEntity>> AsUpdateable(TEntity[] updateObjs)
|
|
||||||
{
|
|
||||||
return (await GetDbSimpleClientAsync()).AsUpdateable(updateObjs);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region SimpleClient模块
|
|
||||||
public virtual async Task<int> CountAsync(Expression<Func<TEntity, bool>> whereExpression)
|
|
||||||
{
|
|
||||||
return await (await GetDbSimpleClientAsync()).CountAsync(whereExpression);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<bool> DeleteAsync(TEntity deleteObj)
|
|
||||||
{
|
|
||||||
if (deleteObj is ISoftDelete)
|
|
||||||
{
|
|
||||||
ReflexHelper.SetModelValue(nameof(ISoftDelete.IsDeleted), true, deleteObj);
|
|
||||||
return await (await GetDbSimpleClientAsync()).UpdateAsync(deleteObj);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return await (await GetDbSimpleClientAsync()).DeleteAsync(deleteObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<bool> DeleteAsync(List<TEntity> deleteObjs)
|
|
||||||
{
|
|
||||||
if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity)))
|
|
||||||
{
|
|
||||||
deleteObjs.ForEach(e => ReflexHelper.SetModelValue(nameof(ISoftDelete.IsDeleted), true, e));
|
|
||||||
return await (await GetDbSimpleClientAsync()).UpdateRangeAsync(deleteObjs);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return await (await GetDbSimpleClientAsync()).DeleteAsync(deleteObjs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<bool> DeleteAsync(Expression<Func<TEntity, bool>> whereExpression)
|
|
||||||
{
|
|
||||||
if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity)))
|
|
||||||
{
|
|
||||||
return await (await GetDbSimpleClientAsync()).AsUpdateable().SetColumns(nameof(ISoftDelete), true).Where(whereExpression).ExecuteCommandAsync() > 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return await (await GetDbSimpleClientAsync()).DeleteAsync(whereExpression);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<bool> DeleteByIdAsync(dynamic id)
|
|
||||||
{
|
|
||||||
if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity)))
|
|
||||||
{
|
|
||||||
var entity = await GetByIdAsync(id);
|
|
||||||
//反射赋值
|
|
||||||
ReflexHelper.SetModelValue(nameof(ISoftDelete.IsDeleted), true, entity);
|
|
||||||
return await UpdateAsync(entity);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return await (await GetDbSimpleClientAsync()).DeleteByIdAsync(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<bool> DeleteByIdsAsync(dynamic[] ids)
|
|
||||||
{
|
|
||||||
if (typeof(ISoftDelete).IsAssignableFrom(typeof(TEntity)))
|
|
||||||
{
|
|
||||||
var simpleClient = (await GetDbSimpleClientAsync());
|
|
||||||
var entities = await simpleClient.AsQueryable().In(ids).ToListAsync();
|
|
||||||
if (entities.Count == 0)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
//反射赋值
|
|
||||||
entities.ForEach(e => ReflexHelper.SetModelValue(nameof(ISoftDelete.IsDeleted), true, e));
|
|
||||||
return await UpdateRangeAsync(entities);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return await (await GetDbSimpleClientAsync()).DeleteByIdAsync(ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<TEntity> GetByIdAsync(dynamic id)
|
|
||||||
{
|
|
||||||
return await (await GetDbSimpleClientAsync()).GetByIdAsync(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public virtual async Task<TEntity> GetFirstAsync(Expression<Func<TEntity, bool>> whereExpression)
|
|
||||||
{
|
|
||||||
return await (await GetDbSimpleClientAsync()).GetFirstAsync(whereExpression);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<List<TEntity>> GetListAsync()
|
|
||||||
{
|
|
||||||
return await (await GetDbSimpleClientAsync()).GetListAsync();
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> whereExpression)
|
|
||||||
{
|
|
||||||
return await (await GetDbSimpleClientAsync()).GetListAsync(whereExpression);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<List<TEntity>> GetPageListAsync(Expression<Func<TEntity, bool>> whereExpression, int pageNum, int pageSize)
|
|
||||||
{
|
|
||||||
return await (await GetDbSimpleClientAsync()).GetPageListAsync(whereExpression, new PageModel() { PageIndex = pageNum, PageSize = pageSize });
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<List<TEntity>> GetPageListAsync(Expression<Func<TEntity, bool>> whereExpression, int pageNum, int pageSize, Expression<Func<TEntity, object>>? orderByExpression = null, OrderByType orderByType = OrderByType.Asc)
|
|
||||||
{
|
|
||||||
return await (await GetDbSimpleClientAsync()).GetPageListAsync(whereExpression, new PageModel { PageIndex = pageNum, PageSize = pageSize }, orderByExpression, orderByType);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<TEntity> GetSingleAsync(Expression<Func<TEntity, bool>> whereExpression)
|
|
||||||
{
|
|
||||||
return await (await GetDbSimpleClientAsync()).GetSingleAsync(whereExpression);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<bool> InsertAsync(TEntity insertObj)
|
|
||||||
{
|
|
||||||
return await (await GetDbSimpleClientAsync()).InsertAsync(insertObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<bool> InsertOrUpdateAsync(TEntity data)
|
|
||||||
{
|
|
||||||
return await (await GetDbSimpleClientAsync()).InsertOrUpdateAsync(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<bool> InsertOrUpdateAsync(List<TEntity> datas)
|
|
||||||
{
|
|
||||||
return await (await GetDbSimpleClientAsync()).InsertOrUpdateAsync(datas);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<bool> InsertRangeAsync(List<TEntity> insertObjs)
|
|
||||||
{
|
|
||||||
return await (await GetDbSimpleClientAsync()).InsertRangeAsync(insertObjs);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<long> InsertReturnBigIdentityAsync(TEntity insertObj)
|
|
||||||
{
|
|
||||||
return await (await GetDbSimpleClientAsync()).InsertReturnBigIdentityAsync(insertObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<TEntity> InsertReturnEntityAsync(TEntity insertObj)
|
|
||||||
{
|
|
||||||
return await (await GetDbSimpleClientAsync()).InsertReturnEntityAsync(insertObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<int> InsertReturnIdentityAsync(TEntity insertObj)
|
|
||||||
{
|
|
||||||
return await (await GetDbSimpleClientAsync()).InsertReturnIdentityAsync(insertObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<long> InsertReturnSnowflakeIdAsync(TEntity insertObj)
|
|
||||||
{
|
|
||||||
return await (await GetDbSimpleClientAsync()).InsertReturnSnowflakeIdAsync(insertObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<bool> IsAnyAsync(Expression<Func<TEntity, bool>> whereExpression)
|
|
||||||
{
|
|
||||||
return await (await GetDbSimpleClientAsync()).IsAnyAsync(whereExpression);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<bool> UpdateAsync(TEntity updateObj)
|
|
||||||
{
|
|
||||||
return await (await GetDbSimpleClientAsync()).UpdateAsync(updateObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<bool> UpdateAsync(Expression<Func<TEntity, TEntity>> columns, Expression<Func<TEntity, bool>> whereExpression)
|
|
||||||
{
|
|
||||||
return await (await GetDbSimpleClientAsync()).UpdateAsync(columns, whereExpression);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public virtual async Task<bool> UpdateRangeAsync(List<TEntity> updateObjs)
|
|
||||||
{
|
|
||||||
return await (await GetDbSimpleClientAsync()).UpdateRangeAsync(updateObjs);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
|
||||||
}
|
|
||||||
|
|
||||||
public class SqlSugarRepository<TEntity, TKey> : SqlSugarRepository<TEntity>, ISqlSugarRepository<TEntity, TKey>, IRepository<TEntity, TKey> where TEntity : class, IEntity<TKey>, new()
|
|
||||||
{
|
|
||||||
public SqlSugarRepository(ISugarDbContextProvider<ISqlSugarDbContext> sugarDbContextProvider) : base(sugarDbContextProvider)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task DeleteAsync(TKey id, bool autoSave = false, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
await DeleteByIdAsync(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task DeleteManyAsync(IEnumerable<TKey> ids, bool autoSave = false, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
await DeleteByIdsAsync(ids.Select(x => (object)x).ToArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<TEntity?> FindAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
return await GetByIdAsync(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual async Task<TEntity> GetAsync(TKey id, bool includeDetails = true, CancellationToken cancellationToken = default)
|
|
||||||
{
|
|
||||||
return await GetByIdAsync(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
using System.Reflection;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using SqlSugar;
|
|
||||||
using Volo.Abp.Data;
|
|
||||||
using Volo.Abp.DependencyInjection;
|
|
||||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
|
||||||
|
|
||||||
namespace Yi.Framework.SqlSugarCore
|
|
||||||
{
|
|
||||||
|
|
||||||
public class SqlSugarDbConnectionCreator: ISqlSugarDbConnectionCreator,ITransientDependency
|
|
||||||
{
|
|
||||||
public SqlSugarDbConnectionCreator(IOptions<DbConnOptions> options)
|
|
||||||
{
|
|
||||||
Options = options.Value;
|
|
||||||
}
|
|
||||||
public DbConnOptions Options { get; }
|
|
||||||
|
|
||||||
public void SetDbAop(ISqlSugarClient currentDb)
|
|
||||||
{
|
|
||||||
currentDb.Aop.OnLogExecuting = this.OnLogExecuting;
|
|
||||||
currentDb.Aop.OnLogExecuted = this.OnLogExecuted;
|
|
||||||
currentDb.Aop.DataExecuting = this.DataExecuting;
|
|
||||||
currentDb.Aop.DataExecuted = this.DataExecuted;
|
|
||||||
OnSqlSugarClientConfig(currentDb);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public ConnectionConfig Build(Action<ConnectionConfig>? action=null)
|
|
||||||
{
|
|
||||||
var dbConnOptions = Options;
|
|
||||||
#region 组装options
|
|
||||||
if (dbConnOptions.DbType is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentException("DbType配置为空");
|
|
||||||
}
|
|
||||||
var slavaConFig = new List<SlaveConnectionConfig>();
|
|
||||||
if (dbConnOptions.EnabledReadWrite)
|
|
||||||
{
|
|
||||||
if (dbConnOptions.ReadUrl is null)
|
|
||||||
{
|
|
||||||
throw new ArgumentException("读写分离为空");
|
|
||||||
}
|
|
||||||
|
|
||||||
var readCon = dbConnOptions.ReadUrl;
|
|
||||||
|
|
||||||
readCon.ForEach(s =>
|
|
||||||
{
|
|
||||||
//如果是动态saas分库,这里的连接串都不能写死,需要动态添加,这里只配置共享库的连接
|
|
||||||
slavaConFig.Add(new SlaveConnectionConfig() { ConnectionString = s });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
|
|
||||||
#region 组装连接config
|
|
||||||
var connectionConfig = new ConnectionConfig()
|
|
||||||
{
|
|
||||||
ConfigId= ConnectionStrings.DefaultConnectionStringName,
|
|
||||||
DbType = dbConnOptions.DbType ?? DbType.Sqlite,
|
|
||||||
ConnectionString = dbConnOptions.Url,
|
|
||||||
IsAutoCloseConnection = true,
|
|
||||||
SlaveConnectionConfigs = slavaConFig,
|
|
||||||
//设置codefirst非空值判断
|
|
||||||
ConfigureExternalServices = new ConfigureExternalServices
|
|
||||||
{
|
|
||||||
EntityService = (c, p) =>
|
|
||||||
{
|
|
||||||
if (new NullabilityInfoContext()
|
|
||||||
.Create(c).WriteState is NullabilityState.Nullable)
|
|
||||||
{
|
|
||||||
p.IsNullable = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
EntityService(c, p);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
//这里多租户有个坑,无效的
|
|
||||||
AopEvents = new AopEvents
|
|
||||||
{
|
|
||||||
DataExecuted = DataExecuted,
|
|
||||||
DataExecuting = DataExecuting,
|
|
||||||
OnLogExecuted = OnLogExecuted,
|
|
||||||
OnLogExecuting = OnLogExecuting
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
if (action is not null)
|
|
||||||
{
|
|
||||||
action.Invoke(connectionConfig);
|
|
||||||
}
|
|
||||||
#endregion
|
|
||||||
return connectionConfig;
|
|
||||||
}
|
|
||||||
[DisablePropertyInjection]
|
|
||||||
public Action<ISqlSugarClient> OnSqlSugarClientConfig { get; set; }
|
|
||||||
|
|
||||||
[DisablePropertyInjection]
|
|
||||||
public Action<object, DataAfterModel> DataExecuted { get; set; }
|
|
||||||
|
|
||||||
[DisablePropertyInjection]
|
|
||||||
public Action<object, DataFilterModel> DataExecuting { get; set; }
|
|
||||||
|
|
||||||
[DisablePropertyInjection]
|
|
||||||
public Action<string, SugarParameter[]> OnLogExecuting { get; set; }
|
|
||||||
|
|
||||||
[DisablePropertyInjection]
|
|
||||||
public Action<string, SugarParameter[]> OnLogExecuted { get; set; }
|
|
||||||
|
|
||||||
[DisablePropertyInjection]
|
|
||||||
public Action<PropertyInfo, EntityColumnInfo> EntityService { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,371 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Security.Policy;
|
|
||||||
using System.Text;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.Logging;
|
|
||||||
using Microsoft.Extensions.Options;
|
|
||||||
using SqlSugar;
|
|
||||||
using Volo.Abp;
|
|
||||||
using Volo.Abp.Auditing;
|
|
||||||
using Volo.Abp.Data;
|
|
||||||
using Volo.Abp.DependencyInjection;
|
|
||||||
using Volo.Abp.Domain.Entities;
|
|
||||||
using Volo.Abp.Domain.Entities.Events;
|
|
||||||
using Volo.Abp.Guids;
|
|
||||||
using Volo.Abp.MultiTenancy;
|
|
||||||
using Volo.Abp.Users;
|
|
||||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
|
||||||
|
|
||||||
namespace Yi.Framework.SqlSugarCore
|
|
||||||
{
|
|
||||||
public class SqlSugarDbContext : ISqlSugarDbContext
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// SqlSugar 客户端
|
|
||||||
/// </summary>
|
|
||||||
public ISqlSugarClient SqlSugarClient { get; private set; }
|
|
||||||
public ICurrentUser CurrentUser => LazyServiceProvider.GetRequiredService<ICurrentUser>();
|
|
||||||
private IAbpLazyServiceProvider LazyServiceProvider { get; }
|
|
||||||
|
|
||||||
private IGuidGenerator GuidGenerator => LazyServiceProvider.LazyGetRequiredService<IGuidGenerator>();
|
|
||||||
protected ILoggerFactory Logger => LazyServiceProvider.LazyGetRequiredService<ILoggerFactory>();
|
|
||||||
private ICurrentTenant CurrentTenant => LazyServiceProvider.LazyGetRequiredService<ICurrentTenant>();
|
|
||||||
public IDataFilter DataFilter => LazyServiceProvider.LazyGetRequiredService<IDataFilter>();
|
|
||||||
protected virtual bool IsMultiTenantFilterEnabled => DataFilter?.IsEnabled<IMultiTenant>() ?? false;
|
|
||||||
|
|
||||||
protected virtual bool IsSoftDeleteFilterEnabled => DataFilter?.IsEnabled<ISoftDelete>() ?? false;
|
|
||||||
|
|
||||||
public IEntityChangeEventHelper EntityChangeEventHelper => LazyServiceProvider.LazyGetService<IEntityChangeEventHelper>(NullEntityChangeEventHelper.Instance);
|
|
||||||
public DbConnOptions Options => LazyServiceProvider.LazyGetRequiredService<IOptions<DbConnOptions>>().Value;
|
|
||||||
public AbpDbConnectionOptions ConnectionOptions => LazyServiceProvider.LazyGetRequiredService<IOptions<AbpDbConnectionOptions>>().Value;
|
|
||||||
private ISqlSugarDbConnectionCreator _dbConnectionCreator;
|
|
||||||
|
|
||||||
public void SetSqlSugarClient(ISqlSugarClient sqlSugarClient)
|
|
||||||
{
|
|
||||||
SqlSugarClient = sqlSugarClient;
|
|
||||||
}
|
|
||||||
public SqlSugarDbContext(IAbpLazyServiceProvider lazyServiceProvider)
|
|
||||||
{
|
|
||||||
LazyServiceProvider = lazyServiceProvider;
|
|
||||||
var connectionCreator = LazyServiceProvider.LazyGetRequiredService<ISqlSugarDbConnectionCreator>();
|
|
||||||
_dbConnectionCreator = connectionCreator;
|
|
||||||
connectionCreator.OnSqlSugarClientConfig = OnSqlSugarClientConfig;
|
|
||||||
connectionCreator.EntityService = EntityService;
|
|
||||||
connectionCreator.DataExecuting = DataExecuting;
|
|
||||||
connectionCreator.DataExecuted = DataExecuted;
|
|
||||||
connectionCreator.OnLogExecuting = OnLogExecuting;
|
|
||||||
connectionCreator.OnLogExecuted = OnLogExecuted;
|
|
||||||
SqlSugarClient = new SqlSugarClient(connectionCreator.Build(action: options =>
|
|
||||||
{
|
|
||||||
options.ConnectionString = GetCurrentConnectionString();
|
|
||||||
options.DbType = GetCurrentDbType();
|
|
||||||
}));
|
|
||||||
connectionCreator.SetDbAop(SqlSugarClient);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// db切换多库支持
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
protected virtual string GetCurrentConnectionString()
|
|
||||||
{
|
|
||||||
var defautlUrl = Options.Url ?? ConnectionOptions.GetConnectionStringOrNull(ConnectionStrings.DefaultConnectionStringName);
|
|
||||||
//如果未开启多租户,返回db url 或者 默认连接字符串
|
|
||||||
if (!Options.EnabledSaasMultiTenancy)
|
|
||||||
{
|
|
||||||
return defautlUrl;
|
|
||||||
}
|
|
||||||
|
|
||||||
//开启了多租户
|
|
||||||
var connectionStringResolver = LazyServiceProvider.LazyGetRequiredService<IConnectionStringResolver>();
|
|
||||||
var connectionString = connectionStringResolver.ResolveAsync().GetAwaiter().GetResult();
|
|
||||||
|
|
||||||
|
|
||||||
//没有检测到使用多租户功能,默认使用默认库即可
|
|
||||||
if (string.IsNullOrWhiteSpace(connectionString))
|
|
||||||
{
|
|
||||||
Volo.Abp.Check.NotNull(Options.Url, "租户默认库Defalut未找到");
|
|
||||||
connectionString = defautlUrl;
|
|
||||||
}
|
|
||||||
return connectionString!;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual DbType GetCurrentDbType()
|
|
||||||
{
|
|
||||||
if (CurrentTenant.Name is not null)
|
|
||||||
{
|
|
||||||
var dbTypeFromTenantName = GetDbTypeFromTenantName(CurrentTenant.Name);
|
|
||||||
if (dbTypeFromTenantName is not null)
|
|
||||||
{
|
|
||||||
return dbTypeFromTenantName.Value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Volo.Abp.Check.NotNull(Options.DbType, "默认DbType未配置!");
|
|
||||||
return Options.DbType!.Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
//根据租户name进行匹配db类型: Test_Sqlite,[来自AI]
|
|
||||||
private DbType? GetDbTypeFromTenantName(string name)
|
|
||||||
{
|
|
||||||
if (string.IsNullOrWhiteSpace(name))
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查找下划线的位置
|
|
||||||
int underscoreIndex = name.LastIndexOf('_');
|
|
||||||
|
|
||||||
if (underscoreIndex == -1 || underscoreIndex == name.Length - 1)
|
|
||||||
{
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 提取 枚举 部分
|
|
||||||
string enumString = name.Substring(underscoreIndex + 1);
|
|
||||||
|
|
||||||
// 尝试将 尾缀 转换为枚举
|
|
||||||
if (Enum.TryParse<DbType>(enumString, out DbType result))
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 条件不满足时返回 null
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 上下文对象扩展
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sqlSugarClient"></param>
|
|
||||||
protected virtual void OnSqlSugarClientConfig(ISqlSugarClient sqlSugarClient)
|
|
||||||
{
|
|
||||||
//需自定义扩展
|
|
||||||
if (IsSoftDeleteFilterEnabled)
|
|
||||||
{
|
|
||||||
sqlSugarClient.QueryFilter.AddTableFilter<ISoftDelete>(u => u.IsDeleted == false);
|
|
||||||
}
|
|
||||||
if (IsMultiTenantFilterEnabled)
|
|
||||||
{
|
|
||||||
//表达式不能放方法
|
|
||||||
Guid? tenantId = CurrentTenant?.Id;
|
|
||||||
sqlSugarClient.QueryFilter.AddTableFilter<IMultiTenant>(u => u.TenantId == tenantId);
|
|
||||||
}
|
|
||||||
CustomDataFilter(sqlSugarClient);
|
|
||||||
}
|
|
||||||
protected virtual void CustomDataFilter(ISqlSugarClient sqlSugarClient)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
protected virtual void DataExecuted(object oldValue, DataAfterModel entityInfo)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 数据
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="oldValue"></param>
|
|
||||||
/// <param name="entityInfo"></param>
|
|
||||||
protected virtual void DataExecuting(object oldValue, DataFilterModel entityInfo)
|
|
||||||
{
|
|
||||||
//审计日志
|
|
||||||
switch (entityInfo.OperationType)
|
|
||||||
{
|
|
||||||
case DataFilterType.UpdateByObject:
|
|
||||||
|
|
||||||
if (entityInfo.PropertyName.Equals(nameof(IAuditedObject.LastModificationTime)))
|
|
||||||
{
|
|
||||||
if (!DateTime.MinValue.Equals(oldValue))
|
|
||||||
{
|
|
||||||
entityInfo.SetValue(DateTime.Now);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (entityInfo.PropertyName.Equals(nameof(IAuditedObject.LastModifierId)))
|
|
||||||
{
|
|
||||||
if (CurrentUser.Id != null)
|
|
||||||
{
|
|
||||||
entityInfo.SetValue(CurrentUser.Id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DataFilterType.InsertByObject:
|
|
||||||
if (entityInfo.PropertyName.Equals(nameof(IEntity<Guid>.Id)))
|
|
||||||
{
|
|
||||||
//主键为空或者为默认最小值
|
|
||||||
if (Guid.Empty.Equals(oldValue))
|
|
||||||
{
|
|
||||||
entityInfo.SetValue(GuidGenerator.Create());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (entityInfo.PropertyName.Equals(nameof(IAuditedObject.CreationTime)))
|
|
||||||
{
|
|
||||||
//为空或者为默认最小值
|
|
||||||
if (oldValue is null || DateTime.MinValue.Equals(oldValue))
|
|
||||||
{
|
|
||||||
entityInfo.SetValue(DateTime.Now);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (entityInfo.PropertyName.Equals(nameof(IAuditedObject.CreatorId)))
|
|
||||||
{
|
|
||||||
if (CurrentUser.Id != null)
|
|
||||||
{
|
|
||||||
entityInfo.SetValue(CurrentUser.Id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//插入时,需要租户id,先预留
|
|
||||||
if (entityInfo.PropertyName.Equals(nameof(IMultiTenant.TenantId)))
|
|
||||||
{
|
|
||||||
if (CurrentTenant is not null)
|
|
||||||
{
|
|
||||||
entityInfo.SetValue(CurrentTenant.Id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//领域事件
|
|
||||||
switch (entityInfo.OperationType)
|
|
||||||
{
|
|
||||||
case DataFilterType.InsertByObject:
|
|
||||||
if (entityInfo.PropertyName == nameof(IEntity<object>.Id))
|
|
||||||
{
|
|
||||||
EntityChangeEventHelper.PublishEntityCreatedEvent(entityInfo.EntityValue);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DataFilterType.UpdateByObject:
|
|
||||||
if (entityInfo.PropertyName == nameof(IEntity<object>.Id))
|
|
||||||
{
|
|
||||||
//软删除,发布的是删除事件
|
|
||||||
if (entityInfo.EntityValue is ISoftDelete softDelete)
|
|
||||||
{
|
|
||||||
if (softDelete.IsDeleted == true)
|
|
||||||
{
|
|
||||||
EntityChangeEventHelper.PublishEntityDeletedEvent(entityInfo.EntityValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
EntityChangeEventHelper.PublishEntityUpdatedEvent(entityInfo.EntityValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case DataFilterType.DeleteByObject:
|
|
||||||
if (entityInfo.PropertyName == nameof(IEntity<object>.Id))
|
|
||||||
{
|
|
||||||
//这里sqlsugar有个特殊,删除会返回批量的结果
|
|
||||||
if (entityInfo.EntityValue is IEnumerable entityValues)
|
|
||||||
{
|
|
||||||
foreach (var entityValue in entityValues)
|
|
||||||
{
|
|
||||||
|
|
||||||
EntityChangeEventHelper.PublishEntityDeletedEvent(entityValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 日志
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sql"></param>
|
|
||||||
/// <param name="pars"></param>
|
|
||||||
protected virtual void OnLogExecuting(string sql, SugarParameter[] pars)
|
|
||||||
{
|
|
||||||
if (Options.EnabledSqlLog)
|
|
||||||
{
|
|
||||||
StringBuilder sb = new StringBuilder();
|
|
||||||
sb.AppendLine();
|
|
||||||
sb.AppendLine("==========Yi-SQL执行:==========");
|
|
||||||
sb.AppendLine(UtilMethods.GetSqlString(DbType.SqlServer, sql, pars));
|
|
||||||
sb.AppendLine("===============================");
|
|
||||||
Logger.CreateLogger<SqlSugarDbContext>().LogDebug(sb.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 日志
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="sql"></param>
|
|
||||||
/// <param name="pars"></param>
|
|
||||||
protected virtual void OnLogExecuted(string sql, SugarParameter[] pars)
|
|
||||||
{
|
|
||||||
if (Options.EnabledSqlLog)
|
|
||||||
{
|
|
||||||
var sqllog = $"=========Yi-SQL耗时{SqlSugarClient.Ado.SqlExecutionTime.TotalMilliseconds}毫秒=====";
|
|
||||||
Logger.CreateLogger<SqlSugarDbContext>().LogDebug(sqllog.ToString());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 实体配置
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="property"></param>
|
|
||||||
/// <param name="column"></param>
|
|
||||||
protected virtual void EntityService(PropertyInfo property, EntityColumnInfo column)
|
|
||||||
{
|
|
||||||
if (property.Name == "ConcurrencyStamp")
|
|
||||||
{
|
|
||||||
column.IsIgnore = true;
|
|
||||||
}
|
|
||||||
if (property.PropertyType == typeof(ExtraPropertyDictionary))
|
|
||||||
{
|
|
||||||
column.IsIgnore = true;
|
|
||||||
}
|
|
||||||
if (property.Name == nameof(Entity<object>.Id))
|
|
||||||
{
|
|
||||||
column.IsPrimarykey = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void BackupDataBase()
|
|
||||||
{
|
|
||||||
string directoryName = "database_backup";
|
|
||||||
string fileName = DateTime.Now.ToString($"yyyyMMdd_HHmmss") + $"_{SqlSugarClient.Ado.Connection.Database}";
|
|
||||||
if (!Directory.Exists(directoryName))
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory(directoryName);
|
|
||||||
}
|
|
||||||
switch (Options.DbType)
|
|
||||||
{
|
|
||||||
case DbType.MySql:
|
|
||||||
//MySql
|
|
||||||
SqlSugarClient.DbMaintenance.BackupDataBase(SqlSugarClient.Ado.Connection.Database, $"{Path.Combine(directoryName, fileName)}.sql");//mysql 只支持.net core
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
case DbType.Sqlite:
|
|
||||||
//Sqlite
|
|
||||||
SqlSugarClient.DbMaintenance.BackupDataBase(null, $"{fileName}.db"); //sqlite 只支持.net core
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
case DbType.SqlServer:
|
|
||||||
//SqlServer
|
|
||||||
SqlSugarClient.DbMaintenance.BackupDataBase(SqlSugarClient.Ado.Connection.Database, $"{Path.Combine(directoryName, fileName)}.bak"/*服务器路径*/);//第一个参数库名
|
|
||||||
break;
|
|
||||||
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new NotImplementedException("其他数据库备份未实现");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
using System.Data.Common;
|
|
||||||
using Volo.Abp;
|
|
||||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
|
||||||
|
|
||||||
namespace Yi.Framework.SqlSugarCore;
|
|
||||||
|
|
||||||
public class SqlSugarDbContextCreationContext
|
|
||||||
{
|
|
||||||
public static SqlSugarDbContextCreationContext Current => _current.Value;
|
|
||||||
private static readonly AsyncLocal<SqlSugarDbContextCreationContext> _current = new AsyncLocal<SqlSugarDbContextCreationContext>();
|
|
||||||
public string ConnectionStringName { get; }
|
|
||||||
|
|
||||||
public string ConnectionString { get; }
|
|
||||||
|
|
||||||
public DbConnection ExistingConnection { get; internal set; }
|
|
||||||
|
|
||||||
public SqlSugarDbContextCreationContext(string connectionStringName, string connectionString)
|
|
||||||
{
|
|
||||||
ConnectionStringName = connectionStringName;
|
|
||||||
ConnectionString = connectionString;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IDisposable Use(SqlSugarDbContextCreationContext context)
|
|
||||||
{
|
|
||||||
var previousValue = Current;
|
|
||||||
_current.Value = context;
|
|
||||||
return new DisposeAction(() => _current.Value = previousValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
|
||||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
|
||||||
|
|
||||||
namespace Yi.Framework.SqlSugarCore
|
|
||||||
{
|
|
||||||
public static class SqlsugarCoreExtensions
|
|
||||||
{
|
|
||||||
public static IServiceCollection AddYiDbContext<DbContext>(this IServiceCollection service, ServiceLifetime serviceLifetime = ServiceLifetime.Transient) where DbContext : class, ISqlSugarDbContext
|
|
||||||
{
|
|
||||||
service.Replace(new ServiceDescriptor(typeof(ISqlSugarDbContext), typeof(DbContext), serviceLifetime));
|
|
||||||
return service;
|
|
||||||
}
|
|
||||||
public static IServiceCollection TryAddYiDbContext<DbContext>(this IServiceCollection service, ServiceLifetime serviceLifetime = ServiceLifetime.Transient) where DbContext : class, ISqlSugarDbContext
|
|
||||||
{
|
|
||||||
service.TryAdd(new ServiceDescriptor(typeof(ISqlSugarDbContext), typeof(DbContext), serviceLifetime));
|
|
||||||
return service;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static IServiceCollection AddYiDbContext<DbContext>(this IServiceCollection service, Action<DbConnOptions> options) where DbContext : class, ISqlSugarDbContext
|
|
||||||
{
|
|
||||||
|
|
||||||
service.Configure<DbConnOptions>(ops =>
|
|
||||||
{
|
|
||||||
options.Invoke(ops);
|
|
||||||
});
|
|
||||||
service.AddYiDbContext<DbContext>();
|
|
||||||
return service;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Volo.Abp.Uow;
|
|
||||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
|
||||||
|
|
||||||
namespace Yi.Framework.SqlSugarCore.Uow
|
|
||||||
{
|
|
||||||
public class SqlSugarDatabaseApi : IDatabaseApi
|
|
||||||
{
|
|
||||||
public ISqlSugarDbContext DbContext { get; }
|
|
||||||
|
|
||||||
public SqlSugarDatabaseApi(ISqlSugarDbContext dbContext)
|
|
||||||
{
|
|
||||||
DbContext = dbContext;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user