添加项目文件。

This commit is contained in:
zel
2025-03-05 19:42:01 +08:00
parent 659f1a2ad9
commit 47dcdeb55d
582 changed files with 242004 additions and 0 deletions

25
.dockerignore Normal file
View File

@@ -0,0 +1,25 @@
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/azds.yaml
**/bin
**/charts
**/docker-compose*
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/obj
**/secrets.dev.yaml
**/values.dev.yaml
LICENSE
README.md

4
.editorconfig Normal file
View File

@@ -0,0 +1,4 @@
[*.cs]
# CS1591: 缺少对公共可见类型或成员的 XML 注释
dotnet_diagnostic.CS1591.severity = none

345
.gitignore vendored Normal file
View File

@@ -0,0 +1,345 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
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
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# ASP.NET Core default setup: bower directory is configured as wwwroot/lib/ and bower restore is true
**/wwwroot/lib/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# 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
/WaterCloud.Web/DataProtection
/WaterCloud.Web/wwwroot/file/local/20221006
/WaterCloud.Web/watercloudnetdb.db-journal
/RabbitMq

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2020 钱玮鸿
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

101
README.md Normal file
View File

@@ -0,0 +1,101 @@
<p></p>
<p></p>
<p align="center">
<img src="https://images.gitee.com/uploads/images/2021/0528/215200_accc4311_7353672.jpeg" height="80"/>
</p>
<div align="center">
[![star](https://gitee.com/qian_wei_hong/WaterCloud/badge/star.svg)](https://gitee.com/qian_wei_hong/WaterCloud/stargazers)
[![fork](https://gitee.com/qian_wei_hong/WaterCloud/badge/fork.svg)](https://gitee.com/qian_wei_hong/WaterCloud/members)
![](https://img.shields.io/badge/release-3.0.0.preview-red)
![](https://img.shields.io/badge/.net-8.0.0-blue)
![](https://img.shields.io/badge/SqlSugar-5.1.4.59-blue)
![](https://img.shields.io/badge/layui-2.9.0-blue)
</div>
----
# WaterCloud
#### 介绍
- 请勿用于违反我国法律的项目上。
- WaterCloud是一套基于ASP.NET 8.0 MVC + API + SqlSugar + LayUI的框架源代码完全开源可以帮助你解决C#.NET项目的重复工作
- 采用主流架构思想,容易上手,简单易学,学习成本低。
- 可完全实现二次开发让开发更多关注业务逻辑。既能快速提高开发效率,帮助公司节省人力成本,同时又不失灵活性。
- 支持SQLServer、MySQL 等多数据库类型。模块化设计,层次结构清晰。内置一系列企业信息管理的基础功能。
- 操作权限基于RBAC权限控制精密细致对所有管理链接都进行权限验证可控制到导航菜单、功能按钮控制到行级列表级表单字段级。
- 数据权限,精细化数据权限控制,实现不同人看不同数据。
- 代码生成功能,简单前后端代码生成。
- 表单设计器,提供多种方式设计表单,动态表单拖拉式设计以及自定义表单。
- 流程设计器,动态设计流程,节点及连线条件设计。
- 内容管理已配置好wangEditor编辑器可以使用。
- 文件管理,提供文件上传及下载功能。
- 提高开发效率及质量。常用类封装日志、缓存、验证、字典、文件、邮件、Excel。等等。
- 页面为响应式设计,支持电脑、平板、智能手机等设备,微信浏览器以及各种常见浏览器。
- 适用范围可以开发OA、ERP、BPM、CRM、WMS、TMS、MIS、BI、电商平台后台、物流管理系统、快递管理系统、教务管理系统等各类管理软件。
- 租户管理基于Database的多租户功能(SqlSugar支持)。
- 定时任务基于quartz的定时任务功能(可以集群)。
- 项目演示地址http://47.116.127.212:5000/ 账号admin 密码0000数据库2个小时还原一次
- 文档地址https://gitee.com/qian_wei_hong/WaterCloud/wikis/pages
- 在线项目地址https://replit.com/@MonsterUncle/WaterCloud
#### 前端以及后端使用技术介绍
1、前端技术
- js框架jquery-3.4.1、LayUI、LayUI mini开源
- 图标Font Awesome 4.7.0及LayUI自带。
- 客户端验证LayUI verify。
- 富文本编辑器开源wangEditor、LayUI editor。
- 上传文件LayUI upoload。
- 动态页签LayUI mini miniTab。
- 数据表格LayUI table、LayUI 开源 soul-table组件(已实现后端筛选)。
- 下拉选择框LayUI select、xmselect。
- 树结构控件LayUI 开源 dtree。
- 树状表格LayUI 开源 treetable-lay,框架改造treetable低版本(兼容soul-table组件、修复固定列等BUG)。
- 穿梭框LayUI transfer。
- 页面布局LayUI、LayUI mini。
- 图表插件echarts
- 日期控件LayUI laydate
- 图标选择LayUI 开源 IconPicker
- 省市区选择LayUI 开源 layarea
2、后端技术
- 核心框架ASP.NET 8.0、WEB API
- 定时任务QuartZ实现web控制
- 持久层框架SqlSugar支持多种数据库复杂查询操作、多租户、分库分表等、Chloe(支持多种数据库,复杂查询操作,比较稳定)
- 安全支持过滤器、Sql注入、请求伪造
- 服务端验证:实体模型验证
- 缓存框架Redis/Memory单点登录控制
- 消息队列: RabbitMq
- 事件总线: Jaina
- 日志管理Log、登录日志、操作日志
- 工具类MiniExcel、Newtonsoft.Json、验证码、丰富公共类
- 其他AutoFac、Swagger
#### 环境要求
1. VS2022及以上版本
2. Asp.net 8.0
3. Mysql或者SQLSERVER2005及以上版本database文件夹下有sql文件可执行
4. 请使用VS2022及以上版本打开解决方案。
5. Redis和RabbitMq在项目文件夹里有
#### 友情链接
1. 前端框架Layui 文档地址https://layui.gitee.io/v2/
2. Layui前端框架Layuimini 码云地址https://gitee.com/zhongshaofa/layuimini
3. SqlSugar.ORM 文档地址https://www.donet5.com/home/doc
4. WaterCloud讨论交流QQ群1065447456[![](https://pub.idqqimg.com/wpa/images/group.png)](https://jq.qq.com/?_wv=1027&k=51RHQVG)
5. .NET易用底层框架 Furion码云地址https://gitee.com/dotnetchina/Furion
#### 捐赠支持
开源项目不易,若此项目能得到你的青睐,可以捐赠支持作者持续开发与维护,感谢所有支持开源的朋友。
![输入图片说明](https://images.gitee.com/uploads/images/2020/0331/144842_7cf04ad6_7353672.jpeg "1585637076201.jpg") ![输入图片说明](https://images.gitee.com/uploads/images/2020/0331/144852_8b26c8cb_7353672.png "mm_facetoface_collect_qrcode_1585637044089.png")

BIN
Redis/Redis-x64-3.2.100.msi Normal file

Binary file not shown.

BIN
Redis/Redis说明.docx Normal file

Binary file not shown.

BIN
Redis/打开.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

View File

@@ -0,0 +1,32 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
namespace WaterCloud.Code
{
/// <summary>
/// 管理员特性MVC使用
/// </summary>
public class HandlerAdminAttribute : ActionFilterAttribute
{
private readonly bool _isSuper;
public HandlerAdminAttribute(bool isSuper = true)
{
_isSuper = isSuper;
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (OperatorProvider.Provider.GetCurrent() != null && _isSuper == true ? OperatorProvider.Provider.GetCurrent().IsSuperAdmin : OperatorProvider.Provider.GetCurrent().IsAdmin)
{
return;
}
else
{
//filterContext.HttpContext.Response.WriteAsync("<script>top.location.href ='" + filterContext.HttpContext.Request.PathBase + "/Home/Error?msg=403" + "';if(document.all) window.event.returnValue = false;</script>");
filterContext.Result = new RedirectResult(filterContext.HttpContext.Request.PathBase + "/Home/Error?msg=403");
return;
}
}
}
}

View File

@@ -0,0 +1,34 @@
using Microsoft.AspNetCore.Mvc.Abstractions;
using Microsoft.AspNetCore.Mvc.ActionConstraints;
using Microsoft.AspNetCore.Routing;
using System;
namespace WaterCloud.Code
{
/// <summary>
/// ajax验证
/// </summary>
[AttributeUsage(AttributeTargets.Method)]
public class HandlerAjaxOnlyAttribute : ActionMethodSelectorAttribute
{
public bool Ignore { get; set; }
public HandlerAjaxOnlyAttribute(bool ignore = false)
{
Ignore = ignore;
}
public override bool IsValidForRequest(RouteContext routeContext, ActionDescriptor action)
{
if (Ignore)
return true;
bool result = false;
var xreq = routeContext.HttpContext.Request.Headers.ContainsKey("x-requested-with");
if (xreq)
{
result = routeContext.HttpContext.Request.Headers.ContainsKey("x-requested-with");
}
return result;
}
}
}

View File

@@ -0,0 +1,56 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
namespace WaterCloud.Code
{
/// <summary>
/// 防重复锁MVC使用
/// </summary>
public class HandlerLockAttribute : ActionFilterAttribute
{
public HandlerLockAttribute()
{
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (OperatorProvider.Provider.GetCurrent() == null)
{
WebHelper.WriteCookie("WaterCloud_login_error", "overdue");
//filterContext.HttpContext.Response.WriteAsync("<script>top.location.href ='" + filterContext.HttpContext.Request.PathBase + "/Home/Error?msg=408" + "';if(document.all) window.event.returnValue = false;</script>");
OperatorProvider.Provider.EmptyCurrent("pc_").GetAwaiter().GetResult();
filterContext.Result = new RedirectResult(filterContext.HttpContext.Request.PathBase + "/Home/Error?msg=408");
return;
}
else
{
string token = filterContext.HttpContext.Request.Cookies["pc_" + GlobalContext.SystemConfig.TokenName];
string cacheToken = CacheHelper.GetAsync<string>("pc_" + GlobalContext.SystemConfig.TokenName + "_" + OperatorProvider.Provider.GetCurrent().UserId + "_" + OperatorProvider.Provider.GetCurrent().LoginTime).GetAwaiter().GetResult();
if (string.IsNullOrWhiteSpace(token))
{
filterContext.Result = new JsonResult(new AlwaysResult { state = ResultType.error.ToString(), message = "token不能空" });
return;
}
if (string.IsNullOrWhiteSpace(cacheToken))
{
filterContext.Result = new JsonResult(new AlwaysResult { state = ResultType.error.ToString(), message = "token不能空" });
return;
}
if (token != cacheToken)
{
filterContext.Result = new JsonResult(new AlwaysResult { state = ResultType.error.ToString(), message = "请求异常" });
return;
}
//固定加锁5秒
bool result = CacheHelper.SetNx(token, token, 5);
if (!result)
{
filterContext.Result = new JsonResult(new AlwaysResult { state = ResultType.error.ToString(), message = "请求太频繁,请稍后" });
return;
}
}
//随机值
base.OnActionExecuting(filterContext);
}
}
}

View File

@@ -0,0 +1,52 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Diagnostics;
using System.Threading.Tasks;
namespace WaterCloud.Code
{
/// <summary>
/// 防重复提交,api使用
/// </summary>
public class LockAttribute : ActionFilterAttribute
{
/// <summary>
/// 拦截
/// </summary>
/// <param name="context"></param>
/// <param name="next"></param>
/// <returns></returns>
public override async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
Stopwatch sw = new Stopwatch();
sw.Start();
if (GlobalContext.SystemConfig.Debug == false)
{
if (OperatorProvider.Provider.GetCurrent() == null)
{
context.Result = new JsonResult(new AlwaysResult { state = ResultType.error.ToString(), message = "抱歉,没有操作权限" });
return;
}
else
{
string token = context.HttpContext.Request.Headers[GlobalContext.SystemConfig.TokenName].ParseToString();
if (string.IsNullOrWhiteSpace(token))
{
context.Result = new JsonResult(new AlwaysResult { state = ResultType.error.ToString(), message = "token不能空" });
return;
}
//固定加锁5秒
bool result = CacheHelper.SetNx(token, token, 5);
if (!result)
{
context.Result = new JsonResult(new AlwaysResult { state = ResultType.error.ToString(), message = "请求太频繁,请稍后" });
return;
}
}
}
await next();
sw.Stop();
}
}
}

View File

@@ -0,0 +1,23 @@
using System;
namespace WaterCloud.Code
{
[AttributeUsage(AttributeTargets.Class, Inherited = true)]
public class ServiceDescriptionAttribute : Attribute
{
public string ClassDescription
{
get;
set;
}
private ServiceDescriptionAttribute()
{
}
public ServiceDescriptionAttribute(string classDescription)
{
ClassDescription = classDescription;
}
}
}

View File

@@ -0,0 +1,468 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace WaterCloud.Code
{
public abstract class BaseHelper : RedisHelper<BaseHelper>
{ }
public abstract class HandleLogHelper : RedisHelper<HandleLogHelper>
{ }
public class CacheHelper
{
private static string cacheProvider = GlobalContext.SystemConfig.CacheProvider;
/// <summary>
/// 添加缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="value">缓存Value</param>
/// <param name="expiresIn">缓存时长h</param>
/// <param name="isSliding">是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间)</param>
/// <returns></returns>
public static async Task<bool> SetAsync(string key, object value, int expiresIn = -1, bool isSliding = true)
{
return await SetBySecondAsync(key, value, expiresIn * 3600, isSliding);
}
/// <summary>
/// 添加缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="value">缓存Value</param>
/// <param name="expiresIn">缓存时长秒</param>
/// <param name="isSliding">是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间)</param>
/// <returns></returns>
public static async Task<bool> SetBySecondAsync(string key, object value, int expiresIn = -1, bool isSliding = true)
{
if (string.IsNullOrEmpty(key))
throw new ArgumentNullException(nameof(key));
if (value == null)
throw new ArgumentNullException(nameof(value));
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
if (expiresIn > 0)
{
await BaseHelper.SetAsync(key, value, expiresIn);
}
else
{
await BaseHelper.SetAsync(key, value);
}
return await ExistsAsync(key);
case Define.CACHEPROVIDER_MEMORY:
if (expiresIn > 0)
{
MemoryCacheHelper.Set(key, value, TimeSpan.FromSeconds(expiresIn), isSliding);
}
else
{
MemoryCacheHelper.Set(key, value);
}
return await ExistsAsync(key);
default:
if (expiresIn > 0)
{
MemoryCacheHelper.Set(key, value, TimeSpan.FromSeconds(expiresIn), isSliding);
}
else
{
MemoryCacheHelper.Set(key, value);
}
return await ExistsAsync(key);
}
}
/// <summary>
/// 添加缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="value">缓存Value</param>
/// <param name="expiresIn">缓存时长秒</param>
/// <param name="isSliding">是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间)</param>
/// <returns></returns>
public static bool SetBySecond(string key, object value, int expiresIn = -1, bool isSliding = true)
{
if (string.IsNullOrEmpty(key))
throw new ArgumentNullException(nameof(key));
if (value == null)
throw new ArgumentNullException(nameof(value));
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
if (expiresIn > 0)
{
BaseHelper.Set(key, value, expiresIn);
}
else
{
BaseHelper.Set(key, value);
}
return Exists(key);
case Define.CACHEPROVIDER_MEMORY:
if (expiresIn > 0)
{
MemoryCacheHelper.Set(key, value, TimeSpan.FromSeconds(expiresIn), isSliding);
}
else
{
MemoryCacheHelper.Set(key, value);
}
return Exists(key);
default:
if (expiresIn > 0)
{
MemoryCacheHelper.Set(key, value, TimeSpan.FromSeconds(expiresIn), isSliding);
}
else
{
MemoryCacheHelper.Set(key, value);
}
return Exists(key);
}
}
/// <summary>
/// 获取缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public static async Task<T> GetAsync<T>(string key)
{
if (string.IsNullOrEmpty(key))
throw new ArgumentNullException(nameof(key));
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
return await BaseHelper.GetAsync<T>(key);
case Define.CACHEPROVIDER_MEMORY:
return MemoryCacheHelper.Get<T>(key);
default:
return MemoryCacheHelper.Get<T>(key);
}
}
/// <summary>
/// 获取缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public static T Get<T>(string key)
{
if (string.IsNullOrEmpty(key))
throw new ArgumentNullException(nameof(key));
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
return BaseHelper.Get<T>(key);
case Define.CACHEPROVIDER_MEMORY:
return MemoryCacheHelper.Get<T>(key);
default:
return MemoryCacheHelper.Get<T>(key);
}
}
/// <summary>
/// 删除缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public static async Task RemoveAsync(string key)
{
if (string.IsNullOrEmpty(key))
throw new ArgumentNullException(nameof(key));
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
await BaseHelper.DelAsync(key);
break;
case Define.CACHEPROVIDER_MEMORY:
MemoryCacheHelper.Remove(key);
break;
}
}
/// <summary>
/// 删除缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public static void Remove(string key)
{
if (string.IsNullOrEmpty(key))
throw new ArgumentNullException(nameof(key));
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
BaseHelper.Del(key);
break;
case Define.CACHEPROVIDER_MEMORY:
MemoryCacheHelper.Remove(key);
break;
}
}
/// <summary>
/// 验证缓存项是否存在
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public static async Task<bool> ExistsAsync(string key)
{
if (string.IsNullOrEmpty(key))
throw new ArgumentNullException(nameof(key));
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
return await BaseHelper.ExistsAsync(key);
case Define.CACHEPROVIDER_MEMORY:
return MemoryCacheHelper.Exists(key);
default:
return MemoryCacheHelper.Exists(key);
}
}
/// <summary>
/// 验证缓存项是否存在
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public static bool Exists(string key)
{
if (string.IsNullOrEmpty(key))
throw new ArgumentNullException(nameof(key));
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
return BaseHelper.Exists(key);
case Define.CACHEPROVIDER_MEMORY:
return MemoryCacheHelper.Exists(key);
default:
return MemoryCacheHelper.Exists(key);
}
}
/// <summary>
/// 缓存续期
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="hour">时间小时</param>
/// <returns></returns>
public static async Task ExpireAsync(string key, int hour)
{
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
await BaseHelper.ExpireAtAsync(key, DateTime.Now.AddHours(hour));
break;
default:
break;
}
}
/// <summary>
/// 缓存续期
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="hour">时间小时</param>
/// <returns></returns>
public static void Expire(string key, int hour)
{
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
BaseHelper.ExpireAt(key, DateTime.Now.AddHours(hour));
break;
default:
break;
}
}
/// <summary>
/// 清空缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public static async Task FlushAllAsync()
{
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
await BaseHelper.NodesServerManager.FlushDbAsync();
break;
case Define.CACHEPROVIDER_MEMORY:
MemoryCacheHelper.RemoveCacheAll();
break;
default:
MemoryCacheHelper.RemoveCacheAll();
break;
}
}
/// <summary>
/// 清空缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public static void FlushAll1()
{
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
BaseHelper.NodesServerManager.FlushDb();
break;
case Define.CACHEPROVIDER_MEMORY:
MemoryCacheHelper.RemoveCacheAll();
break;
default:
MemoryCacheHelper.RemoveCacheAll();
break;
}
}
/// <summary>
/// 不存在就插入
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="value">缓存Value</param>
/// <param name="second">过期时间</param>
/// <returns></returns>
public static async Task<bool> SetNxAsync(string key, object value, int second = 10)
{
bool result = false;
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
result = await BaseHelper.SetNxAsync(key, value);
await BaseHelper.ExpireAtAsync(key, DateTime.Now.AddSeconds(second));
break;
case Define.CACHEPROVIDER_MEMORY:
if (MemoryCacheHelper.Exists(key))
{
result = false;
MemoryCacheHelper.Get(key);
}
else
{
result = true;
MemoryCacheHelper.Set(key, value, TimeSpan.FromSeconds(second), true);
}
break;
default:
if (MemoryCacheHelper.Exists(key))
{
result = false;
MemoryCacheHelper.Get(key);
}
else
{
result = true;
MemoryCacheHelper.Set(key, value, TimeSpan.FromSeconds(second), true);
}
break;
}
return result;
}
/// <summary>
/// 不存在就插入
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="value">缓存Value</param>
/// <param name="second">过期时间</param>
/// <returns></returns>
public static bool SetNx(string key, object value, int second = 10)
{
bool result = false;
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
result = BaseHelper.SetNx(key, value);
BaseHelper.ExpireAt(key, DateTime.Now.AddSeconds(second));
break;
case Define.CACHEPROVIDER_MEMORY:
if (MemoryCacheHelper.Exists(key))
{
result = false;
MemoryCacheHelper.Get(key);
}
else
{
result = true;
MemoryCacheHelper.Set(key, value, TimeSpan.FromSeconds(second), true);
}
break;
default:
if (MemoryCacheHelper.Exists(key))
{
result = false;
MemoryCacheHelper.Get(key);
}
else
{
result = true;
MemoryCacheHelper.Set(key, value, TimeSpan.FromSeconds(second), true);
}
break;
}
return result;
}
public static async Task<IEnumerable<string>> GetAllKeyAsync<V>()
{
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
return await BaseHelper.KeysAsync("SqlSugarDataCache.*");
case Define.CACHEPROVIDER_MEMORY:
return MemoryCacheHelper.GetCacheKeys();
default:
return MemoryCacheHelper.GetCacheKeys();
}
}
public static IEnumerable<string> GetAllKey<V>()
{
switch (cacheProvider)
{
case Define.CACHEPROVIDER_REDIS:
return BaseHelper.Keys("SqlSugarDataCache.*");
case Define.CACHEPROVIDER_MEMORY:
return MemoryCacheHelper.GetCacheKeys();
default:
return MemoryCacheHelper.GetCacheKeys();
}
}
}
}

View File

@@ -0,0 +1,244 @@
using Microsoft.Extensions.Caching.Memory;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
namespace WaterCloud.Code
{
/// <summary>
/// 缓存帮助类
/// </summary>
public class MemoryCacheHelper
{
private static readonly MemoryCache Cache = new MemoryCache(new MemoryCacheOptions());
/// <summary>
/// 验证缓存项是否存在
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public static bool Exists(string key)
{
if (key == null)
throw new ArgumentNullException(nameof(key));
return Cache.TryGetValue(key, out _);
}
/// <summary>
/// 添加缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="value">缓存Value</param>
/// <param name="expiresSliding">滑动过期时长(如果在过期时间内有操作,则以当前时间点延长过期时间)</param>
/// <param name="expiressAbsoulte">绝对过期时长</param>
/// <returns></returns>
public static bool Set(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte)
{
if (key == null)
throw new ArgumentNullException(nameof(key));
if (value == null)
throw new ArgumentNullException(nameof(value));
Cache.Set(key, value.ToJson(),
new MemoryCacheEntryOptions().SetSlidingExpiration(expiresSliding)
.SetAbsoluteExpiration(expiressAbsoulte));
return Exists(key);
}
/// <summary>
/// 添加缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="value">缓存Value</param>
/// <param name="expiresIn">缓存时长</param>
/// <param name="isSliding">是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间)</param>
/// <returns></returns>
public static bool Set(string key, object value, TimeSpan expiresIn, bool isSliding = false)
{
if (key == null)
throw new ArgumentNullException(nameof(key));
if (value == null)
throw new ArgumentNullException(nameof(value));
Cache.Set(key, value.ToJson(),
isSliding
? new MemoryCacheEntryOptions().SetSlidingExpiration(expiresIn)
: new MemoryCacheEntryOptions().SetAbsoluteExpiration(expiresIn));
return Exists(key);
}
/// <summary>
/// 添加缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="value">缓存Value</param>
/// <returns></returns>
public static bool Set(string key, object value)
{
if (key == null)
throw new ArgumentNullException(nameof(key));
if (value == null)
throw new ArgumentNullException(nameof(value));
Cache.Set(key, value.ToJson());
return Exists(key);
}
#region
/// <summary>
/// 删除缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public static void Remove(string key)
{
if (key == null)
throw new ArgumentNullException(nameof(key));
Cache.Remove(key);
}
/// <summary>
/// 批量删除缓存
/// </summary>
/// <returns></returns>
public static void RemoveAll(IEnumerable<string> keys)
{
if (keys == null)
throw new ArgumentNullException(nameof(keys));
keys.ToList().ForEach(item => Cache.Remove(item));
}
#endregion
#region
/// <summary>
/// 获取缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public static T Get<T>(string key)
{
if (key == null)
throw new ArgumentNullException(nameof(key));
object temp;
if (Cache.TryGetValue(key, out temp))
{
return temp.ToString().ToObject<T>();
}
return default(T);
}
/// <summary>
/// 获取缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public static string Get(string key)
{
if (key == null)
throw new ArgumentNullException(nameof(key));
if (Cache.Get(key) == null)
{
return string.Empty;
}
return Cache.Get(key).ToString();
}
/// <summary>
/// 获取缓存集合
/// </summary>
/// <param name="keys">缓存Key集合</param>
/// <returns></returns>
public static IDictionary<string, object> GetAll(IEnumerable<string> keys)
{
if (keys == null)
throw new ArgumentNullException(nameof(keys));
var dict = new Dictionary<string, object>();
keys.ToList().ForEach(item => dict.Add(item, Cache.Get(item)));
return dict;
}
#endregion
/// <summary>
/// 删除所有缓存
/// </summary>
public static void RemoveCacheAll()
{
var l = GetCacheKeys();
foreach (var s in l)
{
Remove(s);
}
}
/// <summary>
/// 删除匹配到的缓存
/// </summary>
/// <param name="pattern"></param>
/// <returns></returns>
public static void RemoveCacheRegex(string pattern)
{
IEnumerable<string> l = SearchCacheRegex(pattern);
foreach (var s in l)
{
Remove(s);
}
}
/// <summary>
/// 搜索 匹配到的缓存
/// </summary>
/// <param name="pattern"></param>
/// <returns></returns>
public static IEnumerable<string> SearchCacheRegex(string pattern)
{
var cacheKeys = GetCacheKeys();
var l = cacheKeys.Where(k => Regex.IsMatch(k, pattern)).ToList();
return l.AsReadOnly();
}
/// <summary>
/// 获取所有缓存键
/// </summary>
/// <returns></returns>
public static List<string> GetCacheKeys()
{
#if NET8_0
const BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;
var entries = Cache.GetType().GetField("_coherentState", flags)?.GetValue(Cache);
var cacheItems = entries?.GetType()?.GetProperty("EntriesCollection", flags)?.GetValue(entries) as ICollection; //entries as IDictionary;
var keys = new List<string>();
if (cacheItems == null) return keys;
foreach (var item in cacheItems)
{
var methodInfo = item.GetType().GetProperty("Key");
var val = methodInfo.GetValue(item);
keys.Add(val.ToString());
}
return keys;
#else
const BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;
var entries = Cache.GetType().GetField("_entries", flags).GetValue(Cache);
var cacheItems = entries as IDictionary;
var keys = new List<string>();
if (cacheItems == null) return keys;
foreach (DictionaryEntry cacheItem in cacheItems)
{
keys.Add(cacheItem.Key.ToString());
}
return keys;
#endif
}
}
}

View File

@@ -0,0 +1,368 @@
using Autofac;
using CSRedis;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.ResponseCompression;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using Serenity.Abstractions;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Reflection;
using System.Text.Encodings.Web;
using System.Text.Unicode;
using WaterCloud.Code.Model;
namespace WaterCloud.Code
{
public class DefaultStartUp
{
protected IConfiguration Configuration { get; set; }
protected IWebHostEnvironment WebHostEnvironment { get; set; }
public DefaultStartUp(IConfiguration configuration, IWebHostEnvironment env)
{
Configuration = configuration;
WebHostEnvironment = env;
GlobalContext.LogWhenStart(env);
GlobalContext.HostingEnvironment = env;
}
public virtual void ConfigureServices(IServiceCollection services)
{
var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
//没有设置环境变量就默认生产环境
if (string.IsNullOrWhiteSpace(environment))
environment = "Production";
Configuration = new ConfigurationBuilder().AddJsonFile($"appsettings.{environment}.json", optional: true, reloadOnChange: true).Build();
GlobalContext.SystemConfig = Configuration.GetSection("SystemConfig").Get<SystemConfig>();
GlobalContext.Services = services;
GlobalContext.Configuration = Configuration;
services.Configure<CookiePolicyOptions>(options =>
{
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
//解决session问题
services.AddSession(options =>
{
options.Cookie.IsEssential = true;//是否强制存储cookie
options.Cookie.SameSite = SameSiteMode.None;
});
//代替HttpContext.Current
services.AddHttpContextAccessor();
//缓存缓存选择
if (GlobalContext.SystemConfig.CacheProvider != Define.CACHEPROVIDER_REDIS)
{
services.AddMemoryCache();
}
else
{
//redis 注入服务
string redisConnectiong = GlobalContext.SystemConfig.RedisConnectionString;
// 多客户端 1、基础 2、操作日志
var redisDB1 = new CSRedisClient(redisConnectiong + ",defaultDatabase=" + 0);
BaseHelper.Initialization(redisDB1);
var redisDB2 = new CSRedisClient(redisConnectiong + ",defaultDatabase=" + 1);
HandleLogHelper.Initialization(redisDB2);
services.AddSingleton(redisDB1);
services.AddSingleton(redisDB2);
}
//连续guid初始化,示例IDGen.NextId()
services.AddSingleton<IDistributedIDGenerator, SequentialGuidIDGenerator>();
services.AddCors(options => options.AddPolicy("CorsPolicy",
builder =>
{
builder.AllowAnyMethod().AllowAnyHeader()
.WithOrigins(GlobalContext.SystemConfig.AllowCorsSite.Split(","))
.AllowCredentials();
}));
services.AddOptions();
services.AddHttpClient();
services.AddAntiforgery(options => options.HeaderName = "X-CSRF-TOKEN");
services.AddControllersWithViews().AddControllersAsServices();
//启用 Gzip 和 Brotil 压缩功能
services.AddResponseCompression(options =>
{
options.Providers.Add<BrotliCompressionProvider>();
options.Providers.Add<GzipCompressionProvider>();
options.MimeTypes =
ResponseCompressionDefaults.MimeTypes.Concat(
new[] { "image/svg+xml" });
});
services.Configure<BrotliCompressionProviderOptions>(options =>
{
options.Level = CompressionLevel.SmallestSize;
});
services.AddDataProtection().PersistKeysToFileSystem(new DirectoryInfo(GlobalContext.HostingEnvironment.ContentRootPath + Path.DirectorySeparatorChar + "DataProtection"));
}
/// <summary>
/// Autofac配置
/// </summary>
/// <param name="builder"></param>
/// <param name="projects">扫描程序</param>
/// <param name="controller">控制器</param>
/// <param name="IService">服务接口</param>
/// <param name="program">程序</param>
public void AutofacConfigureContainer(ContainerBuilder builder, List<string> projects, Type controller, Type IService, Type program)
{
if (projects == null)
{
projects = new List<string>();
}
var baseType = IService;//IDenpendency 是一个接口(所有要实现依赖注入的借口都要继承该接口)
var controllerBaseType = controller;
foreach (var item in projects)
{
var assemblys = Assembly.Load(item);//Service是继承接口的实现方法类库名称
builder.RegisterAssemblyTypes(assemblys).Where(m => baseType.IsAssignableFrom(m) && m != baseType)
.InstancePerLifetimeScope()//生命周期,这里没有使用接口方式
.PropertiesAutowired();//属性注入
//插件Controller中使用属性注入
builder.RegisterAssemblyTypes(assemblys)
.Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType)
.PropertiesAutowired();
}
//Controller中使用属性注入
builder.RegisterAssemblyTypes(program.Assembly)
.Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType)
.PropertiesAutowired();
//注册html解析
builder.RegisterInstance(HtmlEncoder.Create(UnicodeRanges.All)).SingleInstance();
}
public virtual void Configure(IApplicationBuilder app)
{
GlobalContext.RootServices = app.ApplicationServices;
//实时通讯跨域
app.UseCors("CorsPolicy");
if (WebHostEnvironment.IsDevelopment())
{
GlobalContext.SystemConfig.Debug = true;
app.UseDeveloperExceptionPage();
}
else
{
app.UseDeveloperExceptionPage();
}
//文件地址Resource
//静态资源wwwroot
app.UseStaticFiles(new StaticFileOptions
{
ContentTypeProvider = new CustomerFileExtensionContentTypeProvider(),
OnPrepareResponse = GlobalContext.SetCacheControl
});
//启用 Gzip 和 Brotil 压缩功能
app.UseResponseCompression();
app.Use(async (context, next) =>
{
context.Request.EnableBuffering();
// 执行下一个中间件
await next.Invoke();
// 释放所有未托管的服务提供器
GlobalContext.DisposeUnmanagedObjects();
});
//session
app.UseSession();
//路径
app.UseRouting();
}
}
/// <summary>
/// StartUp扩展
/// </summary>
public static class StartUpExtends
{
/// <summary>
/// 默认MVC配置
/// </summary>
/// <param name="services"></param>
/// <returns></returns>
public static IMvcBuilder AddDefaultMVC(this IServiceCollection services)
{
return services.AddControllersWithViews(options =>
{
options.Filters.Add<GlobalExceptionFilter>();
options.Filters.Add<ModelActionFilter>();
options.ModelMetadataDetailsProviders.Add(new ModelBindingMetadataProvider());
//options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
});
}
/// <summary>
/// 默认API配置
/// </summary>
/// <param name="services"></param>
/// <returns></returns>
public static IMvcBuilder AddDefaultAPI(this IServiceCollection services)
{
services.AddDirectoryBrowser();
return services.AddControllers(options =>
{
options.Filters.Add<ModelActionFilter>();
options.ModelMetadataDetailsProviders.Add(new ModelBindingMetadataProvider());
}).ConfigureApiBehaviorOptions(options =>
{
options.SuppressModelStateInvalidFilter = true;
});
}
/// <summary>
/// 默认API配置
/// </summary>
/// <param name="services"></param>
/// <returns></returns>
public static IServiceCollection AddDefaultSwaggerGen(this IServiceCollection services, string name)
{
services.AddSwaggerGen(config =>
{
foreach (var item in GlobalContext.SystemConfig.DocumentSettings.GroupOpenApiInfos)
{
config.SwaggerDoc($"{item.Group}", new OpenApiInfo { Title = item.Title, Version = item.Version, Description = item.Description });
}
var xmlFile = $"{name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
config.IncludeXmlComments(xmlPath, true); //添加控制器层注释true表示显示控制器注释
config.AddSecurityDefinition(GlobalContext.SystemConfig.TokenName, new OpenApiSecurityScheme
{
Description = "header token",
Name = GlobalContext.SystemConfig.TokenName,
In = ParameterLocation.Header,
Scheme = "",
Type = SecuritySchemeType.ApiKey,//设置类型
BearerFormat = ""
});
config.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = GlobalContext.SystemConfig.TokenName }
},
new List<string>()
}
});
});
return services;
}
/// <summary>
/// 默认API配置
/// </summary>
/// <param name="services"></param>
/// <returns></returns>
public static IApplicationBuilder AddDefaultSwaggerGen(this IApplicationBuilder app)
{
app.UseSwagger(c =>
{
c.RouteTemplate = "api-doc/{documentName}/swagger.json";
});
app.UseSwaggerUI(c =>
{
c.RoutePrefix = "api-doc";
foreach (var item in GlobalContext.SystemConfig.DocumentSettings.GroupOpenApiInfos)
{
c.SwaggerEndpoint($"{item.Group}/swagger.json", $"{item.Title}");
}
});
return app;
}
/// <summary>
/// 注入RabbitMq
/// </summary>
/// <param name="this"></param>
/// <param name="configuration">json配置</param>
/// <param name="lifeTime">生命周期,默认:单例模式</param>
/// <returns></returns>
public static IServiceCollection AddRabbitMq(
this IServiceCollection @this,
ServiceLifetime lifeTime = ServiceLifetime.Singleton)
{
if (GlobalContext.SystemConfig.RabbitMq.Enabled == false)
return @this;
switch (lifeTime)
{
case ServiceLifetime.Singleton:
@this.AddSingleton(x => new RabbitMqHelper(GlobalContext.SystemConfig.RabbitMq));
break;
case ServiceLifetime.Scoped:
@this.AddScoped(x => new RabbitMqHelper(GlobalContext.SystemConfig.RabbitMq));
break;
case ServiceLifetime.Transient:
@this.AddTransient(x => new RabbitMqHelper(GlobalContext.SystemConfig.RabbitMq));
break;
default:
break;
}
return @this;
}
#region AddWorkerService
/// <summary>
/// 自动注入 继承 BackgroundService 的后台服务
/// </summary>
/// <param name="this"></param>
/// <returns></returns>
public static IServiceCollection AddWorkerService(
this IServiceCollection @this)
{
var ret = new List<Type>();
var assemblies = Directory.GetFiles(AppContext.BaseDirectory, "WaterCloud.*.dll")
.Select(x => x.Substring(@"\").Substring(@"/").Replace(".dll", ""))
.Select(x => Assembly.Load(x)).ToArray();
//排除列表
var ignoreList= new List<string>{ "EventBusHostedService" };
foreach (var item in assemblies)
{
ret.AddRange(item.GetTypes() //获取当前类库下所有类型
.Where(t => typeof(BackgroundService).IsAssignableFrom(t)) //获取间接或直接继承t的所有类型
.Where(t => !t.IsAbstract && t.IsClass && !ignoreList.Contains(t.Name)));//获取非抽象类 排除接口继承
}
foreach (var item in ret)
{
@this.AddTransient(typeof(IHostedService), item);
}
return @this;
}
#endregion AddWorkerService
#region AddIf
/// <summary>
/// 根据条件注入服务
/// </summary>
/// <param name="this"></param>
/// <param name="condition"></param>
/// <param name="action"></param>
/// <returns></returns>
public static IServiceCollection AddIf(
this IServiceCollection @this,
bool condition,
Action<IServiceCollection> action)
{
if (condition && action != null)
action(@this);
return @this;
}
#endregion AddIf
}
}

View File

@@ -0,0 +1,40 @@
// -----------------------------------------------------------------------------
// 让 .NET 开发更简单,更通用,更流行。
// Copyright © 2020-2021 Furion, 百小僧, Baiqian Co.,Ltd.
//
// 框架名称Furion
// 框架作者:百小僧
// 框架版本2.7.9
// 源码地址Gitee https://gitee.com/dotnetchina/Furion
// Githubhttps://github.com/monksoul/Furion
// 开源协议Apache-2.0https://gitee.com/dotnetchina/Furion/blob/master/LICENSE
// -----------------------------------------------------------------------------
using System.ComponentModel;
namespace WaterCloud.Code
{
/// <summary>
/// 连续 GUID 类型选项
/// </summary>
public enum SequentialGuidType
{
/// <summary>
/// 标准连续 GUID 字符串
/// </summary>
[Description("标准连续 GUID 字符串")]
SequentialAsString,
/// <summary>
/// Byte 数组类型的连续 `GUID` 字符串
/// </summary>
[Description("Byte 数组类型的连续 `GUID` 字符串")]
SequentialAsBinary,
/// <summary>
/// 连续部分在末尾展示
/// </summary>
[Description("连续部分在末尾展示")]
SequentialAtEnd
}
}

View File

@@ -0,0 +1,27 @@
// -----------------------------------------------------------------------------
// 让 .NET 开发更简单,更通用,更流行。
// Copyright © 2020-2021 Furion, 百小僧, Baiqian Co.,Ltd.
//
// 框架名称Furion
// 框架作者:百小僧
// 框架版本2.7.9
// 源码地址Gitee https://gitee.com/dotnetchina/Furion
// Githubhttps://github.com/monksoul/Furion
// 开源协议Apache-2.0https://gitee.com/dotnetchina/Furion/blob/master/LICENSE
// -----------------------------------------------------------------------------
namespace WaterCloud.Code
{
/// <summary>
/// 分布式 ID 生成器
/// </summary>
public interface IDistributedIDGenerator
{
/// <summary>
/// 生成逻辑
/// </summary>
/// <param name="idGeneratorOptions"></param>
/// <returns></returns>
object Create(object idGeneratorOptions = default);
}
}

View File

@@ -0,0 +1,86 @@
// -----------------------------------------------------------------------------
// 让 .NET 开发更简单,更通用,更流行。
// Copyright © 2020-2021 Furion, 百小僧, Baiqian Co.,Ltd.
//
// 框架名称Furion
// 框架作者:百小僧
// 框架版本2.7.9
// 源码地址Gitee https://gitee.com/dotnetchina/Furion
// Githubhttps://github.com/monksoul/Furion
// 开源协议Apache-2.0https://gitee.com/dotnetchina/Furion/blob/master/LICENSE
// -----------------------------------------------------------------------------
using System;
using System.Security.Cryptography;
namespace WaterCloud.Code
{
/// <summary>
/// 连续 GUID ID 生成器
/// <para>代码参考自https://github.com/PomeloFoundation/Pomelo.EntityFrameworkCore.MySql/blob/ebe011a6f1b2a2a9709fe558cfc7ed3215b55c37/src/EFCore.MySql/ValueGeneration/Internal/MySqlSequentialGuidValueGenerator.cs </para>
/// </summary>
public class SequentialGuidIDGenerator : IDistributedIDGenerator
{
/// <summary>
/// 随机数生成器
/// </summary>
private static readonly RandomNumberGenerator _rng = RandomNumberGenerator.Create();
/// <summary>
/// 生成逻辑
/// </summary>
/// <param name="idGeneratorOptions"></param>
/// <returns></returns>
public object Create(object idGeneratorOptions = null)
{
// According to RFC 4122:
// dddddddd-dddd-Mddd-Ndrr-rrrrrrrrrrrr
// - M = RFC version, in this case '4' for random UUID
// - N = RFC variant (plus other bits), in this case 0b1000 for variant 1
// - d = nibbles based on UTC date/time in ticks
// - r = nibbles based on random bytes
var options = (idGeneratorOptions ?? new SequentialGuidSettings()) as SequentialGuidSettings;
var randomBytes = new byte[7];
_rng.GetBytes(randomBytes);
var ticks = (ulong)options.TimeNow.Ticks;
var uuidVersion = (ushort)4;
var uuidVariant = (ushort)0b1000;
var ticksAndVersion = (ushort)((ticks << 48 >> 52) | (ushort)(uuidVersion << 12));
var ticksAndVariant = (byte)((ticks << 60 >> 60) | (byte)(uuidVariant << 4));
if (options.LittleEndianBinary16Format)
{
var guidBytes = new byte[16];
var tickBytes = BitConverter.GetBytes(ticks);
if (BitConverter.IsLittleEndian)
{
Array.Reverse(tickBytes);
}
Buffer.BlockCopy(tickBytes, 0, guidBytes, 0, 6);
guidBytes[6] = (byte)(ticksAndVersion << 8 >> 8);
guidBytes[7] = (byte)(ticksAndVersion >> 8);
guidBytes[8] = ticksAndVariant;
Buffer.BlockCopy(randomBytes, 0, guidBytes, 9, 7);
return new Guid(guidBytes);
}
var guid = new Guid((uint)(ticks >> 32), (ushort)(ticks << 32 >> 48), ticksAndVersion,
ticksAndVariant,
randomBytes[0],
randomBytes[1],
randomBytes[2],
randomBytes[3],
randomBytes[4],
randomBytes[5],
randomBytes[6]);
return guid;
}
}
}

View File

@@ -0,0 +1,45 @@
// -----------------------------------------------------------------------------
// 让 .NET 开发更简单,更通用,更流行。
// Copyright © 2020-2021 Furion, 百小僧, Baiqian Co.,Ltd.
//
// 框架名称Furion
// 框架作者:百小僧
// 框架版本2.7.9
// 源码地址Gitee https://gitee.com/dotnetchina/Furion
// Githubhttps://github.com/monksoul/Furion
// 开源协议Apache-2.0https://gitee.com/dotnetchina/Furion/blob/master/LICENSE
// -----------------------------------------------------------------------------
using System;
namespace WaterCloud.Code
{
/// <summary>
/// ID 生成器
/// </summary>
public static class IDGen
{
/// <summary>
/// 生成唯一 ID
/// </summary>
/// <param name="idGeneratorOptions"></param>
/// <param name="serviceProvider"></param>
/// <returns></returns>
public static object NextID(object idGeneratorOptions)
{
return ((IDistributedIDGenerator)GlobalContext.RootServices.GetService(typeof(IDistributedIDGenerator))).Create(idGeneratorOptions);
}
/// <summary>
/// 生成连续 GUID
/// </summary>
/// <param name="guidType"></param>
/// <param name="serviceProvider"></param>
/// <returns></returns>
public static Guid NextID(SequentialGuidType guidType = SequentialGuidType.SequentialAsString)
{
var sequentialGuid = GlobalContext.RootServices.GetService(typeof(IDistributedIDGenerator)) as IDistributedIDGenerator;
return (Guid)sequentialGuid.Create();
}
}
}

View File

@@ -0,0 +1,32 @@
// -----------------------------------------------------------------------------
// 让 .NET 开发更简单,更通用,更流行。
// Copyright © 2020-2021 Furion, 百小僧, Baiqian Co.,Ltd.
//
// 框架名称Furion
// 框架作者:百小僧
// 框架版本2.7.9
// 源码地址Gitee https://gitee.com/dotnetchina/Furion
// Githubhttps://github.com/monksoul/Furion
// 开源协议Apache-2.0https://gitee.com/dotnetchina/Furion/blob/master/LICENSE
// -----------------------------------------------------------------------------
using System;
namespace WaterCloud.Code
{
/// <summary>
/// 连续 GUID 配置
/// </summary>
public sealed class SequentialGuidSettings
{
/// <summary>
/// 当前时间
/// </summary>
public DateTimeOffset TimeNow { get; set; } = DateTimeOffset.UtcNow;
/// <summary>
/// LittleEndianBinary 16 格式化
/// </summary>
public bool LittleEndianBinary16Format { get; set; } = false;
}
}

View File

@@ -0,0 +1,35 @@
// -----------------------------------------------------------------------------
// 让 .NET 开发更简单,更通用,更流行。
// Copyright © 2020-2021 Furion, 百小僧, Baiqian Co.,Ltd.
//
// 框架名称Furion
// 框架作者:百小僧
// 框架版本2.7.9
// 源码地址Gitee https://gitee.com/dotnetchina/Furion
// Githubhttps://github.com/monksoul/Furion
// 开源协议Apache-2.0https://gitee.com/dotnetchina/Furion/blob/master/LICENSE
// -----------------------------------------------------------------------------
namespace WaterCloud.Code
{
/// <summary>
/// 短 ID 约束
/// </summary>
internal static class Constants
{
/// <summary>
/// 最小长度
/// </summary>
public const int MinimumAutoLength = 8;
/// <summary>
/// 最大长度
/// </summary>
public const int MaximumAutoLength = 14;
/// <summary>
/// 最小可选字符长度
/// </summary>
public const int MinimumCharacterSetLength = 50;
}
}

View File

@@ -0,0 +1,46 @@
// -----------------------------------------------------------------------------
// 让 .NET 开发更简单,更通用,更流行。
// Copyright © 2020-2021 Furion, 百小僧, Baiqian Co.,Ltd.
//
// 框架名称Furion
// 框架作者:百小僧
// 框架版本2.7.9
// 源码地址Gitee https://gitee.com/dotnetchina/Furion
// Githubhttps://github.com/monksoul/Furion
// 开源协议Apache-2.0https://gitee.com/dotnetchina/Furion/blob/master/LICENSE
// -----------------------------------------------------------------------------
using System;
namespace WaterCloud.Code
{
/// <summary>
/// 随机数帮助类
/// </summary>
internal static class RandomHelpers
{
/// <summary>
/// 随机数对象
/// </summary>
private static readonly Random Random = new();
/// <summary>
/// 线程锁
/// </summary>
private static readonly object ThreadLock = new();
/// <summary>
/// 生成线程安全的范围内随机数
/// </summary>
/// <param name="min"></param>
/// <param name="max"></param>
/// <returns></returns>
public static int GenerateNumberInRange(int min, int max)
{
lock (ThreadLock)
{
return Random.Next(min, max);
}
}
}
}

View File

@@ -0,0 +1,37 @@
// -----------------------------------------------------------------------------
// 让 .NET 开发更简单,更通用,更流行。
// Copyright © 2020-2021 Furion, 百小僧, Baiqian Co.,Ltd.
//
// 框架名称Furion
// 框架作者:百小僧
// 框架版本2.7.9
// 源码地址Gitee https://gitee.com/dotnetchina/Furion
// Githubhttps://github.com/monksoul/Furion
// 开源协议Apache-2.0https://gitee.com/dotnetchina/Furion/blob/master/LICENSE
// -----------------------------------------------------------------------------
namespace WaterCloud.Code
{
/// <summary>
/// 短 ID 生成配置选项
/// </summary>
public class GenerationOptions
{
/// <summary>
/// 是否使用数字
/// <para>默认 false</para>
/// </summary>
public bool UseNumbers { get; set; }
/// <summary>
/// 是否使用特殊字符
/// <para>默认 true</para>
/// </summary>
public bool UseSpecialCharacters { get; set; } = true;
/// <summary>
/// 设置短 ID 长度
/// </summary>
public int Length { get; set; } = RandomHelpers.GenerateNumberInRange(Constants.MinimumAutoLength, Constants.MaximumAutoLength);
}
}

View File

@@ -0,0 +1,161 @@
// -----------------------------------------------------------------------------
// 让 .NET 开发更简单,更通用,更流行。
// Copyright © 2020-2021 Furion, 百小僧, Baiqian Co.,Ltd.
//
// 框架名称Furion
// 框架作者:百小僧
// 框架版本2.7.9
// 源码地址Gitee https://gitee.com/dotnetchina/Furion
// Githubhttps://github.com/monksoul/Furion
// 开源协议Apache-2.0https://gitee.com/dotnetchina/Furion/blob/master/LICENSE
// -----------------------------------------------------------------------------
using System;
using System.Linq;
using System.Text;
namespace WaterCloud.Code
{
/// <summary>
/// 短 ID 生成核心代码
/// <para>代码参考自https://github.com/bolorundurowb/shortid </para>
/// </summary>
public static class ShortIDGen
{
/// <summary>
/// 短 ID 生成器期初数据
/// </summary>
private static Random _random = new();
private const string Bigs = "ABCDEFGHIJKLMNPQRSTUVWXY";
private const string Smalls = "abcdefghjklmnopqrstuvwxyz";
private const string Numbers = "0123456789";
private const string Specials = "_-";
private static string _pool = $"{Smalls}{Bigs}";
/// <summary>
/// 线程安全锁
/// </summary>
private static readonly object ThreadLock = new();
/// <summary>
/// 生成目前比较主流的短 ID
/// <para>包含字母、数字,不包含特殊字符</para>
/// <para>默认生成 8 位</para>
/// </summary>
/// <returns></returns>
public static string NextID()
{
return NextID(new GenerationOptions
{
UseNumbers = true,
UseSpecialCharacters = false,
Length = 8
});
}
/// <summary>
/// 生成短 ID
/// </summary>
/// <param name="options"></param>
/// <returns></returns>
public static string NextID(GenerationOptions options)
{
// 配置必填
if (options == null)
{
throw new ArgumentNullException(nameof(options));
}
// 判断生成的长度是否小于规定的长度,规定为 8
if (options.Length < Constants.MinimumAutoLength)
{
throw new ArgumentException(
$"The specified length of {options.Length} is less than the lower limit of {Constants.MinimumAutoLength} to avoid conflicts.");
}
var characterPool = _pool;
var poolBuilder = new StringBuilder(characterPool);
// 是否包含数字
if (options.UseNumbers)
{
poolBuilder.Append(Numbers);
}
// 是否包含特殊字符
if (options.UseSpecialCharacters)
{
poolBuilder.Append(Specials);
}
var pool = poolBuilder.ToString();
// 生成拼接
var output = new char[options.Length];
for (var i = 0; i < options.Length; i++)
{
lock (ThreadLock)
{
var charIndex = _random.Next(0, pool.Length);
output[i] = pool[charIndex];
}
}
return new string(output);
}
/// <summary>
/// 设置参与运算的字符,最少 50 位
/// </summary>
/// <param name="characters"></param>
public static void SetCharacters(string characters)
{
if (string.IsNullOrWhiteSpace(characters))
{
throw new ArgumentException("The replacement characters must not be null or empty.");
}
var charSet = characters
.ToCharArray()
.Where(x => !char.IsWhiteSpace(x))
.Distinct()
.ToArray();
if (charSet.Length < Constants.MinimumCharacterSetLength)
{
throw new InvalidOperationException(
$"The replacement characters must be at least {Constants.MinimumCharacterSetLength} letters in length and without whitespace.");
}
lock (ThreadLock)
{
_pool = new string(charSet);
}
}
/// <summary>
/// 设置种子步长
/// </summary>
/// <param name="seed"></param>
public static void SetSeed(int seed)
{
lock (ThreadLock)
{
_random = new Random(seed);
}
}
/// <summary>
/// 重置所有配置
/// </summary>
public static void Reset()
{
lock (ThreadLock)
{
_random = new Random();
_pool = $"{Smalls}{Bigs}";
}
}
}
}

View File

@@ -0,0 +1,788 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System;
using System.Collections;
using System.Collections.Generic;
namespace WaterCloud.Code
{
public static partial class Extensions
{
#region
/// <summary>
/// 转换为整型
/// </summary>
/// <param name="data">数据</param>
public static int ToInt(this object data)
{
if (data == null)
return 0;
int result;
var success = int.TryParse(data.ToString(), out result);
if (success)
return result;
try
{
return Convert.ToInt32(ToDouble(data, 0));
}
catch (Exception)
{
return 0;
}
}
/// <summary>
/// 将object转换为long若转换失败则返回0。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static long ToLong(this object obj)
{
try
{
return long.Parse(obj.ToString());
}
catch
{
return 0L;
}
}
/// <summary>
/// 转换为可空整型
/// </summary>
/// <param name="data">数据</param>
public static int? ToIntOrNull(this object data)
{
if (data == null)
return null;
int result;
bool isValid = int.TryParse(data.ToString(), out result);
if (isValid)
return result;
return null;
}
/// <summary>
/// 转换为双精度浮点数
/// </summary>
/// <param name="data">数据</param>
public static double ToDouble(this object data)
{
if (data == null)
return 0;
double result;
return double.TryParse(data.ToString(), out result) ? result : 0;
}
/// <summary>
/// 转换为双精度浮点数,并按指定的小数位4舍5入
/// </summary>
/// <param name="data">数据</param>
/// <param name="digits">小数位数</param>
public static double ToDouble(this object data, int digits)
{
return Math.Round(ToDouble(data), digits);
}
/// <summary>
/// 转换为可空双精度浮点数
/// </summary>
/// <param name="data">数据</param>
public static double? ToDoubleOrNull(this object data)
{
if (data == null)
return null;
double result;
bool isValid = double.TryParse(data.ToString(), out result);
if (isValid)
return result;
return null;
}
/// <summary>
/// 转换为高精度浮点数
/// </summary>
/// <param name="data">数据</param>
public static decimal ToDecimal(this object data)
{
if (data == null)
return 0;
decimal result;
return decimal.TryParse(data.ToString(), out result) ? result : 0;
}
/// <summary>
/// 转换为高精度浮点数,并按指定的小数位4舍5入
/// </summary>
/// <param name="data">数据</param>
/// <param name="digits">小数位数</param>
public static decimal ToDecimal(this object data, int digits)
{
return Math.Round(ToDecimal(data), digits);
}
/// <summary>
/// 转换为可空高精度浮点数
/// </summary>
/// <param name="data">数据</param>
public static decimal? ToDecimalOrNull(this object data)
{
if (data == null)
return null;
decimal result;
bool isValid = decimal.TryParse(data.ToString(), out result);
if (isValid)
return result;
return null;
}
/// <summary>
/// 转换为可空高精度浮点数,并按指定的小数位4舍5入
/// </summary>
/// <param name="data">数据</param>
/// <param name="digits">小数位数</param>
public static decimal? ToDecimalOrNull(this object data, int digits)
{
var result = ToDecimalOrNull(data);
if (result == null)
return null;
return Math.Round(result.Value, digits);
}
#endregion
#region
/// <summary>
/// 转换为日期
/// </summary>
/// <param name="data">数据</param>
public static DateTime ToDate(this object data)
{
if (data == null)
return DateTime.MinValue;
DateTime result;
return DateTime.TryParse(data.ToString(), out result) ? result : DateTime.MinValue;
}
/// <summary>
/// 转换为可空日期
/// </summary>
/// <param name="data">数据</param>
public static DateTime? ToDateOrNull(this object data)
{
if (data == null)
return null;
DateTime result;
bool isValid = DateTime.TryParse(data.ToString(), out result);
if (isValid)
return result;
return null;
}
#endregion
#region
/// <summary>
/// 转换为布尔值
/// </summary>
/// <param name="data">数据</param>
public static bool ToBool(this object data)
{
if (data == null)
return false;
bool? value = GetBool(data);
if (value != null)
return value.Value;
bool result;
return bool.TryParse(data.ToString(), out result) && result;
}
/// <summary>
/// 获取布尔值
/// </summary>
private static bool? GetBool(this object data)
{
switch (data.ToString().Trim().ToLower())
{
case "0":
return false;
case "1":
return true;
case "是":
return true;
case "否":
return false;
case "yes":
return true;
case "no":
return false;
default:
return null;
}
}
/// <summary>
/// 转换为可空布尔值
/// </summary>
/// <param name="data">数据</param>
public static bool? ToBoolOrNull(this object data)
{
if (data == null)
return null;
bool? value = GetBool(data);
if (value != null)
return value.Value;
bool result;
bool isValid = bool.TryParse(data.ToString(), out result);
if (isValid)
return result;
return null;
}
#endregion
#region
/// <summary>
/// 是否为空
/// </summary>
/// <param name="value">值</param>
public static bool IsEmpty(this string value)
{
return string.IsNullOrWhiteSpace(value);
}
/// <summary>
/// 是否为空
/// </summary>
/// <param name="value"></param>
/// <returns></returns>
public static bool IsEmpty(this object value)
{
if (value != null && !string.IsNullOrEmpty(value.ToString()))
{
return false;
}
else
{
return true;
}
}
/// <summary>
/// 是否为空
/// </summary>
/// <param name="value">值</param>
public static bool IsEmpty(this Guid? value)
{
if (value == null)
return true;
return IsEmpty(value.Value);
}
/// <summary>
/// 是否为空
/// </summary>
/// <param name="value">值</param>
public static bool IsEmpty(this Guid value)
{
if (value == Guid.Empty)
return true;
return false;
}
#endregion
#region
/// <summary>
/// 强制转换类型
/// </summary>
/// <typeparam name="TResult"></typeparam>
/// <param name="source"></param>
/// <returns></returns>
public static IEnumerable<TResult> CastSuper<TResult>(this IEnumerable source)
{
foreach (object item in source)
{
yield return (TResult)Convert.ChangeType(item, typeof(TResult));
}
}
#endregion
#region long
/// <summary>
/// 将object转换为long若转换失败则返回0。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static long ParseToLong(this object obj)
{
try
{
return long.Parse(obj.ToString());
}
catch
{
return 0L;
}
}
/// <summary>
/// 将object转换为long若转换失败则返回指定值。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static long ParseToLong(this string str, long defaultValue)
{
try
{
return long.Parse(str);
}
catch
{
return defaultValue;
}
}
#endregion long
#region int
/// <summary>
/// 将object转换为int若转换失败则返回0。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static int ParseToInt(this object str)
{
try
{
return Convert.ToInt32(str);
}
catch
{
return 0;
}
}
/// <summary>
/// 将object转换为int若转换失败则返回指定值。不抛出异常。
/// null返回默认值
/// </summary>
/// <param name="str"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static int ParseToInt(this object str, int defaultValue)
{
if (str == null)
{
return defaultValue;
}
try
{
return Convert.ToInt32(str);
}
catch
{
return defaultValue;
}
}
#endregion int
#region short
/// <summary>
/// 将object转换为short若转换失败则返回0。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static short ParseToShort(this object obj)
{
try
{
return short.Parse(obj.ToString());
}
catch
{
return 0;
}
}
/// <summary>
/// 将object转换为short若转换失败则返回指定值。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static short ParseToShort(this object str, short defaultValue)
{
try
{
return short.Parse(str.ToString());
}
catch
{
return defaultValue;
}
}
#endregion short
#region demical
/// <summary>
/// 将object转换为demical若转换失败则返回指定值。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static decimal ParseToDecimal(this object str, decimal defaultValue)
{
try
{
return decimal.Parse(str.ToString());
}
catch
{
return defaultValue;
}
}
/// <summary>
/// 将object转换为demical若转换失败则返回0。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static decimal ParseToDecimal(this object str)
{
try
{
return decimal.Parse(str.ToString());
}
catch
{
return 0;
}
}
#endregion demical
#region bool
/// <summary>
/// 将object转换为bool若转换失败则返回false。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static bool ParseToBool(this object str)
{
try
{
return bool.Parse(str.ToString());
}
catch
{
return false;
}
}
/// <summary>
/// 将object转换为bool若转换失败则返回指定值。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static bool ParseToBool(this object str, bool result)
{
try
{
return bool.Parse(str.ToString());
}
catch
{
return result;
}
}
#endregion bool
#region float
/// <summary>
/// 将object转换为float若转换失败则返回0。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static float ParseToFloat(this object str)
{
try
{
return float.Parse(str.ToString());
}
catch
{
return 0;
}
}
/// <summary>
/// 将object转换为float若转换失败则返回指定值。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static float ParseToFloat(this object str, float result)
{
try
{
return float.Parse(str.ToString());
}
catch
{
return result;
}
}
#endregion float
#region Guid
/// <summary>
/// 将string转换为Guid若转换失败则返回Guid.Empty。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static Guid ParseToGuid(this string str)
{
try
{
return new Guid(str);
}
catch
{
return Guid.Empty;
}
}
#endregion Guid
#region DateTime
/// <summary>
/// 将string转换为DateTime若转换失败则返回日期最小值。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static DateTime ParseToDateTime(this 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;
}
}
/// <summary>
/// 将string转换为DateTime若转换失败则返回默认值。
/// </summary>
/// <param name="str"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static DateTime ParseToDateTime(this string str, DateTime? defaultValue)
{
try
{
if (string.IsNullOrWhiteSpace(str))
{
return defaultValue.GetValueOrDefault();
}
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 defaultValue.GetValueOrDefault();
}
}
#endregion DateTime
#region string
/// <summary>
/// 将object转换为string若转换失败则返回""。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string ParseToString(this object obj)
{
try
{
if (obj == null)
{
return string.Empty;
}
else
{
return obj.ToString();
}
}
catch
{
return string.Empty;
}
}
public static string ParseToStrings<T>(this object obj)
{
try
{
var list = obj as IEnumerable<T>;
if (list != null)
{
return string.Join(",", list);
}
else
{
return obj.ToString();
}
}
catch
{
return string.Empty;
}
}
#endregion string
#region double
/// <summary>
/// 将object转换为double若转换失败则返回0。不抛出异常。
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
public static double ParseToDouble(this object obj)
{
try
{
return double.Parse(obj.ToString());
}
catch
{
return 0;
}
}
/// <summary>
/// 将object转换为double若转换失败则返回指定值。不抛出异常。
/// </summary>
/// <param name="str"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static double ParseToDouble(this object str, double defaultValue)
{
try
{
return double.Parse(str.ToString());
}
catch
{
return defaultValue;
}
}
#endregion double
/// <summary>
/// 安全返回值
/// </summary>
/// <param name="value">可空值</param>
public static T SafeValue<T>(this T? value) where T : struct
{
return value ?? default(T);
}
}
}

View File

@@ -0,0 +1,187 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System;
using System.Text;
namespace WaterCloud.Code
{
public static partial class Extensions
{
/// <summary>
/// 获取格式化字符串,带时分秒,格式:"yyyy-MM-dd HH:mm:ss"
/// </summary>
/// <param name="dateTime">日期</param>
/// <param name="isRemoveSecond">是否移除秒</param>
public static string ToDateTimeString(this DateTime dateTime, bool isRemoveSecond = false)
{
if (isRemoveSecond)
return dateTime.ToString("yyyy-MM-dd HH:mm");
return dateTime.ToString("yyyy-MM-dd HH:mm:ss");
}
/// <summary>
/// 获取格式化字符串,带时分秒,格式:"yyyy-MM-dd HH:mm:ss"
/// </summary>
/// <param name="dateTime">日期</param>
/// <param name="isRemoveSecond">是否移除秒</param>
public static string ToDateTimeString(this DateTime? dateTime, bool isRemoveSecond = false)
{
if (dateTime == null)
return string.Empty;
return ToDateTimeString(dateTime.Value, isRemoveSecond);
}
/// <summary>
/// 获取格式化字符串,不带时分秒,格式:"yyyy-MM-dd"
/// </summary>
/// <param name="dateTime">日期</param>
public static string ToDateString(this DateTime dateTime)
{
return dateTime.ToString("yyyy-MM-dd");
}
/// <summary>
/// 获取格式化字符串,不带时分秒,格式:"yyyy-MM-dd"
/// </summary>
/// <param name="dateTime">日期</param>
public static string ToDateString()
{
return DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
}
/// <summary>
/// 获取格式化字符串,不带时分秒,格式:"yyyy-MM-dd"
/// </summary>
/// <param name="dateTime">日期</param>
public static string ToDateString(this DateTime? dateTime)
{
if (dateTime == null)
return string.Empty;
return ToDateString(dateTime.Value);
}
/// <summary>
/// 获取格式化字符串,不带年月日,格式:"HH:mm:ss"
/// </summary>
/// <param name="dateTime">日期</param>
public static string ToTimeString(this DateTime dateTime)
{
return dateTime.ToString("HH:mm:ss");
}
/// <summary>
/// 获取格式化字符串,不带年月日,格式:"HH:mm:ss"
/// </summary>
/// <param name="dateTime">日期</param>
public static string ToTimeString(this DateTime? dateTime)
{
if (dateTime == null)
return string.Empty;
return ToTimeString(dateTime.Value);
}
/// <summary>
/// 获取格式化字符串,带毫秒,格式:"yyyy-MM-dd HH:mm:ss.fff"
/// </summary>
/// <param name="dateTime">日期</param>
public static string ToMillisecondString(this DateTime dateTime)
{
return dateTime.ToString("yyyy-MM-dd HH:mm:ss.fff");
}
/// <summary>
/// 获取格式化字符串,带毫秒,格式:"yyyy-MM-dd HH:mm:ss.fff"
/// </summary>
/// <param name="dateTime">日期</param>
public static string ToMillisecondString(this DateTime? dateTime)
{
if (dateTime == null)
return string.Empty;
return ToMillisecondString(dateTime.Value);
}
/// <summary>
/// 获取格式化字符串,不带时分秒,格式:"yyyy年MM月dd日"
/// </summary>
/// <param name="dateTime">日期</param>
public static string ToChineseDateString(this DateTime dateTime)
{
return string.Format("{0}年{1}月{2}日", dateTime.Year, dateTime.Month, dateTime.Day);
}
/// <summary>
/// 获取格式化字符串,不带时分秒,格式:"yyyy年MM月dd日"
/// </summary>
/// <param name="dateTime">日期</param>
public static string ToChineseDateString(this DateTime? dateTime)
{
if (dateTime == null)
return string.Empty;
return ToChineseDateString(dateTime.SafeValue());
}
/// <summary>
/// 获取格式化字符串,带时分秒,格式:"yyyy年MM月dd日 HH时mm分"
/// </summary>
/// <param name="dateTime">日期</param>
/// <param name="isRemoveSecond">是否移除秒</param>
public static string ToChineseDateTimeString(this DateTime dateTime, bool isRemoveSecond = false)
{
StringBuilder result = new StringBuilder();
result.AppendFormat("{0}年{1}月{2}日", dateTime.Year, dateTime.Month, dateTime.Day);
result.AppendFormat(" {0}时{1}分", dateTime.Hour, dateTime.Minute);
if (isRemoveSecond == false)
result.AppendFormat("{0}秒", dateTime.Second);
return result.ToString();
}
/// <summary>
/// 获取格式化字符串,带时分秒,格式:"yyyy年MM月dd日 HH时mm分"
/// </summary>
/// <param name="dateTime">日期</param>
/// <param name="isRemoveSecond">是否移除秒</param>
public static string ToChineseDateTimeString(this DateTime? dateTime, bool isRemoveSecond = false)
{
if (dateTime == null)
return string.Empty;
return ToChineseDateTimeString(dateTime.Value);
}
#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
}
}

View File

@@ -0,0 +1,114 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
namespace WaterCloud.Code
{
public static partial class Extensions
{
#region dictionary类型
/// <summary>
/// 转成dictionary类型
/// </summary>
/// <param name="enumType"></param>
/// <returns></returns>
public static Dictionary<int, string> EnumToDictionary(this Type enumType)
{
Dictionary<int, string> dictionary = new Dictionary<int, string>();
Type typeDescription = typeof(DescriptionAttribute);
FieldInfo[] fields = enumType.GetFields();
int sValue = 0;
string sText = string.Empty;
foreach (FieldInfo field in fields)
{
if (field.FieldType.IsEnum)
{
sValue = ((int)enumType.InvokeMember(field.Name, BindingFlags.GetField, null, null, null));
object[] arr = field.GetCustomAttributes(typeDescription, true);
if (arr.Length > 0)
{
DescriptionAttribute da = (DescriptionAttribute)arr[0];
sText = da.Description;
}
else
{
sText = field.Name;
}
dictionary.Add(sValue, sText);
}
}
return dictionary;
}
/// <summary>
/// 枚举成员转成键值对Json字符串
/// </summary>
/// <param name="enumType"></param>
/// <returns></returns>
public static string EnumToDictionaryString(this Type enumType)
{
List<KeyValuePair<int, string>> dictionaryList = EnumToDictionary(enumType).ToList();
var sJson = JsonConvert.SerializeObject(dictionaryList);
return sJson;
}
#endregion dictionary类型
#region
/// <summary>
/// 获取枚举值对应的描述
/// </summary>
/// <param name="enumType"></param>
/// <returns></returns>
public static string GetDescription(this System.Enum enumType)
{
FieldInfo EnumInfo = enumType.GetType().GetField(enumType.ToString());
if (EnumInfo != null)
{
DescriptionAttribute[] EnumAttributes = (DescriptionAttribute[])EnumInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
if (EnumAttributes.Length > 0)
{
return EnumAttributes[0].Description;
}
}
return enumType.ToString();
}
#endregion
#region
public static string GetDescriptionByEnum<T>(this object obj)
{
var tEnum = System.Enum.Parse(typeof(T), obj.ParseToString()) as System.Enum;
var description = tEnum.GetDescription();
return description;
}
/// <summary>
/// 枚举
/// </summary>
/// <param name="enumType"></param>
/// <returns></returns>
public static string ToDescription(this Enum enumType)
{
if (enumType == null)
return "";
System.Reflection.FieldInfo fieldInfo = enumType.GetType().GetField(enumType.ToString());
object[] attribArray = fieldInfo.GetCustomAttributes(false);
if (attribArray.Length == 0)
return enumType.ToString();
else
return (attribArray[0] as DescriptionAttribute).Description;
}
#endregion
}
}

View File

@@ -0,0 +1,14 @@
using System;
namespace WaterCloud.Code
{
public static partial class Extensions
{
public static Exception GetOriginalException(this Exception ex)
{
if (ex.InnerException == null) return ex;
return ex.InnerException.GetOriginalException();
}
}
}

View File

@@ -0,0 +1,156 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
namespace WaterCloud.Code
{
public static partial class Extensions
{
/// <summary>
/// 获取描述
/// </summary>
/// <param name="value">布尔值</param>
public static string Description(this bool value)
{
return value ? "是" : "否";
}
/// <summary>
/// 获取描述
/// </summary>
/// <param name="value">布尔值</param>
public static string Description(this bool? value)
{
return value == null ? "" : Description(value.Value);
}
/// <summary>
/// 获取格式化字符串
/// </summary>
/// <param name="number">数值</param>
/// <param name="defaultValue">空值显示的默认文本</param>
public static string Format(this int number, string defaultValue = "")
{
if (number == 0)
return defaultValue;
return number.ToString();
}
/// <summary>
/// 获取格式化字符串
/// </summary>
/// <param name="number">数值</param>
/// <param name="defaultValue">空值显示的默认文本</param>
public static string Format(this int? number, string defaultValue = "")
{
return Format(number.SafeValue(), defaultValue);
}
/// <summary>
/// 获取格式化字符串
/// </summary>
/// <param name="number">数值</param>
/// <param name="defaultValue">空值显示的默认文本</param>
public static string Format(this decimal number, string defaultValue = "")
{
if (number == 0)
return defaultValue;
return string.Format("{0:0.##}", number);
}
/// <summary>
/// 获取格式化字符串
/// </summary>
/// <param name="number">数值</param>
/// <param name="defaultValue">空值显示的默认文本</param>
public static string Format(this decimal? number, string defaultValue = "")
{
return Format(number.SafeValue(), defaultValue);
}
/// <summary>
/// 获取格式化字符串
/// </summary>
/// <param name="number">数值</param>
/// <param name="defaultValue">空值显示的默认文本</param>
public static string Format(this double number, string defaultValue = "")
{
if (number == 0)
return defaultValue;
return string.Format("{0:0.##}", number);
}
/// <summary>
/// 获取格式化字符串
/// </summary>
/// <param name="number">数值</param>
/// <param name="defaultValue">空值显示的默认文本</param>
public static string Format(this double? number, string defaultValue = "")
{
return Format(number.SafeValue(), defaultValue);
}
/// <summary>
/// 获取格式化字符串,带¥
/// </summary>
/// <param name="number">数值</param>
public static string FormatRmb(this decimal number)
{
if (number == 0)
return "¥0";
return string.Format("¥{0:0.##}", number);
}
/// <summary>
/// 获取格式化字符串,带¥
/// </summary>
/// <param name="number">数值</param>
public static string FormatRmb(this decimal? number)
{
return FormatRmb(number.SafeValue());
}
/// <summary>
/// 获取格式化字符串,带%
/// </summary>
/// <param name="number">数值</param>
public static string FormatPercent(this decimal number)
{
if (number == 0)
return string.Empty;
return string.Format("{0:0.##}%", number);
}
/// <summary>
/// 获取格式化字符串,带%
/// </summary>
/// <param name="number">数值</param>
public static string FormatPercent(this decimal? number)
{
return FormatPercent(number.SafeValue());
}
/// <summary>
/// 获取格式化字符串,带%
/// </summary>
/// <param name="number">数值</param>
public static string FormatPercent(this double number)
{
if (number == 0)
return string.Empty;
return string.Format("{0:0.##}%", number);
}
/// <summary>
/// 获取格式化字符串,带%
/// </summary>
/// <param name="number">数值</param>
public static string FormatPercent(this double? number)
{
return FormatPercent(number.SafeValue());
}
}
}

View File

@@ -0,0 +1,211 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace WaterCloud.Code
{
public static partial class ExtLinq
{
public static Expression Property(this Expression expression, string propertyName)
{
return Expression.Property(expression, propertyName);
}
public static Expression AndAlso(this Expression left, Expression right)
{
return Expression.AndAlso(left, right);
}
public static Expression OrElse(this Expression left, Expression right)
{
return Expression.OrElse(left, right);
}
public static Expression Call(this Expression instance, string methodName, params Expression[] arguments)
{
return Expression.Call(instance, instance.Type.GetMethod(methodName), arguments);
}
public static Expression GreaterThan(this Expression left, Expression right)
{
return Expression.GreaterThan(left, right);
}
public static Expression<T> ToLambda<T>(this Expression body, params ParameterExpression[] parameters)
{
return Expression.Lambda<T>(body, parameters);
}
public static Expression<Func<T, bool>> True<T>()
{ return param => true; }
public static Expression<Func<T, bool>> False<T>()
{ return param => false; }
public static Expression<Func<T, bool>> AndAlso<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
{
return first.Compose(second, Expression.AndAlso);
}
public static Expression<Func<T, bool>> OrElse<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
{
return first.Compose(second, Expression.OrElse);
}
public static Expression<T> Compose<T>(this Expression<T> first, Expression<T> second, Func<Expression, Expression, Expression> merge)
{
var map = first.Parameters
.Select((f, i) => new { f, s = second.Parameters[i] })
.ToDictionary(p => p.s, p => p.f);
var secondBody = ParameterRebinder.ReplaceParameters(map, second.Body);
return Expression.Lambda<T>(merge(first.Body, secondBody), first.Parameters);
}
private class ParameterRebinder : ExpressionVisitor
{
private readonly Dictionary<ParameterExpression, ParameterExpression> map;
/// <summary>
/// Initializes a new instance of the <see cref="ParameterRebinder"/> class.
/// </summary>
/// <param name="map">The map.</param>
private ParameterRebinder(Dictionary<ParameterExpression, ParameterExpression> map)
{
this.map = map ?? new Dictionary<ParameterExpression, ParameterExpression>();
}
/// <summary>
/// Replaces the parameters.
/// </summary>
/// <param name="map">The map.</param>
/// <param name="exp">The exp.</param>
/// <returns>Expression</returns>
public static Expression ReplaceParameters(Dictionary<ParameterExpression, ParameterExpression> map, Expression exp)
{
return new ParameterRebinder(map).Visit(exp);
}
protected override Expression VisitParameter(ParameterExpression p)
{
ParameterExpression replacement;
if (map.TryGetValue(p, out replacement))
{
p = replacement;
}
return base.VisitParameter(p);
}
}
public static ParameterExpression CreateLambdaParam<T>(string name)
{
return Expression.Parameter(typeof(T), name);
}
/// <summary>
/// 创建完整的lambda
/// </summary>
public static LambdaExpression GenerateLambda(this ParameterExpression param, Expression body)
{
//c=>c.XXX=="XXX"
return Expression.Lambda(body, param);
}
public static Expression<Func<T, bool>> GenerateTypeLambda<T>(this ParameterExpression param, Expression body)
{
return (Expression<Func<T, bool>>)(param.GenerateLambda(body));
}
public static Expression Or(this Expression expression, Expression expressionRight)
{
return Expression.Or(expression, expressionRight);
}
public static Expression And(this Expression expression, Expression expressionRight)
{
return Expression.And(expression, expressionRight);
}
public static IOrderedQueryable<TEntity> SortBy<TEntity>(this IQueryable<TEntity> query, Expression<Func<TEntity, dynamic>> sortPredicate)
where TEntity : class, new()
{
return InvokeSortBy(query, sortPredicate, SortOrder.Ascending);
}
public static IOrderedQueryable<TEntity> SortByDescending<TEntity>(this IQueryable<TEntity> query, Expression<Func<TEntity, dynamic>> sortPredicate)
where TEntity : class, new()
{
return InvokeSortBy(query, sortPredicate, SortOrder.Descending);
}
private static IOrderedQueryable<TEntity> InvokeSortBy<TEntity>(IQueryable<TEntity> query,
Expression<Func<TEntity, dynamic>> sortPredicate, SortOrder sortOrder)
where TEntity : class, new()
{
var param = sortPredicate.Parameters[0];
string propertyName = null;
Type propertyType = null;
Expression bodyExpression = null;
if (sortPredicate.Body is UnaryExpression)
{
var unaryExpression = sortPredicate.Body as UnaryExpression;
bodyExpression = unaryExpression.Operand;
}
else if (sortPredicate.Body is MemberExpression)
{
bodyExpression = sortPredicate.Body;
}
else
throw new ArgumentException(@"The body of the sort predicate expression should be
either UnaryExpression or MemberExpression.", "sortPredicate");
var memberExpression = (MemberExpression)bodyExpression;
propertyName = memberExpression.Member.Name;
if (memberExpression.Member.MemberType == MemberTypes.Property)
{
var propertyInfo = memberExpression.Member as PropertyInfo;
if (propertyInfo != null) propertyType = propertyInfo.PropertyType;
}
else
throw new InvalidOperationException(@"Cannot evaluate the type of property since the member expression
represented by the sort predicate expression does not contain a PropertyInfo object.");
var funcType = typeof(Func<,>).MakeGenericType(typeof(TEntity), propertyType);
var convertedExpression = Expression.Lambda(funcType,
Expression.Convert(Expression.Property(param, propertyName), propertyType), param);
var sortingMethods = typeof(Queryable).GetMethods(BindingFlags.Public | BindingFlags.Static);
var sortingMethodName = GetSortingMethodName(sortOrder);
var sortingMethod = sortingMethods.First(sm => sm.Name == sortingMethodName &&
sm.GetParameters().Length == 2);
return (IOrderedQueryable<TEntity>)sortingMethod
.MakeGenericMethod(typeof(TEntity), propertyType)
.Invoke(null, new object[] { query, convertedExpression });
}
private static string GetSortingMethodName(SortOrder sortOrder)
{
switch (sortOrder)
{
case SortOrder.Ascending:
return "OrderBy";
case SortOrder.Descending:
return "OrderByDescending";
default:
throw new ArgumentException("Sort Order must be specified as either Ascending or Descending.",
"sortOrder");
}
}
}
}

View File

@@ -0,0 +1,103 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace WaterCloud.Code
{
public static partial class Extensions
{
/// <summary>
/// 获取表里某页的数据
/// </summary>
/// <param name="data">表数据</param>
/// <param name="pageIndex">当前页</param>
/// <param name="pageSize">分页大小</param>
/// <param name="allPage">返回总页数</param>
/// <returns>返回当页表数据</returns>
public static List<T> GetPage<T>(this List<T> data, int pageIndex, int pageSize, out int allPage)
{
allPage = 1;
return null;
}
/// <summary>
/// IList转成List<T>
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list"></param>
/// <returns></returns>
public static List<T> IListToList<T>(IList list)
{
T[] array = new T[list.Count];
list.CopyTo(array, 0);
return new List<T>(array);
}
/// <summary>
/// 去除空元素
/// </summary>
public static List<string> removeNull(List<string> oldList)
{
// 临时集合
List<string> listTemp = new List<string>();
foreach (var item in oldList)
{
if (!string.IsNullOrEmpty(item))
{
listTemp.Add(item);
}
}
return listTemp;
}
}
public class ExtList<T> : IEqualityComparer<T> where T : class, new()
{
private string[] comparintFiledName = { };
public ExtList()
{ }
public ExtList(params string[] comparintFiledName)
{
this.comparintFiledName = comparintFiledName;
}
bool IEqualityComparer<T>.Equals(T x, T y)
{
if (x == null && y == null)
{
return false;
}
if (comparintFiledName.Length == 0)
{
return x.Equals(y);
}
bool result = true;
var typeX = x.GetType();//获取类型
var typeY = y.GetType();
foreach (var filedName in comparintFiledName)
{
var xPropertyInfo = (from p in typeX.GetProperties() where p.Name.Equals(filedName) select p).FirstOrDefault();
var yPropertyInfo = (from p in typeY.GetProperties() where p.Name.Equals(filedName) select p).FirstOrDefault();
result = result
&& xPropertyInfo != null && yPropertyInfo != null
&& xPropertyInfo.GetValue(x, null).ToString().Equals(yPropertyInfo.GetValue(y, null));
}
return result;
}
int IEqualityComparer<T>.GetHashCode(T obj)
{
return obj.ToString().GetHashCode();
}
}
}

View File

@@ -0,0 +1,59 @@
using AutoMapper;
using System;
using System.Collections;
using System.Collections.Generic;
namespace WaterCloud.Code
{
public static partial class Extensions
{
/// <summary>
/// 类型映射
/// </summary>
public static T MapTo<T>(this object obj)
{
if (obj == null) return default(T);
var config = new MapperConfiguration(cfg => cfg.CreateMap(obj.GetType(), typeof(T)));
var mapper = config.CreateMapper();
return mapper.Map<T>(obj);
}
/// <summary>
/// 集合列表类型映射
/// </summary>
public static List<TDestination> MapToList<TDestination>(this IEnumerable source)
{
Type sourceType = source.GetType().GetGenericArguments()[0]; //获取枚举的成员类型
var config = new MapperConfiguration(cfg => cfg.CreateMap(sourceType, typeof(TDestination)));
var mapper = config.CreateMapper();
return mapper.Map<List<TDestination>>(source);
}
/// <summary>
/// 集合列表类型映射
/// </summary>
public static List<TDestination> MapToList<TSource, TDestination>(this IEnumerable<TSource> source)
{
var config = new MapperConfiguration(cfg => cfg.CreateMap(typeof(TSource), typeof(TDestination)));
var mapper = config.CreateMapper();
return mapper.Map<List<TDestination>>(source);
}
/// <summary>
/// 类型映射
/// </summary>
public static TDestination MapTo<TSource, TDestination>(this TSource source, TDestination destination)
where TSource : class
where TDestination : class
{
if (source == null) return destination;
var config = new MapperConfiguration(cfg => cfg.CreateMap(typeof(TSource), typeof(TDestination)));
var mapper = config.CreateMapper();
return mapper.Map<TDestination>(source);
}
}
}

View File

@@ -0,0 +1,96 @@
using System;
using System.Text;
using System.Collections.Generic;
using System.Security.Cryptography;
namespace WaterCloud.Code
{
/// <summary>
/// 数值扩展类
/// </summary>
public static partial class Extensions
{
#region
/// <summary>
/// 10进制转换到2-36进制
/// </summary>
/// <param name="this">10进制数字</param>
/// <param name="radix">进制范围2-36</param>
/// <param name="digits">编码取值规则,最大转换位数不能大于该字符串的长度</param>
/// <returns></returns>
public static string ToBase(this long @this, int radix, string digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ")
{
const int BitsInLong = 64;
if (radix < 2 || radix > digits.Length)
throw new ArgumentException("The radix must be >= 2 and <= " + digits.Length.ToString());
if (@this == 0)
return "0";
var index = BitsInLong - 1;
var currentNumber = Math.Abs(@this);
var charArray = new char[BitsInLong];
while (currentNumber != 0)
{
var remainder = (int)(currentNumber % radix);
charArray[index--] = digits[remainder];
currentNumber /= radix;
}
var result = new string(charArray, index + 1, BitsInLong - index - 1);
if (@this < 0)
{
result = "-" + result;
}
return result;
}
/// <summary>
/// byte转16进制
/// </summary>
/// <param name="this"></param>
/// <returns></returns>
public static string ToHex(this byte @this) => Convert.ToString(@this, 16);
/// <summary>
/// 2进制转16进制
/// </summary>
/// <param name="this"></param>
/// <returns></returns>
public static string ToHex(this string @this) => Convert.ToString(Convert.ToInt64(@this, 2), 16);
/// <summary>
/// 16进制转2进制
/// </summary>
/// <param name="this"></param>
/// <returns></returns>
public static string ToBinary(this string @this) => Convert.ToString(Convert.ToInt64(@this, 16), 2);
/// <summary>
/// 2进制/16进制转8进制
/// </summary>
/// <param name="this"></param>
/// <param name="fromBase">2或者16表示2进制或者16进制</param>
/// <returns></returns>
public static string ToOctal(this string @this, int fromBase) => Convert.ToString(Convert.ToInt64(@this, fromBase), 8);
/// <summary>
/// 2进制/16进制转10进制
/// </summary>
/// <param name="this"></param>
/// <param name="fromBase">2或者16表示2进制或者16进制</param>
/// <returns></returns>
public static string ToDecimalism(this string @this, int fromBase)
{
if (fromBase == 16)
return Convert.ToInt32(@this, 16).ToString();
else
return Convert.ToString(Convert.ToInt64(@this, 2), 10);
}
#endregion
}
}

View File

@@ -0,0 +1,37 @@
using System;
namespace WaterCloud.Code
{
/// <summary>
/// string扩展类
/// </summary>
public static partial class Extensions
{
/// <summary>
/// 从分隔符开始向尾部截取字符串
/// </summary>
/// <param name="this">源字符串</param>
/// <param name="separator">分隔符</param>
/// <param name="lastIndexOf">true从最后一个匹配的分隔符开始截取false从第一个匹配的分隔符开始截取默认true</param>
/// <returns>string</returns>
public static string Substring(this string @this, string separator, bool lastIndexOf = true)
{
var startIndex = (lastIndexOf ?
@this.LastIndexOf(separator, StringComparison.OrdinalIgnoreCase) :
@this.IndexOf(separator, StringComparison.OrdinalIgnoreCase)) +
separator.Length;
var length = @this.Length - startIndex;
return @this.Substring(startIndex, length);
}
#region
public static string ReplaceFrist(this string str, string oldChar, string newChar)
{
int idx = str.IndexOf(oldChar);
str = str.Remove(idx, oldChar.Length);
str = str.Insert(idx, newChar);
return str;
}
#endregion
}
}

View File

@@ -0,0 +1,70 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System.Data;
namespace WaterCloud.Code
{
public static partial class Extensions
{
/// <summary>
/// 获取表里某页的数据
/// </summary>
/// <param name="data">表数据</param>
/// <param name="pageIndex">当前页</param>
/// <param name="pageSize">分页大小</param>
/// <param name="allPage">返回总页数</param>
/// <returns>返回当页表数据</returns>
public static DataTable GetPage(this DataTable data, int pageIndex, int pageSize, out int allPage)
{
allPage = data.Rows.Count / pageSize;
allPage += data.Rows.Count % pageSize == 0 ? 0 : 1;
DataTable Ntable = data.Clone();
int startIndex = pageIndex * pageSize;
int endIndex = startIndex + pageSize > data.Rows.Count ? data.Rows.Count : startIndex + pageSize;
if (startIndex < endIndex)
for (int i = startIndex; i < endIndex; i++)
{
Ntable.ImportRow(data.Rows[i]);
}
return Ntable;
}
/// <summary>
/// 根据字段过滤表的内容
/// </summary>
/// <param name="data">表数据</param>
/// <param name="condition">条件</param>
/// <returns></returns>
///
public static DataTable GetDataFilter(DataTable data, string condition)
{
if (data != null && data.Rows.Count > 0)
{
if (condition.Trim() == "")
{
return data;
}
else
{
DataTable newdt = new DataTable();
newdt = data.Clone();
DataRow[] dr = data.Select(condition);
for (int i = 0; i < dr.Length; i++)
{
newdt.ImportRow((DataRow)dr[i]);
}
return newdt;
}
}
else
{
return null;
}
}
}
}

View File

@@ -0,0 +1,30 @@
using Microsoft.AspNetCore.Http;
using System;
namespace WaterCloud.Code
{
public static partial class Extensions
{
public static bool IsNullOrZero(this object value)
{
if (value == null || value.ParseToString().Trim() == "0")
{
return true;
}
else
{
return false;
}
}
public static bool IsAjaxRequest(this HttpRequest request)
{
if (request == null)
throw new ArgumentNullException("request");
if (request.Headers != null)
return request.Headers["X-Requested-With"] == "XMLHttpRequest";
return false;
}
}
}

View File

@@ -0,0 +1,41 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using System.Threading.Tasks;
namespace WaterCloud.Code
{
/// <summary>
/// 全局异常过滤器,MVC使用
/// </summary>
public class GlobalExceptionFilter : IExceptionFilter, IAsyncExceptionFilter
{
public void OnException(ExceptionContext context)
{
LogHelper.WriteWithTime(context);
if (context.HttpContext.Request.IsAjaxRequest())
{
AlwaysResult obj = new AlwaysResult();
obj.state = ResultType.error.ToString();
obj.message = context.Exception.GetOriginalException().Message;
if (string.IsNullOrEmpty(obj.message))
{
obj.message = "抱歉,系统错误,请联系管理员!";
}
context.Result = new JsonResult(obj);
context.ExceptionHandled = true;
}
else
{
//context.HttpContext.Response.WriteAsync("<script>top.location.href ='" + context.HttpContext.Request.PathBase + "/Home/Error?msg=500" + "';if(document.all) window.event.returnValue = false;</script>");
context.Result = new RedirectResult(context.HttpContext.Request.PathBase + "/Home/Error?msg=500");
context.ExceptionHandled = true;
}
}
public Task OnExceptionAsync(ExceptionContext context)
{
OnException(context);
return Task.CompletedTask;
}
}
}

View File

@@ -0,0 +1,47 @@
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using System;
using System.Net;
using System.Threading.Tasks;
namespace WaterCloud.Code
{
/// <summary>
/// 全局异常中间件api使用
/// </summary>
public class GlobalExceptionMiddleware
{
private readonly RequestDelegate next;
public GlobalExceptionMiddleware(RequestDelegate next)
{
this.next = next;
}
public async Task Invoke(HttpContext context /* other dependencies */)
{
try
{
await next(context);
}
catch (Exception ex)
{
await HandleExceptionAsync(context, ex);
}
}
private static Task HandleExceptionAsync(HttpContext context, Exception exception)
{
var code = HttpStatusCode.OK;
LogHelper.WriteWithTime(exception);
var result = JsonConvert.SerializeObject(new AlwaysResult
{
state = ResultType.error.ToString(),
message = exception.Message
});
context.Response.ContentType = "application/json";
context.Response.StatusCode = (int)code;
return context.Response.WriteAsync(result);
}
}
}

View File

@@ -0,0 +1,31 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
namespace WaterCloud.Code
{
/// <summary>
/// 模型验证过滤器
/// </summary>
public class ModelActionFilter : ActionFilterAttribute, IActionFilter
{
public override void OnActionExecuting(ActionExecutingContext context)
{
string message = "";
if (!context.ModelState.IsValid)
{
foreach (var item in context.ModelState.Values)
{
foreach (var error in item.Errors)
{
message = message += error.ErrorMessage + "|";
}
}
if (message.Length > 0)
{
message = message.Substring(0, message.Length - 1);
}
context.Result = new JsonResult(new AlwaysResult { state = ResultType.error.ToString(), message = message });
}
}
}
}

View File

@@ -0,0 +1,13 @@
using System.Collections.Generic;
namespace WaterCloud.Code
{
public class Flow
{
public string title { get; set; }
public int initNum { get; set; }
public List<FlowLine> lines { get; set; }
public List<FlowNode> nodes { get; set; }
public List<FlowArea> areas { get; set; }
}
}

View File

@@ -0,0 +1,18 @@
namespace WaterCloud.Code
{
public class FlowArea
{
public string id { get; set; }
public string name { get; set; }
public string color { get; set; }
public int left { get; set; }
public int top { get; set; }
public int width { get; set; }
public int height { get; set; }
public bool alt { get; set; }
}
}

View File

@@ -0,0 +1,272 @@
using Newtonsoft.Json.Linq;
using System.Collections.Generic;
using System.Linq;
namespace WaterCloud.Code
{
/// <summary>
/// 流程连线
/// </summary>
public class FlowLine
{
public string id { get; set; }
public string label { get; set; }
public string type { get; set; }
public string from { get; set; }
public string to { get; set; }
public string name { get; set; }
public bool dash { get; set; }
public double M { get; set; }
public bool alt { get; set; }
/// <summary> 分支条件 </summary>
public List<DataCompare> Compares { get; set; }
public bool Compare(JObject frmDataJson)
{
bool result = true;
foreach (var compare in Compares)
{
compare.FieldName = compare.FieldName.ToLower();
compare.Value = compare.Value.ToLower();
decimal value = 0; //参考值
decimal frmvalue = 0; //表单中填写的值
if (compare.Operation != DataCompare.Equal && compare.Operation != DataCompare.NotEqual)
{
value = decimal.Parse(compare.Value);
frmvalue = decimal.Parse(frmDataJson.GetValue(compare.FieldName.ToLower()).ToString()); //表单中填写的值
}
bool res = false;
if (compare.Condition == "and")
{
switch (compare.Operation)
{
case DataCompare.Equal:
result &= compare.Value == frmDataJson.GetValue(compare.FieldName).ToString();
break;
case DataCompare.NotEqual:
result &= compare.Value != frmDataJson.GetValue(compare.FieldName).ToString();
break;
case DataCompare.Larger:
result &= frmvalue > value;
break;
case DataCompare.Less:
result &= frmvalue < value;
break;
case DataCompare.LargerEqual:
result &= frmvalue <= value;
break;
case DataCompare.LessEqual:
result &= frmvalue <= value;
break;
case DataCompare.In:
if (compare.FieldName == "申请人" || compare.FieldName == "所属部门")
{
var arr = compare.Value.Split(',');
foreach (var item in frmDataJson.GetValue(compare.FieldName).ToString().Split(','))
{
if (arr.Contains(item))
{
res = true;
break;
}
}
result &= res;
break;
}
else
{
var arr = compare.Value.Split(',');
if (arr.Contains(frmvalue.ToString()))
{
res = true;
break;
}
result &= res;
break;
}
case DataCompare.NotIn:
if (compare.FieldName == "申请人" || compare.FieldName == "所属部门")
{
var arr = compare.Value.Split(',');
foreach (var item in frmDataJson.GetValue(compare.FieldName).ToString().Split(','))
{
if (arr.Contains(item))
{
res = false;
break;
}
}
result &= res;
break;
}
else
{
var arr = compare.Value.Split(',');
if (arr.Contains(frmvalue.ToString()))
{
res = false;
break;
}
result &= res;
break;
}
}
}
else
{
switch (compare.Operation)
{
case DataCompare.Equal:
if (compare.FieldName == "申请人" || compare.FieldName == "所属部门")
{
var arr = compare.Value.Split(',');
foreach (var item in frmDataJson.GetValue(compare.FieldName).ToString().Split(','))
{
if (arr.Contains(item))
{
res = true;
break;
}
}
result |= res;
break;
}
result |= compare.Value == frmDataJson.GetValue(compare.FieldName).ToString();
break;
case DataCompare.NotEqual:
if (compare.FieldName == "申请人" || compare.FieldName == "所属部门")
{
var arr = compare.Value.Split(',');
foreach (var item in frmDataJson.GetValue(compare.FieldName).ToString().Split(','))
{
if (arr.Contains(item))
{
res = false;
break;
}
}
result |= res;
break;
}
result |= compare.Value != frmDataJson.GetValue(compare.FieldName).ToString();
break;
case DataCompare.Larger:
result |= frmvalue > value;
break;
case DataCompare.Less:
result |= frmvalue < value;
break;
case DataCompare.LargerEqual:
result |= frmvalue <= value;
break;
case DataCompare.LessEqual:
result |= frmvalue <= value;
break;
case DataCompare.In:
if (compare.FieldName == "申请人" || compare.FieldName == "所属部门")
{
var arr = compare.Value.Split(',');
foreach (var item in frmDataJson.GetValue(compare.FieldName).ToString().Split(','))
{
if (arr.Contains(item))
{
res = true;
break;
}
}
result |= res;
break;
}
else
{
var arr = compare.Value.Split(',');
if (arr.Contains(frmvalue.ToString()))
{
res = true;
}
result |= res;
break;
}
case DataCompare.NotIn:
if (compare.FieldName == "申请人" || compare.FieldName == "所属部门")
{
var arr = compare.Value.Split(',');
foreach (var item in frmDataJson.GetValue(compare.FieldName).ToString().Split(','))
{
if (arr.Contains(item))
{
res = false;
break;
}
}
result |= res;
break;
}
else
{
var arr = compare.Value.Split(',');
if (arr.Contains(frmvalue.ToString()))
{
res = false;
}
result |= res;
break;
}
}
}
}
return result;
}
}
/// <summary>
/// 分支条件
/// </summary>
public class DataCompare
{
public const string Larger = ">";
public const string Less = "<";
public const string LargerEqual = ">=";
public const string LessEqual = "<=";
public const string NotEqual = "!=";
public const string Equal = "=";
public const string In = "in";
public const string NotIn = "not in";
/// <summary>操作类型比如大于/等于/小于</summary>
public string Operation { get; set; }
/// <summary> form种的字段名称 </summary>
public string FieldName { get; set; }
/// <summary> 字段类型:"form":为表单中的字段,后期扩展系统表等. </summary>
public string FieldType { get; set; }
/// <summary>实际的值</summary>
public string Value { get; set; }
/// <summary>
/// 显示值
/// </summary>
public string Name { get; set; }
/// <summary>
/// 条件关系
/// </summary>
public string Condition { get; set; }
}
}

View File

@@ -0,0 +1,131 @@
namespace WaterCloud.Code
{
/// <summary>
/// 流程节点
/// </summary>
public class FlowNode
{
public const string START = "start round mix";
public const string END = "end round";
public const string NODE = "node";
public const string FORK = "fork"; //会签开始节点
public const string JOIN = "join"; //会签结束节点
public string id { get; set; }
public string name { get; set; }
public string type { get; set; }
public int left { get; set; }
public int top { get; set; }
public int width { get; set; }
public int height { get; set; }
public bool alt { get; set; }
/// <summary>
/// 节点的附加数据项
/// </summary>
/// <value>The set information.</value>
public Setinfo setInfo { get; set; }
}
public class Setinfo
{
public const string SPECIAL_USER = "SPECIAL_USER"; //指定用户
public const string ALL_USER = "ALL_USER"; //所有用户
public const string SPECIAL_ROLE = "SPECIAL_ROLE"; //指定角色
public const string DEPARTMENT_MANAGER = "DEPARTMENT_MANAGER"; //部门负责人
public const string USER_MANAGER = "USER_MANAGER"; //直属上级
public const string MORE_USER_MANAGER = "MORE_USER_MANAGER"; //连续多级直属上级
public const string RUNTIME_SPECIAL_ROLE = "RUNTIME_SPECIAL_ROLE"; //运行时指定角色
public const string RUNTIME_SPECIAL_USER = "RUNTIME_SPECIAL_USER"; //运行时指定用户
/// <summary>
/// 节点执行权限类型
/// </summary>
public string NodeDesignate { get; set; }
public Nodedesignatedata NodeDesignateData { get; set; }
public string NodeCode { get; set; }
public string NodeName { get; set; }
/// <summary>
/// 流程执行时三方回调的URL地址
/// </summary>
public string ThirdPartyUrl { get; set; }
/// <summary>
/// 驳回节点0"前一步"1"第一步"2"某一步" 3"不处理"
/// </summary>
public string NodeRejectType { get; set; }
public int? Taged { get; set; }
public string UserName { get; set; }
public string UserId { get; set; }
public string Description { get; set; }
public string TagedTime { get; set; }
//节点会签方式,
//all/空:默认为全部通过
//one :至少有一个通过
public string NodeConfluenceType { get; set; }
/// <summary>
/// 会签通过的个数
/// </summary>
public int? ConfluenceOk { get; set; }
/// <summary>
/// 会签拒绝的个数
/// </summary>
public int? ConfluenceNo { get; set; }
/// <summary>
/// 可写的表单项ID
/// </summary>
public string[] CanWriteFormItemIds { get; set; }
}
/// <summary>
/// 节点执行人
/// </summary>
public class Nodedesignatedata
{
public string[] users { get; set; }
public string[] roles { get; set; }
public string[] orgs { get; set; }
public bool currentDepart { get; set; }
}
/// <summary>
/// 节点执行结果标签
/// </summary>
public class Tag
{
/// <summary>
/// 1: 通过
/// 2不通过
/// 3驳回
/// </summary>
public int Taged { get; set; }
public string UserId { get; set; }
public string UserName { get; set; }
public string Description { get; set; }
public string TagedTime { get; set; }
}
/// <summary>
/// 1: 通过
/// 2不通过
/// 3驳回
/// </summary>
public enum TagState
{
Ok = 1,
No,
Reject
}
}

View File

@@ -0,0 +1,58 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
namespace WaterCloud.Code
{
public class FormUtil
{
/// <summary>
/// 获取值
/// </summary>
/// <param name="form">The form.</param>
/// <returns>System.String.</returns>
public static List<string> SetValue(string content)
{
List<FormValue> list = JsonHelper.ToObject<List<FormValue>>(content);
List<string> temp = new List<string>();
SetFormValue(list, temp);
return temp;
}
private static List<string> SetFormValue(List<FormValue> list, List<string> temp)
{
foreach (var item in list)
{
if (item.tag == "grid")
{
foreach (var column in item.columns)
{
SetFormValue(column.list, temp);
}
}
else
{
temp.Add(item.id);
}
}
return temp;
}
public static List<string> SetValueByWeb(string webForm)
{
var path = AppDomain.CurrentDomain.RelativeSearchPath ?? AppDomain.CurrentDomain.BaseDirectory;
var referencedAssemblies = Directory.GetFiles(path, "*.dll").Select(Assembly.LoadFrom).ToArray();
var t = referencedAssemblies
.SelectMany(a => a.GetTypes().Where(t => t.FullName.Contains("WaterCloud.Domain.") && t.FullName.Contains("." + webForm + "Entity"))).First();
List<string> temp = new List<string>();
PropertyInfo[] pArray = t.GetProperties();
Array.ForEach<PropertyInfo>(pArray, p =>
{
temp.Add(p.Name);
});
return temp;
}
}
}

View File

@@ -0,0 +1,24 @@
using System.Collections.Generic;
namespace WaterCloud.Code
{
/// <summary>
/// 表单设计类
/// </summary>
public class FormValue
{
public string id { get; set; }
public string label { get; set; }
public int index { get; set; }
public string tag { get; set; }
public int span { get; set; }
public List<FormEx> columns { get; set; }
public string name { get; set; }
}
public class FormEx
{
public int span { get; set; }
public List<FormValue> list { get; set; }
}
}

View File

@@ -0,0 +1,254 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.StaticFiles;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyModel;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
using System.Text;
using WaterCloud.Code.Model;
namespace WaterCloud.Code
{
public static class GlobalContext
{
/// <summary>
/// 构造函数
/// </summary>
static GlobalContext()
{
// 未托管的对象
UnmanagedObjects = new ConcurrentBag<IDisposable>();
Assemblies = GetAssemblies();
EffectiveTypes = Assemblies.SelectMany(GetTypes);
}
/// <summary>
/// 服务集合
/// </summary>
public static IServiceCollection Services { get; set; }
/// <summary>
/// 根服务
/// </summary>
public static IServiceProvider RootServices { get; set; }
public static IConfiguration Configuration { get; set; }
public static IWebHostEnvironment HostingEnvironment { get; set; }
/// <summary>
/// 未托管的对象集合
/// </summary>
public static readonly ConcurrentBag<IDisposable> UnmanagedObjects;
public static HttpContext HttpContext => RootServices?.GetService<IHttpContextAccessor>()?.HttpContext;
public static SystemConfig SystemConfig { get; set; }
/// <summary>
/// 应用有效程序集(类型为project,项目应用的,不包括包和手动应用)
/// </summary>
public static readonly IEnumerable<Assembly> Assemblies;
/// <summary>
/// 有效程序集类型
/// </summary>
public static readonly IEnumerable<System.Type> EffectiveTypes;
/// <summary>
/// 获取请求生存周期的服务(未注册返回null)
/// </summary>
/// <typeparam name="TService"></typeparam>
/// <param name="serviceProvider"></param>
/// <returns></returns>
public static TService GetService<TService>(IServiceProvider serviceProvider = null) where TService : class
{
return GetService(typeof(TService), serviceProvider) as TService;
}
/// <summary>
/// 获取请求生存周期的服务(未注册返回null)
/// </summary>
/// <param name="type"></param>
/// <param name="serviceProvider"></param>
/// <returns></returns>
public static object GetService(Type type, IServiceProvider serviceProvider = null)
{
return (serviceProvider ?? GetServiceProvider(type)).GetService(type);
}
/// <summary>
/// 获取请求生存周期的服务(未注册异常)
/// </summary>
/// <typeparam name="TService"></typeparam>
/// <param name="serviceProvider"></param>
/// <returns></returns>
public static TService GetRequiredService<TService>(IServiceProvider serviceProvider = null) where TService : class
{
return GetRequiredService(typeof(TService), serviceProvider) as TService;
}
/// <summary>
/// 获取请求生存周期的服务(未注册异常)
/// </summary>
/// <typeparam name="type"></typeparam>
/// <param name="serviceProvider"></param>
/// <returns></returns>
public static object GetRequiredService(Type type, IServiceProvider serviceProvider = null)
{
return (serviceProvider ?? GetServiceProvider(type)).GetRequiredService(type);
}
/// <summary>
/// 获取服务注册器
/// </summary>
/// <param name="serviceType"></param>
/// <returns></returns>
public static IServiceProvider GetServiceProvider(Type serviceType)
{
if (HostingEnvironment == null)
{
return RootServices;
}
if (RootServices != null && Services.Where((ServiceDescriptor u) => u.ServiceType == (serviceType.IsGenericType ? serviceType.GetGenericTypeDefinition() : serviceType)).Any((ServiceDescriptor u) => u.Lifetime == ServiceLifetime.Singleton))
{
return RootServices;
}
// 第二选择是获取 HttpContext 对象的 RequestServices
var httpContext = HttpContext;
if (httpContext?.RequestServices != null) return httpContext.RequestServices;
// 第三选择,创建新的作用域并返回服务提供器
else if (RootServices != null)
{
var scoped = RootServices.CreateScope();
UnmanagedObjects.Add(scoped);
return scoped.ServiceProvider;
}
// 第四选择,构建新的服务对象(性能最差)
else
{
var serviceProvider = Services.BuildServiceProvider();
UnmanagedObjects.Add(serviceProvider);
return serviceProvider;
}
}
/// <summary>
/// GC 回收默认间隔
/// </summary>
private const int GC_COLLECT_INTERVAL_SECONDS = 5;
/// <summary>
/// 记录最近 GC 回收时间
/// </summary>
private static DateTime? LastGCCollectTime { get; set; }
/// <summary>
/// 释放所有未托管的对象
/// </summary>
public static void DisposeUnmanagedObjects()
{
foreach (var dsp in UnmanagedObjects)
{
try
{
dsp?.Dispose();
}
finally { }
}
// 强制手动回收 GC 内存
if (UnmanagedObjects.Any())
{
var nowTime = DateTime.UtcNow;
if ((LastGCCollectTime == null || (nowTime - LastGCCollectTime.Value).TotalSeconds > GC_COLLECT_INTERVAL_SECONDS))
{
LastGCCollectTime = nowTime;
GC.Collect();
GC.WaitForPendingFinalizers();
}
}
UnmanagedObjects.Clear();
}
/// <summary>
/// 获取版本号
/// </summary>
/// <returns></returns>
public static string GetVersion()
{
Version version = Assembly.GetEntryAssembly().GetName().Version;
return version.ToString();
}
/// <summary>
/// 获取请求跟踪 Id
/// </summary>
/// <returns></returns>
public static string GetTraceId()
{
return Activity.Current?.Id ?? (RootServices == null ? default : HttpContext?.TraceIdentifier);
}
/// <summary>
/// 程序启动时,记录目录
/// </summary>
/// <param name="env"></param>
public static void LogWhenStart(IWebHostEnvironment env)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("程序启动");
sb.AppendLine("ContentRootPath:" + env.ContentRootPath);
sb.AppendLine("WebRootPath:" + env.WebRootPath);
sb.AppendLine("IsDevelopment:" + env.IsDevelopment());
LogHelper.WriteWithTime(sb.ToString());
}
/// <summary>
/// 设置cache control
/// </summary>
/// <param name="context"></param>
public static void SetCacheControl(StaticFileResponseContext context)
{
int second = 365 * 24 * 60 * 60;
context.Context.Response.Headers.Add("Cache-Control", new[] { "public,max-age=" + second });
context.Context.Response.Headers.Add("Expires", new[] { DateTime.UtcNow.AddYears(1).ToString("R") }); // Format RFC1123
}
public static IEnumerable<Assembly> GetAssemblies()
{
var projects = DependencyContext
.Default
.RuntimeLibraries
.Where(u => u.Type == "project" || u.Type == "reference")
.Select(u => AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(u.Name)));
return projects;
}
/// <summary>
/// 加载程序集中的所有类型
/// </summary>
/// <param name="ass"></param>
/// <returns></returns>
private static IEnumerable<System.Type> GetTypes(Assembly ass)
{
var types = Array.Empty<System.Type>();
try
{
types = ass.GetTypes();
}
catch
{
Console.WriteLine($"Error load `{ass.FullName}` assembly.");
}
return types.Where(u => u.IsPublic);
}
}
}

View File

@@ -0,0 +1,45 @@
using System.Collections.Generic;
namespace WaterCloud.Code
{
public class FilterSo
{
/**
* 唯一id
*/
public long id { get; set; }
/**
* 前缀 and、or
*/
public string prefix { get; set; }
/**
* 模式 in、condition、date
*/
public string mode { get; set; }
/**
* 字段名
*/
public string field { get; set; }
/**
* 筛选类型
*/
public string type { get; set; }
/**
* 是否有分隔符
*/
public string split { get; set; }
/**
* 筛选值
*/
public string value { get; set; }
/**
* 筛选值
*/
public List<string> values { get; set; }
/**
* 子组数据
*/
public List<FilterSo> children { get; set; }
}
}

View File

@@ -0,0 +1,210 @@
using Serenity;
using System;
using System.Collections.Generic;
using System.Linq;
namespace WaterCloud.Code
{
/// <summary>
///封装table查询数据
/// </summary>
/// <typeparam name="T"></typeparam>
public class SoulPage<T>
{
/**
* layui表格必须参数⬇⬇⬇⬇⬇⬇
*/
public int state { get; set; }
public string message { get; set; }
/**
* 总记录
*/
public int count { get; set; }
/**
* 显示的记录
*/
public List<T> data { get; set; }
/**
* 请求条件
*/
public object obj { get; set; }
/**
* 查询条件
*/
public Dictionary<string, object> condition = new Dictionary<string, object>();
/**
* 请求参数⬇⬇⬇⬇⬇⬇
*/
/**
* 当前页 从1开始
*/
public int page { get; set; }
/**
* 页大小
*/
public int rows { get; set; }
/**
* 查询列数据
*/
public string columns { get; set; }
/**
* 表格列类型
*/
public string tableFilterType { get; set; }
/**
* 筛选信息
*/
public string filterSos { get; set; }
/**
* 排序信息
*/
public string field { get; set; }
public string order { get; set; }
public SoulPage()
{
this.state = 0;
this.message = "";
this.page = 1;
this.rows = 100000000;
this.order = "asc";
}
public SoulPage(int page, int limit)
{
this.state = 0;
this.message = "";
this.page = 1;
this.rows = 100000000;
this.order = "asc";
this.page = page;
this.rows = limit;
}
public List<FilterSo> getFilterSos()
{
if (string.IsNullOrEmpty(filterSos))
{
return new List<FilterSo>();
}
return filterSos.ToObject<List<FilterSo>>();
}
public bool isColumn()
{
return getColumns().Count > 0;
}
public int getOffset()
{
return (page - 1) * rows;
}
public List<string> getColumns()
{
return !string.IsNullOrEmpty(columns) ? columns.ToObject<List<string>>() : new List<string>();
}
private string dateFormat(DateTime date, string format)
{
if (string.IsNullOrEmpty(format))
{
return date.ToString("yyyy-MM-dd HH:mm:ss");
}
else
{
return date.ToString(format);
}
}
public Dictionary<string, Dictionary<string, string>> getTypeMap()
{
Dictionary<string, Dictionary<string, string>> typeMap = new Dictionary<string, Dictionary<string, string>>();
if (!string.IsNullOrEmpty(tableFilterType))
{
Dictionary<string, string> filterType = tableFilterType.ToObject<Dictionary<string, string>>();
foreach (var item in filterType)
{
Dictionary<string, string> map = new Dictionary<string, string>();
map.Add("type", item.Value.Substring(0, item.Value.IndexOf("[")));
int IndexofA = item.Value.IndexOf('['); //字符串的话总以第一位为指定位置
int IndexofB = item.Value.IndexOf(']');
map.Add("value", item.Value.Substring(IndexofA + 1, IndexofB - IndexofA - 1));
typeMap.Add(item.Key, map);
};
}
return typeMap;
}
public string getFormatValue(Dictionary<string, Dictionary<string, string>> typeMap, string column, object columnObject)
{
string columnValue;
if (typeMap.ContainsKey(column))
{
if ("date".Equals(typeMap.Get(column).Get("type")) && columnObject is DateTime)
{
columnValue = dateFormat((DateTime)columnObject, typeMap.Get(column).Get("value"));
}
else
{
columnValue = columnObject.ToString();
}
}
else
{
if (columnObject is DateTime || columnObject is Nullable<DateTime>)
{
columnValue = dateFormat((DateTime)columnObject, null);
}
else if (columnObject is bool || columnObject is Nullable<bool>)
{
columnValue = (bool)columnObject == true ? "1" : "0";
}
else
{
columnValue = columnObject.ToString();
}
}
return columnValue;
}
public Object setData(List<T> data)
{
if (isColumn())
{
Dictionary<string, Dictionary<string, string>> typeMap = getTypeMap();
Dictionary<string, HashSet<string>> columnMap = new Dictionary<string, HashSet<string>>();
foreach (T datum in data)
{
foreach (string column in getColumns())
{
if (!columnMap.ContainsKey(column))
{
columnMap.Add(column, new HashSet<string>());
}
var columnObject = ReflectionHelper.GetObjectPropertyValue(datum, column);
if (columnObject != null)
{ //空值不展示
columnMap.Get(column).Add(getFormatValue(typeMap, column, columnObject));
}
}
}
Dictionary<string, List<string>> columnSortMap = new Dictionary<string, List<string>>();
foreach (var item in columnMap)
{
columnSortMap.Add(item.Key, item.Value.ToList());
}
return columnSortMap;
}
else
{
this.data = data;
return this;
}
}
}
}

View File

@@ -0,0 +1,83 @@
namespace WaterCloud.Code
{
/// <summary>
/// LayUI Table 列
/// </summary>
public class TableCols
{
/// <summary>
/// 类型normal常规列、checkbox复选框、radio单选框、numbers序号、space
/// </summary>
public string type { get; set; }
/// <summary>
/// 字段
/// </summary>
public string field { get; set; }
/// <summary>
/// 标题
/// </summary>
public string title { get; set; }
/// <summary>
/// 宽度
/// </summary>
public int? width { get; set; }
/// <summary>
/// 最小宽度
/// </summary>
public int? minWidth { get; set; }
/// <summary>
/// 是否全选
/// </summary>
public bool? LAY_CHECKED { get; set; }
/// <summary>
/// 固定列
/// </summary>
public string Fixed { get; set; }
/// <summary>
/// 隐藏
/// </summary>
public string hide { get; set; }
/// <summary>
/// 排序
/// </summary>
public bool? sort { get; set; }
/// <summary>
/// 是否禁用拖到列
/// </summary>
public bool? unresize { get; set; }
/// <summary>
/// 样式
/// </summary>
public string style { get; set; }
/// <summary>
/// 对齐方式
/// </summary>
public string align { get; set; }
/// <summary>
/// 所占列数
/// </summary>
public int? colspan { get; set; }
/// <summary>
/// 所占行数
/// </summary>
public int? rowspan { get; set; }
/// <summary>
/// 绑定工具栏模板
/// </summary>
public string toolbar { get; set; }
}
}

View File

@@ -0,0 +1,15 @@
using System.ComponentModel;
using System.ComponentModel.DataAnnotations.Schema;
namespace WaterCloud.Code.Model
{
/// <summary>
/// 这个是移动端Api用的
/// </summary>
public class BaseApiToken
{
[NotMapped]
[Description("WebApi没有Cookie和Session所以需要传入Token来标识用户身份请加在Url后面")]
public string Token { get; set; }
}
}

View File

@@ -0,0 +1,7 @@
namespace WaterCloud.Code.Model
{
public class AppLogEntity
{
public string FileName { get; set; }
}
}

View File

@@ -0,0 +1,41 @@
/*******************************************************************************
* Copyright © 2020 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System.ComponentModel;
namespace WaterCloud.Code
{
public enum DbLogType
{
[Description("其他")]
Other = 0,
[Description("登录")]
Login = 1,
[Description("退出")]
Exit = 2,
[Description("访问")]
Visit = 3,
[Description("新增")]
Create = 4,
[Description("删除")]
Delete = 5,
[Description("修改")]
Update = 6,
[Description("提交")]
Submit = 7,
[Description("异常")]
Exception = 8,
}
}

View File

@@ -0,0 +1,18 @@
namespace WaterCloud.Code
{
public static class Define
{
public const string PROVIDER_COOKIE = "Cookie";
public const string PROVIDER_SESSION = "Session";
public const string PROVIDER_WEBAPI = "WebApi";
public const string CACHEPROVIDER_REDIS = "Redis";
public const string CACHEPROVIDER_MEMORY = "Memory";
public const string DATAPRIVILEGE_LOGINUSER = "{loginUser}"; //数据权限配置中当前登录用户的key
public const string DATAPRIVILEGE_LOGINROLE = "{loginRole}"; //数据权限配置中当前登录用户角色的key
public const string DATAPRIVILEGE_LOGINORG = "{loginOrg}"; //数据权限配置中当前登录用户部门的key
public const string SQL_MORE = "MoreSql";//多库
public const string SQL_TENANT = "TenantSql";//多租户
}
}

View File

@@ -0,0 +1,22 @@
namespace WaterCloud.Code
{
public class Filter
{
public string Key { get; set; }
public string Value { get; set; }
public string Contrast { get; set; }
public string Text { get; set; }
}
public class FilterList
{
/// <summary>
/// and
/// </summary>
public string Operation { get; set; }
public string Filters { get; set; }
public string Description { get; set; }
}
}

View File

@@ -0,0 +1,9 @@
namespace WaterCloud.Code
{
public class KeyValue
{
public string Key { get; set; }
public string Value { get; set; }
public string Description { get; set; }
}
}

View File

@@ -0,0 +1,31 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WaterCloud.Code.Model
{
public class PrintEntity
{
public string cmd { get; set; } = "print";
public string requestId { get; set; }
public PrintDetail data { get; set; }
}
public class PrintDetail
{
public PrintInitInfo printIniInfo { get; set; }
public object data { get; set; }
}
public class PrintInitInfo
{
public string filePath { get; set; }
public string realName { get; set; }
public int? printType { get; set; } = 1;
public string printName { get; set; } = "";
public bool landscape { get; set; } = true;
public string paperSize { get; set; }
public string duplex { get; set; }
public bool? isBatch { get; set; } = false;
}
}

View File

@@ -0,0 +1,185 @@
using System.Collections.Generic;
namespace WaterCloud.Code.Model
{
public class SystemConfig
{
/// <summary>
/// 是否是Demo模式
/// </summary>
public bool Demo { get; set; }
/// <summary>
/// 是否是调试模式
/// </summary>
public bool Debug { get; set; }
/// <summary>
/// 允许一个用户在多个电脑同时登录
/// </summary>
public bool LoginMultiple { get; set; }
/// <summary>
/// 允许跨域的站点
/// </summary>
public string AllowCorsSite { get; set; }
/// <summary>
/// 主库数据库类型
/// </summary>
public string DBProvider { get; set; }
/// <summary>
/// 主库数据库连接
/// </summary>
public string DBConnectionString { get; set; }
/// <summary>
/// 数据库连接超时
/// </summary>
public int DBCommandTimeout { get; set; }
/// <summary>
/// 是否初始化数据库
/// </summary>
public bool IsInitDb { get; set; }
/// <summary>
/// 是否初始化种子数据
/// </summary>
public bool IsSeedData { get; set; }
/// <summary>
/// 缓存类型
/// </summary>
public string CacheProvider { get; set; }
/// <summary>
/// redis连接串
/// </summary>
public string RedisConnectionString { get; set; }
/// <summary>
/// api token名称
/// </summary>
public string TokenName { get; set; }
//缓存过期时间
public int LoginExpire { get; set; }
/// <summary>
/// 主页
/// </summary>
public string HomePage { get; set; }
/// <summary>
/// 是否局域网
/// </summary>
public bool? LocalLAN { get; set; }
/// <summary>
/// 数据库模式
/// </summary>
public string SqlMode { get; set; }
/// <summary>
/// 项目前缀
/// </summary>
public string ProjectPrefix { get; set; }
/// <summary>
/// 是否重置密码
/// </summary>
public bool? ReviseSystem { get; set; }
/// <summary>
/// 登录错误次数
/// </summary>
public int? LoginErrorCount { get; set; }
/// <summary>
/// 多数据库组
/// </summary>
public List<DBConfig> SqlConfig { get; set; }
/// <summary>
/// 是否集群
/// </summary>
public bool? IsCluster { get; set; }
/// <summary>
/// 是否删除定时调度任务
/// </summary>
public bool? NeedClear { get; set; }
/// <summary>
/// 主程序数据库编号
/// </summary>
public string MainDbNumber { get; set; }
/// <summary>
/// 是否开启定时任务
/// </summary>
public bool? OpenQuartz { get; set; }
/// <summary>
/// api文档配置
/// </summary>
public DocumentSettings DocumentSettings { get; set; }
/// <summary>
/// rabbitmq配置
/// </summary>
public MqConfig RabbitMq { get; set; }
}
public class DocumentSettings
{
/// <summary>
/// 标题
/// </summary>
public string DocumentTitle { get; set; }
public List<GroupOpenApiInfo> GroupOpenApiInfos { get; set; }
}
public class GroupOpenApiInfo
{
/// <summary>
/// 分组
/// </summary>
public string Group { get; set; }
/// <summary>
/// 组标题
/// </summary>
public string Title { get; set; }
/// <summary>
/// 描述
/// </summary>
public string Description { get; set; }
/// <summary>
/// 版本
/// </summary>
public string Version { get; set; }
}
public class DBConfig
{
/// <summary>
/// 数据库序号
/// </summary>
public string DBNumber { get; set; }
/// <summary>
/// 数据库类型
/// </summary>
public string DBProvider { get; set; }
/// <summary>
/// 数据库连接
/// </summary>
public string DBConnectionString { get; set; }
}
}

View File

@@ -0,0 +1,47 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System;
namespace WaterCloud.Code
{
/// <summary>
/// 当前用户信息
/// </summary>
public class OperatorModel
{
public string UserId { get; set; }
public string UserCode { get; set; }
public string UserName { get; set; }
public string UserPwd { get; set; }
public string CompanyId { get; set; }
public string OrganizeId { get; set; }
public string RoleId { get; set; }
public string LoginIPAddress { get; set; }
public string LoginIPAddressName { get; set; }
public string LoginToken { get; set; }
public DateTime LoginTime { get; set; }
//超管
public bool IsSuperAdmin { get; set; }
public bool IsAdmin { get; set; }
public bool IsBoss { get; set; }
public bool IsSenior { get; set; }
public bool IsSaleman { get; set; }
// 拓展字段2019-03-03
public string DdUserId { get; set; }
public string WxOpenId { get; set; }
public string Avatar { get; set; }
public string loginMark { get; set; }
//扩展字段 数据库序号2021-05-12
public string DbNumber { get; set; }
}
}

View File

@@ -0,0 +1,395 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace WaterCloud.Code
{
public class OperatorProvider
{
//是否允许一个账户在多处登录
private static bool LoginMultiple = GlobalContext.SystemConfig.LoginMultiple;
//缓存过期时间
private static int LoginExpire = GlobalContext.SystemConfig.LoginExpire;
private static string projectPrefix = GlobalContext.SystemConfig.ProjectPrefix;
public static OperatorProvider Provider
{
get { return new OperatorProvider(); }
}
//watercloud_operator_pc_ PC端登录
//watercloud_operator_info_ 登录次数
//
/// <summary>
/// 缓存操作类
/// </summary>
private string cacheKeyOperator = projectPrefix + "_operator_";// +登录者token
private string cacheKeyToken = projectPrefix + "_token_";// +登录者token
private string cacheKeyError = projectPrefix + "_error_";// + Mark
/// <summary>
/// 秘钥
/// </summary>
private string LoginUserToken = projectPrefix + "_Token";
/// <summary>
/// 标记登录的浏览器
/// </summary>
private string LoginUserMarkKey = projectPrefix + "_Mark";
public string GetProvider(string key)
{
var token = GetToken();
if (!string.IsNullOrEmpty(token))
return token;
token = WebHelper.GetCookie(key).ToString();
if (!string.IsNullOrEmpty(token))
return token;
return WebHelper.GetSession(key).ToString();
}
public void SetProvider(string key, string value)
{
WebHelper.WriteCookie(key, value);
WebHelper.WriteSession(key, value);
}
public string GetToken()
{
try
{
if (GlobalContext.HttpContext == null)
{
return null;
}
//查请求头
string token = GlobalContext.HttpContext.Request.Headers[GlobalContext.SystemConfig.TokenName].ParseToString();
if (!String.IsNullOrEmpty(token)) return token;
//查参数
token = GlobalContext.HttpContext.Request.Query[GlobalContext.SystemConfig.TokenName];
if (!String.IsNullOrEmpty(token)) return token;
//查cookies
string cookie = GlobalContext.HttpContext.Request.Cookies[GlobalContext.SystemConfig.TokenName];
return cookie == null ? string.Empty : cookie;
}
catch (Exception)
{
return null;
}
}
public void RemoveProvider(string key)
{
WebHelper.RemoveCookie(key);
WebHelper.RemoveSession(key);
}
public OperatorModel GetCurrent()
{
OperatorModel operatorModel = new OperatorModel();
try
{
string loginMark = GetProvider(LoginUserMarkKey);
operatorModel = CacheHelper.Get<OperatorModel>(cacheKeyOperator + loginMark);
}
catch
{
operatorModel = null;
}
return operatorModel;
}
/// <summary>
/// 获取浏览器设配号
/// </summary>
/// <returns></returns>
public string GetMark()
{
string cookieMark = GetProvider(LoginUserMarkKey);
if (string.IsNullOrEmpty(cookieMark))
{
cookieMark = Guid.NewGuid().ToString();
SetProvider(LoginUserMarkKey, cookieMark);
}
return cookieMark;
}
/// <summary>
/// 登录者信息添加到缓存中
/// </summary>
/// <param name="userEntity">用户</param>
/// <param name="loginMark">设备标识uid</param>
/// <param name="facilityMark">设备类型</param>
/// <param name="cookie">是否保存cookie默认是</param>
/// <returns></returns>
public async Task<string> AddLoginUser(OperatorModel operatorModel, string loginMark, string facilityMark)
{
string token = Guid.NewGuid().ToString();
try
{
// 填写登录信息
operatorModel.LoginToken = token;
//登录信息更新
if (string.IsNullOrEmpty(loginMark))
{
string cookieMark = GetProvider(LoginUserMarkKey);
if (string.IsNullOrEmpty(cookieMark))
{
operatorModel.loginMark = Guid.NewGuid().ToString();
SetProvider(LoginUserMarkKey, operatorModel.loginMark);
}
else
{
operatorModel.loginMark = cookieMark;
}
SetProvider(LoginUserToken, token);
}
else
{
operatorModel.loginMark = loginMark;
RemoveProvider(LoginUserMarkKey);
}
//redis 登录token列表更新
Dictionary<string, string> tokenMarkList = await CacheHelper.GetAsync<Dictionary<string, string>>(cacheKeyToken + operatorModel.UserId);
if (tokenMarkList == null)// 此账号第一次登录
{
tokenMarkList = new Dictionary<string, string>();
tokenMarkList.Add(operatorModel.loginMark, token);
}
else
{
if (tokenMarkList.ContainsKey(operatorModel.loginMark))
{
tokenMarkList[operatorModel.loginMark] = token;
}
else
{
tokenMarkList.Add(operatorModel.loginMark, token);
}
}
await CacheHelper.SetAsync(cacheKeyToken + operatorModel.UserId, tokenMarkList);
await CacheHelper.SetAsync(cacheKeyOperator + operatorModel.loginMark, operatorModel, LoginExpire);
await CacheHelper.RemoveAsync(cacheKeyOperator + facilityMark + operatorModel.UserId);
await CacheHelper.SetAsync(cacheKeyOperator + facilityMark + operatorModel.UserId, token, LoginExpire);
return token;
}
catch (Exception)
{
throw;
}
}
/// <summary>
/// 清空当前登录信息
/// </summary>
/// <param name="apitoken">apitoken</param>
/// <param name="facilityMark">设备类型</param>
public async Task EmptyCurrent(string facilityMark)
{
try
{
string token = GetProvider(LoginUserToken);
string loginMark = GetProvider(LoginUserMarkKey);
await EmptyCurrent(token, facilityMark, loginMark);
RemoveProvider(LoginUserMarkKey.Trim());
RemoveProvider(LoginUserToken.Trim());
}
catch (Exception)
{
}
}
/// <summary>
/// 清空当前登录信息
/// </summary>
/// <param name="token">登录票据</param>
/// <param name="facilityMark">登录设备</param>
/// <param name="loginMark">登录设备标识</param>
public async Task EmptyCurrent(string token, string facilityMark, string loginMark)
{
try
{
OperatorModel operatorInfo = await CacheHelper.GetAsync<OperatorModel>(cacheKeyOperator + loginMark);
if (operatorInfo != null)
{
Dictionary<string, string> tokenMarkList = await CacheHelper.GetAsync<Dictionary<string, string>>(cacheKeyToken + operatorInfo.UserId);
tokenMarkList.Remove(loginMark);
await CacheHelper.RemoveAsync(cacheKeyOperator + loginMark);
if (operatorInfo.LoginToken == token || facilityMark == "api_")
{
await CacheHelper.RemoveAsync(cacheKeyOperator + facilityMark + operatorInfo.UserId);
}
await CacheHelper.SetAsync(cacheKeyToken + operatorInfo.UserId, tokenMarkList);
await CacheHelper.RemoveAsync(facilityMark + GlobalContext.SystemConfig.TokenName + "_" + operatorInfo.UserId + "_" + operatorInfo.LoginTime);
}
}
catch (Exception)
{
}
}
/// <summary>
/// 判断登录状态
/// </summary>
/// <param name="facilityMark">登录设备</param>
/// <param name="apitoken">apitoken</param>
/// <returns>-1未登录,1登录成功,0登录过期,-2账号被顶</returns>
public async Task<OperatorResult> IsOnLine(string facilityMark)
{
try
{
string token = GetProvider(LoginUserToken);
string loginMark = GetProvider(LoginUserMarkKey);
return await IsOnLine(token, facilityMark, loginMark);
}
catch (Exception)
{
return new OperatorResult { stateCode = -1 };
}
}
/// <summary>
/// 判断登录状态
/// </summary>
/// <param name="token">登录票据</param>
/// <param name="facilityMark">登录设备</param>
/// <param name="loginMark">登录设备标识</param>
/// <returns>-1未登录,1登录成功,0登录过期,-2账号被顶</returns>
public async Task<OperatorResult> IsOnLine(string token, string facilityMark, string loginMark)
{
OperatorResult operatorResult = new OperatorResult();
operatorResult.stateCode = -1; // -1未登录,1登录成功,0登录过期
try
{
if (string.IsNullOrEmpty(token) || string.IsNullOrEmpty(loginMark))
{
return operatorResult;
}
OperatorModel operatorInfo = await CacheHelper.GetAsync<OperatorModel>(cacheKeyOperator + loginMark);
if (operatorInfo != null)
{
Dictionary<string, string> tokenMarkList = await CacheHelper.GetAsync<Dictionary<string, string>>(cacheKeyToken + operatorInfo.UserId);
if ((token == operatorInfo.LoginToken || facilityMark == "api_") && tokenMarkList.ContainsKey(operatorInfo.loginMark) && tokenMarkList[operatorInfo.loginMark] == operatorInfo.LoginToken)
{
////账号被顶(排除admin)
if (!LoginMultiple && !operatorInfo.IsSuperAdmin && operatorInfo.LoginToken != await CacheHelper.GetAsync<string>(cacheKeyOperator + facilityMark + operatorInfo.UserId))
{
operatorResult.stateCode = -2;
tokenMarkList = await CacheHelper.GetAsync<Dictionary<string, string>>(cacheKeyToken + operatorInfo.UserId);
tokenMarkList.Remove(loginMark);
await CacheHelper.SetAsync(cacheKeyToken + operatorInfo.UserId, tokenMarkList);
await CacheHelper.RemoveAsync(cacheKeyOperator + loginMark);
}
else
{
operatorResult.userInfo = operatorInfo;
operatorResult.stateCode = 1;
await CacheHelper.ExpireAsync(cacheKeyOperator + loginMark, LoginExpire);
await CacheHelper.ExpireAsync(cacheKeyOperator + facilityMark + operatorInfo.UserId, LoginExpire);
await CacheHelper.ExpireAsync(facilityMark + GlobalContext.SystemConfig.TokenName + "_" + operatorInfo.UserId + "_" + operatorInfo.LoginTime, LoginExpire);
}
}
}
return operatorResult;
}
catch (Exception)
{
return operatorResult;
}
}
#region
/// <summary>
/// 获取当前登录错误次数
/// </summary>
/// <returns></returns>
public async Task<int> GetCurrentErrorNum()
{
int res = 0;
try
{
string cookieMark = GetProvider(LoginUserMarkKey);
if (string.IsNullOrEmpty(cookieMark))
{
cookieMark = Guid.NewGuid().ToString();
SetProvider(LoginUserMarkKey, cookieMark);
}
string num = await CacheHelper.GetAsync<string>(cacheKeyError + cookieMark);
if (!string.IsNullOrEmpty(num))
{
res = Convert.ToInt32(num);
}
}
catch (Exception)
{
}
return res;
}
/// <summary>
/// 增加错误次数
/// </summary>
/// <returns></returns>
public async Task<int> AddCurrentErrorNum()
{
int res = 0;
try
{
string cookieMark = GetProvider(LoginUserMarkKey);
if (string.IsNullOrEmpty(cookieMark))
{
cookieMark = Guid.NewGuid().ToString();
SetProvider(LoginUserMarkKey, cookieMark);
}
string num = await CacheHelper.GetAsync<string>(cacheKeyError + cookieMark);
if (!string.IsNullOrEmpty(num))
{
res = Convert.ToInt32(num);
}
res++;
num = res + "";
await CacheHelper.SetAsync(cacheKeyError + cookieMark, num, 24);
}
catch (Exception)
{
}
return res;
}
/// <summary>
/// 清除当前登录错误次数
/// </summary>
public async Task ClearCurrentErrorNum()
{
try
{
string cookieMark = GetProvider(LoginUserMarkKey);
if (string.IsNullOrEmpty(cookieMark))
{
cookieMark = Guid.NewGuid().ToString();
SetProvider(LoginUserMarkKey, cookieMark);
}
await CacheHelper.RemoveAsync(cacheKeyError + cookieMark);
}
catch (Exception)
{
}
}
#endregion
}
}

View File

@@ -0,0 +1,15 @@
namespace WaterCloud.Code
{
public class OperatorResult
{
/// <summary>
/// 状态码-1未登录,1登录成功,0登录过期
/// </summary>
public int stateCode { get; set; }
/// <summary>
/// 登录者用户信息
/// </summary>
public OperatorModel userInfo { get; set; }
}
}

View File

@@ -0,0 +1,50 @@
using System;
namespace WaterCloud.Code
{
public class OperatorUserInfo
{
//密码
public string F_UserPassword { get; set; }
//
public string F_UserSecretkey { get; set; }
//登录时间设置
public DateTime? F_AllowStartTime { get; set; }
public DateTime? F_AllowEndTime { get; set; }
//锁定时间设置
public DateTime? F_LockStartDate { get; set; }
public DateTime? F_LockEndDate { get; set; }
//第一次登录
public DateTime? F_FirstVisitTime { get; set; }
//上一次登录时间
public DateTime? F_PreviousVisitTime { get; set; }
//最后一次登录时间
public DateTime? F_LastVisitTime { get; set; }
//修改密码时间
public DateTime? F_ChangePasswordDate { get; set; }
//登录次数
public int? F_LogOnCount { get; set; }
//在线标记
public bool? F_UserOnLine { get; set; }
//安全问题
public string F_Question { get; set; }
//问题答案
public string F_AnswerQuestion { get; set; }
//默认主题
public string F_Theme { get; set; }
}
}

View File

@@ -0,0 +1,27 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:59747/",
"sslPort": 44332
}
},
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"WaterCloud.Code": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:5001;http://localhost:5000"
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,18 @@
using Microsoft.AspNetCore.Mvc.ModelBinding.Metadata;
namespace WaterCloud.Code
{
/// <summary>
/// Controller Model Binding 处理
/// </summary>
public class ModelBindingMetadataProvider : IMetadataDetailsProvider, IDisplayMetadataProvider
{
public void CreateDisplayMetadata(DisplayMetadataProviderContext context)
{
if (context.Key.MetadataKind == ModelMetadataKind.Property)
{
context.DisplayMetadata.ConvertEmptyStringToNull = false;
}
}
}
}

View File

@@ -0,0 +1,238 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System;
using System.Security.Cryptography;
using System.Text;
namespace WaterCloud.Code
{
/// <summary>
/// DES加密、解密帮助类
/// </summary>
public class DESEncrypt
{
private static string DESKey = "WaterCloud_desencrypt_2019";
#region ================
/// <summary>
/// 加密
/// </summary>
/// <param name="Text"></param>
/// <returns></returns>
public static string Encrypt(string Text)
{
return Encrypt(Text, DESKey);
}
/// <summary>
/// 加密数据用Web.Security的Hash方式加密
/// </summary>
/// <param name="Text"></param>
/// <param name="sKey"></param>
/// <returns></returns>
public static string Encrypt(string Text, string sKey)
{
DES des = DES.Create();
byte[] inputByteArray;
inputByteArray = Encoding.Default.GetBytes(Text);
des.Key = ASCIIEncoding.ASCII.GetBytes(DecryptMd5(sKey));
des.IV = ASCIIEncoding.ASCII.GetBytes(DecryptMd5(sKey));
System.IO.MemoryStream ms = new System.IO.MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
StringBuilder ret = new StringBuilder();
foreach (byte b in ms.ToArray())
{
ret.AppendFormat("{0:X2}", b);
}
return ret.ToString();
}
/// <summary>
/// 加密数据, 用Security.MD5而非Web.Security的Hash方式加密
/// </summary>
/// <param name="Text"></param>
/// <returns></returns>
public static string Encrypt2(string Text)
{
return Encrypt2(Text, DESKey);
}
/// <summary>
/// 加密数据, 用Security.MD5而非Web.Security的Hash方式加密
/// </summary>
/// <param name="Text"></param>
/// <param name="sKey"></param>
/// <returns></returns>
public static string Encrypt2(string Text, string sKey)
{
DES des = DES.Create();
byte[] inputByteArray;
inputByteArray = Encoding.Default.GetBytes(Text);
sKey = MD5(sKey).Substring(0, 8);
des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
System.IO.MemoryStream ms = new System.IO.MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
StringBuilder ret = new StringBuilder();
foreach (byte b in ms.ToArray())
{
ret.AppendFormat("{0:X2}", b);
}
return ret.ToString();
}
#endregion ================
#region ================
/// <summary>
/// 解密
/// </summary>
/// <param name="Text"></param>
/// <returns></returns>
public static string Decrypt(string Text)
{
if (!string.IsNullOrEmpty(Text))
{
return Decrypt(Text, DESKey);
}
else
{
return "";
}
}
/// <summary>
/// 解密数据用Web.Security的Hash方式加密
/// </summary>
/// <param name="Text"></param>
/// <param name="sKey"></param>
/// <returns></returns>
public static string Decrypt(string Text, string sKey)
{
DES des = DES.Create();
int len;
len = Text.Length / 2;
byte[] inputByteArray = new byte[len];
int x, i;
for (x = 0; x < len; x++)
{
i = Convert.ToInt32(Text.Substring(x * 2, 2), 16);
inputByteArray[x] = (byte)i;
}
des.Key = ASCIIEncoding.ASCII.GetBytes(DecryptMd5(sKey));
des.IV = ASCIIEncoding.ASCII.GetBytes(DecryptMd5(sKey));
System.IO.MemoryStream ms = new System.IO.MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
return Encoding.Default.GetString(ms.ToArray());
}
public static string DecryptMd5(string str)
{
string strEncrypt = string.Empty;
var md5 = System.Security.Cryptography.MD5.Create();
var data = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
StringBuilder builder = new StringBuilder();
// 循环遍历哈希数据的每一个字节并格式化为十六进制字符串
for (int i = 0; i < data.Length; i++)
{
builder.Append(data[i].ToString("X2"));
}
strEncrypt = builder.ToString().Substring(0, 8);
return strEncrypt;
}
/// <summary>
/// 解密数据,用Security.MD5而非Web.Security的Hash方式加密
/// </summary>
/// <param name="Text"></param>
/// <returns></returns>
public static string Decrypt2(string Text)
{
if (!string.IsNullOrEmpty(Text))
{
return Decrypt2(Text, DESKey);
}
else
{
return "";
}
}
/// <summary>
/// 解密数据,用Security.MD5而非Web.Security的Hash方式加密
/// </summary>
/// <param name="Text"></param>
/// <param name="sKey"></param>
/// <returns></returns>
public static string Decrypt2(string Text, string sKey)
{
DES des = DES.Create();
int len;
len = Text.Length / 2;
byte[] inputByteArray = new byte[len];
int x, i;
for (x = 0; x < len; x++)
{
i = Convert.ToInt32(Text.Substring(x * 2, 2), 16);
inputByteArray[x] = (byte)i;
}
sKey = MD5(sKey).Substring(0, 8);
des.Key = ASCIIEncoding.ASCII.GetBytes(sKey);
des.IV = ASCIIEncoding.ASCII.GetBytes(sKey);
System.IO.MemoryStream ms = new System.IO.MemoryStream();
CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
return Encoding.Default.GetString(ms.ToArray());
}
#endregion ================
public static string MD5(string pwd)
{
MD5 md5 = System.Security.Cryptography.MD5.Create();
byte[] data = System.Text.Encoding.Default.GetBytes(pwd);
byte[] md5data = md5.ComputeHash(data);
md5.Clear();
string str = "";
for (int i = 0; i < md5data.Length; i++)
{
str += md5data[i].ToString("x").PadLeft(2, '0');
}
return str;
}
/// <summary>
/// 基于Sha1的自定义加密字符串方法输入一个字符串返回一个由40个字符组成的十六进制的哈希散列字符串
/// </summary>
/// <param name="str">要加密的字符串</param>
/// <returns>加密后的十六进制的哈希散列(字符串)</returns>
public static string Sha1(string str)
{
var buffer = Encoding.UTF8.GetBytes(str);
var data = SHA1.Create().ComputeHash(buffer);
var sb = new StringBuilder();
foreach (var t in data)
{
sb.Append(t.ToString("X2"));
}
return sb.ToString();
}
}
}

View File

@@ -0,0 +1,95 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System;
using System.Security.Cryptography;
using System.Text;
namespace WaterCloud.Code
{
/// <summary>
/// MD5加密
/// </summary>
public class Md5
{
/// <summary>
/// MD5加密
/// </summary>
/// <param name="str">加密字符</param>
/// <param name="code">加密位数16/32</param>
/// <returns></returns>
public static string md5(string str, int code)
{
string strEncrypt = string.Empty;
if (code == 16)
{
var md5 = System.Security.Cryptography.MD5.Create();
var data = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
StringBuilder builder = new StringBuilder();
// 循环遍历哈希数据的每一个字节并格式化为十六进制字符串
for (int i = 0; i < data.Length; i++)
{
builder.Append(data[i].ToString("X2"));
}
strEncrypt = builder.ToString().Substring(8, 16);
}
if (code == 32)
{
var md5 = System.Security.Cryptography.MD5.Create();
var data = md5.ComputeHash(Encoding.UTF8.GetBytes(str));
StringBuilder builder = new StringBuilder();
// 循环遍历哈希数据的每一个字节并格式化为十六进制字符串
for (int i = 0; i < data.Length; i++)
{
builder.Append(data[i].ToString("X2"));
}
strEncrypt = builder.ToString();
}
return strEncrypt;
}
public static string MD5(string str)
{
MD5 md5 = System.Security.Cryptography.MD5.Create();
byte[] data = System.Text.Encoding.Default.GetBytes(str);
byte[] md5data = md5.ComputeHash(data);
md5.Clear();
str = "";
for (int i = 0; i < md5data.Length; i++)
{
str += md5data[i].ToString("x").PadLeft(2, '0');
}
return str;
}
public static string MD5Lower16(string str)
{
return MD5(str).ToLower().Substring(8, 16);
}
public static string MD5Lower32(string str)
{
return MD5(str).ToLower(); ;
}
/// <summary>
/// 32位小写
/// </summary>
/// <returns></returns>
public static string SHA1(string s)
{
SHA1 sha1 = System.Security.Cryptography.SHA1.Create();
byte[] hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(s));
string shaStr = BitConverter.ToString(hash);
shaStr = shaStr.Replace("-", "");
shaStr = shaStr.ToLower();
return s.ToLower();
}
}
}

View File

@@ -0,0 +1,28 @@
using System;
using System.Threading.Tasks;
namespace WaterCloud.Code
{
public class AsyncTaskHelper
{
/// <summary>
/// 开始异步任务
/// </summary>
/// <param name="action"></param>
public static void StartTask(Action action)
{
try
{
Action newAction = () =>
{ };
newAction += action;
Task task = new Task(newAction);
task.Start();
}
catch (Exception ex)
{
LogHelper.WriteWithTime(ex);
}
}
}
}

View File

@@ -0,0 +1,124 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
namespace WaterCloud.Code
{
public enum StatusEnum
{
[Description("启用")]
Yes = 1,
[Description("禁用")]
No = 0
}
public enum IsEnum
{
[Description("是")]
Yes = 1,
[Description("否")]
No = 0
}
public enum NeedEnum
{
[Description("不需要")]
NotNeed = 0,
[Description("需要")]
Need = 1
}
public enum OperateStatusEnum
{
[Description("失败")]
Fail = 0,
[Description("成功")]
Success = 1
}
public enum UploadFileType
{
[Description("头像")]
Portrait = 1,
[Description("新闻图片")]
News = 2,
[Description("导入的文件")]
Import = 10
}
public enum PlatformEnum
{
[Description("Web后台")]
Web = 1,
[Description("WebApi")]
WebApi = 2
}
public enum PayStatusEnum
{
[Description("未知")]
Unknown = 0,
[Description("已支付")]
Success = 1,
[Description("转入退款")]
Refund = 2,
[Description("未支付")]
NotPay = 3,
[Description("已关闭")]
Closed = 4,
[Description("已撤销(付款码支付)")]
Revoked = 5,
[Description("用户支付中(付款码支付)")]
UserPaying = 6,
[Description("支付失败(其他原因,如银行返回失败)")]
PayError = 7
}
public class EnumHelper
{
/// <summary>
/// 获取枚举列表
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static Dictionary<int, string> EnumToDic<T>()
{
Dictionary<int, string> list = new Dictionary<int, string>();
foreach (var e in Enum.GetValues(typeof(T)))
{
list.Add(Convert.ToInt32(e), e.GetDescriptionByEnum<T>());
}
return list;
}
/// <summary>
/// 获取枚举列表
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static List<string> EnumToList<T>()
{
List<string> list = new List<string>();
foreach (var e in Enum.GetValues(typeof(T)))
{
list.Add(e.GetDescriptionByEnum<T>());
}
return list;
}
}
}

View File

@@ -0,0 +1,150 @@
using System;
using System.Runtime.InteropServices;
namespace WaterCloud.Code
{
public class ComputerHelper
{
public static ComputerInfo GetComputerInfo()
{
ComputerInfo computerInfo = new ComputerInfo();
try
{
MemoryMetricsClient client = new MemoryMetricsClient();
MemoryMetrics memoryMetrics = client.GetMetrics();
computerInfo.TotalRAM = Math.Ceiling(memoryMetrics.Total / 1024).ToString() + " GB";
computerInfo.RAMRate = Math.Ceiling(100 * memoryMetrics.Used / memoryMetrics.Total).ToString();
computerInfo.CPURate = Math.Ceiling(GetCPURate().ToDouble()).ToString();
computerInfo.RunTime = GetRunTime();
}
catch (Exception ex)
{
LogHelper.WriteWithTime(ex);
}
return computerInfo;
}
public static bool IsUnix()
{
var isUnix = RuntimeInformation.IsOSPlatform(OSPlatform.OSX) || RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
return isUnix;
}
public static string GetCPURate()
{
string cpuRate = string.Empty;
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;
}
public static string GetRunTime()
{
string runTime = string.Empty;
try
{
if (IsUnix())
{
string output = ShellHelper.Bash("uptime -s");
output = output.Trim();
runTime = Extensions.FormatTime((DateTime.Now - output.ToDate()).TotalMilliseconds.ToString().Split('.')[0].ToLong());
}
else
{
string output = ShellHelper.Cmd("wmic", "OS get LastBootUpTime/Value");
string[] outputArr = output.Split("=", StringSplitOptions.RemoveEmptyEntries);
if (outputArr.Length == 2)
{
runTime = Extensions.FormatTime((DateTime.Now - outputArr[1].Split('.')[0].ToDate()).TotalMilliseconds.ToString().Split('.')[0].ToLong());
}
}
}
catch (Exception ex)
{
LogHelper.WriteWithTime(ex);
}
return runTime;
}
}
public class MemoryMetrics
{
public double Total { get; set; }
public double Used { get; set; }
public double Free { get; set; }
}
public class MemoryMetricsClient
{
public MemoryMetrics GetMetrics()
{
if (ComputerHelper.IsUnix())
{
return GetUnixMetrics();
}
return GetWindowsMetrics();
}
private MemoryMetrics GetWindowsMetrics()
{
string output = ShellHelper.Cmd("wmic", "OS get FreePhysicalMemory,TotalVisibleMemorySize /Value");
var lines = output.Trim().Split("\n");
var freeMemoryParts = lines[0].Split("=", StringSplitOptions.RemoveEmptyEntries);
var totalMemoryParts = lines[1].Split("=", StringSplitOptions.RemoveEmptyEntries);
var metrics = new MemoryMetrics();
metrics.Total = Math.Round(double.Parse(totalMemoryParts[1]) / 1024, 0);
metrics.Free = Math.Round(double.Parse(freeMemoryParts[1]) / 1024, 0);
metrics.Used = metrics.Total - metrics.Free;
return metrics;
}
private MemoryMetrics GetUnixMetrics()
{
string output = ShellHelper.Bash("free -m");
var lines = output.Split("\n");
var memory = lines[1].Split(" ", StringSplitOptions.RemoveEmptyEntries);
var metrics = new MemoryMetrics();
metrics.Total = double.Parse(memory[1]);
metrics.Used = double.Parse(memory[2]);
metrics.Free = double.Parse(memory[3]);
return metrics;
}
}
public class ComputerInfo
{
/// <summary>
/// CPU使用率
/// </summary>
public string CPURate { get; set; }
/// <summary>
/// 总内存
/// </summary>
public string TotalRAM { get; set; }
/// <summary>
/// 内存使用率
/// </summary>
public string RAMRate { get; set; }
/// <summary>
/// 系统运行时间
/// </summary>
public string RunTime { get; set; }
}
}

View File

@@ -0,0 +1,140 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
namespace WaterCloud.Code
{
public class ConcurrentList<T> : IList<T>
{
protected static object _lock = new object();
protected List<T> _interalList = new List<T>();
public IEnumerator<T> GetEnumerator()
{
return Clone().GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return Clone().GetEnumerator();
}
public int Count
{ get { return _interalList.Count; } }
public bool IsReadOnly
{ get { return false; } }
public T this[int index]
{
get
{
lock (_lock)
{
return _interalList[index];
}
}
set
{
lock (_lock)
{
_interalList[index] = value;
}
}
}
public List<T> Clone()
{
List<T> newList = new List<T>();
lock (_lock)
{
_interalList.ForEach(x => newList.Add(x));
}
return newList;
}
public int IndexOf(T item)
{
return _interalList.IndexOf(item);
}
public void Insert(int index, T item)
{
_interalList.Insert(index, item);
}
public void RemoveAt(int index)
{
lock (_lock)
{
_interalList.RemoveAt(index);
}
}
public void Add(T item)
{
lock (_lock)
{
_interalList.Add(item);
}
}
public void AddRange(IEnumerable<T> list)
{
foreach (T item in list)
{
Add(item);
}
}
public void Clear()
{
lock (_lock)
{
_interalList.Clear();
}
}
public bool Contains(T item)
{
return _interalList.Contains(item);
}
public void CopyTo(T[] array, int arrayIndex)
{
_interalList.CopyTo(array, arrayIndex);
}
public bool Remove(T item)
{
if (item == null)
{
return false;
}
lock (_lock)
{
return _interalList.Remove(item);
}
}
public void RemoveAll(Predicate<T> match)
{
if (match == null)
{
return;
}
Contract.Ensures(Contract.Result<int>() >= 0);
Contract.Ensures(Contract.Result<int>() <= Contract.OldValue(Count));
Contract.EndContractBlock();
foreach (T t in Clone())
{
if (match(t))
{
Remove(t);
}
}
}
}
}

View File

@@ -0,0 +1,128 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Reflection;
namespace WaterCloud.Code
{
public static class DataTableHelper
{
public static DataTable ListToDataTable<T>(List<T> entitys)
{
//检查实体集合不能为空
if (entitys == null || entitys.Count < 1)
{
throw new Exception("需转换的集合为空");
}
//取出第一个实体的所有Propertie
Type entityType = entitys[0].GetType();
PropertyInfo[] entityProperties = entityType.GetProperties();
//生成DataTable的structure
//生产代码中应将生成的DataTable结构Cache起来此处略
DataTable dt = new DataTable();
for (int i = 0; i < entityProperties.Length; i++)
{
dt.Columns.Add(entityProperties[i].Name);
}
//将所有entity添加到DataTable中
foreach (object entity in entitys)
{
//检查所有的的实体都为同一类型
if (entity.GetType() != entityType)
{
throw new Exception("要转换的集合元素类型不一致");
}
object[] entityValues = new object[entityProperties.Length];
for (int i = 0; i < entityProperties.Length; i++)
{
entityValues[i] = entityProperties[i].GetValue(entity, null);
}
dt.Rows.Add(entityValues);
}
return dt;
}
/// <summary>
/// List过滤
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="entitys"></param>
/// <param name="list"></param>
/// <returns></returns>
public static List<T> ListFilter<T>(List<T> entitys, List<string> list)
{
//检查实体集合不能为空
if (entitys == null || entitys.Count < 1)
{
throw new Exception("需转换的集合为空");
}
//取出第一个实体的所有Propertie
Type entityType = entitys[0].GetType();
PropertyInfo[] entityProperties = entityType.GetProperties();
//将所有entity过滤
foreach (object entity in entitys)
{
//检查所有的的实体都为同一类型
if (entity.GetType() != entityType)
{
throw new Exception("要转换的集合元素类型不一致");
}
for (int i = 0; i < entityProperties.Length; i++)
{
if (!list.Contains(entityProperties[i].Name))
{
entityProperties[i].SetValue(entity, null);
}
}
}
return entitys;
}
/// <summary>
/// DataTable转成List
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="dt"></param>
/// <returns></returns>
public static List<T> ToDataList<T>(this DataTable dt)
{
var list = new List<T>();
var plist = new List<PropertyInfo>(typeof(T).GetProperties());
foreach (DataRow item in dt.Rows)
{
T s = Activator.CreateInstance<T>();
for (int i = 0; i < dt.Columns.Count; i++)
{
PropertyInfo info = plist.Find(p => p.Name == dt.Columns[i].ColumnName);
if (info != null)
{
try
{
if (!Convert.IsDBNull(item[i]))
{
object v = null;
if (info.PropertyType.ToString().Contains("System.Nullable"))
{
v = Convert.ChangeType(item[i], Nullable.GetUnderlyingType(info.PropertyType));
}
else
{
v = Convert.ChangeType(item[i], info.PropertyType);
}
info.SetValue(s, v, null);
}
}
catch (Exception ex)
{
throw new Exception("字段[" + info.Name + "]转换出错," + ex.Message);
}
}
}
list.Add(s);
}
return list;
}
}
}

View File

@@ -0,0 +1,697 @@
using System;
using System.Data;
using System.IO;
using System.Text;
namespace WaterCloud.Code
{
public class FileHelper
{
public static string MapPath(string path)
{
try
{
string rootdir = Directory.GetCurrentDirectory();
//DirectoryInfo Dir = Directory.GetParent(rootdir);
//string root = Dir.Parent.Parent.Parent.FullName;
return rootdir + path;
}
catch (Exception)
{
return path;
}
}
#region
/// <summary>
/// 读取指定位置文件列表到集合中
/// </summary>
/// <param name="path">指定路径</param>
/// <returns></returns>
public static DataTable GetFileTable(string path)
{
DataTable dt = new DataTable();
dt.Columns.Add("name", typeof(string));
dt.Columns.Add("ext", typeof(string));
dt.Columns.Add("size", typeof(long));
dt.Columns.Add("time", typeof(DateTime));
if (Directory.Exists(path))
{
DirectoryInfo dirinfo = new DirectoryInfo(path);
FileInfo fi;
DirectoryInfo dir;
string FileName, FileExt;
long FileSize = 0;
DateTime FileModify;
try
{
foreach (FileSystemInfo fsi in dirinfo.GetFileSystemInfos())
{
FileName = string.Empty;
FileExt = string.Empty;
if (fsi is FileInfo)
{
fi = (FileInfo)fsi;
//获取文件名称
FileName = fi.Name;
//获取文件扩展名
FileExt = fi.Extension;
//获取文件大小
FileSize = fi.Length;
//获取文件最后修改时间
FileModify = fi.LastWriteTime;
}
else
{
dir = (DirectoryInfo)fsi;
//获取目录名
FileName = dir.Name;
//获取目录最后修改时间
FileModify = dir.LastWriteTime;
//设置目录文件为文件夹
FileExt = "文件夹";
}
DataRow dr = dt.NewRow();
dr["name"] = FileName;
dr["ext"] = FileExt;
dr["size"] = FileSize;
dr["time"] = FileModify;
dt.Rows.Add(dr);
}
}
catch
{
throw;
}
}
return dt;
}
#endregion
#region
/// <summary>
/// 检测指定路径是否存在
/// </summary>
/// <param name="path">目录的绝对路径</param>
public static bool IsExistDirectory(string path)
{
return Directory.Exists(path);
}
#endregion
#region ,true
/// <summary>
/// 检测指定文件是否存在,如果存在则返回true
/// </summary>
/// <param name="filePath">文件的绝对路径</param>
public static bool IsExistFile(string filePath)
{
return File.Exists(filePath);
}
#endregion ,true
#region
/// <summary>
/// 创建文件夹
/// </summary>
/// <param name="folderPath">文件夹的绝对路径</param>
public static void CreateFolder(string folderPath)
{
if (!IsExistDirectory(folderPath))
{
Directory.CreateDirectory(folderPath);
}
}
#endregion
#region
/// <summary>
/// 判断上传文件后缀名
/// </summary>
/// <param name="strExtension">后缀名</param>
public static bool IsCanEdit(string strExtension)
{
strExtension = strExtension.ToLower();
if (strExtension.LastIndexOf(".", StringComparison.Ordinal) >= 0)
{
strExtension = strExtension.Substring(strExtension.LastIndexOf(".", StringComparison.Ordinal));
}
else
{
strExtension = ".txt";
}
string[] strArray = new string[] { ".htm", ".html", ".txt", ".js", ".css", ".xml", ".sitemap" };
for (int i = 0; i < strArray.Length; i++)
{
if (strExtension.Equals(strArray[i]))
{
return true;
}
}
return false;
}
public static bool IsSafeName(string strExtension)
{
strExtension = strExtension.ToLower();
if (strExtension.LastIndexOf(".") >= 0)
{
strExtension = strExtension.Substring(strExtension.LastIndexOf("."));
}
else
{
strExtension = ".txt";
}
string[] strArray = new string[] { ".jpg", ".gif", ".png" };
for (int i = 0; i < strArray.Length; i++)
{
if (strExtension.Equals(strArray[i]))
{
return true;
}
}
return false;
}
public static bool IsZipName(string strExtension)
{
strExtension = strExtension.ToLower();
if (strExtension.LastIndexOf(".") >= 0)
{
strExtension = strExtension.Substring(strExtension.LastIndexOf("."));
}
else
{
strExtension = ".txt";
}
string[] strArray = new string[] { ".zip", ".rar" };
for (int i = 0; i < strArray.Length; i++)
{
if (strExtension.Equals(strArray[i]))
{
return true;
}
}
return false;
}
#endregion
#region
/// <summary>
/// 创建文件夹
/// </summary>
/// <param name="fileName">文件的绝对路径</param>
public static void CreateSuffic(string fileName)
{
try
{
if (!Directory.Exists(fileName))
{
Directory.CreateDirectory(fileName);
}
}
catch (Exception)
{
throw;
}
}
/// <summary>
/// 创建文件夹
/// </summary>
/// <param name="fileName">文件的绝对路径</param>
public static void CreateFiles(string fileName)
{
try
{
//判断文件是否存在,不存在创建该文件
if (!IsExistFile(fileName))
{
FileInfo file = new FileInfo(fileName);
FileStream fs = file.Create();
fs.Close();
}
}
catch (Exception ex)
{
LogHelper.WriteWithTime(ex);
}
}
#region
/// <summary>
/// 创建文件
/// </summary>
/// <param name="path"></param>
/// <param name="content"></param>
public static void CreateFile(string path, string content)
{
if (!Directory.Exists(Path.GetDirectoryName(path)))
{
Directory.CreateDirectory(Path.GetDirectoryName(path));
}
using (StreamWriter sw = new StreamWriter(path, false, Encoding.UTF8))
{
sw.Write(content);
}
}
#endregion
/// <summary>
/// 创建一个文件,并将字节流写入文件。
/// </summary>
/// <param name="filePath">文件的绝对路径</param>
/// <param name="buffer">二进制流数据</param>
public static void CreateFile(string filePath, byte[] buffer)
{
try
{
//判断文件是否存在,不存在创建该文件
if (!IsExistFile(filePath))
{
FileInfo file = new FileInfo(filePath);
FileStream fs = file.Create();
fs.Write(buffer, 0, buffer.Length);
fs.Close();
}
else
{
File.WriteAllBytes(filePath, buffer);
}
}
catch (Exception ex)
{
LogHelper.WriteWithTime(ex);
}
}
#endregion
#region
/// <summary>
/// 将文件移动到指定目录
/// </summary>
/// <param name="sourceFilePath">需要移动的源文件的绝对路径</param>
/// <param name="descDirectoryPath">移动到的目录的绝对路径</param>
public static void Move(string sourceFilePath, string descDirectoryPath)
{
string sourceName = GetFileName(sourceFilePath);
if (IsExistDirectory(descDirectoryPath))
{
//如果目标中存在同名文件,则删除
if (IsExistFile(descDirectoryPath + "\\" + sourceFilePath))
{
DeleteFile(descDirectoryPath + "\\" + sourceFilePath);
}
else
{
//将文件移动到指定目录
File.Move(sourceFilePath, descDirectoryPath + "\\" + sourceFilePath);
}
}
}
#endregion
#region
/// <summary>
/// 将源文件的内容复制到目标文件中
/// </summary>
/// <param name="sourceFilePath">源文件的绝对路径</param>
/// <param name="descDirectoryPath">目标文件的绝对路径</param>
public static void Copy(string sourceFilePath, string descDirectoryPath)
{
File.Copy(sourceFilePath, descDirectoryPath, true);
}
#endregion
#region ( )
/// <summary>
/// 从文件的绝对路径中获取文件名( 不包含扩展名 )
/// </summary>
/// <param name="filePath">文件的绝对路径</param>
public static string GetFileName(string filePath)
{
FileInfo file = new FileInfo(filePath);
return file.Name;
}
#endregion ( )
#region
/// <summary>
/// 获取文件的后缀名
/// </summary>
/// <param name="filePath">文件的绝对路径</param>
public static string GetExtension(string filePath)
{
FileInfo file = new FileInfo(filePath);
return file.Extension;
}
/// <summary>
/// 返回文件扩展名,不含“.”
/// </summary>
/// <param name="filepath">文件全名称</param>
/// <returns>string</returns>
public static string GetFileExt(string filepath)
{
if (string.IsNullOrEmpty(filepath))
{
return "";
}
if (filepath.LastIndexOf(".", StringComparison.Ordinal) > 0)
{
return filepath.Substring(filepath.LastIndexOf(".", StringComparison.Ordinal) + 1); //文件扩展名,不含“.”
}
return "";
}
#endregion
#region
/// <summary>
/// 删除指定文件
/// </summary>
/// <param name="filePath">文件的绝对路径</param>
public static void DeleteFile(string filePath)
{
if (IsExistFile(filePath))
{
File.Delete(filePath);
}
}
#endregion
#region
/// <summary>
/// 删除指定目录及其所有子目录
/// </summary>
/// <param name="directoryPath">文件的绝对路径</param>
public static void DeleteDirectory(string directoryPath)
{
if (IsExistDirectory(directoryPath))
{
Directory.Delete(directoryPath);
}
}
#endregion
#region ,.
/// <summary>
/// 清空指定目录下所有文件及子目录,但该目录依然保存.
/// </summary>
/// <param name="directoryPath">指定目录的绝对路径</param>
public static void ClearDirectory(string directoryPath)
{
if (!IsExistDirectory(directoryPath)) return;
//删除目录中所有的文件
string[] fileNames = GetFileNames(directoryPath);
for (int i = 0; i < fileNames.Length; i++)
{
DeleteFile(fileNames[i]);
}
//删除目录中所有的子目录
string[] directoryNames = GetDirectories(directoryPath);
for (int i = 0; i < directoryNames.Length; i++)
{
DeleteDirectory(directoryNames[i]);
}
}
#endregion ,.
#region
/// <summary>
/// 剪切文件
/// </summary>
/// <param name="source">原路径</param>
/// <param name="destination">新路径</param>
public bool FileMove(string source, string destination)
{
bool ret = false;
FileInfo file_s = new FileInfo(source);
FileInfo file_d = new FileInfo(destination);
if (file_s.Exists)
{
if (!file_d.Exists)
{
file_s.MoveTo(destination);
ret = true;
}
}
if (ret == true)
{
//Response.Write("<script>alert('剪切文件成功!');</script>");
}
else
{
//Response.Write("<script>alert('剪切文件失败!');</script>");
}
return ret;
}
#endregion
#region
/// <summary>
/// 检测指定目录是否为空
/// </summary>
/// <param name="directoryPath">指定目录的绝对路径</param>
public static bool IsEmptyDirectory(string directoryPath)
{
try
{
//判断文件是否存在
string[] fileNames = GetFileNames(directoryPath);
if (fileNames.Length > 0)
{
return false;
}
//判断是否存在文件夹
string[] directoryNames = GetDirectories(directoryPath);
if (directoryNames.Length > 0)
{
return false;
}
return true;
}
catch (Exception)
{
return true;
}
}
#endregion
#region
/// <summary>
/// 获取指定目录中所有文件列表
/// </summary>
/// <param name="directoryPath">指定目录的绝对路径</param>
public static string[] GetFileNames(string directoryPath)
{
if (!IsExistDirectory(directoryPath))
{
throw new FileNotFoundException();
}
return Directory.GetFiles(directoryPath);
}
#endregion
#region
/// <summary>
/// 获取指定目录中所有子目录列表,若要搜索嵌套的子目录列表,请使用重载方法
/// </summary>
/// <param name="directoryPath">指定目录的绝对路径</param>
public static string[] GetDirectories(string directoryPath)
{
return Directory.GetDirectories(directoryPath);
}
/// <summary>
/// 获取指定目录及子目录中所有子目录列表
/// </summary>
/// <param name="directoryPath">指定目录的绝对路径</param>
/// <param name="searchPattern">模式字符串,"*"代表0或N个字符"?"代表1个字符。
/// 范例:"Log*.xml"表示搜索所有以Log开头的Xml文件。</param>
/// <param name="isSearchChild">是否搜索子目录</param>
public static string[] GetDirectories(string directoryPath, string searchPattern, bool isSearchChild)
{
if (isSearchChild)
{
return Directory.GetDirectories(directoryPath, searchPattern, SearchOption.AllDirectories);
}
else
{
return Directory.GetDirectories(directoryPath, searchPattern, SearchOption.TopDirectoryOnly);
}
}
#endregion
#region
/// <summary>
/// 获取一个文件的长度,单位为Byte
/// </summary>
/// <param name="filePath">文件的绝对路径</param>
public static int GetFileSize(string filePath)
{
//创建一个文件对象
FileInfo fi = new FileInfo(filePath);
//获取文件的大小
return (int)fi.Length;
}
/// <summary>
/// 获取一个文件的长度,单位为KB
/// </summary>
/// <param name="filePath">文件的路径</param>
public static double GetFileSizeByKb(string filePath)
{
//创建一个文件对象
FileInfo fi = new FileInfo(filePath);
//获取文件的大小
return Math.Round(Convert.ToDouble(filePath.Length) / 1024, 2);// ConvertHelper.ToDouble(ConvertHelper.ToDouble(fi.Length) / 1024, 1);
}
/// <summary>
/// 获取一个文件的长度,单位为MB
/// </summary>
/// <param name="filePath">文件的路径</param>
public static double GetFileSizeByMb(string filePath)
{
//创建一个文件对象
FileInfo fi = new FileInfo(filePath);
//获取文件的大小
return Math.Round(Convert.ToDouble(Convert.ToDouble(fi.Length) / 1024 / 1024), 2);
}
#endregion
#region BKBGBTB
/// <summary>
/// 计算文件大小函数(保留两位小数),Size为字节大小
/// </summary>
/// <param name="size">初始文件大小</param>
/// <returns></returns>
public static string ToFileSize(long size)
{
string m_strSize = "";
long FactSize = 0;
FactSize = size;
if (FactSize < 1024.00)
m_strSize = FactSize.ToString("F2") + " 字节";
else if (FactSize >= 1024.00 && FactSize < 1048576)
m_strSize = (FactSize / 1024.00).ToString("F2") + " KB";
else if (FactSize >= 1048576 && FactSize < 1073741824)
m_strSize = (FactSize / 1024.00 / 1024.00).ToString("F2") + " MB";
else if (FactSize >= 1073741824)
m_strSize = (FactSize / 1024.00 / 1024.00 / 1024.00).ToString("F2") + " GB";
return m_strSize;
}
#endregion BKBGBTB
#region
/// <summary>
/// 将文件读取到字符串中
/// </summary>
/// <param name="filePath">文件的绝对路径</param>
public static string FileToString(string filePath)
{
return FileToString(filePath, Encoding.UTF8);
}
/// <summary>
/// 将文件读取到字符串中
/// </summary>
/// <param name="filePath">文件的绝对路径</param>
/// <param name="encoding">字符编码</param>
public static string FileToString(string filePath, Encoding encoding)
{
//创建流读取器
StreamReader reader = new StreamReader(filePath, encoding);
try
{
//读取流
return reader.ReadToEnd();
}
finally
{
//关闭流读取器
reader.Close();
}
}
#endregion
#region
// 判断文件是否是bai图片
public static bool IsPicture(string fileName)
{
string strFilter = ".jpeg|.gif|.jpg|.png|.bmp|.pic|.tiff|.ico|.iff|.lbm|.mag|.mac|.mpt|.opt|";
char[] separtor = { '|' };
string[] tempFileds = StringSplit(strFilter, separtor);
foreach (string str in tempFileds)
{
if (str.ToUpper() == fileName.Substring(fileName.LastIndexOf("."), fileName.Length - fileName.LastIndexOf(".")).ToUpper()) { return true; }
}
return false;
}
// 判断文件是否是excle
public static bool IsExcel(string fileName)
{
string strFilter = ".xls|.xlsx|";
char[] separtor = { '|' };
string[] tempFileds = StringSplit(strFilter, separtor);
foreach (string str in tempFileds)
{
if (str.ToUpper() == fileName.Substring(fileName.LastIndexOf("."), fileName.Length - fileName.LastIndexOf(".")).ToUpper()) { return true; }
}
return false;
}
// 通过字符串分隔符返回zhistring[]数组 
public static string[] StringSplit(string s, char[] separtor)
{
string[] tempFileds = s.Trim().Split(separtor); return tempFileds;
}
#endregion
}
}

View File

@@ -0,0 +1,225 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
namespace WaterCloud.Code
{
public class HttpWebClient
{
private IHttpClientFactory _httpClientFactory;
public HttpWebClient(IHttpClientFactory httpClientFactory)
{
this._httpClientFactory = httpClientFactory;
}
/// <summary>
/// Get异步请求
/// </summary>
/// <param name="url"></param>
/// <param name="dicHeaders"></param>
/// <param name="timeoutSecond"></param>
/// <returns></returns>
public async Task<string> GetAsync(string url, Dictionary<string, string> dicHeaders, int timeoutSecond = 120)
{
var client = _httpClientFactory.CreateClient();
var request = new HttpRequestMessage(HttpMethod.Get, url);
if (dicHeaders != null)
{
foreach (var header in dicHeaders)
{
request.Headers.Add(header.Key, header.Value);
}
}
client.Timeout = TimeSpan.FromSeconds(timeoutSecond);
var response = await client.SendAsync(request);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsStringAsync();
return result;
}
else
{
throw new CustomerHttpException($"接口请求错误,错误代码{response.StatusCode},错误原因{response.ReasonPhrase}");
}
}
/// <summary>
///
/// </summary>
/// <param name="url"></param>
/// <param name="requestString"></param>
/// <param name="dicHeaders"></param>
/// <param name="timeoutSecond"></param>
/// <returns></returns>
public async Task<string> PostAsync(string url, string requestString, Dictionary<string, string> dicHeaders, int timeoutSecond)
{
var client = _httpClientFactory.CreateClient();
var requestContent = new StringContent(requestString);
if (dicHeaders != null)
{
foreach (var head in dicHeaders)
{
requestContent.Headers.Add(head.Key, head.Value);
}
}
client.Timeout = TimeSpan.FromSeconds(timeoutSecond);
var response = await client.PostAsync(url, requestContent);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsStringAsync();
return result;
}
else
{
throw new CustomerHttpException($"接口请求错误,错误代码{response.StatusCode},错误原因{response.ReasonPhrase}");
}
}
/// <summary>
///
/// </summary>
/// <param name="url"></param>
/// <param name="requestString"></param>
/// <param name="dicHeaders"></param>
/// <param name="timeoutSecond"></param>
/// <returns></returns>
public async Task<string> PutAsync(string url, string requestString, Dictionary<string, string> dicHeaders, int timeoutSecond)
{
var client = _httpClientFactory.CreateClient();
var requestContent = new StringContent(requestString);
if (dicHeaders != null)
{
foreach (var head in dicHeaders)
{
requestContent.Headers.Add(head.Key, head.Value);
}
}
client.Timeout = TimeSpan.FromSeconds(timeoutSecond);
var response = await client.PutAsync(url, requestContent);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsStringAsync();
return result;
}
else
{
throw new CustomerHttpException($"接口请求错误,错误代码{response.StatusCode},错误原因{response.ReasonPhrase}");
}
}
/// <summary>
/// Patch异步请求
/// </summary>
/// <param name="url"></param>
/// <param name="requestString"></param>
/// <param name="dicHeaders"></param>
/// <param name="timeoutSecond"></param>
/// <returns></returns>
public async Task<string> PatchAsync(string url, string requestString, Dictionary<string, string> dicHeaders, int timeoutSecond)
{
var client = _httpClientFactory.CreateClient();
var requestContent = new StringContent(requestString);
if (dicHeaders != null)
{
foreach (var head in dicHeaders)
{
requestContent.Headers.Add(head.Key, head.Value);
}
}
client.Timeout = TimeSpan.FromSeconds(timeoutSecond);
var response = await client.PatchAsync(url, requestContent);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsStringAsync();
return result;
}
else
{
throw new CustomerHttpException($"接口请求错误,错误代码{response.StatusCode},错误原因{response.ReasonPhrase}");
}
}
public async Task<string> DeleteAsync(string url, Dictionary<string, string> dicHeaders, int timeoutSecond)
{
var client = _httpClientFactory.CreateClient();
var request = new HttpRequestMessage(HttpMethod.Delete, url);
if (dicHeaders != null)
{
foreach (var head in dicHeaders)
{
request.Headers.Add(head.Key, head.Value);
}
}
client.Timeout = TimeSpan.FromSeconds(timeoutSecond);
var response = await client.SendAsync(request);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsStringAsync();
return result;
}
else
{
throw new CustomerHttpException($"接口请求错误,错误代码{response.StatusCode},错误原因{response.ReasonPhrase}");
}
}
/// <summary>
/// 异步请求(通用)
/// </summary>
/// <param name="url"></param>
/// <param name="method"></param>
/// <param name="requestString"></param>
/// <param name="dicHeaders"></param>
/// <param name="timeoutSecond"></param>
/// <returns></returns>
public async Task<string> ExecuteAsync(string url, HttpMethod method, string requestString, Dictionary<string, string> dicHeaders, int timeoutSecond = 120,
string accept = "application/json")
{
var client = _httpClientFactory.CreateClient();
if (url.IndexOf('?') > -1)
{
url += "&v=" + DateTime.Now.ToString("yyyyMMddhhmmss");
}
else
{
url += "?v=" + DateTime.Now.ToString("yyyyMMddhhmmss");
}
var request = new HttpRequestMessage(method, url)
{
Content = new StringContent(requestString),
};
request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json");
if (dicHeaders != null)
{
foreach (var header in dicHeaders)
{
request.Headers.Add(header.Key, header.Value);
}
}
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(accept) { CharSet = "utf-8" });
var response = await client.SendAsync(request);
if (response.IsSuccessStatusCode)
{
var result = await response.Content.ReadAsStringAsync();
return result;
}
else
{
throw new CustomerHttpException($"接口请求错误,错误代码{response.StatusCode},错误原因{response.ReasonPhrase}");
}
}
}
public class CustomerHttpException : Exception
{
public CustomerHttpException() : base()
{ }
public CustomerHttpException(string message) : base(message)
{
}
}
}

View File

@@ -0,0 +1,138 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
namespace WaterCloud.Code
{
#region JsonHelper
public static class JsonHelper
{
/// <summary>
/// 把数组转为逗号连接的字符串
/// </summary>
/// <param name="data"></param>
/// <param name="Str"></param>
/// <returns></returns>
public static string ArrayToString(dynamic data, string Str)
{
string resStr = Str;
foreach (var item in data)
{
if (resStr != "")
{
resStr += ",";
}
if (item is string)
{
resStr += item;
}
else
{
resStr += item.Value;
}
}
return resStr;
}
public static object ToObject(this string Json)
{
return string.IsNullOrEmpty(Json) ? null : JsonConvert.DeserializeObject(Json);
}
public static T ToObject<T>(this string Json)
{
Json = Json.Replace("&nbsp;", "");
return Json == null ? default(T) : JsonConvert.DeserializeObject<T>(Json);
}
public static JObject ToJObject(this string Json)
{
return Json == null ? JObject.Parse("{}") : JObject.Parse(Json.Replace("&nbsp;", ""));
}
public static List<T> ToList<T>(this string Json)
{
return Json == null ? null : JsonConvert.DeserializeObject<List<T>>(Json);
}
public static string ToJson(this object obj, string dateFormat = "yyyy/MM/dd HH:mm:ss")
{
return obj == null ? string.Empty : JsonConvert.SerializeObject(obj, new IsoDateTimeConverter { DateTimeFormat = dateFormat });
}
}
#endregion JsonHelper
#region JsonConverter
/// <summary>
/// Json数据返回到前端js的时候把数值很大的long类型转成字符串
/// </summary>
public class StringJsonConverter : JsonConverter
{
public StringJsonConverter()
{ }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return reader.Value.ToLong();
}
public override bool CanConvert(Type objectType)
{
return true;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
{
writer.WriteNull();
return;
}
string sValue = value.ToString();
writer.WriteValue(sValue);
}
}
/// <summary>
/// DateTime类型序列化的时候转成指定的格式
/// </summary>
public class DateTimeJsonConverter : JsonConverter
{
public DateTimeJsonConverter()
{ }
public override bool CanConvert(Type objectType)
{
return true;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
return reader.Value.ParseToString().ToDate();
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
if (value == null)
{
writer.WriteNull();
return;
}
DateTime? dt = value as DateTime?;
if (dt == null)
{
writer.WriteNull();
return;
}
writer.WriteValue(dt.Value.ToString("yyyy/MM/dd HH:mm:ss"));
}
}
#endregion JsonConverter
}

View File

@@ -0,0 +1,252 @@
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc.Filters;
using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace WaterCloud.Code
{
public class LogHelper
{
private static object lockHelper = new object();
#region
/// <summary>
/// 写日志 异步
/// 默认路径:根目录/Log/yyyy-MM/
/// 默认文件yyyy-MM-dd.log
/// </summary>
/// <param name="logContent">日志内容 自动附加时间</param>
public static void Write(string logContent)
{
string logPath = DateTime.Now.ToString("yyyy-MM");
Write(logPath, logContent);
}
public static void WriteWithTime(string logContent)
{
string logPath = DateTime.Now.ToString("yyyy-MM");
logContent = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + Environment.NewLine + logContent;
Write(logPath, logContent);
}
#endregion
#region
/// <summary>
/// 写异常日志
/// </summary>
/// <param name="ex"></param>
public static void Write(Exception ex)
{
string logContent = string.Empty;
string logPath = DateTime.Now.ToString("yyyy-MM");
logContent += GetExceptionMessage(ex);
Write(logPath, logContent);
}
public static void WriteWithTime(Exception ex)
{
string logContent = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + Environment.NewLine;
string logPath = DateTime.Now.ToString("yyyy-MM");
logContent += GetExceptionMessage(ex);
Write(logPath, logContent);
}
public static void WriteWithTime(ExceptionContext ex)
{
if (ex == null)
return;
string logContent = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + Environment.NewLine;
logContent += "程序异常" + Environment.NewLine;
string logPath = DateTime.Now.ToString("yyyy-MM");
Exception Error = ex.Exception;
LogMessage logMessage = new LogMessage();
logMessage.OperationTime = DateTime.Now;
logMessage.Url = ex.HttpContext.Request.GetDisplayUrl();
if (ex.ActionDescriptor != null)
{
logMessage.Class = ex.ActionDescriptor.DisplayName;
}
else
{
logMessage.Class = "服务器配置问题";
}
logMessage.Ip = WebHelper.Ip;
logMessage.Host = ex.HttpContext.Request.Host.ToString();
var current = OperatorProvider.Provider.GetCurrent();
if (current != null)
{
logMessage.UserName = current.UserCode + "" + current.UserName + "";
}
var err = Error.GetOriginalException();
logMessage.ExceptionInfo = err.Message;
logMessage.ExceptionSource = err.Source;
logMessage.ExceptionRemark = err.StackTrace;
logContent += ExceptionFormat(logMessage);
Write(logPath, logContent);
}
private static string GetExceptionMessage(Exception ex)
{
string message = string.Empty;
if (ex != null)
{
message += ex.Message;
message += Environment.NewLine;
Exception originalException = ex.GetOriginalException();
if (originalException != null)
{
if (originalException.Message != ex.Message)
{
message += originalException.Message;
message += Environment.NewLine;
}
}
message += ex.StackTrace;
message += Environment.NewLine;
}
return message;
}
#endregion
#region
/// <summary>
/// 写日志 异步
/// 默认文件yyyy-MM-dd.log
/// </summary>
/// <param name="logPath">日志目录[默认程序根目录\Log\下添加,故使用相对路径,如:营销任务]</param>
/// <param name="logContent">日志内容 自动附加时间</param>
public static void Write(string logPath, string logContent)
{
string logFileName = DateTime.Now.ToString("yyyy-MM-dd") + ".log";
Write(logPath, logFileName, logContent);
}
/// <summary>
/// 写日志 异步
/// </summary>
/// <param name="logPath">日志目录</param>
/// <param name="logFileName">日志文件名</param>
/// <param name="logContent">日志内容 自动附加时间</param>
public static void Write(string logPath, string logFileName, string logContent)
{
if (string.IsNullOrWhiteSpace(logContent))
{
return;
}
if (string.IsNullOrWhiteSpace(logPath))
{
logPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "logs", DateTime.Now.ToString("yyyy-MM"));
}
else
{
logPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "logs", logPath.Trim('\\'));
}
if (string.IsNullOrWhiteSpace(logFileName))
{
logFileName = DateTime.Now.ToString("yyyy-MM-dd") + ".log";
}
if (!Directory.Exists(logPath))
{
Directory.CreateDirectory(logPath);
}
string fileName = Path.Combine(logPath, logFileName);
Action taskAction = () =>
{
lock (lockHelper)
{
using (StreamWriter sw = File.AppendText(fileName))
{
sw.WriteLine(logContent + Environment.NewLine);
sw.Flush();
sw.Close();
}
}
};
Task task = new Task(taskAction);
task.Start();
}
/// <summary>
/// 生成异常信息
/// </summary>
/// <param name="logMessage">对象</param>
/// <returns></returns>
public static string ExceptionFormat(LogMessage logMessage)
{
StringBuilder strInfo = new StringBuilder();
strInfo.Append("1. 调试: >> 操作时间: " + logMessage.OperationTime + " 操作人: " + logMessage.UserName + " \r\n");
strInfo.Append("2. 地址: " + logMessage.Url + " \r\n");
strInfo.Append("3. 类名: " + logMessage.Class + " \r\n");
strInfo.Append("4. 主机: " + logMessage.Host + " Ip : " + logMessage.Ip + " \r\n");
strInfo.Append("5. 异常: " + logMessage.ExceptionInfo + "\r\n");
strInfo.Append("6. 来源: " + logMessage.ExceptionSource + "\r\n");
strInfo.Append("7. 实例: " + logMessage.ExceptionRemark + "\r\n");
strInfo.Append("-----------------------------------------------------------------------------------------------------------------------------\r\n");
return strInfo.ToString();
}
/// <summary>
/// 格式化异常信息
/// </summary>
/// <param name="logMessage">对象</param>
/// <returns></returns>
public static string ExMsgFormat(string message)
{
//数据库异常
if (message.Contains("An exception occurred while executing DbCommand."))
{
if (message.Contains("Duplicate entry '") && message.Contains("key"))
{
message = "数据违反唯一约束,请检查";
}
else if (message.Contains("Data too long for column"))
{
message = "数据长度过长,请检查";
}
else
{
message = "数据操作异常,请联系管理员";
}
}
//其他异常
else
{
if (message.Contains("Object reference not set to an instance of an object."))
{
message = "操作对象为空,请联系管理员";
}
else if (message.Contains("Value cannot be null"))
{
message = "值为空,请联系管理员";
}
}
if (!IsHasCHZN(message))
{
message = "程序内部异常,请联系管理员";
}
return message;
}
/// <summary>
/// 检测是否有中文字符
/// </summary>
/// <param name="inputData"></param>
/// <returns></returns>
private static bool IsHasCHZN(string inputData)
{
Regex RegCHZN = new Regex("[\u4e00-\u9fa5]");
Match m = RegCHZN.Match(inputData);
return m.Success;
}
#endregion
}
}

View File

@@ -0,0 +1,57 @@
using System;
namespace WaterCloud.Code
{
public class LogMessage
{
/// <summary>
/// 操作时间
/// </summary>
public DateTime OperationTime { get; set; }
/// <summary>
/// Url地址
/// </summary>
public string Url { get; set; }
/// <summary>
/// 类名
/// </summary>
public string Class { get; set; }
/// <summary>
/// IP
/// </summary>
public string Ip { get; set; }
/// <summary>
/// 主机
/// </summary>
public string Host { get; set; }
/// <summary>
/// 操作人
/// </summary>
public string UserName { get; set; }
/// <summary>
/// 内容
/// </summary>
public string Content { get; set; }
/// <summary>
/// 异常信息
/// </summary>
public string ExceptionInfo { get; set; }
/// <summary>
/// 异常来源
/// </summary>
public string ExceptionSource { get; set; }
/// <summary>
/// 异常信息备注
/// </summary>
public string ExceptionRemark { get; set; }
}
}

View File

@@ -0,0 +1,236 @@
using System;
using System.Collections;
namespace WaterCloud.Code
{
// 通过自己定义一个静态类
// 将所有的Content Type都扔进去吧
// 调用的时候直接调用静态方法即可。
public static class MimeMapping
{
private static Hashtable _mimeMappingTable;
private static void AddMimeMapping(string extension, string MimeType)
{
MimeMapping._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)MimeMapping._mimeMappingTable[FileName.Substring(num)];
}
if (text == null)
{
text = (string)MimeMapping._mimeMappingTable[".*"];
}
return text;
}
static MimeMapping()
{
MimeMapping._mimeMappingTable = new Hashtable(190, StringComparer.CurrentCultureIgnoreCase);
MimeMapping.AddMimeMapping(".323", "text/h323");
MimeMapping.AddMimeMapping(".asx", "video/x-ms-asf");
MimeMapping.AddMimeMapping(".acx", "application/internet-property-stream");
MimeMapping.AddMimeMapping(".ai", "application/postscript");
MimeMapping.AddMimeMapping(".aif", "audio/x-aiff");
MimeMapping.AddMimeMapping(".aiff", "audio/aiff");
MimeMapping.AddMimeMapping(".axs", "application/olescript");
MimeMapping.AddMimeMapping(".aifc", "audio/aiff");
MimeMapping.AddMimeMapping(".asr", "video/x-ms-asf");
MimeMapping.AddMimeMapping(".avi", "video/x-msvideo");
MimeMapping.AddMimeMapping(".asf", "video/x-ms-asf");
MimeMapping.AddMimeMapping(".au", "audio/basic");
MimeMapping.AddMimeMapping(".application", "application/x-ms-application");
MimeMapping.AddMimeMapping(".bin", "application/octet-stream");
MimeMapping.AddMimeMapping(".bas", "text/plain");
MimeMapping.AddMimeMapping(".bcpio", "application/x-bcpio");
MimeMapping.AddMimeMapping(".bmp", "image/bmp");
MimeMapping.AddMimeMapping(".cdf", "application/x-cdf");
MimeMapping.AddMimeMapping(".cat", "application/vndms-pkiseccat");
MimeMapping.AddMimeMapping(".crt", "application/x-x509-ca-cert");
MimeMapping.AddMimeMapping(".c", "text/plain");
MimeMapping.AddMimeMapping(".css", "text/css");
MimeMapping.AddMimeMapping(".cer", "application/x-x509-ca-cert");
MimeMapping.AddMimeMapping(".crl", "application/pkix-crl");
MimeMapping.AddMimeMapping(".cmx", "image/x-cmx");
MimeMapping.AddMimeMapping(".csh", "application/x-csh");
MimeMapping.AddMimeMapping(".cod", "image/cis-cod");
MimeMapping.AddMimeMapping(".cpio", "application/x-cpio");
MimeMapping.AddMimeMapping(".clp", "application/x-msclip");
MimeMapping.AddMimeMapping(".crd", "application/x-mscardfile");
MimeMapping.AddMimeMapping(".deploy", "application/octet-stream");
MimeMapping.AddMimeMapping(".dll", "application/x-msdownload");
MimeMapping.AddMimeMapping(".dot", "application/msword");
MimeMapping.AddMimeMapping(".doc", "application/msword");
MimeMapping.AddMimeMapping(".dvi", "application/x-dvi");
MimeMapping.AddMimeMapping(".dir", "application/x-director");
MimeMapping.AddMimeMapping(".dxr", "application/x-director");
MimeMapping.AddMimeMapping(".der", "application/x-x509-ca-cert");
MimeMapping.AddMimeMapping(".dib", "image/bmp");
MimeMapping.AddMimeMapping(".dcr", "application/x-director");
MimeMapping.AddMimeMapping(".disco", "text/xml");
MimeMapping.AddMimeMapping(".exe", "application/octet-stream");
MimeMapping.AddMimeMapping(".etx", "text/x-setext");
MimeMapping.AddMimeMapping(".evy", "application/envoy");
MimeMapping.AddMimeMapping(".eml", "message/rfc822");
MimeMapping.AddMimeMapping(".eps", "application/postscript");
MimeMapping.AddMimeMapping(".flr", "x-world/x-vrml");
MimeMapping.AddMimeMapping(".fif", "application/fractals");
MimeMapping.AddMimeMapping(".gtar", "application/x-gtar");
MimeMapping.AddMimeMapping(".gif", "image/gif");
MimeMapping.AddMimeMapping(".gz", "application/x-gzip");
MimeMapping.AddMimeMapping(".hta", "application/hta");
MimeMapping.AddMimeMapping(".htc", "text/x-component");
MimeMapping.AddMimeMapping(".htt", "text/webviewhtml");
MimeMapping.AddMimeMapping(".h", "text/plain");
MimeMapping.AddMimeMapping(".hdf", "application/x-hdf");
MimeMapping.AddMimeMapping(".hlp", "application/winhlp");
MimeMapping.AddMimeMapping(".html", "text/html");
MimeMapping.AddMimeMapping(".htm", "text/html");
MimeMapping.AddMimeMapping(".hqx", "application/mac-binhex40");
MimeMapping.AddMimeMapping(".isp", "application/x-internet-signup");
MimeMapping.AddMimeMapping(".iii", "application/x-iphone");
MimeMapping.AddMimeMapping(".ief", "image/ief");
MimeMapping.AddMimeMapping(".ivf", "video/x-ivf");
MimeMapping.AddMimeMapping(".ins", "application/x-internet-signup");
MimeMapping.AddMimeMapping(".ico", "image/x-icon");
MimeMapping.AddMimeMapping(".jpg", "image/jpeg");
MimeMapping.AddMimeMapping(".jfif", "image/pjpeg");
MimeMapping.AddMimeMapping(".jpe", "image/jpeg");
MimeMapping.AddMimeMapping(".jpeg", "image/jpeg");
MimeMapping.AddMimeMapping(".js", "application/x-javascript");
MimeMapping.AddMimeMapping(".lsx", "video/x-la-asf");
MimeMapping.AddMimeMapping(".latex", "application/x-latex");
MimeMapping.AddMimeMapping(".lsf", "video/x-la-asf");
MimeMapping.AddMimeMapping(".manifest", "application/x-ms-manifest");
MimeMapping.AddMimeMapping(".mhtml", "message/rfc822");
MimeMapping.AddMimeMapping(".mny", "application/x-msmoney");
MimeMapping.AddMimeMapping(".mht", "message/rfc822");
MimeMapping.AddMimeMapping(".mid", "audio/mid");
MimeMapping.AddMimeMapping(".mpv2", "video/mpeg");
MimeMapping.AddMimeMapping(".man", "application/x-troff-man");
MimeMapping.AddMimeMapping(".mvb", "application/x-msmediaview");
MimeMapping.AddMimeMapping(".mpeg", "video/mpeg");
MimeMapping.AddMimeMapping(".m3u", "audio/x-mpegurl");
MimeMapping.AddMimeMapping(".mdb", "application/x-msaccess");
MimeMapping.AddMimeMapping(".mpp", "application/vnd.ms-project");
MimeMapping.AddMimeMapping(".m1v", "video/mpeg");
MimeMapping.AddMimeMapping(".mpa", "video/mpeg");
MimeMapping.AddMimeMapping(".me", "application/x-troff-me");
MimeMapping.AddMimeMapping(".m13", "application/x-msmediaview");
MimeMapping.AddMimeMapping(".movie", "video/x-sgi-movie");
MimeMapping.AddMimeMapping(".m14", "application/x-msmediaview");
MimeMapping.AddMimeMapping(".mpe", "video/mpeg");
MimeMapping.AddMimeMapping(".mp2", "video/mpeg");
MimeMapping.AddMimeMapping(".mov", "video/quicktime");
MimeMapping.AddMimeMapping(".mp3", "audio/mpeg");
MimeMapping.AddMimeMapping(".mpg", "video/mpeg");
MimeMapping.AddMimeMapping(".ms", "application/x-troff-ms");
MimeMapping.AddMimeMapping(".nc", "application/x-netcdf");
MimeMapping.AddMimeMapping(".nws", "message/rfc822");
MimeMapping.AddMimeMapping(".oda", "application/oda");
MimeMapping.AddMimeMapping(".ods", "application/oleobject");
MimeMapping.AddMimeMapping(".pmc", "application/x-perfmon");
MimeMapping.AddMimeMapping(".p7r", "application/x-pkcs7-certreqresp");
MimeMapping.AddMimeMapping(".p7b", "application/x-pkcs7-certificates");
MimeMapping.AddMimeMapping(".p7s", "application/pkcs7-signature");
MimeMapping.AddMimeMapping(".pmw", "application/x-perfmon");
MimeMapping.AddMimeMapping(".ps", "application/postscript");
MimeMapping.AddMimeMapping(".p7c", "application/pkcs7-mime");
MimeMapping.AddMimeMapping(".pbm", "image/x-portable-bitmap");
MimeMapping.AddMimeMapping(".ppm", "image/x-portable-pixmap");
MimeMapping.AddMimeMapping(".pub", "application/x-mspublisher");
MimeMapping.AddMimeMapping(".pnm", "image/x-portable-anymap");
MimeMapping.AddMimeMapping(".png", "image/png");
MimeMapping.AddMimeMapping(".pml", "application/x-perfmon");
MimeMapping.AddMimeMapping(".p10", "application/pkcs10");
MimeMapping.AddMimeMapping(".pfx", "application/x-pkcs12");
MimeMapping.AddMimeMapping(".p12", "application/x-pkcs12");
MimeMapping.AddMimeMapping(".pdf", "application/pdf");
MimeMapping.AddMimeMapping(".pps", "application/vnd.ms-powerpoint");
MimeMapping.AddMimeMapping(".p7m", "application/pkcs7-mime");
MimeMapping.AddMimeMapping(".pko", "application/vndms-pkipko");
MimeMapping.AddMimeMapping(".ppt", "application/vnd.ms-powerpoint");
MimeMapping.AddMimeMapping(".pmr", "application/x-perfmon");
MimeMapping.AddMimeMapping(".pma", "application/x-perfmon");
MimeMapping.AddMimeMapping(".pot", "application/vnd.ms-powerpoint");
MimeMapping.AddMimeMapping(".prf", "application/pics-rules");
MimeMapping.AddMimeMapping(".pgm", "image/x-portable-graymap");
MimeMapping.AddMimeMapping(".qt", "video/quicktime");
MimeMapping.AddMimeMapping(".ra", "audio/x-pn-realaudio");
MimeMapping.AddMimeMapping(".rgb", "image/x-rgb");
MimeMapping.AddMimeMapping(".ram", "audio/x-pn-realaudio");
MimeMapping.AddMimeMapping(".rmi", "audio/mid");
MimeMapping.AddMimeMapping(".ras", "image/x-cmu-raster");
MimeMapping.AddMimeMapping(".roff", "application/x-troff");
MimeMapping.AddMimeMapping(".rtf", "application/rtf");
MimeMapping.AddMimeMapping(".rtx", "text/richtext");
MimeMapping.AddMimeMapping(".sv4crc", "application/x-sv4crc");
MimeMapping.AddMimeMapping(".spc", "application/x-pkcs7-certificates");
MimeMapping.AddMimeMapping(".setreg", "application/set-registration-initiation");
MimeMapping.AddMimeMapping(".snd", "audio/basic");
MimeMapping.AddMimeMapping(".stl", "application/vndms-pkistl");
MimeMapping.AddMimeMapping(".setpay", "application/set-payment-initiation");
MimeMapping.AddMimeMapping(".stm", "text/html");
MimeMapping.AddMimeMapping(".shar", "application/x-shar");
MimeMapping.AddMimeMapping(".sh", "application/x-sh");
MimeMapping.AddMimeMapping(".sit", "application/x-stuffit");
MimeMapping.AddMimeMapping(".spl", "application/futuresplash");
MimeMapping.AddMimeMapping(".sct", "text/scriptlet");
MimeMapping.AddMimeMapping(".scd", "application/x-msschedule");
MimeMapping.AddMimeMapping(".sst", "application/vndms-pkicertstore");
MimeMapping.AddMimeMapping(".src", "application/x-wais-source");
MimeMapping.AddMimeMapping(".sv4cpio", "application/x-sv4cpio");
MimeMapping.AddMimeMapping(".tex", "application/x-tex");
MimeMapping.AddMimeMapping(".tgz", "application/x-compressed");
MimeMapping.AddMimeMapping(".t", "application/x-troff");
MimeMapping.AddMimeMapping(".tar", "application/x-tar");
MimeMapping.AddMimeMapping(".tr", "application/x-troff");
MimeMapping.AddMimeMapping(".tif", "image/tiff");
MimeMapping.AddMimeMapping(".txt", "text/plain");
MimeMapping.AddMimeMapping(".texinfo", "application/x-texinfo");
MimeMapping.AddMimeMapping(".trm", "application/x-msterminal");
MimeMapping.AddMimeMapping(".tiff", "image/tiff");
MimeMapping.AddMimeMapping(".tcl", "application/x-tcl");
MimeMapping.AddMimeMapping(".texi", "application/x-texinfo");
MimeMapping.AddMimeMapping(".tsv", "text/tab-separated-values");
MimeMapping.AddMimeMapping(".ustar", "application/x-ustar");
MimeMapping.AddMimeMapping(".uls", "text/iuls");
MimeMapping.AddMimeMapping(".vcf", "text/x-vcard");
MimeMapping.AddMimeMapping(".wps", "application/vnd.ms-works");
MimeMapping.AddMimeMapping(".wav", "audio/wav");
MimeMapping.AddMimeMapping(".wrz", "x-world/x-vrml");
MimeMapping.AddMimeMapping(".wri", "application/x-mswrite");
MimeMapping.AddMimeMapping(".wks", "application/vnd.ms-works");
MimeMapping.AddMimeMapping(".wmf", "application/x-msmetafile");
MimeMapping.AddMimeMapping(".wcm", "application/vnd.ms-works");
MimeMapping.AddMimeMapping(".wrl", "x-world/x-vrml");
MimeMapping.AddMimeMapping(".wdb", "application/vnd.ms-works");
MimeMapping.AddMimeMapping(".wsdl", "text/xml");
MimeMapping.AddMimeMapping(".xap", "application/x-silverlight-app");
MimeMapping.AddMimeMapping(".xml", "text/xml");
MimeMapping.AddMimeMapping(".xlm", "application/vnd.ms-excel");
MimeMapping.AddMimeMapping(".xaf", "x-world/x-vrml");
MimeMapping.AddMimeMapping(".xla", "application/vnd.ms-excel");
MimeMapping.AddMimeMapping(".xls", "application/vnd.ms-excel");
MimeMapping.AddMimeMapping(".xof", "x-world/x-vrml");
MimeMapping.AddMimeMapping(".xlt", "application/vnd.ms-excel");
MimeMapping.AddMimeMapping(".xlc", "application/vnd.ms-excel");
MimeMapping.AddMimeMapping(".xsl", "text/xml");
MimeMapping.AddMimeMapping(".xbm", "image/x-xbitmap");
MimeMapping.AddMimeMapping(".xlw", "application/vnd.ms-excel");
MimeMapping.AddMimeMapping(".xpm", "image/x-xpixmap");
MimeMapping.AddMimeMapping(".xwd", "image/x-xwindowdump");
MimeMapping.AddMimeMapping(".xsd", "text/xml");
MimeMapping.AddMimeMapping(".z", "application/x-compress");
MimeMapping.AddMimeMapping(".zip", "application/x-zip-compressed");
MimeMapping.AddMimeMapping(".*", "application/octet-stream");
MimeMapping.AddMimeMapping(".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
}
}
}

View File

@@ -0,0 +1,58 @@
using iTextSharp.text;
using iTextSharp.text.pdf;
namespace WaterCloud.Code
{
public class PdfHelper
{
}
public class PDFFooter : PdfPageEventHelper
{
// write on top of document
public override void OnOpenDocument(PdfWriter writer, Document document)
{
base.OnOpenDocument(writer, document);
PdfPTable tabFot = new PdfPTable(new float[] { 1F });
tabFot.SpacingAfter = 10F;
PdfPCell cell;
tabFot.TotalWidth = 300F;
cell = new PdfPCell(new Phrase("Header"));
tabFot.AddCell(cell);
tabFot.WriteSelectedRows(0, -1, 150, document.Top, writer.DirectContent);
}
// write on start of each page
public override void OnStartPage(PdfWriter writer, Document document)
{
base.OnStartPage(writer, document);
}
// write on end of each page
public override void OnEndPage(PdfWriter writer, Document document)
{
base.OnEndPage(writer, document);
//PdfPTable tabFot = new PdfPTable(new float[] { 1F });
//tabFot.TotalWidth = 700f;
//tabFot.DefaultCell.Border = 0;
//// var footFont = FontFactory.GetFont("Lato", 12 * 0.667f, new Color(60, 60, 60));
//string fontpath = HttpContext.Current.Server.MapPath("~/App_Data");
//BaseFont customfont = BaseFont.CreateFont(fontpath + "\\Lato-Regular.ttf", BaseFont.CP1252, BaseFont.EMBEDDED);
//var footFont = new Font(customfont, 12 * 0.667f, Font.NORMAL, new Color(170, 170, 170));
//PdfPCell cell;
//cell = new PdfPCell(new Phrase("@ 2016 . All Rights Reserved", footFont));
//cell.VerticalAlignment = Element.ALIGN_CENTER;
//cell.Border = 0;
//cell.PaddingLeft = 100f;
//tabFot.AddCell(cell);
//tabFot.WriteSelectedRows(0, -1, 150, document.Bottom, writer.DirectContent);
}
//write on close of document
public override void OnCloseDocument(PdfWriter writer, Document document)
{
base.OnCloseDocument(writer, document);
}
}
}

View File

@@ -0,0 +1,162 @@
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
namespace WaterCloud.Code
{
/// <summary>
/// 队列工具类,用于另起线程处理执行类型数据
/// </summary>
/// <typeparam name="T"></typeparam>
public class QueueHelper<T> : IDisposable
{
#region Private Field
/// <summary>
/// The inner queue.
/// </summary>
private readonly ConcurrentQueue<T> _innerQueue;
/// <summary>
/// The deal task.
/// </summary>
private readonly Task _dealTask;
/// <summary>
/// The flag for end thread.
/// </summary>
private bool _endThreadFlag = false;
/// <summary>
/// The auto reset event.
/// </summary>
private readonly AutoResetEvent _autoResetEvent = new(true);
#endregion Private Field
#region Public Property
/// <summary>
/// The deal action.
/// </summary>
public Action<T> DealAction { get; set; }
#endregion Public Property
#region Constructor
/// <summary>
/// Initializes a new instance of the QueueHelper`1 class.
/// </summary>
public QueueHelper()
{
this._innerQueue = new();
this._dealTask = Task.Run(() => this.DealQueue());
}
/// <summary>
/// Initializes a new instance of the QueueHelper&lt;T&gt; class.
/// </summary>
/// <param name="DealAction">The deal action.</param>
public QueueHelper(Action<T> DealAction)
{
this.DealAction = DealAction;
this._innerQueue = new();
this._dealTask = Task.Run(() => this.DealQueue());
}
#endregion Constructor
#region Public Method
/// <summary>
/// Save entity to Queue.
/// </summary>
/// <param name="entity">The entity what will be deal.</param>
public bool Enqueue(T entity)
{
if (!this._endThreadFlag)
{
this._innerQueue.Enqueue(entity);
this._autoResetEvent.Set();
return true;
}
return false;
}
/// <summary>
/// Disposes current instance, end the deal thread and inner queue.
/// </summary>
public void Dispose()
{
if (!this._endThreadFlag)
{
this._endThreadFlag = true;
this._innerQueue.Enqueue(default);
this._autoResetEvent.Set();
if (!this._dealTask.IsCompleted)
this._dealTask.Wait();
this._dealTask.Dispose();
this._autoResetEvent.Dispose();
this._autoResetEvent.Close();
}
}
#endregion Public Method
#region Private Method
/// <summary>
/// Out Queue.
/// </summary>
/// <param name="entity">The init entity.</param>
/// <returns>The entity what will be deal.</returns>
private bool Dequeue(out T entity)
{
return this._innerQueue.TryDequeue(out entity);
}
/// <summary>
/// Deal entity in Queue.
/// </summary>
private void DealQueue()
{
try
{
while (true)
{
if (this.Dequeue(out T entity))
{
if (this._endThreadFlag && Equals(entity, default(T)))
return;
try
{
this.DealAction?.Invoke(entity);
}
catch (Exception ex)
{
LogHelper.Write(ex);
}
}
else
{
this._autoResetEvent.WaitOne();
}
}
}
catch (Exception ex)
{
LogHelper.Write(ex);
}
}
#endregion Private Method
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,120 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
namespace WaterCloud.Code
{
public class ReflectionHelper
{
private static ConcurrentDictionary<string, object> dictCache = new ConcurrentDictionary<string, object>();
private static List<string> exceptionList = new List<string> { "BaseService", "BaseController" };
#region
/// <summary>
/// 得到类里面的属性集合
/// </summary>
/// <param name="type"></param>
/// <param name="columns"></param>
/// <returns></returns>
public static PropertyInfo[] GetProperties(Type type, string[] columns = null)
{
PropertyInfo[] properties = null;
if (dictCache.ContainsKey(type.FullName))
{
properties = dictCache[type.FullName] as PropertyInfo[];
}
else
{
properties = type.GetProperties();
dictCache.TryAdd(type.FullName, properties);
}
if (columns != null && columns.Length > 0)
{
// 按columns顺序返回属性
var columnPropertyList = new List<PropertyInfo>();
foreach (var column in columns)
{
var columnProperty = properties.Where(p => p.Name == column).FirstOrDefault();
if (columnProperty != null)
{
columnPropertyList.Add(columnProperty);
}
}
return columnPropertyList.ToArray();
}
else
{
return properties;
}
}
public static object GetObjectPropertyValue<T>(T t, string propertyname)
{
Type type = typeof(T);
PropertyInfo property = type.GetProperty(propertyname);
if (property == null) return string.Empty;
object o = property.GetValue(t, null);
if (o == null) return string.Empty;
return o;
}
#endregion
/// <summary>
/// StackTrace获取名称
/// </summary>
/// <param name="count">搜索层级</param>
/// <param name="prefix">前缀</param>
/// <returns></returns>
public static string GetModuleName(int count = 10, bool isReplace = true, string prefix = "Service")
{
try
{
string moduleName = "";
for (int i = 0; i < count; i++)
{
if (!string.IsNullOrEmpty(moduleName))
{
break;
}
string className = new StackFrame(i, true).GetMethod().DeclaringType.FullName;
className = className.Split('+')[0];
className = className.Split('.').LastOrDefault();
bool skip = false;
foreach (var item in exceptionList)
{
if (className.Contains(item))
{
skip = true;
break;
}
}
if (skip)
{
continue;
}
if (className.IndexOf(prefix) > -1)
{
moduleName = className;
if (isReplace)
{
moduleName = moduleName.Replace(prefix, "");
}
}
}
return moduleName;
}
catch (Exception ex)
{
LogHelper.WriteWithTime(ex);
return "";
}
}
}
}

View File

@@ -0,0 +1,44 @@
using System.Diagnostics;
namespace WaterCloud.Code
{
public class ShellHelper
{
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;
}
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;
}
}
}

View File

@@ -0,0 +1,85 @@
using System;
using System.Collections.Generic;
using System.Linq;
namespace WaterCloud.Code
{
public class TextHelper
{
/// <summary>
/// 获取默认值
/// </summary>
/// <param name="value"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static string GetCustomValue(string value, string defaultValue)
{
if (string.IsNullOrEmpty(value))
{
return defaultValue;
}
else
{
return value;
}
}
/// <summary>
/// 截取指定长度的字符串
/// </summary>
/// <param name="value"></param>
/// <param name="length"></param>
/// <returns></returns>
public static string GetSubString(string value, int length, bool ellipsis = false)
{
if (string.IsNullOrEmpty(value))
{
return value;
}
if (value.Length > length)
{
value = value.Substring(0, length);
if (ellipsis)
{
value += "...";
}
}
return value;
}
/// <summary>
/// 字符串转指定类型数组
/// </summary>
/// <param name="value"></param>
/// <param name="split"></param>
/// <returns></returns>
public static T[] SplitToArray<T>(string value, char split)
{
T[] arr = value.Split(new string[] { split.ToString() }, StringSplitOptions.RemoveEmptyEntries).CastSuper<T>().ToArray();
return arr;
}
/// <summary>
/// 判断是否有交集
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="list1"></param>
/// <param name="list2"></param>
/// <returns></returns>
public static bool IsArrayIntersection<T>(List<T> list1, List<T> list2)
{
List<T> t = list1.Distinct().ToList();
var exceptArr = t.Except(list2).ToList();
if (exceptArr.Count < t.Count)
{
return true;
}
else
{
return false;
}
}
}
}

View File

@@ -0,0 +1,37 @@
using System;
namespace WaterCloud.Code
{
public class Utils
{
#region
/// <summary>
/// 表示全局唯一标识符 (GUID)。
/// </summary>
/// <returns></returns>
public static string GuId()
{
return IDGen.NextID().ToString();
}
/// <summary>
/// 自动生成编号 201008251145409865
/// </summary>
/// <returns></returns>
public static string CreateNo()
{
Random random = new Random();
string strRandom = random.Next(1000, 10000).ToString(); //生成编号
string code = DateTime.Now.ToString("yyyyMMddHHmmss") + strRandom;//形如
return code;
}
#endregion
public static string GetGuid()
{
return IDGen.NextID().ToString().Replace("-", string.Empty).ToLower();
}
}
}

View File

@@ -0,0 +1,379 @@
using System;
using System.Linq;
using System.Text.RegularExpressions;
namespace WaterCloud.Code
{
public static class ValidatorHelper
{
#region ()
/// <summary>
/// 验证输入字符串为带小数点正数
/// </summary>
/// <param name="str">输入字符</param>
/// <returns>返回一个bool类型的值</returns>
public static bool IsNumber(this string str)
{
return Regex.IsMatch(str, "^([0]|([1-9]+\\d{0,}?))(.[\\d]+)?$");
}
/// <summary>
/// 验证输入字符串为带小数点正负数
/// </summary>
/// <param name="str">输入字符</param>
/// <returns>返回一个bool类型的值</returns>
public static bool IsNumberic(this string str)
{
return Regex.IsMatch(str, "^-?\\d+$|^(-?\\d+)(\\.\\d+)?$");
}
#endregion ()
#region 010-85849685
/// <summary>
/// 验证中国电话格式是否有效格式010-85849685
/// </summary>
/// <param name="str">输入字符</param>
/// <returns>返回一个bool类型的值</returns>
public static bool IsTel(this string str)
{
return Regex.IsMatch(str, @"^(0[0-9]{2,3}\-)?([2-9][0-9]{6,7})+(\-[0-9]{1,4})?$", RegexOptions.IgnoreCase);
}
#endregion 010-85849685
#region
/// <summary>
/// 验证输入字符串为电话号码
/// </summary>
/// <param name="str">输入字符</param>
/// <returns>返回一个bool类型的值</returns>
public static bool IsPhone(this string str)
{
return Regex.IsMatch(str, @"(^(\d{2,4}[-_—]?)?\d{3,8}([-_—]?\d{3,8})?([-_—]?\d{1,7})?$)|(^0?1[35]\d{9}$)");
//弱一点的验证: @"\d{3,4}-\d{7,8}"
}
#endregion
#region
/// <summary>
/// 验证是否是有效传真号码
/// </summary>
/// <param name="str">输入字符</param>
/// <returns>返回一个bool类型的值</returns>
public static bool IsFax(this string str)
{
return Regex.IsMatch(str, @"^[+]{0,1}(\d){1,3}[ ]?([-]?((\d)|[ ]){1,12})+$");
}
#endregion
#region
/// <summary>
/// 验证手机号是否合法 号段为13,14,15,16,17,18,19 086开头将自动识别
/// </summary>
/// <param name="str">输入字符</param>
/// <returns>返回一个bool类型的值</returns>
public static bool IsMobile(this string str)
{
if (!str.StartsWith("1"))
{
str = str.TrimStart(new char[] { '8', '6', }).TrimStart('0');
}
return Regex.IsMatch(str, @"^(13|14|15|16|17|18|19)\d{9}$");
}
#endregion
#region
/// <summary>
/// 验证身份证是否有效
/// </summary>
/// <param name="str">输入字符</param>
/// <returns>返回一个bool类型的值</returns>
public static bool IsIDCard(this string str)
{
switch (str.Length)
{
case 18:
{
return str.IsIDCard18();
}
case 15:
{
return str.IsIDCard15();
}
default:
return false;
}
}
/// <summary>
/// 验证输入字符串为18位的身份证号码
/// </summary>
/// <param name="str">输入字符</param>
/// <returns>返回一个bool类型的值</returns>
public static bool IsIDCard18(this string str)
{
long n = 0;
if (long.TryParse(str.Remove(17), out n) == false || n < Math.Pow(10, 16) || long.TryParse(str.Replace('x', '0').Replace('X', '0'), out n) == false)
{
return false;//数字验证
}
const string address = "11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x43x52x64x65x71x81x82x91";
if (address.IndexOf(str.Remove(2), StringComparison.Ordinal) == -1)
{
return false;//省份验证
}
string birth = str.Substring(6, 8).Insert(6, "-").Insert(4, "-");
DateTime time;
if (DateTime.TryParse(birth, out time) == false)
{
return false;//生日验证
}
string[] arrVarifyCode = ("1,0,x,9,8,7,6,5,4,3,2").Split(',');
string[] wi = ("7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2").Split(',');
char[] ai = str.Remove(17).ToCharArray();
int sum = 0;
for (int i = 0; i < 17; i++)
{
sum += int.Parse(wi[i]) * int.Parse(ai[i].ToString());
}
int y = -1;
Math.DivRem(sum, 11, out y);
return arrVarifyCode[y] == str.Substring(17, 1).ToLower();
}
/// <summary>
/// 验证输入字符串为15位的身份证号码
/// </summary>
/// <param name="str">输入字符</param>
/// <returns>返回一个bool类型的值</returns>
public static bool IsIDCard15(this string str)
{
long n = 0;
if (long.TryParse(str, out n) == false || n < Math.Pow(10, 14))
{
return false;//数字验证
}
const string address = "11x22x35x44x53x12x23x36x45x54x13x31x37x46x61x14x32x41x50x62x15x33x42x51x63x21x34x43x52x64x65x71x81x82x91";
if (address.IndexOf(str.Remove(2), StringComparison.Ordinal) == -1)
{
return false;//省份验证
}
string birth = str.Substring(6, 6).Insert(4, "-").Insert(2, "-");
DateTime time;
return DateTime.TryParse(birth, out time) != false;
}
#endregion
#region
/// <summary>
/// 验证是否是有效邮箱地址
/// </summary>
/// <param name="str">输入字符</param>
/// <returns>返回一个bool类型的值</returns>
public static bool IsEmail(this string str)
{
return Regex.IsMatch(str, @"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
}
#endregion
#region
/// <summary>
/// 验证是否只含有汉字
/// </summary>
/// <param name="strln">输入字符</param>
/// <returns></returns>
public static bool IsOnlyChinese(this string strln)
{
return Regex.IsMatch(strln, @"^[\u4e00-\u9fa5]+$");
}
#endregion
#region SQL注入
/// <summary>
/// 是否有多余的字符 防止SQL注入
/// </summary>
/// <param name="str">输入字符</param>
/// <returns></returns>
public static bool IsBadString(this string str)
{
if (string.IsNullOrEmpty(str))
return false;
//列举一些特殊字符串
const string badChars = "@,*,#,$,!,+,',=,--,%,^,&,?,(,), <,>,[,],{,},/,\\,;,:,\",\"\",delete,update,drop,alert,select";
var arraryBadChar = badChars.Split(',');
return arraryBadChar.Any(t => !str.Contains(t));
}
#endregion SQL注入
#region 26线
/// <summary>
/// 是否由数字、26个英文字母或者下划线組成的字串
/// </summary>
/// <param name="str">输入字符</param>
/// <returns></returns>
public static bool IsNzx(this string str)
{
return Regex.Match(str, "^[0-9a-zA-Z_]+$").Success;
}
#endregion 26线
#region 26
/// <summary>
/// 由数字、26个英文字母、汉字組成的字串
/// </summary>
/// <param name="str">输入字符</param>
/// <returns></returns>
public static bool IsSzzmChinese(this string str)
{
return Regex.Match(str, @"^[0-9a-zA-Z\u4e00-\u9fa5]+$").Success;
}
#endregion 26
#region 26
/// <summary>
/// 是否由数字、26个英文字母組成的字串
/// </summary>
/// <param name="str">输入字符</param>
/// <returns></returns>
public static bool IsSzzm(this string str)
{
return Regex.Match(str, @"^[0-9a-zA-Z]+$").Success;
}
#endregion 26
#region
/// <summary>
/// 验证输入字符串为邮政编码
/// </summary>
/// <param name="str">输入字符</param>
/// <returns>返回一个bool类型的值</returns>
public static bool IsPostCode(this string str)
{
return Regex.IsMatch(str, @"\d{6}");
}
#endregion
#region
/// <summary>
/// 检查对象的输入长度
/// </summary>
/// <param name="str">输入字符</param>
/// <param name="length">指定的长度</param>
/// <returns>false 太长true -太短</returns>
public static bool CheckLength(this string str, int length)
{
if (str.Length > length)
{
return false;//长度太长
}
return str.Length >= length;
}
#endregion
#region
/// <summary>
/// 判断用户输入是否为日期
/// </summary>
/// <param name="str">输入字符</param>
/// <returns>返回一个bool类型的值</returns>
/// <remarks>
/// 可判断格式如下(其中-可替换为/,不影响验证)
/// YYYY | YYYY-MM | YYYY-MM-DD | YYYY-MM-DD HH:MM:SS | YYYY-MM-DD HH:MM:SS.FFF
/// </remarks>
public static bool IsDateTime(this string str)
{
if (null == str)
{
return false;
}
const string regexDate = @"[1-2]{1}[0-9]{3}((-|\/|\.){1}(([0]?[1-9]{1})|(1[0-2]{1}))((-|\/|\.){1}((([0]?[1-9]{1})|([1-2]{1}[0-9]{1})|(3[0-1]{1})))( (([0-1]{1}[0-9]{1})|2[0-3]{1}):([0-5]{1}[0-9]{1}):([0-5]{1}[0-9]{1})(\.[0-9]{3})?)?)?)?$";
if (Regex.IsMatch(str, regexDate))
{
//以下各月份日期验证,保证验证的完整性
int indexY = -1;
int indexM = -1;
int indexD = -1;
if (-1 != (indexY = str.IndexOf("-", StringComparison.Ordinal)))
{
indexM = str.IndexOf("-", indexY + 1, StringComparison.Ordinal);
indexD = str.IndexOf(":", StringComparison.Ordinal);
}
else
{
indexY = str.IndexOf("/", StringComparison.Ordinal);
indexM = str.IndexOf("/", indexY + 1, StringComparison.Ordinal);
indexD = str.IndexOf(":", StringComparison.Ordinal);
}
//不包含日期部分直接返回true
if (-1 == indexM)
return true;
if (-1 == indexD)
{
indexD = str.Length + 3;
}
int iYear = Convert.ToInt32(str.Substring(0, indexY));
int iMonth = Convert.ToInt32(str.Substring(indexY + 1, indexM - indexY - 1));
int iDate = Convert.ToInt32(str.Substring(indexM + 1, indexD - indexM - 4));
//判断月份日期
if ((iMonth < 8 && 1 == iMonth % 2) || (iMonth > 8 && 0 == iMonth % 2))
{
if (iDate < 32)
return true;
}
else
{
if (iMonth != 2)
{
if (iDate < 31)
return true;
}
else
{
//闰年
if ((0 == iYear % 400) || (0 == iYear % 4 && 0 < iYear % 100))
{
if (iDate < 30)
return true;
}
else
{
if (iDate < 29)
return true;
}
}
}
}
return false;
}
#endregion
}
}

View File

@@ -0,0 +1,86 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System;
using System.DrawingCore;
using System.DrawingCore.Imaging;
using System.IO;
namespace WaterCloud.Code
{
public class VerifyCodeHelper
{
public byte[] GetVerifyCode()
{
int codeW = 80;
int codeH = 30;
int fontSize = 16;
string chkCode = string.Empty;
//颜色列表,用于验证码、噪线、噪点
Color[] color = { Color.Black, Color.Red, Color.Blue, Color.Green, Color.Orange, Color.Brown, Color.Brown, Color.DarkBlue };
//字体列表,用于验证码
string[] font = { "Times New Roman" };
//验证码的字符集,去掉了一些容易混淆的字符
char[] character = { '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'd', 'e', 'f', 'h', 'k', 'm', 'n', 'r', 'x', 'y', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'R', 'S', 'T', 'W', 'X', 'Y' };
Random rnd = new Random();
//生成验证码字符串
for (int i = 0; i < 4; i++)
{
chkCode += character[rnd.Next(character.Length)];
}
//写入Session、验证码加密
WebHelper.WriteSession("wcloud_session_verifycode", Md5.md5(chkCode.ToLower(), 16));
//创建画布
Bitmap bmp = new Bitmap(codeW, codeH);
Graphics g = Graphics.FromImage(bmp);
g.Clear(Color.White);
//画噪线
for (int i = 0; i < 3; i++)
{
int x1 = rnd.Next(codeW);
int y1 = rnd.Next(codeH);
int x2 = rnd.Next(codeW);
int y2 = rnd.Next(codeH);
Color clr = color[rnd.Next(color.Length)];
g.DrawLine(new Pen(clr), x1, y1, x2, y2);
}
//画验证码字符串
for (int i = 0; i < chkCode.Length; i++)
{
string fnt = font[rnd.Next(font.Length)];
Font ft = new Font(fnt, fontSize);
Color clr = color[rnd.Next(color.Length)];
g.DrawString(chkCode[i].ToString(), ft, new SolidBrush(clr), (float)i * 18, (float)0);
}
//将验证码图片写入内存流,并将其以 "image/Png" 格式输出
MemoryStream ms = new MemoryStream();
try
{
bmp.Save(ms, ImageFormat.Png);
return ms.ToArray();
}
catch (Exception)
{
return null;
}
finally
{
g.Dispose();
bmp.Dispose();
}
}
}
public class GetJsVesion
{
public static string GetVcode()
{
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalSeconds).ToString();
}
}
}

View File

@@ -0,0 +1,685 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Http;
using System.Net.Sockets;
using System.Text;
using System.Text.Encodings.Web;
using System.Text.RegularExpressions;
using System.Web;
namespace WaterCloud.Code
{
public class WebHelper
{
#region ResolveUrl(Url)
/// <summary>
/// 解析相对Url
/// </summary>
/// <param name="relativeUrl">相对Url</param>
public static string ResolveUrl(string relativeUrl)
{
if (string.IsNullOrWhiteSpace(relativeUrl))
return string.Empty;
relativeUrl = relativeUrl.Replace("\\", "/");
if (relativeUrl.StartsWith("/"))
return relativeUrl;
if (relativeUrl.Contains("://"))
return relativeUrl;
return VirtualPathUtility.ToAbsolute(relativeUrl);
}
#endregion ResolveUrl(Url)
#region HtmlEncode(html字符串进行编码)
/// <summary>
/// 对html字符串进行编码
/// </summary>
/// <param name="html">html字符串</param>
public static string HtmlEncode(string html)
{
return HttpUtility.HtmlEncode(html);
}
/// <summary>
/// 对html字符串进行解码
/// </summary>
/// <param name="html">html字符串</param>
public static string HtmlDecode(string html)
{
return HttpUtility.HtmlDecode(html);
}
#endregion HtmlEncode(html字符串进行编码)
#region UrlEncode(Url进行编码)
/// <summary>
/// 对Url进行编码
/// </summary>
/// <param name="url">url</param>
/// <param name="isUpper">编码字符是否转成大写,范例,"http://"转成"http%3A%2F%2F"</param>
public static string UrlEncode(string url, bool isUpper = false)
{
return UrlEncode(url, Encoding.UTF8, isUpper);
}
/// <summary>
/// 对Url进行编码
/// </summary>
/// <param name="url">url</param>
/// <param name="encoding">字符编码</param>
/// <param name="isUpper">编码字符是否转成大写,范例,"http://"转成"http%3A%2F%2F"</param>
public static string UrlEncode(string url, Encoding encoding, bool isUpper = false)
{
var result = HttpUtility.UrlEncode(url, encoding);
if (!isUpper)
return result;
return GetUpperEncode(result);
}
/// <summary>
/// 获取大写编码字符串
/// </summary>
private static string GetUpperEncode(string encode)
{
var result = new StringBuilder();
int index = int.MinValue;
for (int i = 0; i < encode.Length; i++)
{
string character = encode[i].ToString();
if (character == "%")
index = i;
if (i - index == 1 || i - index == 2)
character = character.ToUpper();
result.Append(character);
}
return result.ToString();
}
#endregion UrlEncode(Url进行编码)
#region UrlDecode(Url进行解码)
/// <summary>
/// 对Url进行解码,对于javascript的encodeURIComponent函数编码参数,应使用utf-8字符编码来解码
/// </summary>
/// <param name="url">url</param>
public static string UrlDecode(string url)
{
return HttpUtility.UrlDecode(url);
}
/// <summary>
/// 对Url进行解码,对于javascript的encodeURIComponent函数编码参数,应使用utf-8字符编码来解码
/// </summary>
/// <param name="url">url</param>
/// <param name="encoding">字符编码,对于javascript的encodeURIComponent函数编码参数,应使用utf-8字符编码来解码</param>
public static string UrlDecode(string url, Encoding encoding)
{
return HttpUtility.UrlDecode(url, encoding);
}
#endregion UrlDecode(Url进行解码)
#region Session操作
/// <summary>
/// 写Session
/// </summary>
/// <param name="key">Session的键名</param>
/// <param name="value">Session的键值</param>
public static void WriteSession(string key, string value)
{
if (key.IsEmpty())
return;
GlobalContext.HttpContext?.Session.SetString(key, value);
}
/// <summary>
/// 读取Session的值
/// </summary>
/// <param name="key">Session的键名</param>
public static string GetSession(string key)
{
if (string.IsNullOrEmpty(key))
{
return string.Empty;
}
return GlobalContext.HttpContext?.Session.GetString(key) ?? "";
}
/// <summary>
/// 删除指定Session
/// </summary>
/// <param name="key">Session的键名</param>
public static void RemoveSession(string key)
{
if (string.IsNullOrEmpty(key))
{
return;
}
GlobalContext.HttpContext?.Session.Remove(key);
}
#endregion Session操作
#region Cookie操作
/// <summary>
/// 写cookie值
/// </summary>
/// <param name="strName">名称</param>
/// <param name="strValue">值</param>
public static void WriteCookie(string strName, string strValue, CookieOptions option = null)
{
if (option == null)
{
option = new CookieOptions();
option.Expires = DateTime.Now.AddDays(30);
}
GlobalContext.HttpContext?.Response.Cookies.Append(strName, strValue, option);
}
/// <summary>
/// 写cookie值
/// </summary>
/// <param name="strName">名称</param>
/// <param name="strValue">值</param>
/// <param name="strValue">过期时间(分钟)</param>
public static void WriteCookie(string strName, string strValue, int expires)
{
CookieOptions option = new CookieOptions();
option.Expires = DateTime.Now.AddMinutes(expires);
GlobalContext.HttpContext?.Response.Cookies.Append(strName, strValue, option);
}
/// <summary>
/// 读cookie值
/// </summary>
/// <param name="strName">名称</param>
/// <returns>cookie值</returns>
public static string GetCookie(string strName)
{
return GlobalContext.HttpContext?.Request.Cookies[strName] ?? "";
}
/// <summary>
/// 删除Cookie对象
/// </summary>
/// <param name="CookiesName">Cookie对象名称</param>
public static void RemoveCookie(string CookiesName)
{
GlobalContext.HttpContext?.Response.Cookies.Delete(CookiesName);
}
#endregion Cookie操作
#region HTML标记
/// <summary>
/// 去除HTML标记
/// </summary>
/// <param name="NoHTML">包括HTML的源码 </param>
/// <returns>已经去除后的文字</returns>
public static string NoHtml(string Htmlstring)
{
//删除脚本
Htmlstring = Regex.Replace(Htmlstring, @"<script[^>]*?>.*?</script>", "", RegexOptions.IgnoreCase);
//删除HTML
Htmlstring = Regex.Replace(Htmlstring, @"<(.[^>]*)>", "", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"([\r\n])[\s]+", "", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"-->", "", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"<!--.*", "", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"&(quot|#34);", "\"", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"&(amp|#38);", "&", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"&(lt|#60);", "<", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"&(gt|#62);", ">", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"&(nbsp|#160);", " ", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"&(iexcl|#161);", "\xa1", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"&(cent|#162);", "\xa2", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"&(pound|#163);", "\xa3", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"&(copy|#169);", "\xa9", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"&#(\d+);", "", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"&hellip;", "", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"&mdash;", "", RegexOptions.IgnoreCase);
Htmlstring = Regex.Replace(Htmlstring, @"&ldquo;", "", RegexOptions.IgnoreCase);
Htmlstring.Replace("<", "");
Htmlstring = Regex.Replace(Htmlstring, @"&rdquo;", "", RegexOptions.IgnoreCase);
Htmlstring.Replace(">", "");
Htmlstring.Replace("\r\n", "");
Htmlstring = HtmlEncoder.Default.Encode(Htmlstring).Trim();
return Htmlstring;
}
#endregion HTML标记
#region SQL注入
/// <summary>
/// 格式化文本防止SQL注入
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
public static string Formatstr(string html)
{
System.Text.RegularExpressions.Regex regex1 = new System.Text.RegularExpressions.Regex(@"<script[\s\S]+</script *>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex2 = new System.Text.RegularExpressions.Regex(@" href *= *[\s\S]*script *:", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex3 = new System.Text.RegularExpressions.Regex(@" on[\s\S]*=", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex4 = new System.Text.RegularExpressions.Regex(@"<iframe[\s\S]+</iframe *>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex5 = new System.Text.RegularExpressions.Regex(@"<frameset[\s\S]+</frameset *>", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex10 = new System.Text.RegularExpressions.Regex(@"select", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex11 = new System.Text.RegularExpressions.Regex(@"update", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
System.Text.RegularExpressions.Regex regex12 = new System.Text.RegularExpressions.Regex(@"delete", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
html = regex1.Replace(html, ""); //过滤<script></script>标记
html = regex2.Replace(html, ""); //过滤href=javascript: (<A>) 属性
html = regex3.Replace(html, " _disibledevent="); //过滤其它控件的on...事件
html = regex4.Replace(html, ""); //过滤iframe
html = regex10.Replace(html, "s_elect");
html = regex11.Replace(html, "u_pudate");
html = regex12.Replace(html, "d_elete");
html = html.Replace("'", "");
html = html.Replace("&nbsp;", " ");
return html;
}
#endregion SQL注入
#region
public static HttpContext HttpContext
{
get { return GlobalContext.HttpContext; }
}
#endregion
#region
public static string Ip
{
get
{
string result = string.Empty;
try
{
if (HttpContext != null)
{
result = GetWebClientIp();
}
if (string.IsNullOrEmpty(result))
{
result = GetLanIp();
}
}
catch (Exception)
{
return string.Empty;
}
return result;
}
}
private static string GetWebClientIp()
{
try
{
string ip = GetWebRemoteIp();
foreach (var hostAddress in Dns.GetHostAddresses(ip))
{
if (hostAddress.AddressFamily == AddressFamily.InterNetwork)
{
return hostAddress.ToString();
}
else if (hostAddress.AddressFamily == AddressFamily.InterNetworkV6)
{
return hostAddress.MapToIPv4().ToString();
}
}
}
catch (Exception)
{
return string.Empty;
}
return string.Empty;
}
public static string GetLanIp()
{
try
{
foreach (var hostAddress in Dns.GetHostAddresses(Dns.GetHostName()))
{
if (hostAddress.AddressFamily == AddressFamily.InterNetwork)
{
return hostAddress.ToString();
}
else if (hostAddress.AddressFamily == AddressFamily.InterNetworkV6)
{
return hostAddress.MapToIPv4().ToString();
}
}
}
catch (Exception)
{
return string.Empty;
}
return string.Empty;
}
public static string GetWanIp()
{
string ip = string.Empty;
try
{
string url = "http://www.net.cn/static/customercare/yourip.asp";
string html = "";
using (var client = new HttpClient())
{
var reponse = client.GetAsync(url).GetAwaiter().GetResult();
reponse.EnsureSuccessStatusCode();
html = reponse.Content.ReadAsStringAsync().GetAwaiter().GetResult();
}
if (!string.IsNullOrEmpty(html))
{
ip = WebHelper.Resove(html, "<h2>", "</h2>");
}
}
catch (Exception)
{
return string.Empty;
}
return ip;
}
private static string GetWebRemoteIp()
{
try
{
string ip = HttpContext?.Connection?.RemoteIpAddress.ParseToString();
if (HttpContext != null && HttpContext.Request != null)
{
if (HttpContext.Request.Headers.ContainsKey("X-Real-IP"))
{
ip = HttpContext.Request.Headers["X-Real-IP"].ToString();
}
if (HttpContext.Request.Headers.ContainsKey("X-Forwarded-For"))
{
ip = HttpContext.Request.Headers["X-Forwarded-For"].ToString();
}
}
return ip;
}
catch (Exception)
{
return string.Empty;
}
}
public static string UserAgent
{
get
{
string userAgent = string.Empty;
try
{
userAgent = HttpContext?.Request?.Headers["User-Agent"];
}
catch (Exception ex)
{
LogHelper.WriteWithTime(ex);
}
return userAgent;
}
}
public static string GetOSVersion()
{
var osVersion = string.Empty;
try
{
var userAgent = UserAgent;
if (userAgent.Contains("NT 10"))
{
osVersion = "Windows 10";
}
else if (userAgent.Contains("NT 6.3"))
{
osVersion = "Windows 8";
}
else if (userAgent.Contains("NT 6.1"))
{
osVersion = "Windows 7";
}
else if (userAgent.Contains("NT 6.0"))
{
osVersion = "Windows Vista/Server 2008";
}
else if (userAgent.Contains("NT 5.2"))
{
osVersion = "Windows Server 2003";
}
else if (userAgent.Contains("NT 5.1"))
{
osVersion = "Windows XP";
}
else if (userAgent.Contains("NT 5"))
{
osVersion = "Windows 2000";
}
else if (userAgent.Contains("NT 4"))
{
osVersion = "Windows NT4";
}
else if (userAgent.Contains("Android"))
{
osVersion = "Android";
}
else if (userAgent.Contains("Me"))
{
osVersion = "Windows Me";
}
else if (userAgent.Contains("98"))
{
osVersion = "Windows 98";
}
else if (userAgent.Contains("95"))
{
osVersion = "Windows 95";
}
else if (userAgent.Contains("Mac"))
{
osVersion = "Mac";
}
else if (userAgent.Contains("Unix"))
{
osVersion = "UNIX";
}
else if (userAgent.Contains("Linux"))
{
osVersion = "Linux";
}
else if (userAgent.Contains("SunOS"))
{
osVersion = "SunOS";
}
}
catch (Exception ex)
{
LogHelper.WriteWithTime(ex);
}
return osVersion;
}
#endregion
#region IP位置查询
public static string GetIpLocation(string ipAddress)
{
string ipLocation = "未知";
try
{
if (!IsInnerIP(ipAddress))
{
ipLocation = GetIpLocationFromPCOnline(ipAddress);
}
else
{
ipLocation = "本地局域网";
}
}
catch (Exception)
{
return ipLocation;
}
return ipLocation;
}
private static string GetIpLocationFromPCOnline(string ipAddress)
{
string ipLocation = "未知";
try
{
var res = "";
using (var client = new HttpClient())
{
var URL = "http://whois.pconline.com.cn/ip.jsp?ip=" + ipAddress;
var response = client.GetAsync(URL).GetAwaiter().GetResult();
response.EnsureSuccessStatusCode();
res = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
}
if (!string.IsNullOrEmpty(res))
{
ipLocation = res.Trim();
}
}
catch
{
ipLocation = "未知";
}
return ipLocation;
}
#endregion IP位置查询
#region IP
public static bool IsInnerIP(string ipAddress)
{
bool isInnerIp = false;
long ipNum = GetIpNum(ipAddress);
/**
私有IPA类 10.0.0.0-10.255.255.255
B类 172.16.0.0-172.31.255.255
C类 192.168.0.0-192.168.255.255
当然还有127这个网段是环回地址
**/
long aBegin = GetIpNum("10.0.0.0");
long aEnd = GetIpNum("10.255.255.255");
long bBegin = GetIpNum("172.16.0.0");
long bEnd = GetIpNum("172.31.255.255");
long cBegin = GetIpNum("192.168.0.0");
long cEnd = GetIpNum("192.168.255.255");
isInnerIp = IsInner(ipNum, aBegin, aEnd) || IsInner(ipNum, bBegin, bEnd) || IsInner(ipNum, cBegin, cEnd) || ipAddress.Equals("127.0.0.1");
return isInnerIp;
}
/// <summary>
/// 把IP地址转换为Long型数字
/// </summary>
/// <param name="ipAddress">IP地址字符串</param>
/// <returns></returns>
private static long GetIpNum(string ipAddress)
{
string[] ip = ipAddress.Split('.');
long a = int.Parse(ip[0]);
long b = int.Parse(ip[1]);
long c = int.Parse(ip[2]);
long d = int.Parse(ip[3]);
long ipNum = a * 256 * 256 * 256 + b * 256 * 256 + c * 256 + d;
return ipNum;
}
private static bool IsInner(long userIp, long begin, long end)
{
return (userIp >= begin) && (userIp <= end);
}
#endregion IP
#region html处理
/// <summary>
/// Get part Content from HTML by apply prefix part and subfix part
/// </summary>
/// <param name="html">souce html</param>
/// <param name="prefix">prefix</param>
/// <param name="subfix">subfix</param>
/// <returns>part content</returns>
public static string Resove(string html, string prefix, string subfix)
{
int inl = html.IndexOf(prefix);
if (inl == -1)
{
return null;
}
inl += prefix.Length;
int inl2 = html.IndexOf(subfix, inl);
string s = html.Substring(inl, inl2 - inl);
return s;
}
public static string ResoveReverse(string html, string subfix, string prefix)
{
int inl = html.IndexOf(subfix);
if (inl == -1)
{
return null;
}
string subString = html.Substring(0, inl);
int inl2 = subString.LastIndexOf(prefix);
if (inl2 == -1)
{
return null;
}
string s = subString.Substring(inl2 + prefix.Length, subString.Length - inl2 - prefix.Length);
return s;
}
public static List<string> ResoveList(string html, string prefix, string subfix)
{
List<string> list = new List<string>();
int index = prefix.Length * -1;
do
{
index = html.IndexOf(prefix, index + prefix.Length);
if (index == -1)
{
break;
}
index += prefix.Length;
int index4 = html.IndexOf(subfix, index);
string s78 = html.Substring(index, index4 - index);
list.Add(s78);
}
while (index > -1);
return list;
}
#endregion html处理
}
}

View File

@@ -0,0 +1,51 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<Optimize>false</Optimize>
</PropertyGroup>
<ItemGroup>
<Compile Remove="Extend\**" />
<Compile Remove="Extension\**" />
<EmbeddedResource Remove="Extend\**" />
<EmbeddedResource Remove="Extension\**" />
<None Remove="Extend\**" />
<None Remove="Extension\**" />
</ItemGroup>
<ItemGroup>
<Compile Include="Extend\Ext.Mapper.cs" />
<Compile Include="Extend\Ext.Convert.cs" />
<Compile Include="Extend\Ext.DateTime.cs" />
<Compile Include="Extend\Ext.Enum.cs" />
<Compile Include="Extend\Ext.Exception.cs" />
<Compile Include="Extend\Ext.Format.cs" />
<Compile Include="Extend\Ext.String.cs" />
<Compile Include="Extend\Ext.Validate.cs" />
<Compile Include="Extend\Ext.Linq.cs" />
<Compile Include="Extend\Ext.List.cs" />
<Compile Include="Extend\Ext.Table.cs" />
<Compile Include="Extend\Ext.Number.cs" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autofac" Version="8.0.0" />
<PackageReference Include="AutoMapper" Version="13.0.1" />
<PackageReference Include="CSRedisCore" Version="3.8.803" />
<PackageReference Include="iTextSharp.LGPLv2.Core.Fix" Version="1.4.3" />
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.DependencyModel" Version="8.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Serenity.Web" Version="3.14.5" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.6.2" />
<PackageReference Include="System.Drawing.Common" Version="8.0.7" />
<PackageReference Include="ZKWeb.System.Drawing" Version="4.0.1" />
<PackageReference Include="RabbitMQ.Client" Version="6.8.1" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,94 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
namespace WaterCloud.Code
{
/// <summary>
/// 常用返回结果
/// </summary>
public class AlwaysResult
{
/// <summary>
/// 操作结果类型
/// </summary>
public object state { get; set; }
/// <summary>
/// 获取 消息内容
/// </summary>
public string message { get; set; }
}
/// <summary>
/// 常用返回结果
/// </summary>
public class AlwaysResult<T> : AlwaysResult
{
/// <summary>
/// 列表的记录数
/// </summary>
public int count { get; set; }
/// <summary>
/// 获取 返回数据
/// </summary>
public T data { get; set; }
}
/// <summary>
/// DTree返回结果
/// </summary>
public class DTreeResult
{
/// <summary>
/// 操作结果类型
/// </summary>
public StatusInfo status { get; set; }
/// 此页要显示的记录列表
/// </summary>
public object data { get; set; }
}
public class StatusInfo
{
/// <summary>
/// 操作结果类型
/// </summary>
public object code { get; set; }
/// 此页要显示的记录列表
/// </summary>
public object message { get; set; }
}
/// <summary>
/// 表示 ajax 操作结果类型的枚举
/// </summary>
public enum ResultType
{
/// <summary>
/// 消息结果类型
/// </summary>
info,
/// <summary>
/// 成功结果类型
/// </summary>
success,
/// <summary>
/// 警告结果类型
/// </summary>
warning,
/// <summary>
/// 异常结果类型
/// </summary>
error
}
}

View File

@@ -0,0 +1,216 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using System.Text.RegularExpressions;
namespace WaterCloud.Code
{
public class Browser
{
public static bool IsMobile
{
get
{
HttpContext current = GlobalContext.HttpContext;
string text = current.Request.Headers["HTTP_USER_AGENT"];
Regex regex = new Regex("android|avantgo|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\\\/|plucker|pocket|psp|symbian|treo|up\\\\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino", RegexOptions.IgnoreCase | RegexOptions.Multiline);
Regex regex2 = new Regex("1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\\\-(n|u)|c55\\\\/|capi|ccwa|cdm\\\\-|cell|chtm|cldc|cmd\\\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\\\-|_)|g1 u|g560|gene|gf\\\\-5|g\\\\-mo|go(\\\\.w|od)|gr(ad|un)|haie|hcit|hd\\\\-(m|p|t)|hei\\\\-|hi(pt|ta)|hp( i|ip)|hs\\\\-c|ht(c(\\\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\\\-(20|go|ma)|i230|iac( |\\\\-|\\\\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\\\\/)|klon|kpt |kwc\\\\-|kyo(c|k)|le(no|xi)|lg( g|\\\\/(k|l|u)|50|54|e\\\\-|e\\\\/|\\\\-[a-w])|libw|lynx|m1\\\\-w|m3ga|m50\\\\/|ma(te|ui|xo)|mc(01|21|ca)|m\\\\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\\\-2|po(ck|rt|se)|prox|psio|pt\\\\-g|qa\\\\-a|qc(07|12|21|32|60|\\\\-[2-7]|i\\\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\\\\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\\\-|oo|p\\\\-)|sdk\\\\/|se(c(\\\\-|0|1)|47|mc|nd|ri)|sgh\\\\-|shar|sie(\\\\-|m)|sk\\\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\\\-|v\\\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\\\-|tdg\\\\-|tel(i|m)|tim\\\\-|t\\\\-mo|to(pl|sh)|ts(70|m\\\\-|m3|m5)|tx\\\\-9|up(\\\\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|xda(\\\\-|2|g)|yas\\\\-|your|zeto|zte\\\\-", RegexOptions.IgnoreCase | RegexOptions.Multiline);
return regex.IsMatch(text) || regex2.IsMatch(text.Substring(0, 4));
}
}
public static string IP
{
get
{
string text = string.Empty;
text = GlobalContext.HttpContext.Request.Headers["HTTP_X_FORWARDED_FOR"];
string result;
if (text != null && text != string.Empty)
{
if (text.IndexOf(".") == -1)
{
text = null;
}
else if (text.IndexOf(",") != -1)
{
text = text.Replace(" ", "").Replace("\"", "");
string[] array = text.Split(",;".ToCharArray());
for (int i = 0; i < array.Length; i++)
{
if (Browser.IsIPAddress(array[i]) && array[i].Substring(0, 3) != "10." && array[i].Substring(0, 7) != "192.168" && array[i].Substring(0, 7) != "172.16.")
{
result = array[i];
return result;
}
}
}
else
{
if (Browser.IsIPAddress(text))
{
result = text;
return result;
}
text = null;
}
}
if (text == null || text == string.Empty)
{
text = GlobalContext.HttpContext.Request.Headers["REMOTE_ADDR"];
}
if (text == null || text == string.Empty)
{
text = GlobalContext.HttpContext.Features.Get<IHttpConnectionFeature>()?.RemoteIpAddress.ToString();
}
result = text;
return result;
}
}
public static string OS
{
get
{
string text = GlobalContext.HttpContext.Request.Headers["HTTP_USER_AGENT"];
string result;
if (text.IndexOf("NT 4.0") > 0)
{
result = "Windows NT ";
}
else if (text.IndexOf("NT 5.0") > 0)
{
result = "Windows 2000";
}
else if (text.IndexOf("NT 5.1") > 0)
{
result = "Windows XP";
}
else if (text.IndexOf("NT 5.2") > 0)
{
result = "Windows 2003";
}
else if (text.IndexOf("NT 6.0") > 0)
{
result = "Windows Vista";
}
else if (text.IndexOf("NT 6.1") > 0)
{
result = "Windows 2008";
}
else if (text.IndexOf("WindowsCE") > 0)
{
result = "Windows CE";
}
else if (text.IndexOf("NT") > 0)
{
result = "Windows NT ";
}
else if (text.IndexOf("9x") > 0)
{
result = "Windows ME";
}
else if (text.IndexOf("98") > 0)
{
result = "Windows 98";
}
else if (text.IndexOf("95") > 0)
{
result = "Windows 95";
}
else if (text.IndexOf("Win32") > 0)
{
result = "Win32";
}
else if (text.IndexOf("Linux") > 0)
{
result = "Linux";
}
else if (text.IndexOf("SunOS") > 0)
{
result = "SunOS";
}
else if (text.IndexOf("Mac") > 0)
{
result = "Mac";
}
else if (text.IndexOf("Linux") > 0)
{
result = "Linux";
}
else if (text.IndexOf("Windows") > 0)
{
result = "Windows";
}
else
{
result = "未知类型";
}
return result;
}
}
public static string MobileOS
{
get
{
HttpContext current = GlobalContext.HttpContext;
string input = current.Request.Headers["HTTP_USER_AGENT"];
Regex regex = new Regex("android|avantgo|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\\\\/|plucker|pocket|psp|symbian|treo|up\\\\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino", RegexOptions.IgnoreCase | RegexOptions.Multiline);
MatchCollection matchCollection = regex.Matches(input);
string result;
if (matchCollection.Count < 1)
{
result = Browser.OS;
}
else
{
result = matchCollection[0].Value;
}
return result;
}
}
public static string PhoneNumber
{
get
{
string text = "";
HttpContext current = GlobalContext.HttpContext;
if (current.Request.Headers.ContainsKey("DEVICEID"))
{
text = current.Request.Headers["DEVICEID"].ToString();
}
if (current.Request.Headers.ContainsKey("HTTP_X_UP_subno"))
{
text = current.Request.Headers["HTTP_X_UP_subno"].ToString();
text = text.Substring(3, 11);
}
if (current.Request.Headers.ContainsKey("HTTP_X_NETWORK_INFO"))
{
text = current.Request.Headers["HTTP_X_NETWORK_INFO"].ToString();
}
if (current.Request.Headers.ContainsKey("HTTP_X_UP_CALLING_LINE_ID"))
{
text = current.Request.Headers["HTTP_X_UP_CALLING_LINE_ID"].ToString();
}
return text;
}
}
private static bool IsIPAddress(string str1)
{
bool result;
if (str1 == null || str1 == string.Empty || str1.Length < 7 || str1.Length > 15)
{
result = false;
}
else
{
string pattern = "^\\d{1,3}[\\.]\\d{1,3}[\\.]\\d{1,3}[\\.]\\d{1,3}$";
Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);
result = regex.IsMatch(str1);
}
return result;
}
}
}

View File

@@ -0,0 +1,58 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
namespace WaterCloud.Code
{
/// <summary>
/// 分页信息
/// </summary>
public class Pagination
{
/// <summary>
/// 每页行数
/// </summary>
public int rows { get; set; }
/// <summary>
/// 当前页
/// </summary>
public int page { get; set; }
/// <summary>
/// 排序列
/// </summary>
public string field { get; set; }
/// <summary>
/// 排序类型
/// </summary>
public string order { get; set; }
/// <summary>
/// 总记录数
/// </summary>
public int records { get; set; }
/// <summary>
/// 总页数
/// </summary>
public int total
{
get
{
if (records > 0)
{
return records % this.rows == 0 ? records / this.rows : records / this.rows + 1;
}
else
{
return 0;
}
}
}
}
}

View File

@@ -0,0 +1,47 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System.Collections.Generic;
using System.Text;
namespace WaterCloud.Code
{
public static class TreeSelect
{
public static string TreeSelectJson(this List<TreeSelectModel> data)
{
StringBuilder sb = new StringBuilder();
sb.Append("[");
sb.Append(TreeSelectJson(data, "0", ""));
sb.Append("]");
return sb.ToString();
}
private static string TreeSelectJson(List<TreeSelectModel> data, string parentId, string blank)
{
StringBuilder sb = new StringBuilder();
var ChildNodeList = data.FindAll(t => t.parentId == parentId);
var tabline = "";
if (parentId != "0")
{
tabline = "  ";
}
if (ChildNodeList.Count > 0)
{
tabline = tabline + blank;
}
foreach (TreeSelectModel entity in ChildNodeList)
{
entity.text = tabline + entity.text;
string strJson = entity.ToJson();
sb.Append(strJson);
sb.Append(TreeSelectJson(data, entity.id, tabline));
}
return sb.ToString().Replace("}{", "},{");
}
}
}

View File

@@ -0,0 +1,18 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
namespace WaterCloud.Code
{
public class TreeSelectModel
{
public string id { get; set; }
public string text { get; set; }
public string code { get; set; }
public string parentId { get; set; }
public object data { get; set; }
}
}

View File

@@ -0,0 +1,60 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System.Collections.Generic;
using System.Text;
namespace WaterCloud.Code
{
public static class TreeGrid
{
public static string TreeGridJson(this List<TreeGridModel> data)
{
StringBuilder sb = new StringBuilder();
sb.Append(TreeGridJson(data, "0"));
return sb.ToString();
}
private static string TreeGridJson(List<TreeGridModel> data, string parentId)
{
StringBuilder sb = new StringBuilder();
var ChildNodeList = data.FindAll(t => t.parentId == parentId);
sb.Append("[");
if (ChildNodeList.Count > 0)
{
foreach (TreeGridModel entity in ChildNodeList)
{
string strJson = entity.ToJson() + ",";
strJson = strJson.Insert(1, "\"children\":" + TreeGridJson(data, entity.id) + ",");
sb.Append(strJson);
}
sb = sb.Remove(sb.Length - 1, 1);
}
sb.Append("]");
return sb.ToString().Replace("}{", "},{");
}
public static List<TreeGridModel> TreeList(this List<TreeGridModel> data)
{
return TreeList(data, "0");
}
private static List<TreeGridModel> TreeList(List<TreeGridModel> data, string parentId)
{
var ChildNodeList = data.FindAll(t => t.parentId == parentId);
if (ChildNodeList.Count > 0)
{
foreach (TreeGridModel entity in ChildNodeList)
{
entity.children = TreeList(data, entity.id);
}
}
return ChildNodeList;
}
}
}

View File

@@ -0,0 +1,22 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System.Collections.Generic;
namespace WaterCloud.Code
{
public class TreeGridModel
{
public string id { get; set; }
public string parentId { get; set; }
public string title { get; set; }
public object self { get; set; }
public object checkArr { get; set; }
public bool? disabled { get; set; }
public List<TreeGridModel> children { get; set; }
}
}

View File

@@ -0,0 +1,48 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
namespace WaterCloud.Code
{
public static class TreeQuery
{
public static List<T> TreeWhere<T>(this List<T> entityList, Predicate<T> condition, string keyValue = "F_Id", string parentId = "F_ParentId") where T : class
{
List<T> locateList = entityList.FindAll(condition);
var parameter = Expression.Parameter(typeof(T), "t");
List<T> treeList = new List<T>();
foreach (T entity in locateList)
{
treeList.Add(entity);
string pId = entity.GetType().GetProperty(parentId).GetValue(entity, null).ToString();
while (true)
{
if (string.IsNullOrEmpty(pId) && pId == "0")
{
break;
}
Predicate<T> upLambda = (Expression.Equal(parameter.Property(keyValue), Expression.Constant(pId))).ToLambda<Predicate<T>>(parameter).Compile();
T upRecord = entityList.Find(upLambda);
if (upRecord != null)
{
treeList.Add(upRecord);
pId = upRecord.GetType().GetProperty(parentId).GetValue(upRecord, null).ToString();
}
else
{
break;
}
}
}
return treeList.Distinct().ToList();
}
}
}

View File

@@ -0,0 +1,60 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
using System.Collections.Generic;
using System.Text;
namespace WaterCloud.Code
{
public static class TreeView
{
public static string TreeViewJson(this List<TreeViewModel> data, string parentId = "0")
{
StringBuilder strJson = new StringBuilder();
List<TreeViewModel> item = data.FindAll(t => t.parentId == parentId);
strJson.Append("[");
if (item.Count > 0)
{
foreach (TreeViewModel entity in item)
{
strJson.Append("{");
strJson.Append("\"id\":\"" + entity.id + "\",");
strJson.Append("\"text\":\"" + entity.text.Replace("&nbsp;", "") + "\",");
strJson.Append("\"value\":\"" + entity.value + "\",");
if (entity.title != null && !string.IsNullOrEmpty(entity.title.Replace("&nbsp;", "")))
{
strJson.Append("\"title\":\"" + entity.title.Replace("&nbsp;", "") + "\",");
}
if (entity.img != null && !string.IsNullOrEmpty(entity.img.Replace("&nbsp;", "")))
{
strJson.Append("\"img\":\"" + entity.img.Replace("&nbsp;", "") + "\",");
}
if (entity.checkstate != null)
{
strJson.Append("\"checkstate\":" + entity.checkstate + ",");
}
if (entity.parentId != null)
{
strJson.Append("\"parentnodes\":\"" + entity.parentId + "\",");
}
strJson.Append("\"showcheck\":" + entity.showcheck.ToString().ToLower() + ",");
strJson.Append("\"isexpand\":" + entity.isexpand.ToString().ToLower() + ",");
if (entity.complete == true)
{
strJson.Append("\"complete\":" + entity.complete.ToString().ToLower() + ",");
}
strJson.Append("\"hasChildren\":" + entity.hasChildren.ToString().ToLower() + ",");
strJson.Append("\"ChildNodes\":" + TreeViewJson(data, entity.id) + "");
strJson.Append("},");
}
strJson = strJson.Remove(strJson.Length - 1, 1);
}
strJson.Append("]");
return strJson.ToString();
}
}
}

View File

@@ -0,0 +1,24 @@
/*******************************************************************************
* Copyright © 2016 WaterCloud.Framework 版权所有
* Author: WaterCloud
* Description: WaterCloud快速开发平台
* Website
*********************************************************************************/
namespace WaterCloud.Code
{
public class TreeViewModel
{
public string parentId { get; set; }
public string id { get; set; }
public string text { get; set; }
public string value { get; set; }
public int? checkstate { get; set; }
public bool showcheck { get; set; }
public bool complete { get; set; }
public bool isexpand { get; set; }
public bool hasChildren { get; set; }
public string img { get; set; }
public string title { get; set; }
}
}

View File

@@ -0,0 +1,180 @@
using System.Collections.Generic;
namespace WaterCloud.CodeGenerator
{
public class BaseConfigModel
{
/// <summary>
/// 数据库表名sys_menu
/// </summary>
public string TableName { get; set; }
/// <summary>
/// 表名首字母大写Sys_Menu
/// </summary>
public string TableNameUpper { get; set; }
public FileConfigModel FileConfig { get; set; }
public OutputConfigModel OutputConfig { get; set; }
public PageIndexModel PageIndex { get; set; }
public PageFormModel PageForm { get; set; }
}
public class FileConfigModel
{
public string ClassPrefix { get; set; }
public string ClassDescription { get; set; }
public string CreateUserName { get; set; }
public string CreateDate { get; set; }
public string EntityName { get; set; }
public string ServiceName { get; set; }
public string ControllerName { get; set; }
public string PageIndexName { get; set; }
public string PageFormName { get; set; }
public string PageDetailsName { get; set; }
}
public class OutputConfigModel
{
public string OutputModule { get; set; }
public string OutputEntity { get; set; }
public string OutputService { get; set; }
public string OutputWeb { get; set; }
}
public class PageIndexModel
{
/// <summary>
/// 是否菜单显示
/// </summary>
public bool IsMunu { get; set; }
/// <summary>
/// 是否需要搜索框
/// </summary>
public bool IsSearch { get; set; }
/// <summary>
/// 是否树形表格
/// </summary>
public bool IsTree { get; set; }
/// <summary>
/// 是否字段控制
/// </summary>
public bool IsFields { get; set; }
/// <summary>
/// 是否公共
/// </summary>
public bool IsPublic { get; set; }
/// <summary>
/// 是否缓存
/// </summary>
public bool IsCache { get; set; }
/// <summary>
/// 工具栏按钮(新增 修改 删除 查看)
/// </summary>
public List<string> ButtonList { get; set; }
/// <summary>
/// 是否有分页
/// </summary>
public bool IsPagination { get; set; }
/// <summary>
/// 排序字段
/// </summary>
public string SortColumn { get; set; }
/// <summary>
/// 父级字段
/// </summary>
public string ParentColum { get; set; }
/// <summary>
/// 树形显示字段
/// </summary>
public string TreeColum { get; set; }
/// <summary>
/// 模糊查询字段
/// </summary>
public List<string> KeywordColum { get; set; }
/// <summary>
/// 删除字段字段
/// </summary>
public string DeleteColum { get; set; }
/// <summary>
/// 创建时间字段
/// </summary>
public string CreateColum { get; set; }
public bool? IsAsc { get; set; }
public List<ColumnField> ColumnList { get; set; }
}
public class PageFormModel
{
/// <summary>
/// 1表示显示成1列2表示显示成2列
/// </summary>
public int ShowMode { get; set; }
public Dictionary<string, string> FieldList { get; set; }
}
public class ColumnField
{
/// <summary>
/// 字段
/// </summary>
public string field { get; set; }
/// <summary>
/// 列名
/// </summary>
public string title { get; set; }
/// <summary>
/// 宽度
/// </summary>
public int? width { get; set; }
/// <summary>
/// 是否minWidth
/// </summary>
public bool? isAotuWidth { get; set; }
/// <summary>
/// 是否排序
/// </summary>
public bool? isSorted { get; set; }
/// <summary>
/// 是否过滤
/// </summary>
public bool? isFilter { get; set; }
/// <summary>
/// 过滤类型
/// </summary>
public string filterType { get; set; }
/// <summary>
/// 格式化显示
/// </summary>
public string templet { get; set; }
public bool? isShow { get; set; }
/// <summary>
/// 初始值
/// </summary>
public string value { get; set; }
}
}

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