增加新的接口和功能
This commit is contained in:
parent
2489570a15
commit
5e1fcb69b7
|
|
@ -10,3 +10,17 @@
|
|||
/Waste.Web/obj
|
||||
/Waste.Web.Core/bin
|
||||
/Waste.Web.Core/obj
|
||||
/Nirvana.Common/bin
|
||||
/Nirvana.Common/obj
|
||||
/Waste.Doc/苏州垃圾分类计量设备计入标准/4G_2G_NB DTU Products Functions _V2.0_20200219.zip
|
||||
/Waste.Doc/苏州垃圾分类计量设备计入标准/4G_2G_NB Products Operation Guide_20200424.zip
|
||||
/Waste.Doc/苏州垃圾分类计量设备计入标准/HF2411 User Manual-V1.2_20200706.zip
|
||||
/Waste.Doc/苏州垃圾分类计量设备计入标准/4G_2G_NB DTU Products Functions _V2.0_20200219/4G_2G_NB DTU Products Functions_V2.0_20200219.pdf
|
||||
/Waste.Doc/苏州垃圾分类计量设备计入标准/4G_2G_NB Products Operation Guide_20200424/4G_2G_NB Products Operation Guide_20200424.pdf
|
||||
/Waste.Doc/苏州垃圾分类计量设备计入标准/HF2411 User Manual-V1.2_20200706/HF2411 User Manual V1.2(20200706).pdf
|
||||
/Waste.MessageHandler/bin
|
||||
/Waste.MessageHandler/obj
|
||||
/Waste.Socket/bin
|
||||
/Waste.Socket/obj
|
||||
/Waste.Web.Entry/bin
|
||||
/Waste.Web.Entry/obj
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
|
||||
IIS configuration sections.
|
||||
|
|
@ -134,6 +134,7 @@
|
|||
<add name="UnmanagedClassicAppPool" managedRuntimeVersion="" managedPipelineMode="Classic" autoStart="true" />
|
||||
<add name="Waste.Web AppPool" managedRuntimeVersion="" />
|
||||
<add name="Waste.WebApi AppPool" managedRuntimeVersion="" />
|
||||
<add name="Waste.Web.Entry AppPool" managedRuntimeVersion="" />
|
||||
<applicationPoolDefaults managedRuntimeVersion="v4.0">
|
||||
<processModel loadUserProfile="true" setProfileEnvironment="false" />
|
||||
</applicationPoolDefaults>
|
||||
|
|
@ -161,8 +162,8 @@
|
|||
<virtualDirectory path="/" physicalPath="F:\liuzl_ybhdmob\Waste\Waste.Web" />
|
||||
</application>
|
||||
<bindings>
|
||||
<binding protocol="http" bindingInformation="*:52219:localhost" />
|
||||
<binding protocol="https" bindingInformation="*:44378:localhost" />
|
||||
<binding protocol="http" bindingInformation="*:52219:localhost" />
|
||||
<binding protocol="https" bindingInformation="*:44378:localhost" />
|
||||
</bindings>
|
||||
</site>
|
||||
<site name="Waste.WebApi" id="3">
|
||||
|
|
@ -174,6 +175,15 @@
|
|||
<binding protocol="https" bindingInformation="*:44317:localhost" />
|
||||
</bindings>
|
||||
</site>
|
||||
<site name="Waste.Web.Entry" id="4">
|
||||
<application path="/" applicationPool="Waste.Web.Entry AppPool">
|
||||
<virtualDirectory path="/" physicalPath="F:\liuzl_ybhdmob\Waste\Waste.Web.Entry" />
|
||||
</application>
|
||||
<bindings>
|
||||
<binding protocol="http" bindingInformation="*:23881:localhost" />
|
||||
<binding protocol="https" bindingInformation="*:44335:localhost" />
|
||||
</bindings>
|
||||
</site>
|
||||
<siteDefaults>
|
||||
<!-- To enable logging, please change the below attribute "enabled" to "true" -->
|
||||
<logFile logFormat="W3C" directory="%AppData%\Microsoft\IISExpressLogs" enabled="false" />
|
||||
|
|
@ -1021,4 +1031,20 @@
|
|||
</httpCompression>
|
||||
</system.webServer>
|
||||
</location>
|
||||
<location path="Waste.Web.Entry" inheritInChildApplications="false">
|
||||
<system.webServer>
|
||||
<modules>
|
||||
<remove name="WebMatrixSupportModule" />
|
||||
</modules>
|
||||
<handlers>
|
||||
<add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
|
||||
</handlers>
|
||||
<aspNetCore processPath="%LAUNCHER_PATH%" stdoutLogEnabled="false" hostingModel="InProcess" startupTimeLimit="3600" requestTimeout="23:00:00" />
|
||||
<httpCompression>
|
||||
<dynamicTypes>
|
||||
<add mimeType="text/event-stream" enabled="false" />
|
||||
</dynamicTypes>
|
||||
</httpCompression>
|
||||
</system.webServer>
|
||||
</location>
|
||||
</configuration>
|
||||
Binary file not shown.
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* Date :2015-6-4 11:47
|
||||
* Author:吴梦飞
|
||||
* Desc :
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common.ApiBase
|
||||
{
|
||||
public class APIError:ApplicationException
|
||||
{
|
||||
public APIResult ERR_TYPE { get; set; }
|
||||
public string ERR_MESSAGE { get; set; }
|
||||
|
||||
public APIError(string errMsg, APIResult errType):base(errMsg)
|
||||
{
|
||||
this.ERR_MESSAGE = errMsg;
|
||||
this.ERR_TYPE = errType;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* Date :2015-6-4 11:47
|
||||
* Author:吴梦飞
|
||||
* Desc :接口返回状态枚举 可添加
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common.ApiBase
|
||||
{
|
||||
public enum APIResult
|
||||
{
|
||||
FAIL = 0,
|
||||
SUCCESS = 1,
|
||||
WXUNAUTHORITY =2, //微信获取不到用户信息
|
||||
REDIRECT = 404, //未找到
|
||||
SYSTEMERROR = 500,//系统异常
|
||||
NOAUTH =40001,//没有访问权限
|
||||
//100段资源相关
|
||||
DISAblEDRESOURCE =100001,//请求禁用资源请求
|
||||
NORESOURCE=100002 //无资源
|
||||
}
|
||||
|
||||
public enum JFAPIRESULT
|
||||
{
|
||||
/// <summary>
|
||||
/// 成功
|
||||
/// </summary>
|
||||
SUCCESS=0,
|
||||
/// <summary>
|
||||
/// 车牌号错误
|
||||
/// </summary>
|
||||
REGERROR=101,
|
||||
/// <summary>
|
||||
/// 车架号错误
|
||||
/// </summary>
|
||||
VINERROR=102,
|
||||
/// <summary>
|
||||
/// 发动机号错误
|
||||
/// </summary>
|
||||
ENGINEERROR=103,
|
||||
/// <summary>
|
||||
/// 不支持该类型
|
||||
/// </summary>
|
||||
NOTSUPPORT=104,
|
||||
/// <summary>
|
||||
/// 不支持扣分违章代缴
|
||||
/// </summary>
|
||||
NOTSUPPORTADD=105,
|
||||
/// <summary>
|
||||
/// 违章时间格式错误
|
||||
/// </summary>
|
||||
TIMEERROR=106,
|
||||
/// <summary>
|
||||
/// 违章编码错误
|
||||
/// </summary>
|
||||
WZCODEERROR=107,
|
||||
/// <summary>
|
||||
/// 代缴信息重复
|
||||
/// </summary>
|
||||
INFOREPEAT=108,
|
||||
/// <summary>
|
||||
/// 提交订单总金额与实际支付金额不符合
|
||||
/// </summary>
|
||||
MONEYERROR=109,
|
||||
/// <summary>
|
||||
/// 不存在该订单信息
|
||||
/// </summary>
|
||||
NOTFOUND=110,
|
||||
/// <summary>
|
||||
/// 行驶证错误
|
||||
/// </summary>
|
||||
DRIVEERROR=111,
|
||||
/// <summary>
|
||||
/// 驾驶证号错误
|
||||
/// </summary>
|
||||
CARERROR=112,
|
||||
/// <summary>
|
||||
/// 不能办理
|
||||
/// </summary>
|
||||
NOTHANDLER=113,
|
||||
/// <summary>
|
||||
/// 违章信息条数超过限制
|
||||
/// </summary>
|
||||
WZMAXERROR=114,
|
||||
/// <summary>
|
||||
/// 订单已支付
|
||||
/// </summary>
|
||||
WZPAYYED=115,
|
||||
/// <summary>
|
||||
/// 订单超时未支付,自动关闭
|
||||
/// </summary>
|
||||
PAYTIMEOUT=301,
|
||||
/// <summary>
|
||||
/// 订单取消成功
|
||||
/// </summary>
|
||||
CANCELSUCCESS=302,
|
||||
/// <summary>
|
||||
/// 当前订单不能取消
|
||||
/// </summary>
|
||||
CANTCANCEL=303,
|
||||
/// <summary>
|
||||
/// 系统错误
|
||||
/// </summary>
|
||||
SYSTEMERROR=501
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Date :2015-6-4 14:14
|
||||
* Author:吴梦飞
|
||||
* Desc :
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common.ApiBase
|
||||
{
|
||||
public class ListInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 数据总数
|
||||
/// </summary>
|
||||
public int total { get; set; }
|
||||
/// <summary>
|
||||
/// 当前集合总数
|
||||
/// </summary>
|
||||
public int current_total { get; set; }
|
||||
/// <summary>
|
||||
/// 跳过多少记录
|
||||
/// </summary>
|
||||
public int skip_total { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
public class ResultInfo
|
||||
{
|
||||
public int code { get; set; }
|
||||
public string message { get; set; }
|
||||
public object data { get; set; }
|
||||
|
||||
public ResultInfo()
|
||||
{
|
||||
|
||||
}
|
||||
public ResultInfo(int codes,string msg,object datas=null)
|
||||
{
|
||||
this.code = codes;
|
||||
this.message = msg;
|
||||
this.data = datas;
|
||||
}
|
||||
|
||||
}
|
||||
public class ResultState
|
||||
{
|
||||
/// <summary>
|
||||
/// 失败 1
|
||||
/// </summary>
|
||||
public static readonly int FAIL = 1;
|
||||
/// <summary>
|
||||
/// 成功 0
|
||||
/// </summary>
|
||||
public static readonly int SUCCESS = 0;
|
||||
/// <summary>
|
||||
/// 微信获取不到用户信息
|
||||
/// </summary>
|
||||
public static readonly int WXUNAUTHORITY = 2;
|
||||
/// <summary>
|
||||
/// 登录成功
|
||||
/// </summary>
|
||||
public static readonly int LOGINSUCCESS = 3;
|
||||
|
||||
/// <summary>
|
||||
/// 今日还未测测量
|
||||
/// </summary>
|
||||
public static readonly int NORESULT = 4;
|
||||
/// <summary>
|
||||
/// 未找到
|
||||
/// </summary>
|
||||
public static readonly int REDIRECT = 404;
|
||||
/// <summary>
|
||||
/// 系统异常
|
||||
/// </summary>
|
||||
public static readonly int SYSTEMERROR = 500;
|
||||
/// <summary>
|
||||
/// 没有访问权限
|
||||
/// </summary>
|
||||
public static readonly int NOAUTH = 40001;
|
||||
/// <summary>
|
||||
/// TOKEN验证未通过
|
||||
/// </summary>
|
||||
public static readonly int TOKEN = -100;
|
||||
/// <summary>
|
||||
/// 请求禁用资源请求
|
||||
/// </summary>
|
||||
public static readonly int DISAblEDRESOURCE = 100001;
|
||||
/// <summary>
|
||||
/// 无资源
|
||||
/// </summary>
|
||||
public static readonly int NORESOURCE = 100002;
|
||||
}
|
||||
|
||||
public class ResultInfoV1
|
||||
{
|
||||
public string state { get; set; }
|
||||
public string message { get; set; }
|
||||
public object data { get; set; }
|
||||
}
|
||||
public enum ResultStateV1
|
||||
{
|
||||
//失败
|
||||
FAIL = 1,
|
||||
//成功
|
||||
SUCCESS = 0,
|
||||
//100段资源相关
|
||||
//请求禁用资源请求
|
||||
DISAblEDRESOURCE = 100001,
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Nirvana.Common.ApiBase
|
||||
{
|
||||
public class ReturnData<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// 错误码,参考APIResult
|
||||
/// </summary>
|
||||
public int code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回的消息
|
||||
/// </summary>
|
||||
public string message { get; set; }
|
||||
/// <summary>
|
||||
/// 返回的数据
|
||||
/// </summary>
|
||||
public T data { get; set; }
|
||||
|
||||
public ReturnData(APIResult code,string message,T returndata)
|
||||
{
|
||||
this.code = (int)code;
|
||||
this.message = message;
|
||||
this.data = returndata;
|
||||
}
|
||||
}
|
||||
|
||||
public class ReturnData1<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// 错误码,参考APIResult
|
||||
/// </summary>
|
||||
public int code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 返回的数据
|
||||
/// </summary>
|
||||
public T data { get; set; }
|
||||
|
||||
public ReturnData1(APIResult code, string message, T returndata)
|
||||
{
|
||||
this.code = (int)code;
|
||||
this.data = returndata;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Date :2015-6-4 14:13
|
||||
* Author:吴梦飞
|
||||
* Desc :
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common.ApiBase
|
||||
{
|
||||
public class ReturnMultiData<T>
|
||||
{
|
||||
public ReturnStatus status { get; set; }
|
||||
public ListInfo total { get; set; }
|
||||
|
||||
public List<T> datas { get; set; }
|
||||
|
||||
public ReturnMultiData(ReturnStatus returnstatus, List<T> datas, ListInfo returnlistinfo)
|
||||
{
|
||||
this.status = returnstatus;
|
||||
this.datas = datas;
|
||||
this.total = returnlistinfo;
|
||||
}
|
||||
|
||||
public string ToJson()
|
||||
{
|
||||
return Newtonsoft.Json.JsonConvert.SerializeObject(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Date :2015-6-4 14:09
|
||||
* Author:吴梦飞
|
||||
* Desc :
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common.ApiBase
|
||||
{
|
||||
public class ReturnSingleData<T>
|
||||
{
|
||||
public ReturnStatus status { get; set; }
|
||||
public T data { get; set; }
|
||||
public ReturnSingleData(ReturnStatus returnstatues, T returndata)
|
||||
{
|
||||
this.status = returnstatues;
|
||||
this.data = returndata;
|
||||
}
|
||||
|
||||
public string ToJson()
|
||||
{
|
||||
return Newtonsoft.Json.JsonConvert.SerializeObject(this);
|
||||
}
|
||||
}
|
||||
|
||||
public class ReturnSingleDataV2<T>
|
||||
{
|
||||
|
||||
public int code { get; set; }
|
||||
public string name { get; set; }
|
||||
public string message { get; set; }
|
||||
public T data { get; set; }
|
||||
|
||||
public ReturnSingleDataV2(APIResult apiresult, string msg, T returndata)
|
||||
{
|
||||
this.code = (int)apiresult;
|
||||
this.name = apiresult.ToString();
|
||||
this.message = msg;
|
||||
this.data = returndata;
|
||||
}
|
||||
|
||||
public string ToJson()
|
||||
{
|
||||
return Newtonsoft.Json.JsonConvert.SerializeObject(this);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Date :2015-6-4 14:02
|
||||
* Author:吴梦飞
|
||||
* Desc :
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common.ApiBase
|
||||
{
|
||||
public class ReturnStatus
|
||||
{
|
||||
public int code { get; set; }
|
||||
public string name { get; set; }
|
||||
public string message { get; set; }
|
||||
public string devSerial { get; set; }
|
||||
|
||||
public static ReturnStatus GetByResult(APIResult apiresult, string msg="")
|
||||
{
|
||||
return new ReturnStatus()
|
||||
{
|
||||
code = (int)apiresult,
|
||||
name=apiresult.ToString(),
|
||||
message = msg
|
||||
};
|
||||
}
|
||||
public static ReturnStatus GetByResult(JFAPIRESULT apiresult, string msg = "")
|
||||
{
|
||||
return new ReturnStatus()
|
||||
{
|
||||
code = (int)apiresult,
|
||||
message = msg
|
||||
};
|
||||
}
|
||||
/// <summary>
|
||||
/// 针对OEM返回特殊处理
|
||||
/// </summary>
|
||||
/// <param name="apiresult"></param>
|
||||
/// <param name="msg"></param>
|
||||
/// <returns></returns>
|
||||
public static ReturnStatus OEMGetByResult(APIResult apiresult, string msg = "", string devSerial = "")
|
||||
{
|
||||
return new ReturnStatus()
|
||||
{
|
||||
code = (int)apiresult,
|
||||
name = apiresult.ToString(),
|
||||
message = msg,
|
||||
devSerial = devSerial
|
||||
};
|
||||
}
|
||||
|
||||
private class JsonStatus
|
||||
{
|
||||
public ReturnStatus status { get; set; }
|
||||
}
|
||||
|
||||
public string ToJson()
|
||||
{
|
||||
var status = new JsonStatus() { status = this };
|
||||
return Newtonsoft.Json.JsonConvert.SerializeObject(status);
|
||||
}
|
||||
}
|
||||
|
||||
public class WzStatus
|
||||
{
|
||||
public ReturnStatus status { get; set; }
|
||||
}
|
||||
|
||||
public class ReturnStatusV2
|
||||
{
|
||||
public int code { get; set; }
|
||||
public string name { get; set; }
|
||||
public string message { get; set; }
|
||||
|
||||
public static ReturnStatusV2 GetByResult(APIResult apiresult, string msg)
|
||||
{
|
||||
return new ReturnStatusV2()
|
||||
{
|
||||
code = (int)apiresult,
|
||||
name = apiresult.ToString(),
|
||||
message = msg
|
||||
};
|
||||
}
|
||||
private class JsonStatusV2
|
||||
{
|
||||
public ReturnStatusV2 status { get; set; }
|
||||
}
|
||||
|
||||
public string ToJson()
|
||||
{
|
||||
return Newtonsoft.Json.JsonConvert.SerializeObject(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,190 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using ZXing;
|
||||
using ZXing.Common;
|
||||
using ZXing.QrCode;
|
||||
using ZXing.QrCode.Internal;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// 条形码和二维码帮助类
|
||||
/// </summary>
|
||||
public class BarcodeHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 生成二维码
|
||||
/// </summary>
|
||||
/// <param name="text">内容</param>
|
||||
/// <param name="width">宽度</param>
|
||||
/// <param name="height">高度</param>
|
||||
/// <returns></returns>
|
||||
public static Bitmap QrCode(string text, int width, int height, int margin = 1)
|
||||
{
|
||||
var writer = new BarcodeWriterPixelData();
|
||||
writer.Format = BarcodeFormat.QR_CODE;
|
||||
QrCodeEncodingOptions options = new QrCodeEncodingOptions()
|
||||
{
|
||||
DisableECI = true,//设置内容编码
|
||||
CharacterSet = "UTF-8",
|
||||
Width = width,//设置二维码的宽度和高度
|
||||
Height = height,
|
||||
Margin = margin//设置二维码的边距,单位不是固定像素
|
||||
};
|
||||
|
||||
writer.Options = options;
|
||||
var pixdata = writer.Write(text);
|
||||
Bitmap map = PixToBitmap(pixdata.Pixels, pixdata.Width, pixdata.Height);
|
||||
return map;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将一个字节数组转换为位图
|
||||
/// </summary>
|
||||
/// <param name="pixValue">显示字节数组</param>
|
||||
/// <param name="width">图像宽度</param>
|
||||
/// <param name="height">图像高度</param>
|
||||
/// <returns></returns>
|
||||
private static Bitmap PixToBitmap(byte[] pixValue,int width,int height)
|
||||
{
|
||||
//// 申请目标位图的变量,并将其内存区域锁定
|
||||
var m_currBitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);
|
||||
var m_rect = new Rectangle(0, 0, width, height);
|
||||
var m_bitmapData = m_currBitmap.LockBits(m_rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppRgb);
|
||||
|
||||
IntPtr iptr = m_bitmapData.Scan0; // 获取bmpData的内存起始位置
|
||||
|
||||
//// 用Marshal的Copy方法,将刚才得到的内存字节数组复制到BitmapData中
|
||||
System.Runtime.InteropServices.Marshal.Copy(pixValue, 0, iptr, pixValue.Length);
|
||||
m_currBitmap.UnlockBits(m_bitmapData);
|
||||
//// 算法到此结束,返回结果
|
||||
|
||||
return m_currBitmap;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成一维条形码
|
||||
/// </summary>
|
||||
/// <param name="text">内容</param>
|
||||
/// <param name="width">宽度</param>
|
||||
/// <param name="height">高度</param>
|
||||
/// <returns></returns>
|
||||
public static Bitmap BarCode(string text, int width, int height)
|
||||
{
|
||||
var writer = new BarcodeWriter<Bitmap>();
|
||||
//使用ITF 格式,不能被现在常用的支付宝、微信扫出来
|
||||
//如果想生成可识别的可以使用 CODE_128 格式
|
||||
//writer.Format = BarcodeFormat.ITF;
|
||||
writer.Format = BarcodeFormat.CODE_39;
|
||||
EncodingOptions options = new EncodingOptions()
|
||||
{
|
||||
Width = width,
|
||||
Height = height,
|
||||
Margin = 2
|
||||
};
|
||||
writer.Options = options;
|
||||
Bitmap map = writer.Write(text);
|
||||
return map;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成带Logo的二维码
|
||||
/// </summary>
|
||||
/// <param name="text">内容</param>
|
||||
/// <param name="width">宽度</param>
|
||||
/// <param name="height">高度</param>
|
||||
/// <param name="db">true表示删除白边</param>
|
||||
public static Bitmap QrCodeLogo(string text, int width, int height, bool db = false)
|
||||
{
|
||||
//Logo 图片
|
||||
string logoPath = System.AppDomain.CurrentDomain.BaseDirectory + @"\img\logo.png";
|
||||
Bitmap logo = new Bitmap(logoPath);
|
||||
//构造二维码写码器
|
||||
MultiFormatWriter writer = new MultiFormatWriter();
|
||||
Dictionary<EncodeHintType, object> hint = new Dictionary<EncodeHintType, object>();
|
||||
hint.Add(EncodeHintType.CHARACTER_SET, "UTF-8");
|
||||
hint.Add(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
|
||||
//hint.Add(EncodeHintType.MARGIN, 2);//旧版本不起作用,需要手动去除白边
|
||||
width = width + 20;
|
||||
height = height + 20;
|
||||
//生成二维码
|
||||
BitMatrix bm = writer.encode(text, BarcodeFormat.QR_CODE, width, height, hint);
|
||||
if (db)
|
||||
{
|
||||
bm = deleteWhite(bm);
|
||||
}
|
||||
var barcodeWriter = new BarcodeWriter<Bitmap>();
|
||||
Bitmap map = barcodeWriter.Write(bm);
|
||||
|
||||
//获取二维码实际尺寸(去掉二维码两边空白后的实际尺寸)
|
||||
int[] rectangle = bm.getEnclosingRectangle();
|
||||
|
||||
//计算插入图片的大小和位置
|
||||
int middleW = Math.Min((int)(rectangle[2] / 3.5), logo.Width);
|
||||
int middleH = Math.Min((int)(rectangle[3] / 3.5), logo.Height);
|
||||
int middleL = (map.Width - middleW) / 2;
|
||||
int middleT = (map.Height - middleH) / 2;
|
||||
|
||||
// 将img转换成bmp格式,否则后面无法创建Graphics对象
|
||||
Bitmap bmpimg = new Bitmap(map.Width, map.Height, PixelFormat.Format32bppArgb);
|
||||
using (Graphics g = Graphics.FromImage(bmpimg))
|
||||
{
|
||||
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
|
||||
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
|
||||
g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
|
||||
g.DrawImage(map, 0, 0, width, height);
|
||||
//白底将二维码插入图片
|
||||
g.FillRectangle(Brushes.White, middleL, middleT, middleW, middleH);
|
||||
g.DrawImage(logo, middleL, middleT, middleW, middleH);
|
||||
}
|
||||
return bmpimg;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除默认对应的空白
|
||||
/// </summary>
|
||||
/// <param name="matrix"></param>
|
||||
/// <returns></returns>
|
||||
private static BitMatrix deleteWhite(BitMatrix matrix)
|
||||
{
|
||||
int[] rec = matrix.getEnclosingRectangle();
|
||||
int resWidth = rec[2] + 1;
|
||||
int resHeight = rec[3] + 1;
|
||||
|
||||
BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);
|
||||
resMatrix.clear();
|
||||
for (int i = 0; i < resWidth; i++)
|
||||
{
|
||||
for (int j = 0; j < resHeight; j++)
|
||||
{
|
||||
if (matrix[i + rec[0], j + rec[1]])
|
||||
resMatrix[i, j] = true;
|
||||
}
|
||||
}
|
||||
return resMatrix;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 读取二维码,读取失败,返回空字符串
|
||||
/// </summary>
|
||||
/// <param name="filename">指定二维码图片位置</param>
|
||||
public static string ReadCodde(string filename)
|
||||
{
|
||||
BarcodeReader reader = new BarcodeReader();
|
||||
reader.Options.CharacterSet = "UTF-8";
|
||||
Bitmap map = new Bitmap(filename);
|
||||
//MemoryStream ms = new MemoryStream();
|
||||
//map.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
|
||||
//byte[] bytes = ms.GetBuffer(); //byte[] bytes= ms.ToArray(); 这两句都可以,至于区别么,下面有解释
|
||||
//ms.Close();
|
||||
Result result = reader.Decode(map);
|
||||
return result == null ? "" : result.Text;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
public class CacheFactory
|
||||
{
|
||||
public static ICaches Cache()
|
||||
{
|
||||
return new Caches();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
using Microsoft.Extensions.Caching.Memory;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
public class Caches : ICaches
|
||||
{
|
||||
private static MemoryCache cache = MyCache.get;
|
||||
|
||||
public T GetCache<T>(string cacheKey) where T : class
|
||||
{
|
||||
if (cache.Get<T>(cacheKey) != null)
|
||||
{
|
||||
return cache.Get<T>(cacheKey);
|
||||
}
|
||||
return default(T);
|
||||
}
|
||||
public void WriteCache<T>(T value, string cacheKey) where T : class
|
||||
{
|
||||
cache.Set<T>(cacheKey, value, DateTime.Now.AddMinutes(10));
|
||||
}
|
||||
public void WriteCache<T>(T value, string cacheKey, DateTime expireTime) where T : class
|
||||
{
|
||||
cache.Set<T>(cacheKey, value, expireTime);
|
||||
}
|
||||
public void RemoveCache(string cacheKey)
|
||||
{
|
||||
cache.Remove(cacheKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
public interface ICaches
|
||||
{
|
||||
T GetCache<T>(string cacheKey) where T : class;
|
||||
void WriteCache<T>(T value, string cacheKey) where T : class;
|
||||
void WriteCache<T>(T value, string cacheKey, DateTime expireTime) where T : class;
|
||||
void RemoveCache(string cacheKey);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
public static class MyCache
|
||||
{
|
||||
public static IServiceCollection serviceCollection;
|
||||
public static MemoryCache get
|
||||
{
|
||||
get
|
||||
{
|
||||
var factory= serviceCollection.BuildServiceProvider().GetService(typeof(IMemoryCache));
|
||||
MemoryCache cache = (MemoryCache)factory;
|
||||
return cache;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,297 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Text;
|
||||
using System.Web;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// 常用公共类
|
||||
/// </summary>
|
||||
public class Common
|
||||
{
|
||||
#region Stopwatch计时器
|
||||
/// <summary>
|
||||
/// 计时器开始
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static Stopwatch TimerStart()
|
||||
{
|
||||
Stopwatch watch = new Stopwatch();
|
||||
watch.Reset();
|
||||
watch.Start();
|
||||
return watch;
|
||||
}
|
||||
/// <summary>
|
||||
/// 计时器结束
|
||||
/// </summary>
|
||||
/// <param name="watch"></param>
|
||||
/// <returns></returns>
|
||||
public static string TimerEnd(Stopwatch watch)
|
||||
{
|
||||
watch.Stop();
|
||||
double costtime = watch.ElapsedMilliseconds;
|
||||
return costtime.ToString();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 删除数组中的重复项
|
||||
/// <summary>
|
||||
/// 删除数组中的重复项
|
||||
/// </summary>
|
||||
/// <param name="values"></param>
|
||||
/// <returns></returns>
|
||||
public static string[] RemoveDup(string[] values)
|
||||
{
|
||||
List<string> list = new List<string>();
|
||||
for (int i = 0; i < values.Length; i++)//遍历数组成员
|
||||
{
|
||||
if (!list.Contains(values[i]))
|
||||
{
|
||||
list.Add(values[i]);
|
||||
};
|
||||
}
|
||||
return list.ToArray();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 自动生成编号
|
||||
/// <summary>
|
||||
/// 表示全局唯一标识符 (GUID)。
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string GuId()
|
||||
{
|
||||
return Guid.NewGuid().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
|
||||
|
||||
#region 生成0-9随机数
|
||||
/// <summary>
|
||||
/// 生成0-9随机数
|
||||
/// </summary>
|
||||
/// <param name="codeNum">生成长度</param>
|
||||
/// <returns></returns>
|
||||
public static string RndNum(int codeNum)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder(codeNum);
|
||||
Random rand = new Random();
|
||||
for (int i = 1; i < codeNum + 1; i++)
|
||||
{
|
||||
int t = rand.Next(9);
|
||||
sb.AppendFormat("{0}", t);
|
||||
}
|
||||
return sb.ToString();
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 生成订单号
|
||||
/// <summary>
|
||||
/// 生成订单号,共21位,订单号规则,V{年月日}{当前登录账户的手机号后四位}{随机八位数}
|
||||
/// </summary>
|
||||
/// <param name="phone">用户手机号</param>
|
||||
/// <returns></returns>
|
||||
public static string OrderNo(string phone)
|
||||
{
|
||||
//订单号,共21位,订单号规则,V{年月日}{当前登录账户的手机号后四位}{随机八位数}
|
||||
string telphone = "0000";
|
||||
if (!string.IsNullOrEmpty(phone) && phone.Length > 4)
|
||||
{
|
||||
telphone = phone.Substring(phone.Length - 4);
|
||||
}
|
||||
var orderno = $"{DateTime.Now.ToString("yyyyMMdd")}{telphone}{Common.RndNum(8)}";
|
||||
return orderno;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 根据GUID获取16位的唯一字符串
|
||||
public static string Guid16()
|
||||
{
|
||||
long i = 1;
|
||||
foreach (byte b in Guid.NewGuid().ToByteArray())
|
||||
i *= ((int)b + 1);
|
||||
return string.Format("{0:x}", i - DateTime.Now.Ticks);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 删除最后一个字符之后的字符
|
||||
/// <summary>
|
||||
/// 删除最后结尾的一个逗号
|
||||
/// </summary>
|
||||
public static string DelLastComma(string str)
|
||||
{
|
||||
return str.Substring(0, str.LastIndexOf(","));
|
||||
}
|
||||
/// <summary>
|
||||
/// 删除最后结尾的指定字符后的字符
|
||||
/// </summary>
|
||||
public static string DelLastChar(string str, string strchar)
|
||||
{
|
||||
return str.Substring(0, str.LastIndexOf(strchar));
|
||||
}
|
||||
/// <summary>
|
||||
/// 删除最后结尾的长度
|
||||
/// </summary>
|
||||
/// <param name="str"></param>
|
||||
/// <param name="Length"></param>
|
||||
/// <returns></returns>
|
||||
public static string DelLastLength(string str, int Length)
|
||||
{
|
||||
if (string.IsNullOrEmpty(str))
|
||||
return "";
|
||||
str = str.Substring(0, str.Length - Length);
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
#region 计算时间差
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="starttime">开始时间</param>
|
||||
/// <param name="endtime">结束时间</param>
|
||||
/// <param name="t">1-毫秒,2-秒,3-分钟,4-小时,5-天</param>
|
||||
/// <returns></returns>
|
||||
public static double DateDiff(DateTime starttime, DateTime endtime, int t = 1)
|
||||
{
|
||||
TimeSpan ts1 = new TimeSpan(starttime.Ticks);
|
||||
TimeSpan ts2 = new TimeSpan(endtime.Ticks);
|
||||
TimeSpan ts3 = ts1.Subtract(ts2).Duration();
|
||||
if (t == 1) //计算毫秒
|
||||
{
|
||||
return ts3.TotalMilliseconds;
|
||||
}
|
||||
if (t == 2)
|
||||
{
|
||||
return ts3.TotalSeconds;
|
||||
}
|
||||
if (t == 3)
|
||||
{
|
||||
return ts3.TotalMinutes;
|
||||
}
|
||||
if (t == 4)
|
||||
{
|
||||
return ts3.TotalHours;
|
||||
}
|
||||
if (t == 5)
|
||||
{
|
||||
return ts3.TotalDays;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 获取当前时间戳
|
||||
/// <summary>
|
||||
/// 获取当前时间戳
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string GetTimestamp()
|
||||
{
|
||||
TimeSpan ts = DateTimeOffset.Now - new DateTimeOffset(1970, 1, 1, 0, 0, 0, 0, TimeSpan.Zero);
|
||||
return Convert.ToInt64(ts.TotalSeconds).ToString();
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取当前时间戳,int类型
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static int GetTimestampInt()
|
||||
{
|
||||
return GetTimestamp().ToInt();
|
||||
}
|
||||
#endregion
|
||||
#region 生成随机字符串
|
||||
/// <summary>
|
||||
/// 生成随机字符串
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static string GetNoncestr()
|
||||
{
|
||||
return Md5.md5(Guid.NewGuid().ToString(), 32);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 腾讯常用签名生成
|
||||
/// <summary>
|
||||
/// 生成MD5签名
|
||||
/// </summary>
|
||||
/// <param name="param">参数</param>
|
||||
/// <returns></returns>
|
||||
public static string CreateMd5Sign(Hashtable param, string appkey = "")
|
||||
{
|
||||
var str = SortParam(param, appkey);
|
||||
string Sign = Md5.md5(str, 32).ToUpper();
|
||||
return Sign;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 组合生成签名的参数
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
/// <param name="appkey"></param>
|
||||
/// <returns></returns>
|
||||
public static string SortParam(Hashtable param, string appkey = "")
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
ArrayList akeys = new ArrayList(param.Keys);
|
||||
akeys.Sort(ASCIISort.Create());
|
||||
foreach (string k in akeys)
|
||||
{
|
||||
string v = string.Empty;
|
||||
if (param[k] != null)
|
||||
{
|
||||
v = HttpUtility.UrlEncode(param[k].ToString());
|
||||
if (v.Contains("%"))
|
||||
{
|
||||
v = v.ToUpper();
|
||||
}
|
||||
}
|
||||
if (null != v && "".CompareTo(v) != 0
|
||||
&& "sign".CompareTo(k) != 0)
|
||||
{
|
||||
if (sb.Length == 0)
|
||||
{
|
||||
sb.Append(k + "=" + v);
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append("&" + k + "=" + v);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(appkey))
|
||||
{
|
||||
sb.Append("&app_key=" + appkey);
|
||||
}
|
||||
return sb.ToString();
|
||||
}
|
||||
#endregion
|
||||
|
||||
// <summary>
|
||||
/// 根据GUID获取19位的唯一数字序列
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static long GuidToLongID()
|
||||
{
|
||||
byte[] buffer = Guid.NewGuid().ToByteArray();
|
||||
return BitConverter.ToInt64(buffer, 0);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
using Microsoft.Extensions.Configuration;
|
||||
using System;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
public static class Configs
|
||||
{
|
||||
private static IConfiguration _configuration;
|
||||
|
||||
static Configs()
|
||||
{
|
||||
//在当前目录或者根目录中寻找appsettings.json文件
|
||||
var fileName = "appsettings.json";
|
||||
var directory = AppContext.BaseDirectory;
|
||||
directory = directory.Replace("\\", "/");
|
||||
|
||||
var filePath = $"{directory}/{fileName}";
|
||||
if (!System.IO.File.Exists(filePath))
|
||||
{
|
||||
var length = directory.IndexOf("/bin");
|
||||
filePath = $"{directory.Substring(0, length)}/{fileName}";
|
||||
}
|
||||
|
||||
var builder = new ConfigurationBuilder()
|
||||
.AddJsonFile(filePath, false, true);
|
||||
|
||||
_configuration = builder.Build();
|
||||
}
|
||||
public static string GetSectionValue(string key)
|
||||
{
|
||||
if (_configuration.GetSection(key) != null)
|
||||
return _configuration.GetSection(key).Value;
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
public static bool GetBoolValue(string key)
|
||||
{
|
||||
bool value = false;
|
||||
bool.TryParse(GetSectionValue(key), out value);
|
||||
return value;
|
||||
}
|
||||
|
||||
public static int GetIntValue(string key)
|
||||
{
|
||||
int value = 0;
|
||||
int.TryParse(GetSectionValue(key), out value);
|
||||
return value;
|
||||
}
|
||||
|
||||
public static string GetString(string key)
|
||||
{
|
||||
return GetSectionValue(key);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
public static class DataTableListHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// DataTable 转换成泛型List
|
||||
/// </summary>
|
||||
/// <typeparam name="T">实体对象类</typeparam>
|
||||
/// <param name="table">数据DatatTable</param>
|
||||
/// <returns> List<实体对象></returns>
|
||||
public static List<T> ToList<T>(this DataTable table)
|
||||
{
|
||||
if (table == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
List<T> list = new List<T>();
|
||||
T t = default(T);
|
||||
PropertyInfo[] propertypes = null;
|
||||
string tempName = string.Empty;
|
||||
foreach (DataRow row in table.Rows)
|
||||
{
|
||||
t = Activator.CreateInstance<T>();
|
||||
propertypes = t.GetType().GetProperties();
|
||||
foreach (PropertyInfo pro in propertypes)
|
||||
{
|
||||
if (!pro.CanWrite)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
tempName = pro.Name;
|
||||
if (table.Columns.Contains(tempName.ToUpper()))
|
||||
{
|
||||
object value = row[tempName];
|
||||
if (value is System.DBNull)
|
||||
{
|
||||
value = null;
|
||||
if (pro.PropertyType.FullName == "System.String")
|
||||
{
|
||||
value = string.Empty;
|
||||
}
|
||||
}
|
||||
if (pro.PropertyType.IsGenericType
|
||||
&& pro.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)
|
||||
&& value != null)
|
||||
{
|
||||
pro.SetValue(t, Convert.ChangeType(value, Nullable.GetUnderlyingType(pro.PropertyType)), null);
|
||||
}
|
||||
else if (pro.PropertyType.IsEnum)
|
||||
{
|
||||
pro.SetValue(t, Convert.ChangeType(value, Enum.GetUnderlyingType(pro.PropertyType)), null);
|
||||
}
|
||||
else if (pro.PropertyType.FullName == "System.Guid")
|
||||
{
|
||||
pro.SetValue(t, new Guid(value + ""), null);
|
||||
|
||||
}
|
||||
else if(pro.PropertyType.FullName == "System.Decimal")
|
||||
{
|
||||
pro.SetValue(t, Convert.ToDecimal(value), null);
|
||||
}
|
||||
else if(pro.PropertyType.FullName == "System.Int32")
|
||||
{
|
||||
pro.SetValue(t, Convert.ToInt32(value), null);
|
||||
}
|
||||
else
|
||||
{
|
||||
pro.SetValue(t, value, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
list.Add(t);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 将List转换成DataTable
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public static DataTable ToDataTable<T>(this IList<T> data)
|
||||
{
|
||||
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(typeof(T));
|
||||
DataTable dt = new DataTable();
|
||||
for (int i = 0; i < properties.Count; i++)
|
||||
{
|
||||
PropertyDescriptor property = properties[i];
|
||||
if (property.PropertyType.Name != typeof(Nullable<>).Name)
|
||||
{
|
||||
dt.Columns.Add(property.Name, property.PropertyType);
|
||||
}
|
||||
else
|
||||
{
|
||||
dt.Columns.Add(property.Name, property.PropertyType.GenericTypeArguments[0]);
|
||||
}
|
||||
}
|
||||
object[] values = new object[properties.Count];
|
||||
foreach (T item in data)
|
||||
{
|
||||
for (int i = 0; i < values.Length; i++)
|
||||
{
|
||||
values[i] = properties[i].GetValue(item);
|
||||
}
|
||||
dt.Rows.Add(values);
|
||||
}
|
||||
return dt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,342 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
public class EnumHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// 转换如:"enum1,enum2,enum3"字符串到枚举值
|
||||
/// </summary>
|
||||
/// <typeparam name="T">枚举类型</typeparam>
|
||||
/// <param name="obj">枚举字符串</param>
|
||||
/// <returns></returns>
|
||||
public static T Parse<T>(string obj)
|
||||
{
|
||||
if (string.IsNullOrEmpty(obj))
|
||||
return default(T);
|
||||
else
|
||||
return (T)Enum.Parse(typeof(T), obj);
|
||||
}
|
||||
|
||||
public static T TryParse<T>(string obj, T defT = default(T))
|
||||
{
|
||||
try
|
||||
{
|
||||
return Parse<T>(obj);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return defT;
|
||||
}
|
||||
}
|
||||
|
||||
public static readonly string ENUM_TITLE_SEPARATOR = ",";
|
||||
|
||||
/// <summary>
|
||||
/// 根据枚举值,返回描述字符串
|
||||
/// 如果多选枚举,返回以","分割的字符串
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetEnumTitle(Enum e)
|
||||
{
|
||||
if (e == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
string[] valueArray = e.ToString().Split(ENUM_TITLE_SEPARATOR.ToArray(), StringSplitOptions.RemoveEmptyEntries);
|
||||
Type type = e.GetType();
|
||||
string ret = "";
|
||||
foreach (string enumValue in valueArray)
|
||||
{
|
||||
System.Reflection.FieldInfo fi = type.GetField(enumValue.Trim());
|
||||
if (fi == null)
|
||||
continue;
|
||||
EnumTitleAttribute[] attrs = fi.GetCustomAttributes(typeof(EnumTitleAttribute), false) as EnumTitleAttribute[];
|
||||
if (attrs != null && attrs.Length > 0 && attrs[0].IsDisplay)
|
||||
{
|
||||
ret += attrs[0].Title + ENUM_TITLE_SEPARATOR;
|
||||
}
|
||||
}
|
||||
return ret.TrimEnd(ENUM_TITLE_SEPARATOR.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据枚举值,返回描述字符串
|
||||
/// 如果多选枚举,返回以","分割的字符串
|
||||
/// </summary>
|
||||
/// <param name="e"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetAllEnumTitle(Enum e)
|
||||
{
|
||||
if (e == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
string[] valueArray = e.ToString().Split(ENUM_TITLE_SEPARATOR.ToArray(), StringSplitOptions.RemoveEmptyEntries);
|
||||
Type type = e.GetType();
|
||||
string ret = "";
|
||||
foreach (string enumValue in valueArray)
|
||||
{
|
||||
System.Reflection.FieldInfo fi = type.GetField(enumValue.Trim());
|
||||
if (fi == null)
|
||||
continue;
|
||||
EnumTitleAttribute[] attrs = fi.GetCustomAttributes(typeof(EnumTitleAttribute), false) as EnumTitleAttribute[];
|
||||
if (attrs != null && attrs.Length > 0)
|
||||
{
|
||||
ret += attrs[0].Title + ENUM_TITLE_SEPARATOR;
|
||||
}
|
||||
}
|
||||
return ret.TrimEnd(ENUM_TITLE_SEPARATOR.ToArray());
|
||||
}
|
||||
|
||||
public static EnumTitleAttribute GetEnumTitleAttribute(Enum e)
|
||||
{
|
||||
if (e == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
string[] valueArray = e.ToString().Split(ENUM_TITLE_SEPARATOR.ToArray(), StringSplitOptions.RemoveEmptyEntries);
|
||||
Type type = e.GetType();
|
||||
EnumTitleAttribute ret = null;
|
||||
foreach (string enumValue in valueArray)
|
||||
{
|
||||
System.Reflection.FieldInfo fi = type.GetField(enumValue.Trim());
|
||||
if (fi == null)
|
||||
continue;
|
||||
EnumTitleAttribute[] attrs = fi.GetCustomAttributes(typeof(EnumTitleAttribute), false) as EnumTitleAttribute[];
|
||||
if (attrs != null && attrs.Length > 0)
|
||||
{
|
||||
ret = attrs[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static string GetDayOfWeekTitle(DayOfWeek day)
|
||||
{
|
||||
switch (day)
|
||||
{
|
||||
case DayOfWeek.Monday:
|
||||
return "周一";
|
||||
case DayOfWeek.Tuesday:
|
||||
return "周二";
|
||||
case DayOfWeek.Wednesday:
|
||||
return "周三";
|
||||
case DayOfWeek.Thursday:
|
||||
return "周四";
|
||||
case DayOfWeek.Friday:
|
||||
return "周五";
|
||||
case DayOfWeek.Saturday:
|
||||
return "周六";
|
||||
case DayOfWeek.Sunday:
|
||||
return "周日";
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 返回键值对,建为枚举的EnumTitle中指定的名称和近义词名称,值为枚举项
|
||||
/// </summary>
|
||||
/// <typeparam name="T">枚举类型</typeparam>
|
||||
/// <param name="language"></param>
|
||||
/// <returns></returns>
|
||||
public static Dictionary<string, T> GetTitleAndSynonyms<T>() where T : struct
|
||||
{
|
||||
Dictionary<string, T> ret = new Dictionary<string, T>();
|
||||
//枚举值
|
||||
Array arrEnumValue = typeof(T).GetEnumValues();
|
||||
foreach (object enumValue in arrEnumValue)
|
||||
{
|
||||
System.Reflection.FieldInfo fi = typeof(T).GetField(enumValue.ToString());
|
||||
if (fi == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
EnumTitleAttribute[] arrEnumTitleAttr = fi.GetCustomAttributes(typeof(EnumTitleAttribute), false) as EnumTitleAttribute[];
|
||||
if (arrEnumTitleAttr == null || arrEnumTitleAttr.Length < 1 || !arrEnumTitleAttr[0].IsDisplay)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ret.ContainsKey(arrEnumTitleAttr[0].Title))
|
||||
{
|
||||
ret.Add(arrEnumTitleAttr[0].Title, (T)enumValue);
|
||||
}
|
||||
|
||||
if (arrEnumTitleAttr[0].Synonyms == null || arrEnumTitleAttr[0].Synonyms.Length < 1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (string s in arrEnumTitleAttr[0].Synonyms)
|
||||
{
|
||||
if (!ret.ContainsKey(s))
|
||||
{
|
||||
ret.Add(s, (T)enumValue);
|
||||
}
|
||||
}
|
||||
}//using
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据枚举获取包含所有所有值和描述的哈希表,其文本是由应用在枚举值上的EnumTitleAttribute设定
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static Dictionary<T, string> GetItemList<T>() where T : struct
|
||||
{
|
||||
return GetItemValueList<T, T>(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 根据枚举获取包含所有所有值和描述的哈希表,其文本是由应用在枚举值上的EnumTitleAttribute设定
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static Dictionary<T, string> GetAllItemList<T>() where T : struct
|
||||
{
|
||||
return GetItemValueList<T, T>(true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取枚举所有项的标题,其文本是由应用在枚举值上的EnumTitleAttribute设定
|
||||
/// </summary>
|
||||
/// <typeparam name="T">枚举类型</typeparam>
|
||||
/// <param name="language">语言</param>
|
||||
/// <returns></returns>
|
||||
public static Dictionary<int, string> GetItemValueList<T>() where T : struct
|
||||
{
|
||||
return GetItemValueList<T, int>(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取枚举所有项的标题,其文本是由应用在枚举值上的EnumTitleAttribute设定
|
||||
/// </summary>
|
||||
/// <typeparam name="T">枚举类型</typeparam>
|
||||
/// <param name="isAll">是否生成“全部”项</param>
|
||||
/// <param name="language">语言</param>
|
||||
/// <returns></returns>
|
||||
public static Dictionary<TKey, string> GetItemValueList<T, TKey>(bool isAll) where T : struct
|
||||
{
|
||||
if (!typeof(T).IsEnum)
|
||||
{
|
||||
throw new Exception("参数必须是枚举!");
|
||||
}
|
||||
Dictionary<TKey, string> ret = new Dictionary<TKey, string>();
|
||||
|
||||
var titles = EnumHelper.GetItemAttributeList<T>().OrderBy(t => t.Value.Order);
|
||||
foreach (var t in titles)
|
||||
{
|
||||
if (!isAll && (!t.Value.IsDisplay || t.Key.ToString() == "None"))
|
||||
continue;
|
||||
|
||||
if (t.Key.ToString() == "None" && isAll)
|
||||
{
|
||||
ret.Add((TKey)(object)t.Key, "全部");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!string.IsNullOrEmpty(t.Value.Title))
|
||||
ret.Add((TKey)(object)t.Key, t.Value.Title);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static List<T> GetItemKeyList<T>() where T : struct
|
||||
{
|
||||
List<T> list = new List<T>();
|
||||
Array array = typeof(T).GetEnumValues();
|
||||
foreach (object t in array)
|
||||
{
|
||||
list.Add((T)t);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public static Dictionary<T, EnumTitleAttribute> GetItemAttributeList<T>() where T : struct
|
||||
{
|
||||
if (!typeof(T).IsEnum)
|
||||
{
|
||||
throw new Exception("参数必须是枚举!");
|
||||
}
|
||||
Dictionary<T, EnumTitleAttribute> ret = new Dictionary<T, EnumTitleAttribute>();
|
||||
|
||||
Array array = typeof(T).GetEnumValues();
|
||||
foreach (object t in array)
|
||||
{
|
||||
EnumTitleAttribute att = GetEnumTitleAttribute(t as Enum);
|
||||
if (att != null)
|
||||
ret.Add((T)t, att);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取枚举所有项的标题,其文本是由应用在枚举值上的EnumTitleAttribute设定
|
||||
/// </summary>
|
||||
/// <typeparam name="T">枚举类型</typeparam>
|
||||
/// <param name="isAll">是否生成“全部”项</param>
|
||||
/// <param name="language">语言</param>
|
||||
/// <returns></returns>
|
||||
public static Dictionary<TKey, string> GetAllItemValueList<T, TKey>() where T : struct
|
||||
{
|
||||
return GetItemValueList<T, TKey>(true);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取一个枚举的键值对形式
|
||||
/// </summary>
|
||||
/// <typeparam name="TEnum">枚举类型</typeparam>
|
||||
/// <param name="exceptTypes">排除的枚举</param>
|
||||
/// <returns></returns>
|
||||
public static Dictionary<int, string> GetEnumDictionary<TEnum>(IEnumerable<TEnum> exceptTypes = null) where TEnum : struct
|
||||
{
|
||||
var dic = GetItemList<TEnum>();
|
||||
|
||||
Dictionary<int, string> dicNew = new Dictionary<int, string>();
|
||||
foreach (var d in dic)
|
||||
{
|
||||
if (exceptTypes != null && exceptTypes.Contains(d.Key))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
dicNew.Add(d.Key.GetHashCode(), d.Value);
|
||||
}
|
||||
return dicNew;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class EnumTitleAttribute : Attribute
|
||||
{
|
||||
private bool _IsDisplay = true;
|
||||
|
||||
public EnumTitleAttribute(string title, params string[] synonyms)
|
||||
{
|
||||
Title = title;
|
||||
Synonyms = synonyms;
|
||||
Order = int.MaxValue;
|
||||
}
|
||||
public bool IsDisplay { get { return _IsDisplay; } set { _IsDisplay = value; } }
|
||||
public string Title { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string Letter { get; set; }
|
||||
/// <summary>
|
||||
/// 近义词
|
||||
/// </summary>
|
||||
public string[] Synonyms { get; set; }
|
||||
public int Category { get; set; }
|
||||
public int Order { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,358 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
public static partial class Ext
|
||||
{
|
||||
#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>
|
||||
/// 转换成长整形
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public static long ToLong(this object data)
|
||||
{
|
||||
if (data == null)
|
||||
return 0;
|
||||
long result;
|
||||
return long.TryParse(data.ToString(), out result) ? result : 0;
|
||||
}
|
||||
|
||||
/// <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>
|
||||
/// 转换为float
|
||||
/// </summary>
|
||||
/// <param name="data">数据</param>
|
||||
/// <returns></returns>
|
||||
public static float ToFloat(this object data)
|
||||
{
|
||||
if (data == null)
|
||||
return 0;
|
||||
float result;
|
||||
return float.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;
|
||||
}
|
||||
/// <summary>
|
||||
/// 时间格式化,带时分,如果同一年则不显示年,否则显示年份
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public static string ToYearDateTime(this object data)
|
||||
{
|
||||
if (data == null)
|
||||
return string.Empty;
|
||||
DateTime result;
|
||||
bool isValid = DateTime.TryParse(data.ToString(), out result);
|
||||
if (!isValid)
|
||||
return string.Empty;
|
||||
if (result.Year == DateTime.Now.Year)
|
||||
return result.ToString("M-d HH:mm");
|
||||
return result.ToString("yyyy-M-d HH:mm");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 时间格式化,不带时分,如果同一年则不显示年,否则显示年份
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public static string ToYearDate(this object data)
|
||||
{
|
||||
if (data == null)
|
||||
return string.Empty;
|
||||
DateTime result;
|
||||
bool isValid = DateTime.TryParse(data.ToString(), out result);
|
||||
if (!isValid)
|
||||
return string.Empty;
|
||||
if (result.Year == DateTime.Now.Year)
|
||||
return result.ToString("M-d");
|
||||
return result.ToString("yyyy-M-d");
|
||||
}
|
||||
#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="data">数据</param>
|
||||
public static string ToString(this object data)
|
||||
{
|
||||
return data == null ? string.Empty : data.ToString().Trim();
|
||||
}
|
||||
/// <summary>
|
||||
/// 针对可能为空的字符串处理
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public static string ToStr(this string data)
|
||||
{
|
||||
return string.IsNullOrEmpty(data) ? string.Empty : data;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 安全返回值
|
||||
/// </summary>
|
||||
/// <param name="value">可空值</param>
|
||||
public static T SafeValue<T>(this T? value) where T : struct
|
||||
{
|
||||
return value ?? default(T);
|
||||
}
|
||||
/// <summary>
|
||||
/// 是否为空
|
||||
/// </summary>
|
||||
/// <param name="value">值</param>
|
||||
public static bool IsEmpty(this string value)
|
||||
{
|
||||
return string.IsNullOrWhiteSpace(value);
|
||||
}
|
||||
/// <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;
|
||||
}
|
||||
/// <summary>
|
||||
/// 是否为空
|
||||
/// </summary>
|
||||
/// <param name="value">值</param>
|
||||
public static bool IsEmpty(this object value)
|
||||
{
|
||||
if (value != null && !string.IsNullOrEmpty(value.ToString()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,278 @@
|
|||
using System;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
public static partial class Ext
|
||||
{
|
||||
/// <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");
|
||||
}
|
||||
|
||||
/// <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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 时间戳转时间
|
||||
/// </summary>
|
||||
/// <param name="timeStamp"></param>
|
||||
/// <returns></returns>
|
||||
public static DateTime ToDatetimeFromTimeStamp(this string timeStamp)
|
||||
{
|
||||
var ltime = long.Parse(timeStamp);
|
||||
if (timeStamp.Length == 10)
|
||||
{
|
||||
var dto = DateTimeOffset.FromUnixTimeSeconds(ltime);
|
||||
return dto.ToLocalTime().DateTime;
|
||||
}
|
||||
else
|
||||
{
|
||||
var dto = DateTimeOffset.FromUnixTimeMilliseconds(ltime);
|
||||
return dto.ToLocalTime().DateTime;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 时间戳转时间
|
||||
/// </summary>
|
||||
/// <param name="timeStamp"></param>
|
||||
/// <returns></returns>
|
||||
public static DateTime ToDatetimeFromTimeStamp(this long timeStamp, int type = 1)
|
||||
{
|
||||
if (timeStamp <= 0)
|
||||
return DateTime.Now;
|
||||
if (type == 2)
|
||||
{
|
||||
var dto1 = DateTimeOffset.FromUnixTimeMilliseconds(timeStamp);
|
||||
return dto1.ToLocalTime().DateTime;
|
||||
}
|
||||
var dto = DateTimeOffset.FromUnixTimeSeconds(timeStamp);
|
||||
return dto.ToLocalTime().DateTime;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 时间转时间戳
|
||||
/// </summary>
|
||||
/// <param name="time"></param>
|
||||
/// <returns></returns>
|
||||
public static long GetTimeStamp(this DateTime? time)
|
||||
{
|
||||
if (!time.HasValue)
|
||||
return 0;
|
||||
DateTime dateTimeStart = TimeZoneInfo.ConvertTimeToUtc(new DateTime(1970, 1, 1));
|
||||
long t = (time.Value.Ticks - dateTimeStart.Ticks) / 10000;//除10000调整为13位
|
||||
return t;
|
||||
}
|
||||
/// <summary>
|
||||
/// 出生年月转为年龄
|
||||
/// </summary>
|
||||
/// <param name="birthdate"></param>
|
||||
/// <returns></returns>
|
||||
public static int ToAge(this DateTime birthdate)
|
||||
{
|
||||
DateTime now = DateTime.Now;
|
||||
int age = now.Year - birthdate.Year;
|
||||
if (
|
||||
//当前月份小于出生月份,则不满足一年
|
||||
now.Month < birthdate.Month
|
||||
//当前月份等于出生月份并且当前天小于出生天,则不满足一年
|
||||
|| (now.Month == birthdate.Month && now.Day < birthdate.Day))
|
||||
{
|
||||
age--;
|
||||
}
|
||||
return age < 0 ? 0 : age;
|
||||
}
|
||||
|
||||
public static string TomAge(this DateTime birthdate)
|
||||
{
|
||||
DateTime now = DateTime.Now;
|
||||
int age = now.Year - birthdate.Year;
|
||||
if (
|
||||
//当前月份小于出生月份,则不满足一年
|
||||
now.Month < birthdate.Month
|
||||
//当前月份等于出生月份并且当前天小于出生天,则不满足一年
|
||||
|| (now.Month == birthdate.Month && now.Day < birthdate.Day))
|
||||
{
|
||||
age--;
|
||||
}
|
||||
age= age < 0 ? 0 : age;
|
||||
int month = now.Month - birthdate.Month;
|
||||
return month<=0?$"{age}岁":$"{age}岁{month}个月";
|
||||
}
|
||||
/// <summary>
|
||||
/// 岁数
|
||||
/// </summary>
|
||||
/// <param name="month">月龄</param>
|
||||
/// <returns></returns>
|
||||
public static string TomAge(this int month)
|
||||
{
|
||||
int age = month / 12;
|
||||
int m = month % 12;
|
||||
return m <= 0 ? $"{age}岁" : $"{age}岁{m}个月";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 相差的月份
|
||||
/// </summary>
|
||||
/// <param name="birthdate"></param>
|
||||
/// <returns></returns>
|
||||
public static int ToMonth(this DateTime birthdate)
|
||||
{
|
||||
DateTime now = DateTime.Now;
|
||||
int age = now.Year - birthdate.Year;
|
||||
if (
|
||||
//当前月份小于出生月份,则不满足一年
|
||||
now.Month < birthdate.Month
|
||||
//当前月份等于出生月份并且当前天小于出生天,则不满足一年
|
||||
|| (now.Month == birthdate.Month && now.Day < birthdate.Day))
|
||||
{
|
||||
age--;
|
||||
}
|
||||
age = age < 0 ? 0 : age;
|
||||
int month = now.Month - birthdate.Month;
|
||||
return month <= 0 ? age*12 : age*12+month;
|
||||
}
|
||||
|
||||
public static long GetTimeStamp(this DateTime time)
|
||||
{
|
||||
DateTime dateTimeStart = TimeZoneInfo.ConvertTimeToUtc(new DateTime(1970, 1, 1));
|
||||
long t = (time.Ticks - dateTimeStart.Ticks) / 10000;//除10000调整为13位
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
namespace Nirvana.Common
|
||||
{
|
||||
public static partial class Ext
|
||||
{
|
||||
/// <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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
/// <summary>
|
||||
/// 转为树形结构
|
||||
/// </summary>
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
public class ToTree<T> where T:IToTreeModel
|
||||
{
|
||||
public static List<T> ToDo(List<T> models)
|
||||
{
|
||||
var dtoMap = new Dictionary<int, T>();
|
||||
foreach (var item in models)
|
||||
{
|
||||
dtoMap.Add(item.Id, item);
|
||||
}
|
||||
List<T> result = new List<T>();
|
||||
foreach (var item in dtoMap.Values)
|
||||
{
|
||||
if (item.ParentId == 0)
|
||||
{
|
||||
result.Add(item);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dtoMap.ContainsKey(item.ParentId))
|
||||
{
|
||||
dtoMap[item.ParentId].AddChilrden(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public interface IToTreeModel
|
||||
{
|
||||
int Id { get; set; }
|
||||
int ParentId { get; set; }
|
||||
public string Name { get; set; }
|
||||
List<IToTreeModel> treeList { get; set; }
|
||||
void AddChilrden(IToTreeModel node);
|
||||
}
|
||||
|
||||
public class ShowMessageUpdatesViewModel : IToTreeModel
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int ParentId { get; set; }
|
||||
public string Name { get; set; }
|
||||
public int status { get; set; }
|
||||
public List<IToTreeModel> treeList { get; set; }
|
||||
public void AddChilrden(IToTreeModel node)
|
||||
{
|
||||
if (treeList == null)
|
||||
treeList = new List<IToTreeModel>();
|
||||
this.treeList.Add(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
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 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>> And<T>(this Expression<Func<T, bool>> first, Expression<Func<T, bool>> second)
|
||||
{
|
||||
return first.Compose(second, Expression.AndAlso);
|
||||
}
|
||||
public static Expression<Func<T, bool>> Or<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
|
||||
{
|
||||
readonly Dictionary<ParameterExpression, ParameterExpression> map;
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ParameterRebinder"/> class.
|
||||
/// </summary>
|
||||
/// <param name="map">The map.</param>
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Nirvana.Common.Extend
|
||||
{
|
||||
public static class ExtList
|
||||
{
|
||||
/// <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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
using System.Data;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
public static class ExtTable
|
||||
{
|
||||
/// <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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
public class FileHelper
|
||||
{
|
||||
|
||||
public static IWebHostEnvironment _hostingEnvironment;
|
||||
public FileHelper(IWebHostEnvironment environment)
|
||||
{
|
||||
_hostingEnvironment = environment;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取文件的绝对路径,针对window程序和web程序都可使用
|
||||
/// </summary>
|
||||
/// <param name="relativePath">相对路径地址</param>
|
||||
/// <returns></returns>
|
||||
public static string GetAbsolutePath(string relativePath)
|
||||
{
|
||||
if (string.IsNullOrEmpty(relativePath))
|
||||
{
|
||||
throw new ArgumentNullException("参数relativePath空异常!");
|
||||
}
|
||||
relativePath = relativePath.Replace("/", "\\");
|
||||
if (relativePath[0] == '\\')
|
||||
{
|
||||
relativePath = relativePath.Remove(0, 1);
|
||||
}
|
||||
//判断是Web程序还是window程序
|
||||
if (_hostingEnvironment != null)
|
||||
{
|
||||
return Path.Combine(_hostingEnvironment.WebRootPath, relativePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Path.Combine(AppContext.BaseDirectory, relativePath);
|
||||
}
|
||||
}
|
||||
|
||||
#region 检测指定目录是否存在
|
||||
/// <summary>
|
||||
/// 检测指定目录是否存在
|
||||
/// </summary>
|
||||
/// <param name="directoryPath">目录的绝对路径</param>
|
||||
/// <returns></returns>
|
||||
public static bool IsExistDirectory(string directoryPath)
|
||||
{
|
||||
return Directory.Exists(directoryPath);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 删除文件
|
||||
/// <summary>
|
||||
/// 删除文件
|
||||
/// </summary>
|
||||
/// <param name="file">要删除的文件路径和名称</param>
|
||||
public static void DeleteFile(string file)
|
||||
{
|
||||
if (System.IO.File.Exists(file))
|
||||
{
|
||||
System.IO.File.Delete(file);
|
||||
}
|
||||
}
|
||||
|
||||
public static FileStream GetFileStream(string fileName)
|
||||
{
|
||||
FileStream fileStream = null;
|
||||
if (!string.IsNullOrEmpty(fileName) && System.IO.File.Exists(fileName))
|
||||
{
|
||||
fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
|
||||
}
|
||||
return fileStream;
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 读取文件(默认编码)
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <returns></returns>
|
||||
public static string Read(string path)
|
||||
{
|
||||
return Reads(path);
|
||||
}
|
||||
/// <summary>
|
||||
/// 读取文件,指定编码
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="encode"></param>
|
||||
/// <returns></returns>
|
||||
public static string Reads(string path,Encoding encode=null)
|
||||
{
|
||||
if(encode == null)
|
||||
{
|
||||
encode = Encoding.Default;
|
||||
}
|
||||
return Read(GetAbsolutePath(path), encode);
|
||||
}
|
||||
/// <summary>
|
||||
/// 读取文件(指定编码)
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <param name="encode">编码方式</param>
|
||||
/// <returns></returns>
|
||||
public static string Read(string path, Encoding encode)
|
||||
{
|
||||
FileStream fs = null;
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
break;
|
||||
}
|
||||
catch
|
||||
{
|
||||
System.Threading.Thread.Sleep(50);
|
||||
}
|
||||
}
|
||||
if (fs == null) return "";
|
||||
StreamReader sr = null;
|
||||
try
|
||||
{
|
||||
sr = new StreamReader(fs, encode);
|
||||
return sr.ReadToEnd();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// throw ex;
|
||||
return "";
|
||||
}
|
||||
finally
|
||||
{
|
||||
sr.Close();
|
||||
fs.Close();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 返回文件行的数组
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <returns></returns>
|
||||
public static string[] ReadLines(string path)
|
||||
{
|
||||
return ReadLines(GetAbsolutePath(path), Encoding.Default);
|
||||
}
|
||||
/// <summary>
|
||||
/// 返回文件行的数组
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
/// <param name="encode">编码方式</param>
|
||||
/// <returns></returns>
|
||||
public static string[] ReadLines(string path, Encoding encode)
|
||||
{
|
||||
try
|
||||
{
|
||||
return System.IO.File.ReadAllLines(path, encode);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// throw ex;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,273 @@
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using Microsoft.AspNetCore.WebUtilities;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Nirvana.Common.File
|
||||
{
|
||||
public static class FileHelpers
|
||||
{
|
||||
// If you require a check on specific characters in the IsValidFileExtensionAndSignature
|
||||
// method, supply the characters in the _allowedChars field.
|
||||
private static readonly byte[] _allowedChars = { };
|
||||
// For more file signatures, see the File Signatures Database (https://www.filesignatures.net/)
|
||||
// and the official specifications for the file types you wish to add.
|
||||
private static readonly Dictionary<string, List<byte[]>> _fileSignature = new Dictionary<string, List<byte[]>>
|
||||
{
|
||||
{ ".gif", new List<byte[]> { new byte[] { 0x47, 0x49, 0x46, 0x38 } } },
|
||||
{ ".png", new List<byte[]> { new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A } } },
|
||||
{ ".jpeg", new List<byte[]>
|
||||
{
|
||||
new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 },
|
||||
new byte[] { 0xFF, 0xD8, 0xFF, 0xE2 },
|
||||
new byte[] { 0xFF, 0xD8, 0xFF, 0xE3 },
|
||||
}
|
||||
},
|
||||
{ ".jpg", new List<byte[]>
|
||||
{
|
||||
new byte[] { 0xFF, 0xD8, 0xFF, 0xE0 },
|
||||
new byte[] { 0xFF, 0xD8, 0xFF, 0xE1 },
|
||||
new byte[] { 0xFF, 0xD8, 0xFF, 0xE8 },
|
||||
}
|
||||
},
|
||||
{ ".zip", new List<byte[]>
|
||||
{
|
||||
new byte[] { 0x50, 0x4B, 0x03, 0x04 },
|
||||
new byte[] { 0x50, 0x4B, 0x4C, 0x49, 0x54, 0x45 },
|
||||
new byte[] { 0x50, 0x4B, 0x53, 0x70, 0x58 },
|
||||
new byte[] { 0x50, 0x4B, 0x05, 0x06 },
|
||||
new byte[] { 0x50, 0x4B, 0x07, 0x08 },
|
||||
new byte[] { 0x57, 0x69, 0x6E, 0x5A, 0x69, 0x70 },
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
// **WARNING!**
|
||||
// In the following file processing methods, the file's content isn't scanned.
|
||||
// In most production scenarios, an anti-virus/anti-malware scanner API is
|
||||
// used on the file before making the file available to users or other
|
||||
// systems. For more information, see the topic that accompanies this sample
|
||||
// app.
|
||||
|
||||
public static async Task<byte[]> ProcessFormFile<T>(IFormFile formFile,
|
||||
ModelStateDictionary modelState, string[] permittedExtensions,
|
||||
long sizeLimit)
|
||||
{
|
||||
var fieldDisplayName = string.Empty;
|
||||
|
||||
// Use reflection to obtain the display name for the model
|
||||
// property associated with this IFormFile. If a display
|
||||
// name isn't found, error messages simply won't show
|
||||
// a display name.
|
||||
MemberInfo property =
|
||||
typeof(T).GetProperty(
|
||||
formFile.Name.Substring(formFile.Name.IndexOf(".",
|
||||
StringComparison.Ordinal) + 1));
|
||||
|
||||
if (property != null)
|
||||
{
|
||||
if (property.GetCustomAttribute(typeof(DisplayAttribute)) is
|
||||
DisplayAttribute displayAttribute)
|
||||
{
|
||||
fieldDisplayName = $"{displayAttribute.Name} ";
|
||||
}
|
||||
}
|
||||
|
||||
// Don't trust the file name sent by the client. To display
|
||||
// the file name, HTML-encode the value.
|
||||
var trustedFileNameForDisplay = WebUtility.HtmlEncode(
|
||||
formFile.FileName);
|
||||
|
||||
// Check the file length. This check doesn't catch files that only have
|
||||
// a BOM as their content.
|
||||
if (formFile.Length == 0)
|
||||
{
|
||||
modelState.AddModelError(formFile.Name,
|
||||
$"{fieldDisplayName}({trustedFileNameForDisplay}) is empty.");
|
||||
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
if (formFile.Length > sizeLimit)
|
||||
{
|
||||
var megabyteSizeLimit = sizeLimit / 1048576;
|
||||
modelState.AddModelError(formFile.Name,
|
||||
$"{fieldDisplayName}({trustedFileNameForDisplay}) exceeds " +
|
||||
$"{megabyteSizeLimit:N1} MB.");
|
||||
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
await formFile.CopyToAsync(memoryStream);
|
||||
|
||||
// Check the content length in case the file's only
|
||||
// content was a BOM and the content is actually
|
||||
// empty after removing the BOM.
|
||||
if (memoryStream.Length == 0)
|
||||
{
|
||||
modelState.AddModelError(formFile.Name,
|
||||
$"{fieldDisplayName}({trustedFileNameForDisplay}) is empty.");
|
||||
}
|
||||
|
||||
//if (!IsValidFileExtensionAndSignature(
|
||||
// formFile.FileName, memoryStream, permittedExtensions))
|
||||
//{
|
||||
// modelState.AddModelError(formFile.Name,
|
||||
// $"{fieldDisplayName}({trustedFileNameForDisplay}) file " +
|
||||
// "type isn't permitted or the file's signature " +
|
||||
// "doesn't match the file's extension.");
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// return memoryStream.ToArray();
|
||||
//}
|
||||
return memoryStream.ToArray();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
modelState.AddModelError(formFile.Name,
|
||||
$"{fieldDisplayName}({trustedFileNameForDisplay}) upload failed. " +
|
||||
$"Please contact the Help Desk for support. Error: {ex.HResult}");
|
||||
// Log the exception
|
||||
}
|
||||
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
public static async Task<byte[]> ProcessStreamedFile(
|
||||
MultipartSection section, ContentDispositionHeaderValue contentDisposition,
|
||||
ModelStateDictionary modelState, string[] permittedExtensions, long sizeLimit)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var memoryStream = new MemoryStream())
|
||||
{
|
||||
await section.Body.CopyToAsync(memoryStream);
|
||||
|
||||
// Check if the file is empty or exceeds the size limit.
|
||||
if (memoryStream.Length == 0)
|
||||
{
|
||||
modelState.AddModelError("File", "文件不可为空");
|
||||
}
|
||||
else if (memoryStream.Length > sizeLimit)
|
||||
{
|
||||
var megabyteSizeLimit = sizeLimit / 1048576;
|
||||
modelState.AddModelError("File",
|
||||
$"文件大小超过了{megabyteSizeLimit:N1} MB.");
|
||||
}
|
||||
else if (!IsValidFileExtensionAndSignature(
|
||||
contentDisposition.FileName.Value, memoryStream,
|
||||
permittedExtensions))
|
||||
{
|
||||
modelState.AddModelError("File",
|
||||
"此文件格式不支持");
|
||||
}
|
||||
else
|
||||
{
|
||||
return memoryStream.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
modelState.AddModelError("File",
|
||||
$"上传失败,发生错误,请联系客服人员解决. Error: {ex.HResult}");
|
||||
// Log the exception
|
||||
LogFactory.InsertErrorLog($"上传失败,{ex.Message},{ex.HResult}");
|
||||
}
|
||||
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
private static bool IsValidFileExtensionAndSignature(string fileName, Stream data, string[] permittedExtensions)
|
||||
{
|
||||
if (string.IsNullOrEmpty(fileName) || data == null || data.Length == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
var ext = Path.GetExtension(fileName).ToLowerInvariant();
|
||||
|
||||
if (string.IsNullOrEmpty(ext) || !permittedExtensions.Contains(ext))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
data.Position = 0;
|
||||
|
||||
using (var reader = new BinaryReader(data))
|
||||
{
|
||||
if (ext.Equals(".txt") || ext.Equals(".csv") || ext.Equals(".prn"))
|
||||
{
|
||||
if (_allowedChars.Length == 0)
|
||||
{
|
||||
// Limits characters to ASCII encoding.
|
||||
for (var i = 0; i < data.Length; i++)
|
||||
{
|
||||
var a = reader.ReadByte();
|
||||
if (reader.ReadByte() > sbyte.MaxValue)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Limits characters to ASCII encoding and
|
||||
// values of the _allowedChars array.
|
||||
for (var i = 0; i < data.Length; i++)
|
||||
{
|
||||
var b = reader.ReadByte();
|
||||
if (b > sbyte.MaxValue ||
|
||||
!_allowedChars.Contains(b))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Uncomment the following code block if you must permit
|
||||
// files whose signature isn't provided in the _fileSignature
|
||||
// dictionary. We recommend that you add file signatures
|
||||
// for files (when possible) for all file types you intend
|
||||
// to allow on the system and perform the file signature
|
||||
// check.
|
||||
|
||||
if (!_fileSignature.ContainsKey(ext))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// File signature check
|
||||
// --------------------
|
||||
// With the file signatures provided in the _fileSignature
|
||||
// dictionary, the following code tests the input content's
|
||||
// file signature.
|
||||
//var signatures = _fileSignature[ext];
|
||||
//var headerBytes = reader.ReadBytes(signatures.Max(m => m.Length));
|
||||
|
||||
//return signatures.Any(signature =>
|
||||
// headerBytes.Take(signature.Length).SequenceEqual(signature));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// 路径提供程序
|
||||
/// </summary>
|
||||
public interface IPathProvider
|
||||
{
|
||||
string MapPath(string path);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
using Microsoft.Net.Http.Headers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
public static class MultipartRequestHelper
|
||||
{
|
||||
// Content-Type: multipart/form-data; boundary="----WebKitFormBoundarymx2fSWqWSd0OxQqq"
|
||||
// The spec at https://tools.ietf.org/html/rfc2046#section-5.1 states that 70 characters is a reasonable limit.
|
||||
public static string GetBoundary(MediaTypeHeaderValue contentType, int lengthLimit)
|
||||
{
|
||||
var boundary = HeaderUtilities.RemoveQuotes(contentType.Boundary).Value;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(boundary))
|
||||
{
|
||||
throw new InvalidDataException("Missing content-type boundary.");
|
||||
}
|
||||
|
||||
if (boundary.Length > lengthLimit)
|
||||
{
|
||||
throw new InvalidDataException(
|
||||
$"Multipart boundary length limit {lengthLimit} exceeded.");
|
||||
}
|
||||
return boundary;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检查是否是multipart/form-data 类型
|
||||
/// </summary>
|
||||
/// <param name="contentType"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsMultipartContentType(string contentType)
|
||||
{
|
||||
return !string.IsNullOrEmpty(contentType)
|
||||
&& contentType.IndexOf("multipart/", StringComparison.OrdinalIgnoreCase) >= 0;
|
||||
}
|
||||
|
||||
public static bool HasFormDataContentDisposition(ContentDispositionHeaderValue contentDisposition)
|
||||
{
|
||||
// Content-Disposition: form-data; name="key";
|
||||
return contentDisposition != null
|
||||
&& contentDisposition.DispositionType.Equals("form-data")
|
||||
&& string.IsNullOrEmpty(contentDisposition.FileName.Value)
|
||||
&& string.IsNullOrEmpty(contentDisposition.FileNameStar.Value);
|
||||
}
|
||||
|
||||
public static bool HasFileContentDisposition(ContentDispositionHeaderValue contentDisposition)
|
||||
{
|
||||
// Content-Disposition: form-data; name="myfile1"; filename="Misc 002.jpg"
|
||||
return contentDisposition != null
|
||||
&& contentDisposition.DispositionType.Equals("form-data")
|
||||
&& (!string.IsNullOrEmpty(contentDisposition.FileName.Value)
|
||||
|| !string.IsNullOrEmpty(contentDisposition.FileNameStar.Value));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
using Microsoft.AspNetCore.Hosting;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// 路径获取依赖注入类
|
||||
/// </summary>
|
||||
public class PathProvider:IPathProvider
|
||||
{
|
||||
private IWebHostEnvironment _hostingEnvironment;
|
||||
|
||||
public PathProvider(IWebHostEnvironment environment)
|
||||
{
|
||||
_hostingEnvironment = environment;
|
||||
}
|
||||
|
||||
public string MapPath(string path)
|
||||
{
|
||||
var filePath = Path.Combine(_hostingEnvironment.WebRootPath, path);
|
||||
return filePath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// 根据twitter的snowflake算法生成唯一ID
|
||||
/// snowflake算法 64 位
|
||||
/// 0---0000000000 0000000000 0000000000 0000000000 0 --- 00000 ---00000 ---000000000000
|
||||
/// 第一位为未使用(实际上也可作为long的符号位),接下来的41位为毫秒级时间,然后5位datacenter标识位,5位机器ID(并不算标识符,实际是为线程标识),然后12位该毫秒内的当前毫秒内的计数,加起来刚好64位,为一个Long型。
|
||||
/// 其中datacenter标识位起始是机器位,机器ID其实是线程标识,可以同一一个10位来表示不同机器
|
||||
/// </summary>
|
||||
public class IdWorker
|
||||
{
|
||||
//机器ID
|
||||
private static long workerId;
|
||||
private static long twepoch = 1514736000L; //唯一时间,这是一个避免重复的随机量,自行设定不要大于当前时间戳
|
||||
private static long sequence = 0L;
|
||||
private static int workerIdBits = 4; //机器码字节数。4个字节用来保存机器码(定义为Long类型会出现,最大偏移64位,所以左移64位没有意义)
|
||||
public static long maxWorkerId = -1L ^ -1L << workerIdBits; //最大机器ID
|
||||
private static int sequenceBits = 10; //计数器字节数,10个字节用来保存计数码
|
||||
private static int workerIdShift = sequenceBits; //机器码数据左移位数,就是后面计数器占用的位数
|
||||
private static int timestampLeftShift = sequenceBits + workerIdBits; //时间戳左移动位数就是机器码和计数器总字节数
|
||||
public static long sequenceMask = -1L ^ -1L << sequenceBits; //一微秒内可以产生计数,如果达到该值则等到下一微妙在进行生成
|
||||
private long lastTimestamp = -1L;
|
||||
private static readonly Object _Locker = new Object();
|
||||
/// <summary>
|
||||
/// 机器码
|
||||
/// </summary>
|
||||
/// <param name="workerId"></param>
|
||||
public IdWorker(long workerId)
|
||||
{
|
||||
if (workerId > maxWorkerId || workerId < 0)
|
||||
throw new Exception(string.Format("worker Id can't be greater than {0} or less than 0 ", workerId));
|
||||
IdWorker.workerId = workerId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public long nextid()
|
||||
{
|
||||
//var worder = new Snowflake.Net.IdWorker(workerId, 1);
|
||||
//return worder.NextId();
|
||||
lock (_Locker)
|
||||
{
|
||||
long timestamp = timeGen();
|
||||
if (timestamp < lastTimestamp)
|
||||
{//如果当前时间戳比上一次生成ID时时间戳还小,抛出异常,因为不能保证现在生成的ID之前没有生成过
|
||||
throw new Exception(string.Format("Clock moved backwards. Refusing to generate id for {0} milliseconds",
|
||||
this.lastTimestamp - timestamp));
|
||||
}
|
||||
if (this.lastTimestamp == timestamp)
|
||||
{//同一微妙中生成ID
|
||||
IdWorker.sequence = (IdWorker.sequence + 1) & IdWorker.sequenceMask; //用&运算计算该微秒内产生的计数是否已经到达上限
|
||||
if (IdWorker.sequence == 0)
|
||||
{
|
||||
//一微妙内产生的ID计数已达上限,等待下一微妙
|
||||
timestamp = tillNextMillis(this.lastTimestamp);
|
||||
}
|
||||
}
|
||||
else
|
||||
{//不同微秒生成ID
|
||||
IdWorker.sequence = 0;//计数清0
|
||||
}
|
||||
this.lastTimestamp = timestamp; //把当前时间戳保存为最后生成ID的时间戳
|
||||
long nextId = (timestamp - twepoch << timestampLeftShift) | IdWorker.workerId << IdWorker.workerIdShift | IdWorker.sequence;
|
||||
Thread.Sleep(10);
|
||||
return nextId;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取下一微秒时间戳
|
||||
/// </summary>
|
||||
/// <param name="lastTimestamp"></param>
|
||||
/// <returns></returns>
|
||||
private long tillNextMillis(long lastTimestamp)
|
||||
{
|
||||
long timestamp = timeGen();
|
||||
while (timestamp <= lastTimestamp)
|
||||
{
|
||||
timestamp = timeGen();
|
||||
}
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成当前时间戳
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private long timeGen()
|
||||
{
|
||||
return (long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
public class ImageUtil
|
||||
{
|
||||
/// <summary>
|
||||
/// 图片转BASE64编码
|
||||
/// </summary>
|
||||
/// <param name="bmp"></param>
|
||||
/// <returns></returns>
|
||||
public static string ImgToBase64String(Bitmap bmp)
|
||||
{
|
||||
MemoryStream ms = new MemoryStream();
|
||||
bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
|
||||
byte[] arr = new byte[ms.Length];
|
||||
ms.Position = 0;
|
||||
ms.Read(arr, 0, (int)ms.Length);
|
||||
ms.Close();
|
||||
String strbaser64 = Convert.ToBase64String(arr);
|
||||
return strbaser64;
|
||||
}
|
||||
/// <summary>
|
||||
/// 图片转BASE64编码
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns></returns>
|
||||
public static string ImgToBase64String(string path)
|
||||
{
|
||||
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
byte[] byteData = new byte[fs.Length];
|
||||
fs.Read(byteData, 0, byteData.Length);
|
||||
fs.Close();
|
||||
string data = Convert.ToBase64String(byteData);
|
||||
return data;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Base64转图片
|
||||
/// </summary>
|
||||
/// <param name="base64Img">Base64编码</param>
|
||||
/// <returns></returns>
|
||||
public static Bitmap Base64StringToImage(string base64Img)
|
||||
{
|
||||
byte[] bytes = Convert.FromBase64String(base64Img);
|
||||
MemoryStream ms = new MemoryStream();
|
||||
ms.Write(bytes, 0, bytes.Length);
|
||||
Bitmap bmp = new Bitmap(ms);
|
||||
return bmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
public static class Json
|
||||
{
|
||||
public static object ToJson(this string Json)
|
||||
{
|
||||
return Json == null ? null : JsonConvert.DeserializeObject(Json);
|
||||
}
|
||||
public static string ToJson(this object obj)
|
||||
{
|
||||
if (obj == null)
|
||||
return "";
|
||||
var timeConverter = new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" };
|
||||
return JsonConvert.SerializeObject(obj, timeConverter);
|
||||
}
|
||||
public static string ToJson(this object obj, string datetimeformats)
|
||||
{
|
||||
var timeConverter = new IsoDateTimeConverter { DateTimeFormat = datetimeformats };
|
||||
return JsonConvert.SerializeObject(obj, timeConverter);
|
||||
}
|
||||
public static T ToObject<T>(this string Json)
|
||||
{
|
||||
return Json == null ? default(T) : JsonConvert.DeserializeObject<T>(Json);
|
||||
}
|
||||
public static List<T> ToList<T>(this string Json)
|
||||
{
|
||||
return Json == null ? null : JsonConvert.DeserializeObject<List<T>>(Json);
|
||||
}
|
||||
public static DataTable ToTable(this string Json)
|
||||
{
|
||||
return Json == null ? null : JsonConvert.DeserializeObject<DataTable>(Json);
|
||||
}
|
||||
public static JObject ToJObject(this string Json)
|
||||
{
|
||||
return Json == null ? JObject.Parse("{}") : JObject.Parse(Json.Replace(" ", ""));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
using Microsoft.Extensions.Configuration;
|
||||
using Serilog;
|
||||
using Serilog.Core;
|
||||
using Serilog.Events;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
public class LogFactory
|
||||
{
|
||||
public static Logger _logger;
|
||||
static LogFactory()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static Logger GetLogger(IConfiguration configuration)
|
||||
{
|
||||
_logger = new LoggerConfiguration()
|
||||
.ReadFrom.Configuration(configuration)
|
||||
//.MinimumLevel.Information()
|
||||
//.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
|
||||
//.MinimumLevel.Override("Microsoft.AspNetCore", LogEventLevel.Warning)
|
||||
.Enrich.FromLogContext()
|
||||
.WriteTo.Map(
|
||||
evt => evt.Level,
|
||||
(level, wt) => wt.File($"{Configs.GetString("logfile")}/{DateTime.Now.ToString("yyyy-MM-dd")}/" + level + ".log", outputTemplate: "{Timestamp:HH:mm:ss} ({Application}/{MachineName}/{ThreadId})({SourceContext}){NewLine}{Message}{NewLine}{Exception}============================{NewLine}")
|
||||
)
|
||||
.CreateLogger();
|
||||
return _logger;
|
||||
}
|
||||
|
||||
public static void InsertErrorLog(string msg, int type = 1)
|
||||
{
|
||||
msg = $"{msg}";
|
||||
switch (type)
|
||||
{
|
||||
case 1:
|
||||
_logger.Error(msg);
|
||||
break;
|
||||
case 2:
|
||||
_logger.Information(msg);
|
||||
break;
|
||||
case 3:
|
||||
_logger.Warning(msg);
|
||||
break;
|
||||
case 4:
|
||||
_logger.Debug(msg);
|
||||
break;
|
||||
case 5:
|
||||
_logger.Fatal(msg);
|
||||
break;
|
||||
default:
|
||||
_logger.Error(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Diagnostics;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Nirvana.Common.ApiBase;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// 异常处理中间件
|
||||
/// </summary>
|
||||
public class MyExceptionMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
public MyExceptionMiddleware(RequestDelegate next)
|
||||
{
|
||||
_next = next;
|
||||
}
|
||||
public async Task Invoke(HttpContext httpContext)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _next(httpContext);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// new ApiLoggerApplication().InsertErrorLog(ex);
|
||||
await HandleExceptionAsync(httpContext, ex);
|
||||
}
|
||||
}
|
||||
|
||||
private Task HandleExceptionAsync(HttpContext httpContext, Exception ex)
|
||||
{
|
||||
//记录日志
|
||||
// new ApiLoggerApplication().InsertErrorLog(ex);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void OnException(ExceptionContext context)
|
||||
{
|
||||
context.ExceptionHandled = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Extension method used to add the middleware to the HTTP request pipeline.
|
||||
/// </summary>
|
||||
public static class MyExceptionMiddlewareExtensions
|
||||
{
|
||||
public static IApplicationBuilder UseMyExceptionMiddleware(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder.UseMiddleware<MyExceptionMiddleware>();
|
||||
}
|
||||
}
|
||||
|
||||
public static class ExceptionHandlingExtensions
|
||||
{
|
||||
public static void UseMyExceptionHandler(this IApplicationBuilder app)
|
||||
{
|
||||
app.UseExceptionHandler(builder => {
|
||||
|
||||
builder.Run(async context =>
|
||||
{
|
||||
context.Response.StatusCode = StatusCodes.Status500InternalServerError;
|
||||
context.Response.ContentType = "application/json";
|
||||
var ex = context.Features.Get<IExceptionHandlerFeature>();
|
||||
if (ex != null)
|
||||
{
|
||||
var request = context.Request;
|
||||
var action = request.Path.Value;
|
||||
var query_string = request.QueryString.Value;
|
||||
if (request.Method == "POST" && request.ContentLength > 0)
|
||||
{
|
||||
request.EnableBuffering();
|
||||
request.Body.Position = 0;
|
||||
using (var sr = new StreamReader(request.Body))
|
||||
{
|
||||
query_string = await sr.ReadToEndAsync();
|
||||
}
|
||||
}
|
||||
//记录日志
|
||||
// new ApiLoggerApplication().InsertErrorLog(ex.Error, query_string, action);
|
||||
//new ApiLoggerApplication().InsertErrorLog(ex.Error);
|
||||
}
|
||||
var result = new ResultInfo { code = ResultState.SYSTEMERROR, message = ex?.Error?.Message ?? "系统异常" };
|
||||
await context.Response.WriteAsync(result.ToJson());
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,893 @@
|
|||
using RestSharp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Security;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Web;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// http连接操作帮助类
|
||||
/// </summary>
|
||||
public class HttpHelper
|
||||
{
|
||||
#region 预定义方变量
|
||||
//默认的编码
|
||||
private Encoding encoding = Encoding.Default;
|
||||
//Post数据编码
|
||||
private Encoding postencoding = Encoding.Default;
|
||||
//HttpWebRequest对象用来发起请求
|
||||
private HttpWebRequest request = null;
|
||||
//获取影响流的数据对象
|
||||
private HttpWebResponse response = null;
|
||||
#endregion
|
||||
|
||||
#region Public
|
||||
|
||||
/// <summary>
|
||||
/// 根据相传入的数据,得到相应页面数据
|
||||
/// </summary>
|
||||
/// <param name="item">参数类对象</param>
|
||||
/// <returns>返回HttpResult类型</returns>
|
||||
public HttpResult GetHtml(HttpItem item)
|
||||
{
|
||||
//返回参数
|
||||
HttpResult result = new HttpResult();
|
||||
try
|
||||
{
|
||||
//准备参数
|
||||
SetRequest(item);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result.Cookie = string.Empty;
|
||||
result.Header = null;
|
||||
result.Html = ex.Message;
|
||||
result.StatusDescription = "配置参数时出错:" + ex.Message;
|
||||
//配置参数时出错
|
||||
return result;
|
||||
}
|
||||
try
|
||||
{
|
||||
//请求数据
|
||||
using (response = (HttpWebResponse)request.GetResponse())
|
||||
{
|
||||
GetData(item, result);
|
||||
}
|
||||
}
|
||||
catch (WebException ex)
|
||||
{
|
||||
if (ex.Response != null)
|
||||
{
|
||||
using (response = (HttpWebResponse)ex.Response)
|
||||
{
|
||||
GetData(item, result);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.Html = ex.Message;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result.Html = ex.Message;
|
||||
}
|
||||
if (item.IsToLower) result.Html = result.Html.ToLower();
|
||||
return result;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GetData
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据的并解析的方法
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
/// <param name="result"></param>
|
||||
private void GetData(HttpItem item, HttpResult result)
|
||||
{
|
||||
#region base
|
||||
//获取StatusCode
|
||||
result.StatusCode = response.StatusCode;
|
||||
//获取StatusDescription
|
||||
result.StatusDescription = response.StatusDescription;
|
||||
//获取Headers
|
||||
result.Header = response.Headers;
|
||||
//获取CookieCollection
|
||||
if (response.Cookies != null) result.CookieCollection = response.Cookies;
|
||||
//获取set-cookie
|
||||
if (response.Headers["set-cookie"] != null) result.Cookie = response.Headers["set-cookie"];
|
||||
#endregion
|
||||
|
||||
#region byte
|
||||
//处理网页Byte
|
||||
byte[] ResponseByte = GetByte();
|
||||
#endregion
|
||||
|
||||
#region Html
|
||||
if (ResponseByte != null & ResponseByte.Length > 0)
|
||||
{
|
||||
//设置编码
|
||||
SetEncoding(item, result, ResponseByte);
|
||||
//得到返回的HTML
|
||||
result.Html = encoding.GetString(ResponseByte);
|
||||
}
|
||||
else
|
||||
{
|
||||
//没有返回任何Html代码
|
||||
result.Html = string.Empty;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置编码
|
||||
/// </summary>
|
||||
/// <param name="item">HttpItem</param>
|
||||
/// <param name="result">HttpResult</param>
|
||||
/// <param name="ResponseByte">byte[]</param>
|
||||
private void SetEncoding(HttpItem item, HttpResult result, byte[] ResponseByte)
|
||||
{
|
||||
//是否返回Byte类型数据
|
||||
if (item.HttpResultType == HttpResultType.Byte) result.ResultByte = ResponseByte;
|
||||
//从这里开始我们要无视编码了
|
||||
if (encoding == null)
|
||||
{
|
||||
Match meta = Regex.Match(Encoding.Default.GetString(ResponseByte), "<meta[^<]*charset=([^<]*)[\"']", RegexOptions.IgnoreCase);
|
||||
string c = string.Empty;
|
||||
if (meta != null && meta.Groups.Count > 0)
|
||||
{
|
||||
c = meta.Groups[1].Value.ToLower().Trim();
|
||||
}
|
||||
if (c.Length > 2)
|
||||
{
|
||||
try
|
||||
{
|
||||
encoding = Encoding.GetEncoding(c.Replace("\"", string.Empty).Replace("'", "").Replace(";", "").Replace("iso-8859-1", "gbk").Trim());
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (string.IsNullOrEmpty(response.CharacterSet))
|
||||
{
|
||||
encoding = Encoding.UTF8;
|
||||
}
|
||||
else
|
||||
{
|
||||
encoding = Encoding.GetEncoding(response.CharacterSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (string.IsNullOrEmpty(response.CharacterSet))
|
||||
{
|
||||
encoding = Encoding.UTF8;
|
||||
}
|
||||
else
|
||||
{
|
||||
encoding = Encoding.GetEncoding(response.CharacterSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 提取网页Byte
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private byte[] GetByte()
|
||||
{
|
||||
byte[] ResponseByte = null;
|
||||
MemoryStream _stream = new MemoryStream();
|
||||
|
||||
//GZIIP处理
|
||||
if (response.ContentEncoding != null && response.ContentEncoding.Equals("gzip", StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
//开始读取流并设置编码方式
|
||||
_stream = GetMemoryStream(new GZipStream(response.GetResponseStream(), CompressionMode.Decompress));
|
||||
}
|
||||
else
|
||||
{
|
||||
//开始读取流并设置编码方式
|
||||
_stream = GetMemoryStream(response.GetResponseStream());
|
||||
}
|
||||
//获取Byte
|
||||
ResponseByte = _stream.ToArray();
|
||||
_stream.Close();
|
||||
return ResponseByte;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 4.0以下.net版本取数据使用
|
||||
/// </summary>
|
||||
/// <param name="streamResponse">流</param>
|
||||
private MemoryStream GetMemoryStream(Stream streamResponse)
|
||||
{
|
||||
MemoryStream _stream = new MemoryStream();
|
||||
int Length = 256;
|
||||
Byte[] buffer = new Byte[Length];
|
||||
int bytesRead = streamResponse.Read(buffer, 0, Length);
|
||||
while (bytesRead > 0)
|
||||
{
|
||||
_stream.Write(buffer, 0, bytesRead);
|
||||
bytesRead = streamResponse.Read(buffer, 0, Length);
|
||||
}
|
||||
return _stream;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
#region SetRequest
|
||||
|
||||
/// <summary>
|
||||
/// 为请求准备参数
|
||||
/// </summary>
|
||||
///<param name="item">参数列表</param>
|
||||
private void SetRequest(HttpItem item)
|
||||
{
|
||||
// 验证证书
|
||||
SetCer(item);
|
||||
//设置Header参数
|
||||
if (item.Header != null && item.Header.Count > 0) foreach (string key in item.Header.AllKeys)
|
||||
{
|
||||
request.Headers.Add(key, item.Header[key]);
|
||||
}
|
||||
// 设置代理
|
||||
SetProxy(item);
|
||||
if (item.ProtocolVersion != null) request.ProtocolVersion = item.ProtocolVersion;
|
||||
request.ServicePoint.Expect100Continue = item.Expect100Continue;
|
||||
if (item.URL.StartsWith("https://"))
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
//请求方式Get或者Post
|
||||
request.Method = item.Method;
|
||||
request.Timeout = item.Timeout;
|
||||
request.KeepAlive = item.KeepAlive;
|
||||
request.ReadWriteTimeout = item.ReadWriteTimeout;
|
||||
if (item.IfModifiedSince != null) request.IfModifiedSince = Convert.ToDateTime(item.IfModifiedSince);
|
||||
//Accept
|
||||
request.Accept = item.Accept;
|
||||
//ContentType返回类型
|
||||
request.ContentType = item.ContentType;
|
||||
//UserAgent客户端的访问类型,包括浏览器版本和操作系统信息
|
||||
request.UserAgent = item.UserAgent;
|
||||
// 编码
|
||||
encoding = item.Encoding;
|
||||
//设置安全凭证
|
||||
request.Credentials = item.ICredentials;
|
||||
//设置Cookie
|
||||
SetCookie(item);
|
||||
//来源地址
|
||||
request.Referer = item.Referer;
|
||||
//是否执行跳转功能
|
||||
request.AllowAutoRedirect = item.Allowautoredirect;
|
||||
if (item.MaximumAutomaticRedirections > 0)
|
||||
{
|
||||
request.MaximumAutomaticRedirections = item.MaximumAutomaticRedirections;
|
||||
}
|
||||
//设置Post数据
|
||||
SetPostData(item);
|
||||
//设置最大连接
|
||||
if (item.Connectionlimit > 0) request.ServicePoint.ConnectionLimit = item.Connectionlimit;
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置证书
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
private void SetCer(HttpItem item)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(item.CerPath))
|
||||
{
|
||||
//这一句一定要写在创建连接的前面。使用回调的方法进行证书验证。
|
||||
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);
|
||||
//初始化对像,并设置请求的URL地址
|
||||
request = (HttpWebRequest)WebRequest.Create(item.URL);
|
||||
SetCerList(item);
|
||||
//将证书添加到请求里
|
||||
request.ClientCertificates.Add(new X509Certificate(item.CerPath));
|
||||
}
|
||||
else
|
||||
{
|
||||
//初始化对像,并设置请求的URL地址
|
||||
request = (HttpWebRequest)WebRequest.Create(item.URL);
|
||||
SetCerList(item);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置多个证书
|
||||
/// </summary>
|
||||
/// <param name="item"></param>
|
||||
private void SetCerList(HttpItem item)
|
||||
{
|
||||
if (item.ClentCertificates != null && item.ClentCertificates.Count > 0)
|
||||
{
|
||||
foreach (X509Certificate c in item.ClentCertificates)
|
||||
{
|
||||
request.ClientCertificates.Add(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置Cookie
|
||||
/// </summary>
|
||||
/// <param name="item">Http参数</param>
|
||||
private void SetCookie(HttpItem item)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(item.Cookie)) request.Headers[HttpRequestHeader.Cookie] = item.Cookie;
|
||||
//设置CookieCollection
|
||||
if (item.ResultCookieType == ResultCookieType.CookieCollection)
|
||||
{
|
||||
request.CookieContainer = new CookieContainer();
|
||||
if (item.CookieCollection != null && item.CookieCollection.Count > 0)
|
||||
request.CookieContainer.Add(item.CookieCollection);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置Post数据
|
||||
/// </summary>
|
||||
/// <param name="item">Http参数</param>
|
||||
private void SetPostData(HttpItem item)
|
||||
{
|
||||
//验证在得到结果时是否有传入数据
|
||||
if (!request.Method.Trim().ToLower().Contains("get"))
|
||||
{
|
||||
if (item.PostEncoding != null)
|
||||
{
|
||||
postencoding = item.PostEncoding;
|
||||
}
|
||||
byte[] buffer = null;
|
||||
//写入Byte类型
|
||||
if (item.PostDataType == PostDataType.Byte && item.PostdataByte != null && item.PostdataByte.Length > 0)
|
||||
{
|
||||
//验证在得到结果时是否有传入数据
|
||||
buffer = item.PostdataByte;
|
||||
}//写入文件
|
||||
else if (item.PostDataType == PostDataType.FilePath && !string.IsNullOrEmpty(item.Postdata))
|
||||
{
|
||||
StreamReader r = new StreamReader(item.Postdata, postencoding);
|
||||
buffer = postencoding.GetBytes(r.ReadToEnd());
|
||||
r.Close();
|
||||
} //写入字符串
|
||||
else if (!string.IsNullOrEmpty(item.Postdata))
|
||||
{
|
||||
buffer = postencoding.GetBytes(item.Postdata);
|
||||
}
|
||||
if (buffer != null)
|
||||
{
|
||||
request.ContentLength = buffer.Length;
|
||||
request.GetRequestStream().Write(buffer, 0, buffer.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置代理
|
||||
/// </summary>
|
||||
/// <param name="item">参数对象</param>
|
||||
private void SetProxy(HttpItem item)
|
||||
{
|
||||
bool isIeProxy = false;
|
||||
if (!string.IsNullOrEmpty(item.ProxyIp))
|
||||
{
|
||||
isIeProxy = item.ProxyIp.ToLower().Contains("ieproxy");
|
||||
}
|
||||
if (!string.IsNullOrEmpty(item.ProxyIp) && !isIeProxy)
|
||||
{
|
||||
//设置代理服务器
|
||||
if (item.ProxyIp.Contains(":"))
|
||||
{
|
||||
string[] plist = item.ProxyIp.Split(':');
|
||||
WebProxy myProxy = new WebProxy(plist[0].Trim(), Convert.ToInt32(plist[1].Trim()));
|
||||
//建议连接
|
||||
myProxy.Credentials = new NetworkCredential(item.ProxyUserName, item.ProxyPwd);
|
||||
//给当前请求对象
|
||||
request.Proxy = myProxy;
|
||||
}
|
||||
else
|
||||
{
|
||||
WebProxy myProxy = new WebProxy(item.ProxyIp, false);
|
||||
//建议连接
|
||||
myProxy.Credentials = new NetworkCredential(item.ProxyUserName, item.ProxyPwd);
|
||||
//给当前请求对象
|
||||
request.Proxy = myProxy;
|
||||
}
|
||||
}
|
||||
else if (isIeProxy)
|
||||
{
|
||||
//设置为IE代理
|
||||
}
|
||||
else
|
||||
{
|
||||
request.Proxy = item.WebProxy;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region private main
|
||||
/// <summary>
|
||||
/// 回调验证证书问题
|
||||
/// </summary>
|
||||
/// <param name="sender">流对象</param>
|
||||
/// <param name="certificate">证书</param>
|
||||
/// <param name="chain">X509Chain</param>
|
||||
/// <param name="errors">SslPolicyErrors</param>
|
||||
/// <returns>bool</returns>
|
||||
private bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) { return true; }
|
||||
#endregion
|
||||
|
||||
#region common
|
||||
public string GetPostData(NameValueCollection parameters)
|
||||
{
|
||||
var parassb = new StringBuilder();
|
||||
foreach (string key in parameters.Keys)
|
||||
{
|
||||
if (parassb.Length > 0)
|
||||
{
|
||||
parassb.Append("&");
|
||||
}
|
||||
parassb.AppendFormat("{0}={1}", key, HttpUtility.UrlEncode(parameters[key]));
|
||||
}
|
||||
return parassb.ToString();
|
||||
}
|
||||
#endregion
|
||||
|
||||
public string Post(HttpItem item)
|
||||
{
|
||||
item.Method = "POST";
|
||||
var result= GetHtml(item);
|
||||
return result.Html;
|
||||
}
|
||||
|
||||
public HttpResult Post(HttpItem item,int type)
|
||||
{
|
||||
item.Method = "POST";
|
||||
var result = GetHtml(item);
|
||||
return result;
|
||||
}
|
||||
|
||||
public string Get(HttpItem item)
|
||||
{
|
||||
item.Method = "GET";
|
||||
var result = GetHtml(item);
|
||||
return result.Html;
|
||||
}
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// Http请求参考类
|
||||
/// </summary>
|
||||
public class HttpItem
|
||||
{
|
||||
|
||||
string _URL = string.Empty;
|
||||
/// <summary>
|
||||
/// 请求URL必须填写
|
||||
/// </summary>
|
||||
public string URL
|
||||
{
|
||||
get { return _URL; }
|
||||
set { _URL = value; }
|
||||
}
|
||||
string _Method = "GET";
|
||||
/// <summary>
|
||||
/// 请求方式默认为GET方式,当为POST方式时必须设置Postdata的值
|
||||
/// </summary>
|
||||
public string Method
|
||||
{
|
||||
get { return _Method; }
|
||||
set { _Method = value; }
|
||||
}
|
||||
int _Timeout = 100000;
|
||||
/// <summary>
|
||||
/// 默认请求超时时间
|
||||
/// </summary>
|
||||
public int Timeout
|
||||
{
|
||||
get { return _Timeout; }
|
||||
set { _Timeout = value; }
|
||||
}
|
||||
int _ReadWriteTimeout = 30000;
|
||||
/// <summary>
|
||||
/// 默认写入Post数据超时间
|
||||
/// </summary>
|
||||
public int ReadWriteTimeout
|
||||
{
|
||||
get { return _ReadWriteTimeout; }
|
||||
set { _ReadWriteTimeout = value; }
|
||||
}
|
||||
Boolean _KeepAlive = true;
|
||||
/// <summary>
|
||||
/// 获取或设置一个值,该值指示是否与 Internet 资源建立持久性连接默认为true。
|
||||
/// </summary>
|
||||
public Boolean KeepAlive
|
||||
{
|
||||
get { return _KeepAlive; }
|
||||
set { _KeepAlive = value; }
|
||||
}
|
||||
string _Accept = "text/html, application/xhtml+xml, */*";
|
||||
/// <summary>
|
||||
/// 请求标头值 默认为text/html, application/xhtml+xml, */*
|
||||
/// </summary>
|
||||
public string Accept
|
||||
{
|
||||
get { return _Accept; }
|
||||
set { _Accept = value; }
|
||||
}
|
||||
string _ContentType = "text/html";
|
||||
/// <summary>
|
||||
/// 请求返回类型默认 text/html
|
||||
/// </summary>
|
||||
public string ContentType
|
||||
{
|
||||
get { return _ContentType; }
|
||||
set { _ContentType = value; }
|
||||
}
|
||||
string _UserAgent = "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)";
|
||||
/// <summary>
|
||||
/// 客户端访问信息默认Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0)
|
||||
/// </summary>
|
||||
public string UserAgent
|
||||
{
|
||||
get { return _UserAgent; }
|
||||
set { _UserAgent = value; }
|
||||
}
|
||||
Encoding _Encoding = null;
|
||||
/// <summary>
|
||||
/// 返回数据编码默认为NUll,可以自动识别,一般为utf-8,gbk,gb2312
|
||||
/// </summary>
|
||||
public Encoding Encoding
|
||||
{
|
||||
get { return _Encoding; }
|
||||
set { _Encoding = value; }
|
||||
}
|
||||
private PostDataType _PostDataType = PostDataType.String;
|
||||
/// <summary>
|
||||
/// Post的数据类型
|
||||
/// </summary>
|
||||
public PostDataType PostDataType
|
||||
{
|
||||
get { return _PostDataType; }
|
||||
set { _PostDataType = value; }
|
||||
}
|
||||
string _Postdata = string.Empty;
|
||||
/// <summary>
|
||||
/// Post请求时要发送的字符串Post数据
|
||||
/// </summary>
|
||||
public string Postdata
|
||||
{
|
||||
get { return _Postdata; }
|
||||
set { _Postdata = value; }
|
||||
}
|
||||
private byte[] _PostdataByte = null;
|
||||
/// <summary>
|
||||
/// Post请求时要发送的Byte类型的Post数据
|
||||
/// </summary>
|
||||
public byte[] PostdataByte
|
||||
{
|
||||
get { return _PostdataByte; }
|
||||
set { _PostdataByte = value; }
|
||||
}
|
||||
private WebProxy _WebProxy;
|
||||
/// <summary>
|
||||
/// 设置代理对象,不想使用IE默认配置就设置为Null,而且不要设置ProxyIp
|
||||
/// </summary>
|
||||
public WebProxy WebProxy
|
||||
{
|
||||
get { return _WebProxy; }
|
||||
set { _WebProxy = value; }
|
||||
}
|
||||
|
||||
CookieCollection cookiecollection = null;
|
||||
/// <summary>
|
||||
/// Cookie对象集合
|
||||
/// </summary>
|
||||
public CookieCollection CookieCollection
|
||||
{
|
||||
get { return cookiecollection; }
|
||||
set { cookiecollection = value; }
|
||||
}
|
||||
string _Cookie = string.Empty;
|
||||
/// <summary>
|
||||
/// 请求时的Cookie
|
||||
/// </summary>
|
||||
public string Cookie
|
||||
{
|
||||
get { return _Cookie; }
|
||||
set { _Cookie = value; }
|
||||
}
|
||||
string _Referer = string.Empty;
|
||||
/// <summary>
|
||||
/// 来源地址,上次访问地址
|
||||
/// </summary>
|
||||
public string Referer
|
||||
{
|
||||
get { return _Referer; }
|
||||
set { _Referer = value; }
|
||||
}
|
||||
string _CerPath = string.Empty;
|
||||
/// <summary>
|
||||
/// 证书绝对路径
|
||||
/// </summary>
|
||||
public string CerPath
|
||||
{
|
||||
get { return _CerPath; }
|
||||
set { _CerPath = value; }
|
||||
}
|
||||
private Boolean isToLower = false;
|
||||
/// <summary>
|
||||
/// 是否设置为全文小写,默认为不转化
|
||||
/// </summary>
|
||||
public Boolean IsToLower
|
||||
{
|
||||
get { return isToLower; }
|
||||
set { isToLower = value; }
|
||||
}
|
||||
private Boolean allowautoredirect = false;
|
||||
/// <summary>
|
||||
/// 支持跳转页面,查询结果将是跳转后的页面,默认是不跳转
|
||||
/// </summary>
|
||||
public Boolean Allowautoredirect
|
||||
{
|
||||
get { return allowautoredirect; }
|
||||
set { allowautoredirect = value; }
|
||||
}
|
||||
private int connectionlimit = 1024;
|
||||
/// <summary>
|
||||
/// 最大连接数
|
||||
/// </summary>
|
||||
public int Connectionlimit
|
||||
{
|
||||
get { return connectionlimit; }
|
||||
set { connectionlimit = value; }
|
||||
}
|
||||
private string proxyusername = string.Empty;
|
||||
/// <summary>
|
||||
/// 代理Proxy 服务器用户名
|
||||
/// </summary>
|
||||
public string ProxyUserName
|
||||
{
|
||||
get { return proxyusername; }
|
||||
set { proxyusername = value; }
|
||||
}
|
||||
private string proxypwd = string.Empty;
|
||||
/// <summary>
|
||||
/// 代理 服务器密码
|
||||
/// </summary>
|
||||
public string ProxyPwd
|
||||
{
|
||||
get { return proxypwd; }
|
||||
set { proxypwd = value; }
|
||||
}
|
||||
private string proxyip = string.Empty;
|
||||
/// <summary>
|
||||
/// 代理 服务IP ,如果要使用IE代理就设置为ieproxy
|
||||
/// </summary>
|
||||
public string ProxyIp
|
||||
{
|
||||
get { return proxyip; }
|
||||
set { proxyip = value; }
|
||||
}
|
||||
private HttpResultType resulttype = HttpResultType.String;
|
||||
/// <summary>
|
||||
/// 设置返回类型String和Byte
|
||||
/// </summary>
|
||||
public HttpResultType HttpResultType
|
||||
{
|
||||
get { return resulttype; }
|
||||
set { resulttype = value; }
|
||||
}
|
||||
private WebHeaderCollection header = new WebHeaderCollection();
|
||||
/// <summary>
|
||||
/// header对象
|
||||
/// </summary>
|
||||
public WebHeaderCollection Header
|
||||
{
|
||||
get { return header; }
|
||||
set { header = value; }
|
||||
}
|
||||
|
||||
private Version _ProtocolVersion;
|
||||
|
||||
/// <summary>
|
||||
// 获取或设置用于请求的 HTTP 版本。返回结果:用于请求的 HTTP 版本。默认为 System.Net.HttpVersion.Version11。
|
||||
/// </summary>
|
||||
public Version ProtocolVersion
|
||||
{
|
||||
get { return _ProtocolVersion; }
|
||||
set { _ProtocolVersion = value; }
|
||||
}
|
||||
private Boolean _expect100continue = true;
|
||||
/// <summary>
|
||||
/// 获取或设置一个 System.Boolean 值,该值确定是否使用 100-Continue 行为。如果 POST 请求需要 100-Continue 响应,则为 true;否则为 false。默认值为 true。
|
||||
/// </summary>
|
||||
public Boolean Expect100Continue
|
||||
{
|
||||
get { return _expect100continue; }
|
||||
set { _expect100continue = value; }
|
||||
}
|
||||
private X509CertificateCollection _ClentCertificates;
|
||||
/// <summary>
|
||||
/// 设置509证书集合
|
||||
/// </summary>
|
||||
public X509CertificateCollection ClentCertificates
|
||||
{
|
||||
get { return _ClentCertificates; }
|
||||
set { _ClentCertificates = value; }
|
||||
}
|
||||
private Encoding _PostEncoding;
|
||||
/// <summary>
|
||||
/// 设置或获取Post参数编码,默认的为Default编码
|
||||
/// </summary>
|
||||
public Encoding PostEncoding
|
||||
{
|
||||
get { return _PostEncoding; }
|
||||
set { _PostEncoding = value; }
|
||||
}
|
||||
private ResultCookieType _ResultCookieType = ResultCookieType.String;
|
||||
/// <summary>
|
||||
/// Cookie返回类型,默认的是只返回字符串类型
|
||||
/// </summary>
|
||||
public ResultCookieType ResultCookieType
|
||||
{
|
||||
get { return _ResultCookieType; }
|
||||
set { _ResultCookieType = value; }
|
||||
}
|
||||
|
||||
private ICredentials _ICredentials = CredentialCache.DefaultCredentials;
|
||||
/// <summary>
|
||||
/// 获取或设置请求的身份验证信息。
|
||||
/// </summary>
|
||||
public ICredentials ICredentials
|
||||
{
|
||||
get { return _ICredentials; }
|
||||
set { _ICredentials = value; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 设置请求将跟随的重定向的最大数目
|
||||
/// </summary>
|
||||
private int _MaximumAutomaticRedirections;
|
||||
|
||||
public int MaximumAutomaticRedirections
|
||||
{
|
||||
get { return _MaximumAutomaticRedirections; }
|
||||
set { _MaximumAutomaticRedirections = value; }
|
||||
}
|
||||
|
||||
private DateTime? _IfModifiedSince = null;
|
||||
/// <summary>
|
||||
/// 获取和设置IfModifiedSince,默认为当前日期和时间
|
||||
/// </summary>
|
||||
public DateTime? IfModifiedSince
|
||||
{
|
||||
get { return _IfModifiedSince; }
|
||||
set { _IfModifiedSince = value; }
|
||||
}
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// Http返回参数类
|
||||
/// </summary>
|
||||
public class HttpResult
|
||||
{
|
||||
private string _Cookie;
|
||||
/// <summary>
|
||||
/// Http请求返回的Cookie
|
||||
/// </summary>
|
||||
public string Cookie
|
||||
{
|
||||
get { return _Cookie; }
|
||||
set { _Cookie = value; }
|
||||
}
|
||||
|
||||
private CookieCollection _CookieCollection;
|
||||
/// <summary>
|
||||
/// Cookie对象集合
|
||||
/// </summary>
|
||||
public CookieCollection CookieCollection
|
||||
{
|
||||
get { return _CookieCollection; }
|
||||
set { _CookieCollection = value; }
|
||||
}
|
||||
private string _html = string.Empty;
|
||||
/// <summary>
|
||||
/// 返回的String类型数据 只有ResultType.String时才返回数据,其它情况为空
|
||||
/// </summary>
|
||||
public string Html
|
||||
{
|
||||
get { return _html; }
|
||||
set { _html = value; }
|
||||
}
|
||||
private byte[] _ResultByte;
|
||||
/// <summary>
|
||||
/// 返回的Byte数组 只有ResultType.Byte时才返回数据,其它情况为空
|
||||
/// </summary>
|
||||
public byte[] ResultByte
|
||||
{
|
||||
get { return _ResultByte; }
|
||||
set { _ResultByte = value; }
|
||||
}
|
||||
private WebHeaderCollection _Header;
|
||||
/// <summary>
|
||||
/// header对象
|
||||
/// </summary>
|
||||
public WebHeaderCollection Header
|
||||
{
|
||||
get { return _Header; }
|
||||
set { _Header = value; }
|
||||
}
|
||||
private string _StatusDescription;
|
||||
/// <summary>
|
||||
/// 返回状态说明
|
||||
/// </summary>
|
||||
public string StatusDescription
|
||||
{
|
||||
get { return _StatusDescription; }
|
||||
set { _StatusDescription = value; }
|
||||
}
|
||||
private HttpStatusCode _StatusCode;
|
||||
/// <summary>
|
||||
/// 返回状态码,默认为OK
|
||||
/// </summary>
|
||||
public HttpStatusCode StatusCode
|
||||
{
|
||||
get { return _StatusCode; }
|
||||
set { _StatusCode = value; }
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 返回类型
|
||||
/// </summary>
|
||||
public enum HttpResultType
|
||||
{
|
||||
/// <summary>
|
||||
/// 表示只返回字符串 只有Html有数据
|
||||
/// </summary>
|
||||
String,
|
||||
/// <summary>
|
||||
/// 表示返回字符串和字节流 ResultByte和Html都有数据返回
|
||||
/// </summary>
|
||||
Byte
|
||||
}
|
||||
/// <summary>
|
||||
/// Post的数据格式默认为string
|
||||
/// </summary>
|
||||
public enum PostDataType
|
||||
{
|
||||
/// <summary>
|
||||
/// 字符串类型,这时编码Encoding可不设置
|
||||
/// </summary>
|
||||
String,
|
||||
/// <summary>
|
||||
/// Byte类型,需要设置PostdataByte参数的值编码Encoding可设置为空
|
||||
/// </summary>
|
||||
Byte,
|
||||
/// <summary>
|
||||
/// 传文件,Postdata必须设置为文件的绝对路径,必须设置Encoding的值
|
||||
/// </summary>
|
||||
FilePath
|
||||
}
|
||||
/// <summary>
|
||||
/// Cookie返回类型
|
||||
/// </summary>
|
||||
public enum ResultCookieType
|
||||
{
|
||||
/// <summary>
|
||||
/// 只返回字符串类型的Cookie
|
||||
/// </summary>
|
||||
String,
|
||||
/// <summary>
|
||||
/// CookieCollection格式的Cookie集合同时也返回String类型的cookie
|
||||
/// </summary>
|
||||
CookieCollection
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
using RestSharp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// 网络请求封装
|
||||
/// </summary>
|
||||
public class HttpTool
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
public static class MyHttpContext
|
||||
{
|
||||
public static IServiceCollection serviceCollection;
|
||||
|
||||
public static Microsoft.AspNetCore.Http.HttpContext current
|
||||
{
|
||||
get
|
||||
{
|
||||
object factory = serviceCollection.BuildServiceProvider().GetService(typeof(IHttpContextAccessor));
|
||||
Microsoft.AspNetCore.Http.HttpContext context = ((HttpContextAccessor)factory).HttpContext;
|
||||
return context;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// 网络操作
|
||||
/// </summary>
|
||||
public class Net
|
||||
{
|
||||
public static string Ip
|
||||
{
|
||||
get
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = string.Empty;
|
||||
if (MyHttpContext.current != null)
|
||||
result = GetWebClientIp();
|
||||
if (string.IsNullOrWhiteSpace(result))
|
||||
result = GetLanIp();
|
||||
return result;
|
||||
}
|
||||
catch (System.Exception)
|
||||
{
|
||||
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取Web客户端的Ip
|
||||
/// </summary>
|
||||
private static string GetWebClientIp()
|
||||
{
|
||||
var ip = GetWebRemoteIp();
|
||||
foreach (var hostAddress in Dns.GetHostAddresses(ip))
|
||||
{
|
||||
if (hostAddress.AddressFamily == AddressFamily.InterNetwork)
|
||||
return hostAddress.ToString();
|
||||
}
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取远程IP
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static string GetWebRemoteIp()
|
||||
{
|
||||
var ip = MyHttpContext.current.Request.Headers["X-Forwarded-For"].FirstOrDefault();
|
||||
if (string.IsNullOrEmpty(ip))
|
||||
{
|
||||
ip = MyHttpContext.current.Connection.RemoteIpAddress.ToString();
|
||||
}
|
||||
return ip;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取局域网IP
|
||||
/// </summary>
|
||||
private static string GetLanIp()
|
||||
{
|
||||
string userIP = "";
|
||||
System.Net.NetworkInformation.NetworkInterface[] fNetworkInterfaces = System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces();
|
||||
foreach (System.Net.NetworkInformation.NetworkInterface adapter in fNetworkInterfaces)
|
||||
{
|
||||
string fRegistryKey = "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\" + adapter.Id + "\\Connection";
|
||||
Microsoft.Win32.RegistryKey rk = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(fRegistryKey, false);
|
||||
if (rk != null)
|
||||
{
|
||||
// 区分 PnpInstanceID
|
||||
// 如果前面有 PCI 就是本机的真实网卡
|
||||
string fPnpInstanceID = rk.GetValue("PnpInstanceID", "").ToString();
|
||||
int fMediaSubType = Convert.ToInt32(rk.GetValue("MediaSubType", 0));
|
||||
if (fPnpInstanceID.Length > 3 &&
|
||||
fPnpInstanceID.Substring(0, 3) == "PCI")
|
||||
{
|
||||
//string fCardType = "物理网卡";
|
||||
System.Net.NetworkInformation.IPInterfaceProperties fIPInterfaceProperties = adapter.GetIPProperties();
|
||||
System.Net.NetworkInformation.UnicastIPAddressInformationCollection UnicastIPAddressInformationCollection = fIPInterfaceProperties.UnicastAddresses;
|
||||
foreach (System.Net.NetworkInformation.UnicastIPAddressInformation UnicastIPAddressInformation in UnicastIPAddressInformationCollection)
|
||||
{
|
||||
if (UnicastIPAddressInformation.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
|
||||
userIP = UnicastIPAddressInformation.Address.ToString(); // Ip 地址
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
return userIP;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// 网络请求封装
|
||||
/// </summary>
|
||||
public class NetRquest
|
||||
{
|
||||
private IHttpClientFactory _clientFactory;
|
||||
public NetRquest(IHttpClientFactory clientFactory)
|
||||
{
|
||||
_clientFactory = clientFactory;
|
||||
}
|
||||
/// <summary>
|
||||
/// Get请求
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<string> GetAsync(string url,string token="")
|
||||
{
|
||||
var client = _clientFactory.CreateClient();
|
||||
//添加请求头
|
||||
if (!string.IsNullOrEmpty(token))
|
||||
{
|
||||
client.DefaultRequestHeaders.Add("token", token);
|
||||
}
|
||||
client.BaseAddress = new Uri(url);
|
||||
//client.DefaultRequestHeaders.Add("Content-Type", "application/json;charset=utf-8");
|
||||
var res = await client.GetStringAsync(url);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||
<DebugType>none</DebugType>
|
||||
<DebugSymbols>false</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="5.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0" />
|
||||
<PackageReference Include="RestSharp" Version="106.11.7" />
|
||||
<PackageReference Include="Serilog" Version="2.10.0" />
|
||||
<PackageReference Include="Serilog.AspNetCore" Version="3.4.0" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="4.1.0" />
|
||||
<PackageReference Include="Serilog.Sinks.Map" Version="1.0.2" />
|
||||
<PackageReference Include="StackExchange.Redis" Version="2.2.4" />
|
||||
<PackageReference Include="System.Drawing.Common" Version="5.0.0" />
|
||||
<PackageReference Include="ZXing.Net" Version="0.16.6" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// 系统用户实体
|
||||
/// </summary>
|
||||
public class OperatorModel
|
||||
{
|
||||
/// <summary>
|
||||
/// 关联的客户ID
|
||||
/// </summary>
|
||||
public Guid BusinessId { get; set; }
|
||||
/// <summary>
|
||||
/// 客户编码
|
||||
/// </summary>
|
||||
public string BusinessCode { get; set; } = "";
|
||||
/// <summary>
|
||||
/// 用户ID
|
||||
/// </summary>
|
||||
public Guid UserId { get; set; }
|
||||
/// <summary>
|
||||
/// 用户实际名称
|
||||
/// </summary>
|
||||
public string RealName { get; set; }
|
||||
/// <summary>
|
||||
/// 角色ID
|
||||
/// </summary>
|
||||
public Guid RoleId { get; set; }
|
||||
/// <summary>
|
||||
/// 登录的IP
|
||||
/// </summary>
|
||||
public string LoginIPAddress { get; set; }
|
||||
/// <summary>
|
||||
/// 登录时间
|
||||
/// </summary>
|
||||
public DateTime LoginTime { get; set; }
|
||||
/// <summary>
|
||||
/// 账户类型
|
||||
/// </summary>
|
||||
public int AccountType { get; set; }
|
||||
/// <summary>
|
||||
/// 是否为超级管理员
|
||||
/// </summary>
|
||||
public bool IsSuper { get; set; } = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
public class OperatorProvider
|
||||
{
|
||||
public static int ExpiresMin = 10080;//60*24*7 ,登录过期时间,单位为分钟
|
||||
public static OperatorProvider Provider
|
||||
{
|
||||
get { return new OperatorProvider(); }
|
||||
}
|
||||
private static readonly string LoginUserKey = Configs.GetString("LoginProviderKey");
|
||||
private static readonly string LoginProvider = Configs.GetString("LoginProvider");
|
||||
|
||||
public OperatorModel GetCurrent()
|
||||
{
|
||||
try
|
||||
{
|
||||
OperatorModel operatorModel = new OperatorModel();
|
||||
if (LoginProvider == "Cookie")
|
||||
{
|
||||
operatorModel = DESEncrypt.Decrypt(WebHelper.GetCookie(LoginUserKey).ToString()).ToObject<OperatorModel>();
|
||||
}
|
||||
else if (LoginProvider == "CookieAndSession")
|
||||
{
|
||||
var user1 = WebHelper.GetSession(LoginUserKey);
|
||||
if (!string.IsNullOrWhiteSpace(user1))
|
||||
{
|
||||
operatorModel = DESEncrypt.Decrypt(user1).ToObject<OperatorModel>();
|
||||
}
|
||||
else
|
||||
{
|
||||
user1 = WebHelper.GetCookie(LoginUserKey);
|
||||
operatorModel = DESEncrypt.Decrypt(user1).ToObject<OperatorModel>();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
operatorModel = DESEncrypt.Decrypt(WebHelper.GetSession(LoginUserKey).ToString()).ToObject<OperatorModel>();
|
||||
}
|
||||
return operatorModel;
|
||||
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public void AddCurrent(OperatorModel operatorModel)
|
||||
{
|
||||
if (LoginProvider == "Cookie")
|
||||
{
|
||||
WebHelper.WriteCookie(LoginUserKey, DESEncrypt.Encrypt(operatorModel.ToJson()), ExpiresMin);
|
||||
}
|
||||
else if (LoginProvider == "CookieAndSession")
|
||||
{
|
||||
WebHelper.WriteCookie(LoginUserKey, DESEncrypt.Encrypt(operatorModel.ToJson()), ExpiresMin);
|
||||
WebHelper.WriteSession(LoginUserKey, DESEncrypt.Encrypt(operatorModel.ToJson()));
|
||||
}
|
||||
else
|
||||
{
|
||||
WebHelper.WriteSession(LoginUserKey, DESEncrypt.Encrypt(operatorModel.ToJson()));
|
||||
}
|
||||
}
|
||||
public void RemoveCurrent()
|
||||
{
|
||||
if (LoginProvider == "Cookie")
|
||||
{
|
||||
WebHelper.RemoveCookie(LoginUserKey.Trim());
|
||||
}
|
||||
else if (LoginProvider == "CookieAndSession")
|
||||
{
|
||||
WebHelper.RemoveCookie(LoginUserKey.Trim());
|
||||
WebHelper.RemoveSession(LoginUserKey.Trim());
|
||||
}
|
||||
else
|
||||
{
|
||||
WebHelper.RemoveSession(LoginUserKey.Trim());
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 系统内置管理员以便维护
|
||||
/// </summary>
|
||||
/// <param name="usernmae"></param>
|
||||
/// <param name="password"></param>
|
||||
/// <param name="issupper"></param>
|
||||
public bool IsSupperAdmin(string usernmae, string password)
|
||||
{
|
||||
return usernmae.Equals("liuzl") && password.Equals("18638204898");
|
||||
}
|
||||
|
||||
public void BuildLogin()
|
||||
{
|
||||
var current = GetCurrent();
|
||||
if (current != null)
|
||||
AddCurrent(current);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,175 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
public class PageData<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前页码
|
||||
/// </summary>
|
||||
public int CurrentPage { get; set; }
|
||||
/// <summary>
|
||||
/// 总数
|
||||
/// </summary>
|
||||
public int TotalNum { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 实体对象
|
||||
/// </summary>
|
||||
public List<T> Items { get; set; }
|
||||
/// <summary>
|
||||
/// 总页数
|
||||
/// </summary>
|
||||
public int TotalPageCount { get; set; }
|
||||
|
||||
public Object Total { get; set; }
|
||||
}
|
||||
|
||||
public class PageDataAPI<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// 页码
|
||||
/// </summary>
|
||||
public int pagesize { get; set; }
|
||||
/// <summary>
|
||||
/// 总页数
|
||||
/// </summary>
|
||||
public int totalpage { get; set; }
|
||||
/// <summary>
|
||||
/// 总数
|
||||
/// </summary>
|
||||
public int totalnum { get; set; }
|
||||
/// <summary>
|
||||
/// 项
|
||||
/// </summary>
|
||||
public List<T> items { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分页查询返回值
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public class PageParms<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前页码
|
||||
/// </summary>
|
||||
public int page { get; set; }
|
||||
/// <summary>
|
||||
/// 总数
|
||||
/// </summary>
|
||||
public int totalnum { get; set; }
|
||||
/// <summary>
|
||||
/// 每页显示的数量
|
||||
/// </summary>
|
||||
public int limit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 实体对象
|
||||
/// </summary>
|
||||
public List<T> Items { get; set; }
|
||||
/// <summary>
|
||||
/// 总页数
|
||||
/// </summary>
|
||||
public int totalpage
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.totalnum == 0 ? 0 : Convert.ToInt32(Math.Ceiling(totalnum * 1.0 / limit));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分页查询
|
||||
/// </summary>
|
||||
public class QueryParams
|
||||
{
|
||||
/// <summary>
|
||||
/// 排序方式,asc-正序,desc-倒序
|
||||
/// </summary>
|
||||
public string order { get; set; } = "desc";
|
||||
/// <summary>
|
||||
/// 排序字段
|
||||
/// </summary>
|
||||
public string sort { get; set; } = "createtime";
|
||||
/// <summary>
|
||||
/// 当前页
|
||||
/// </summary>
|
||||
public int offset { get; set; }
|
||||
/// <summary>
|
||||
/// 每页显示的数量
|
||||
/// </summary>
|
||||
public int limit { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 多条件查询参数
|
||||
/// </summary>
|
||||
public List<QueryConditional> queryParam { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 分页查询的参数
|
||||
/// </summary>
|
||||
public class ParamQuery
|
||||
{
|
||||
/// <summary>
|
||||
/// 页数
|
||||
/// </summary>
|
||||
public int page { get; set; } = 1;
|
||||
/// <summary>
|
||||
/// 每页显示的数量
|
||||
/// </summary>
|
||||
public int pagesize { get; set; } = 10;
|
||||
|
||||
/// <summary>
|
||||
/// 排序方式,asc-正序,desc-倒序
|
||||
/// </summary>
|
||||
public string order { get; set; } = "desc";
|
||||
/// <summary>
|
||||
/// 排序字段
|
||||
/// </summary>
|
||||
public string sort { get; set; } = "createtime";
|
||||
/// <summary>
|
||||
/// 关键字
|
||||
/// </summary>
|
||||
public string keyword { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 分页查询返回的值
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public class ParamReturnData<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前页码
|
||||
/// </summary>
|
||||
public int page { get; set; }
|
||||
/// <summary>
|
||||
/// 总数
|
||||
/// </summary>
|
||||
public int totalnum { get; set; }
|
||||
/// <summary>
|
||||
/// 每页显示的数量
|
||||
/// </summary>
|
||||
public int pagesize { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 实体对象
|
||||
/// </summary>
|
||||
public List<T> items { get; set; }
|
||||
/// <summary>
|
||||
/// 总页数
|
||||
/// </summary>
|
||||
public int totalpage
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.totalnum == 0 ? 0 : Convert.ToInt32(Math.Ceiling(totalnum * 1.0 / pagesize));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
using Microsoft.Extensions.Configuration;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Nirvana.Common.RabbitMQ
|
||||
{
|
||||
/// <summary>
|
||||
/// 连接字符串类
|
||||
/// </summary>
|
||||
public class RabbitOption
|
||||
{
|
||||
public RabbitOption(IConfiguration config)
|
||||
{
|
||||
if (config == null)
|
||||
throw new ArgumentException(nameof(config));
|
||||
|
||||
var section = config.GetSection("rabbit");
|
||||
section.Bind(this);
|
||||
}
|
||||
|
||||
public string Uri { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,269 @@
|
|||
using Newtonsoft.Json;
|
||||
using StackExchange.Redis;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
public class Cache : ICache
|
||||
{
|
||||
int Default_Timeout = 600; //默认超时时间(秒)
|
||||
string address;
|
||||
JsonSerializerSettings jsonConfig = new JsonSerializerSettings() { ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore, NullValueHandling = NullValueHandling.Ignore };
|
||||
ConnectionMultiplexer connectionMultiplexer;
|
||||
IDatabase database;
|
||||
|
||||
class CacheObject<T>
|
||||
{
|
||||
public int ExpireTime { get; set; }
|
||||
public bool ForceOutofDate { get; set; }
|
||||
public T Value { get; set; }
|
||||
}
|
||||
|
||||
public Cache()
|
||||
{
|
||||
this.address = Configs.GetString("RedisServer");
|
||||
|
||||
if (this.address == null || string.IsNullOrWhiteSpace(this.address.ToString()))
|
||||
throw new ApplicationException("配置文件中未找到RedisServer的有效配置");
|
||||
connectionMultiplexer = ConnectionMultiplexer.Connect(address);
|
||||
database = connectionMultiplexer.GetDatabase();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 连接超时设置
|
||||
/// </summary>
|
||||
public int TimeOut
|
||||
{
|
||||
get
|
||||
{
|
||||
return Default_Timeout;
|
||||
}
|
||||
set
|
||||
{
|
||||
Default_Timeout = value;
|
||||
}
|
||||
}
|
||||
public object Get(string key)
|
||||
{
|
||||
return Get<object>(key);
|
||||
}
|
||||
|
||||
public T Get<T>(string key)
|
||||
{
|
||||
|
||||
DateTime begin = DateTime.Now;
|
||||
var cacheValue = database.StringGet(key);
|
||||
DateTime endCache = DateTime.Now;
|
||||
var value = default(T);
|
||||
if (!cacheValue.IsNull)
|
||||
{
|
||||
var cacheObject = JsonConvert.DeserializeObject<CacheObject<T>>(cacheValue, jsonConfig);
|
||||
if (!cacheObject.ForceOutofDate)
|
||||
database.KeyExpire(key, new TimeSpan(0, 0, cacheObject.ExpireTime));
|
||||
value = cacheObject.Value;
|
||||
}
|
||||
DateTime endJson = DateTime.Now;
|
||||
return value;
|
||||
}
|
||||
|
||||
public T stringGet<T>(string key)
|
||||
{
|
||||
var cacheValue = database.StringGet(key);
|
||||
var value = default(T);
|
||||
if (!cacheValue.IsNull)
|
||||
{
|
||||
var cacheObject = JsonConvert.DeserializeObject<T>(cacheValue, jsonConfig);
|
||||
value = cacheObject;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public void Insert(string key, object data)
|
||||
{
|
||||
var jsonData = GetJsonData(data, TimeOut, false);
|
||||
database.StringSet(key, jsonData);
|
||||
}
|
||||
|
||||
public void Insert(string key, object data, int cacheTime)
|
||||
{
|
||||
var timeSpan = TimeSpan.FromSeconds(cacheTime);
|
||||
var jsonData = GetJsonData(data, TimeOut, true);
|
||||
database.StringSet(key, jsonData, timeSpan);
|
||||
}
|
||||
|
||||
public void Insert(string key, object data, DateTime cacheTime)
|
||||
{
|
||||
var timeSpan = cacheTime - DateTime.Now;
|
||||
var jsonData = GetJsonData(data, TimeOut, true);
|
||||
database.StringSet(key, jsonData, timeSpan);
|
||||
}
|
||||
|
||||
public void Insert<T>(string key, T data)
|
||||
{
|
||||
var jsonData = GetJsonData<T>(data, TimeOut, false);
|
||||
database.StringSet(key, jsonData);
|
||||
}
|
||||
|
||||
public void Insert<T>(string key, T data, int cacheTime)
|
||||
{
|
||||
var timeSpan = TimeSpan.FromSeconds(cacheTime);
|
||||
var jsonData = GetJsonData<T>(data, TimeOut, true);
|
||||
database.StringSet(key, jsonData, timeSpan);
|
||||
}
|
||||
|
||||
public void Insert<T>(string key, T data, DateTime cacheTime)
|
||||
{
|
||||
var timeSpan = cacheTime - DateTime.Now;
|
||||
var jsonData = GetJsonData<T>(data, TimeOut, true);
|
||||
database.StringSet(key, jsonData, timeSpan);
|
||||
}
|
||||
|
||||
|
||||
string GetJsonData(object data, int cacheTime, bool forceOutOfDate)
|
||||
{
|
||||
var cacheObject = new CacheObject<object>() { Value = data, ExpireTime = cacheTime, ForceOutofDate = forceOutOfDate };
|
||||
return JsonConvert.SerializeObject(data, jsonConfig);//序列化对象
|
||||
}
|
||||
|
||||
string GetJsonData<T>(T data, int cacheTime, bool forceOutOfDate)
|
||||
{
|
||||
var cacheObject = new CacheObject<T>() { Value = data, ExpireTime = cacheTime, ForceOutofDate = forceOutOfDate };
|
||||
return JsonConvert.SerializeObject(data, jsonConfig);//序列化对象
|
||||
}
|
||||
/// <summary>
|
||||
/// 删除
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
public void Remove(string key)
|
||||
{
|
||||
database.KeyDelete(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断key是否存在
|
||||
/// </summary>
|
||||
public bool Exists(string key)
|
||||
{
|
||||
return database.KeyExists(key);
|
||||
}
|
||||
/// <summary>
|
||||
/// 判断该字段是否存在hash中
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="field"></param>
|
||||
/// <returns></returns>
|
||||
public bool HashExists(string key, string field)
|
||||
{
|
||||
return database.HashExists(key, field);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从 hash 中移除指定字段
|
||||
/// </summary>
|
||||
/// <param name="redisKey"></param>
|
||||
/// <param name="hashField"></param>
|
||||
/// <returns></returns>
|
||||
public bool HashDelete(string redisKey, string hashField)
|
||||
{
|
||||
return database.HashDelete(redisKey, hashField);
|
||||
}
|
||||
/// <summary>
|
||||
/// 从 hash 中移除指定字段
|
||||
/// </summary>
|
||||
/// <param name="redisKey"></param>
|
||||
/// <param name="hashField"></param>
|
||||
/// <returns></returns>
|
||||
public long HashDelete(string redisKey, IEnumerable<RedisValue> hashField)
|
||||
{
|
||||
return database.HashDelete(redisKey, hashField.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在 hash 设定值
|
||||
/// </summary>
|
||||
/// <param name="redisKey"></param>
|
||||
/// <param name="hashField"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public bool HashSet(string redisKey, string hashField, string value)
|
||||
{
|
||||
return database.HashSet(redisKey, hashField, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在 hash 中设定值
|
||||
/// </summary>
|
||||
/// <param name="redisKey"></param>
|
||||
/// <param name="hashFields"></param>
|
||||
public void HashSet(string redisKey, IEnumerable<HashEntry> hashFields)
|
||||
{
|
||||
database.HashSet(redisKey, hashFields.ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 在 hash 中获取值
|
||||
/// </summary>
|
||||
/// <param name="redisKey"></param>
|
||||
/// <param name="hashField"></param>
|
||||
/// <returns></returns>
|
||||
public RedisValue HashGet(string redisKey, string hashField)
|
||||
{
|
||||
return database.HashGet(redisKey, hashField);
|
||||
}
|
||||
/// <summary>
|
||||
/// 在 hash 中获取值
|
||||
/// </summary>
|
||||
/// <param name="redisKey"></param>
|
||||
/// <param name="hashField"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public RedisValue[] HashGet(string redisKey, RedisValue[] hashField, string value)
|
||||
{
|
||||
return database.HashGet(redisKey, hashField);
|
||||
}
|
||||
/// <summary>
|
||||
/// 从 hash 返回所有的字段值
|
||||
/// </summary>
|
||||
/// <param name="redisKey"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<RedisValue> HashKeys(string redisKey)
|
||||
{
|
||||
return database.HashKeys(redisKey);
|
||||
}
|
||||
/// <summary>
|
||||
/// 返回 hash 中的所有值
|
||||
/// </summary>
|
||||
/// <param name="redisKey"></param>
|
||||
/// <returns></returns>
|
||||
public RedisValue[] HashValues(string redisKey)
|
||||
{
|
||||
return database.HashValues(redisKey);
|
||||
}
|
||||
/// <summary>
|
||||
/// 在 hash 设定值(序列化)
|
||||
/// </summary>
|
||||
/// <param name="redisKey"></param>
|
||||
/// <param name="hashField"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
//public bool HashSet<T>(string redisKey, string hashField, T value)
|
||||
//{
|
||||
// var json = Serialize(value);
|
||||
// return database.HashSet(redisKey, hashField, json);
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// 在 hash 中获取值(反序列化)
|
||||
/// </summary>
|
||||
/// <param name="redisKey"></param>
|
||||
/// <param name="hashField"></param>
|
||||
/// <returns></returns>
|
||||
//public T HashGet<T>(string redisKey, string hashField)
|
||||
//{
|
||||
// return Deserialize<T>(database.HashGet(redisKey, hashField));
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
using StackExchange.Redis;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
public interface ICache
|
||||
{
|
||||
/// <summary>
|
||||
/// 缓存过期时间
|
||||
/// </summary>
|
||||
int TimeOut { set; get; }
|
||||
/// <summary>
|
||||
/// 获得指定键的缓存值
|
||||
/// </summary>
|
||||
/// <param name="key">缓存键</param>
|
||||
/// <returns>缓存值</returns>
|
||||
object Get(string key);
|
||||
/// <summary>
|
||||
/// 获得指定键的缓存值
|
||||
/// </summary>
|
||||
T Get<T>(string key);
|
||||
|
||||
T stringGet<T>(string key);
|
||||
/// <summary>
|
||||
/// 从缓存中移除指定键的缓存值
|
||||
/// </summary>
|
||||
/// <param name="key">缓存键</param>
|
||||
void Remove(string key);
|
||||
/// <summary>
|
||||
/// 清空所有缓存对象
|
||||
/// </summary>
|
||||
//void Clear();
|
||||
/// <summary>
|
||||
/// 将指定键的对象添加到缓存中
|
||||
/// </summary>
|
||||
/// <param name="key">缓存键</param>
|
||||
/// <param name="data">缓存值</param>
|
||||
void Insert(string key, object data);
|
||||
/// <summary>
|
||||
/// 将指定键的对象添加到缓存中
|
||||
/// </summary>
|
||||
/// <param name="key">缓存键</param>
|
||||
/// <param name="data">缓存值</param>
|
||||
void Insert<T>(string key, T data);
|
||||
/// <summary>
|
||||
/// 将指定键的对象添加到缓存中,并指定过期时间
|
||||
/// </summary>
|
||||
/// <param name="key">缓存键</param>
|
||||
/// <param name="data">缓存值</param>
|
||||
/// <param name="cacheTime">缓存过期时间(秒钟)</param>
|
||||
void Insert(string key, object data, int cacheTime);
|
||||
|
||||
/// <summary>
|
||||
/// 将指定键的对象添加到缓存中,并指定过期时间
|
||||
/// </summary>
|
||||
/// <param name="key">缓存键</param>
|
||||
/// <param name="data">缓存值</param>
|
||||
/// <param name="cacheTime">缓存过期时间(秒钟)</param>
|
||||
void Insert<T>(string key, T data, int cacheTime);
|
||||
/// <summary>
|
||||
/// 将指定键的对象添加到缓存中,并指定过期时间
|
||||
/// </summary>
|
||||
/// <param name="key">缓存键</param>
|
||||
/// <param name="data">缓存值</param>
|
||||
/// <param name="cacheTime">缓存过期时间</param>
|
||||
void Insert(string key, object data, DateTime cacheTime);
|
||||
/// <summary>
|
||||
/// 将指定键的对象添加到缓存中,并指定过期时间
|
||||
/// </summary>
|
||||
/// <param name="key">缓存键</param>
|
||||
/// <param name="data">缓存值</param>
|
||||
/// <param name="cacheTime">缓存过期时间</param>
|
||||
void Insert<T>(string key, T data, DateTime cacheTime);
|
||||
/// <summary>
|
||||
/// 判断key是否存在
|
||||
/// </summary>
|
||||
bool Exists(string key);
|
||||
|
||||
/// <summary>
|
||||
/// 判断该字段是否存在hash中
|
||||
/// </summary>
|
||||
/// <param name="key"></param>
|
||||
/// <param name="field"></param>
|
||||
/// <returns></returns>
|
||||
bool HashExists(string key, string field);
|
||||
/// <summary>
|
||||
/// 从 hash 中移除指定字段
|
||||
/// </summary>
|
||||
/// <param name="redisKey"></param>
|
||||
/// <param name="hashField"></param>
|
||||
/// <returns></returns>
|
||||
bool HashDelete(string redisKey, string hashField);
|
||||
|
||||
/// <summary>
|
||||
/// 从 hash 中移除指定字段
|
||||
/// </summary>
|
||||
/// <param name="redisKey"></param>
|
||||
/// <param name="hashField"></param>
|
||||
/// <returns></returns>
|
||||
long HashDelete(string redisKey, IEnumerable<RedisValue> hashField);
|
||||
/// <summary>
|
||||
/// 在 hash 设定值
|
||||
/// </summary>
|
||||
/// <param name="redisKey"></param>
|
||||
/// <param name="hashField"></param>
|
||||
/// <param name="value">
|
||||
bool HashSet(string redisKey, string hashField, string value);
|
||||
/// <summary>
|
||||
/// 在 hash 中设定值
|
||||
/// </summary>
|
||||
/// <param name="redisKey"></param>
|
||||
/// <param name="hashFields"></param>
|
||||
void HashSet(string redisKey, IEnumerable<HashEntry> hashFields);
|
||||
/// <summary>
|
||||
/// 在 hash 中获取值
|
||||
/// </summary>
|
||||
/// <param name="redisKey"></param>
|
||||
/// <param name="hashField"></param>
|
||||
/// <returns></returns>
|
||||
RedisValue HashGet(string redisKey, string hashField);
|
||||
|
||||
/// <summary>
|
||||
/// 在 hash 中获取值
|
||||
/// </summary>
|
||||
/// <param name="redisKey"></param>
|
||||
/// <param name="hashField"></param>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
RedisValue[] HashGet(string redisKey, RedisValue[] hashField, string value);
|
||||
|
||||
IEnumerable<RedisValue> HashKeys(string redisKey);
|
||||
|
||||
RedisValue[] HashValues(string redisKey);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,251 @@
|
|||
using Newtonsoft.Json;
|
||||
using StackExchange.Redis;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
public static class RedisHelpers
|
||||
{
|
||||
private static object cacheLocker = new object();//缓存锁对象
|
||||
private static ICache cache = null;//缓存接口
|
||||
static RedisHelpers()
|
||||
{
|
||||
Load();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载缓存
|
||||
/// </summary>
|
||||
/// <exception cref=""></exception>
|
||||
private static void Load()
|
||||
{
|
||||
try
|
||||
{
|
||||
cache = new Cache();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Log.Error(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public static ICache GetCache()
|
||||
{
|
||||
return cache;
|
||||
}
|
||||
|
||||
/// 缓存过期时间
|
||||
/// </summary>
|
||||
public static int TimeOut
|
||||
{
|
||||
get
|
||||
{
|
||||
return cache.TimeOut;
|
||||
}
|
||||
set
|
||||
{
|
||||
lock (cacheLocker)
|
||||
{
|
||||
cache.TimeOut = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得指定键的缓存值
|
||||
/// </summary>
|
||||
/// <param name="key">缓存键</param>
|
||||
/// <returns>缓存值</returns>
|
||||
public static object Get(string key)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(key))
|
||||
return null;
|
||||
return cache.Get(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获得指定键的缓存值
|
||||
/// </summary>
|
||||
/// <param name="key">缓存键</param>
|
||||
/// <returns>缓存值</returns>
|
||||
public static T Get<T>(string key)
|
||||
{
|
||||
return cache.Get<T>(key);
|
||||
}
|
||||
|
||||
public static T stringGet<T>(string key)
|
||||
{
|
||||
return cache.stringGet<T>(key);
|
||||
}
|
||||
|
||||
public static string stringGet(string key)
|
||||
{
|
||||
return stringGet<string>(key);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将指定键的对象添加到缓存中
|
||||
/// </summary>
|
||||
/// <param name="key">缓存键</param>
|
||||
/// <param name="data">缓存值</param>
|
||||
public static void Insert(string key, object data)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(key) || data == null)
|
||||
return;
|
||||
//lock (cacheLocker)
|
||||
{
|
||||
cache.Insert(key, data);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 将指定键的对象添加到缓存中
|
||||
/// </summary>
|
||||
/// <param name="key">缓存键</param>
|
||||
/// <param name="data">缓存值</param>
|
||||
public static void Insert<T>(string key, T data)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(key) || data == null)
|
||||
return;
|
||||
//lock (cacheLocker)
|
||||
{
|
||||
cache.Insert<T>(key, data);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 将指定键的对象添加到缓存中,并指定过期时间
|
||||
/// </summary>
|
||||
/// <param name="key">缓存键</param>
|
||||
/// <param name="data">缓存值</param>
|
||||
/// <param name="cacheTime">缓存过期时间(秒)</param>
|
||||
public static void Insert(string key, object data, int cacheTime)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(key) && data != null)
|
||||
{
|
||||
//lock (cacheLocker)
|
||||
{
|
||||
cache.Insert(key, data, cacheTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将指定键的对象添加到缓存中,并指定过期时间
|
||||
/// </summary>
|
||||
/// <param name="key">缓存键</param>
|
||||
/// <param name="data">缓存值</param>
|
||||
/// <param name="cacheTime">缓存过期时间(秒)</param>
|
||||
public static void Insert<T>(string key, T data, int cacheTime)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(key) && data != null)
|
||||
{
|
||||
//lock (cacheLocker)
|
||||
{
|
||||
cache.Insert<T>(key, data, cacheTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将指定键的对象添加到缓存中,并指定过期时间
|
||||
/// </summary>
|
||||
/// <param name="key">缓存键</param>
|
||||
/// <param name="data">缓存值</param>
|
||||
/// <param name="cacheTime">缓存过期时间</param>
|
||||
public static void Insert(string key, object data, DateTime cacheTime)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(key) && data != null)
|
||||
{
|
||||
//lock (cacheLocker)
|
||||
{
|
||||
cache.Insert(key, data, cacheTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将指定键的对象添加到缓存中,并指定过期时间
|
||||
/// </summary>
|
||||
/// <param name="key">缓存键</param>
|
||||
/// <param name="data">缓存值</param>
|
||||
/// <param name="cacheTime">缓存过期时间</param>
|
||||
public static void Insert<T>(string key, T data, DateTime cacheTime)
|
||||
{
|
||||
if (!string.IsNullOrWhiteSpace(key) && data != null)
|
||||
{
|
||||
//lock (cacheLocker)
|
||||
{
|
||||
cache.Insert<T>(key, data, cacheTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从缓存中移除指定键的缓存值
|
||||
/// </summary>
|
||||
/// <param name="key">缓存键</param>
|
||||
public static void Remove(string key)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(key))
|
||||
return;
|
||||
lock (cacheLocker)
|
||||
{
|
||||
cache.Remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断key是否存在
|
||||
/// </summary>
|
||||
public static bool Exists(string key)
|
||||
{
|
||||
return cache.Exists(key);
|
||||
}
|
||||
|
||||
#region Hash操作
|
||||
public static bool HashExists(string key, string field)
|
||||
{
|
||||
return cache.HashExists(key, field);
|
||||
}
|
||||
|
||||
public static bool HashDelete(string key, string field)
|
||||
{
|
||||
return cache.HashDelete(key, field);
|
||||
}
|
||||
|
||||
public static bool HashSet(string key, string field, string value)
|
||||
{
|
||||
return cache.HashSet(key, field, value);
|
||||
}
|
||||
|
||||
public static void HashSet(string key, IEnumerable<HashEntry> hashFields)
|
||||
{
|
||||
cache.HashSet(key, hashFields);
|
||||
}
|
||||
|
||||
public static object HashGet(string key, string field)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(key))
|
||||
return null;
|
||||
return cache.HashGet(key, field);
|
||||
}
|
||||
|
||||
public static List<T> HashValues<T>(string key)
|
||||
{
|
||||
List<T> result = new List<T>();
|
||||
RedisValue[] arr = cache.HashValues(key);
|
||||
foreach (var item in arr)
|
||||
{
|
||||
if (!item.IsNullOrEmpty)
|
||||
{
|
||||
result.Add(JsonConvert.DeserializeObject<T>(item));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// AES加密、解密帮助类
|
||||
/// </summary>
|
||||
public class AESEncrypt
|
||||
{
|
||||
/// <summary>
|
||||
/// 默认密钥-密钥的长度必须是32
|
||||
/// </summary>
|
||||
private static string PublicKey = "liuzl_ybhdmob_19";
|
||||
/// <summary>
|
||||
/// 默认向量
|
||||
/// </summary>
|
||||
private const string Iv = "liuzlaiweimob019";
|
||||
|
||||
private static char[] base64CodeArray = new char[]
|
||||
{
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '='
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// AES加密
|
||||
/// </summary>
|
||||
/// <param name="str">需要加密字符串</param>
|
||||
/// <returns>加密后字符串</returns>
|
||||
public static String Encrypt(string str)
|
||||
{
|
||||
return Encrypt(str, PublicKey);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AES解密
|
||||
/// </summary>
|
||||
/// <param name="str">需要解密字符串</param>
|
||||
/// <returns>解密后字符串</returns>
|
||||
public static String Decrypt(string str)
|
||||
{
|
||||
return Decrypt(str, PublicKey);
|
||||
}
|
||||
/// <summary>
|
||||
/// AES加密
|
||||
/// </summary>
|
||||
/// <param name="str">需要加密的字符串</param>
|
||||
/// <param name="key">32位密钥</param>
|
||||
/// <returns>加密后的字符串</returns>
|
||||
public static string Encrypt(string str, string key)
|
||||
{
|
||||
Byte[] keyArray = System.Text.Encoding.UTF8.GetBytes(key);
|
||||
Byte[] toEncryptArray = System.Text.Encoding.UTF8.GetBytes(str);
|
||||
var rijndael = new System.Security.Cryptography.RijndaelManaged();
|
||||
rijndael.Key = keyArray;
|
||||
rijndael.Mode = System.Security.Cryptography.CipherMode.ECB;
|
||||
rijndael.Padding = System.Security.Cryptography.PaddingMode.PKCS7;
|
||||
rijndael.IV = System.Text.Encoding.UTF8.GetBytes(Iv);
|
||||
System.Security.Cryptography.ICryptoTransform cTransform = rijndael.CreateEncryptor();
|
||||
Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
|
||||
return Convert.ToBase64String(resultArray, 0, resultArray.Length);
|
||||
}
|
||||
/// <summary>
|
||||
/// AES解密
|
||||
/// </summary>
|
||||
/// <param name="str">需要解密的字符串</param>
|
||||
/// <param name="key">32位密钥</param>
|
||||
/// <returns>解密后的字符串</returns>
|
||||
public static string Decrypt(string str, string key)
|
||||
{
|
||||
try
|
||||
{
|
||||
Byte[] keyArray = System.Text.Encoding.UTF8.GetBytes(key);
|
||||
//过滤特殊字符
|
||||
string dummyData = str.Trim().Replace("%", "").Replace(",", "").Replace(" ", "+");
|
||||
if (dummyData.Length % 4 > 0)
|
||||
{
|
||||
dummyData = dummyData.PadRight(dummyData.Length + 4 - dummyData.Length % 4, '=');
|
||||
}
|
||||
Byte[] toEncryptArray = Convert.FromBase64String(dummyData);
|
||||
var rijndael = new System.Security.Cryptography.RijndaelManaged();
|
||||
rijndael.Key = keyArray;
|
||||
rijndael.Mode = System.Security.Cryptography.CipherMode.ECB;
|
||||
rijndael.Padding = System.Security.Cryptography.PaddingMode.PKCS7;
|
||||
rijndael.IV = System.Text.Encoding.UTF8.GetBytes(Iv);
|
||||
System.Security.Cryptography.ICryptoTransform cTransform = rijndael.CreateDecryptor();
|
||||
Byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
|
||||
return System.Text.Encoding.UTF8.GetString(resultArray);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsBase64(string base64Str)
|
||||
{
|
||||
byte[] bytes = null;
|
||||
return IsBase64(base64Str, out bytes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否base64字符串
|
||||
/// </summary>
|
||||
/// <param name="base64Str">要判断的字符串</param>
|
||||
/// <param name="bytes">字符串转换成的字节数组</param>
|
||||
/// <returns></returns>
|
||||
private static bool IsBase64(string base64Str, out byte[] bytes)
|
||||
{
|
||||
//string strRegex = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$";
|
||||
bytes = null;
|
||||
if (string.IsNullOrEmpty(base64Str))
|
||||
return false;
|
||||
else
|
||||
{
|
||||
if (base64Str.Contains(","))
|
||||
base64Str = base64Str.Split(',')[1];
|
||||
if (base64Str.Length % 4 != 0)
|
||||
return false;
|
||||
if (base64Str.Any(c => !base64CodeArray.Contains(c)))
|
||||
return false;
|
||||
}
|
||||
try
|
||||
{
|
||||
bytes = Convert.FromBase64String(base64Str);
|
||||
return true;
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// DES加密、解密帮助类
|
||||
/// </summary>
|
||||
public class DESEncrypt
|
||||
{
|
||||
private static string DESKey = "yb_desencrypt_2019";
|
||||
|
||||
#region ========加密========
|
||||
/// <summary>
|
||||
/// 加密
|
||||
/// </summary>
|
||||
/// <param name="Text"></param>
|
||||
/// <returns></returns>
|
||||
public static string Encrypt(string Text)
|
||||
{
|
||||
return Encrypt(Text, DESKey);
|
||||
}
|
||||
/// <summary>
|
||||
/// 加密数据
|
||||
/// </summary>
|
||||
/// <param name="Text"></param>
|
||||
/// <param name="sKey"></param>
|
||||
/// <returns></returns>
|
||||
public static string Encrypt(string Text, string sKey)
|
||||
{
|
||||
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
|
||||
byte[] inputByteArray;
|
||||
inputByteArray = Encoding.Default.GetBytes(Text);
|
||||
|
||||
des.Key = ASCIIEncoding.ASCII.GetBytes(Md5.MD5Encrypt(sKey, new UTF8Encoding()).Substring(0, 8));
|
||||
des.IV = ASCIIEncoding.ASCII.GetBytes(Md5.MD5Encrypt(sKey, new UTF8Encoding()).Substring(0, 8));
|
||||
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>
|
||||
/// 解密数据
|
||||
/// </summary>
|
||||
/// <param name="Text"></param>
|
||||
/// <param name="sKey"></param>
|
||||
/// <returns></returns>
|
||||
public static string Decrypt(string Text, string sKey)
|
||||
{
|
||||
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
|
||||
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(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
|
||||
//des.IV = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
|
||||
des.Key = ASCIIEncoding.ASCII.GetBytes(Md5.MD5Encrypt(sKey, new UTF8Encoding()).Substring(0, 8));
|
||||
des.IV = ASCIIEncoding.ASCII.GetBytes(Md5.MD5Encrypt(sKey, new UTF8Encoding()).Substring(0, 8));
|
||||
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
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
/// <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)
|
||||
{
|
||||
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
|
||||
strEncrypt = System.BitConverter.ToString(md5.ComputeHash(System.Text.UTF8Encoding.Default.GetBytes(str)), 4, 8).Replace("-", "");
|
||||
}
|
||||
|
||||
if (code == 32)
|
||||
{
|
||||
MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
|
||||
strEncrypt = System.BitConverter.ToString(md5.ComputeHash(System.Text.Encoding.Default.GetBytes(str))).Replace("-", "");
|
||||
}
|
||||
|
||||
return strEncrypt;
|
||||
}
|
||||
/// <summary>
|
||||
/// MD5加密
|
||||
/// </summary>
|
||||
/// <param name="input">需要加密的字符串</param>
|
||||
/// <param name="encode">字符的编码</param>
|
||||
/// <returns></returns>
|
||||
public static string MD5Encrypt(string input, Encoding encode)
|
||||
{
|
||||
if (string.IsNullOrEmpty(input))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider();
|
||||
byte[] data = md5Hasher.ComputeHash(encode.GetBytes(input));
|
||||
StringBuilder sBuilder = new StringBuilder();
|
||||
for (int i = 0; i < data.Length; i++)
|
||||
{
|
||||
sBuilder.Append(data[i].ToString("X2"));
|
||||
}
|
||||
return sBuilder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,418 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// RSA加密解密及RSA签名和验证
|
||||
/// </summary>
|
||||
public class RSACryption
|
||||
{
|
||||
public RSACryption()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
#region RSA加密解密
|
||||
|
||||
#region RSA的密钥产生
|
||||
|
||||
/// <summary>
|
||||
/// 生成密钥
|
||||
/// </summary>
|
||||
/// <param name="xmlKeys"></param>
|
||||
/// <param name=""></param>
|
||||
public void RSAKey(out string xmlKeys, out string xmlPublicKey)
|
||||
{
|
||||
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
|
||||
xmlKeys = rsa.ToXmlString(true);
|
||||
xmlPublicKey = rsa.ToXmlString(false);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region RSA的加密函数
|
||||
//##############################################################################
|
||||
//RSA 方式加密
|
||||
//说明KEY必须是XML的行式,返回的是字符串
|
||||
//在有一点需要说明!!该加密方式有 长度 限制的!!
|
||||
//##############################################################################
|
||||
/// <summary>
|
||||
/// RSA加密 string
|
||||
/// </summary>
|
||||
/// <param name="xmlPublicKey"></param>
|
||||
/// <param name="m_strEncryptString"></param>
|
||||
/// <returns></returns>
|
||||
public string RSAEncrypt(string xmlPublicKey, string m_strEncryptString)
|
||||
{
|
||||
byte[] PlainTextBArray;
|
||||
byte[] CypherTextBArray;
|
||||
string Result;
|
||||
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
|
||||
rsa.FromXmlString(xmlPublicKey);
|
||||
PlainTextBArray = (new UnicodeEncoding()).GetBytes(m_strEncryptString);
|
||||
CypherTextBArray = rsa.Encrypt(PlainTextBArray, false);
|
||||
Result = Convert.ToBase64String(CypherTextBArray);
|
||||
return Result;
|
||||
}
|
||||
/// <summary>
|
||||
/// RSA加密 byte[]
|
||||
/// </summary>
|
||||
/// <param name="xmlPublicKey"></param>
|
||||
/// <param name="EncryptString"></param>
|
||||
/// <returns></returns>
|
||||
public string RSAEncrypt(string xmlPublicKey, byte[] EncryptString)
|
||||
{
|
||||
|
||||
byte[] CypherTextBArray;
|
||||
string Result;
|
||||
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
|
||||
rsa.FromXmlString(xmlPublicKey);
|
||||
CypherTextBArray = rsa.Encrypt(EncryptString, false);
|
||||
Result = Convert.ToBase64String(CypherTextBArray);
|
||||
return Result;
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region RSA的解密函数
|
||||
|
||||
/// <summary>
|
||||
/// RSA的解密函数 string
|
||||
/// </summary>
|
||||
/// <param name="xmlPrivateKey"></param>
|
||||
/// <param name="m_strDecryptString"></param>
|
||||
/// <returns></returns>
|
||||
public string RSADecrypt(string xmlPrivateKey, string m_strDecryptString)
|
||||
{
|
||||
byte[] PlainTextBArray;
|
||||
byte[] DypherTextBArray;
|
||||
string Result;
|
||||
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
|
||||
rsa.FromXmlString(xmlPrivateKey);
|
||||
PlainTextBArray = Convert.FromBase64String(m_strDecryptString);
|
||||
DypherTextBArray = rsa.Decrypt(PlainTextBArray, false);
|
||||
Result = (new UnicodeEncoding()).GetString(DypherTextBArray);
|
||||
return Result;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// RSA的解密函数 byte
|
||||
/// </summary>
|
||||
/// <param name="xmlPrivateKey"></param>
|
||||
/// <param name="DecryptString"></param>
|
||||
/// <returns></returns>
|
||||
public string RSADecrypt(string xmlPrivateKey, byte[] DecryptString)
|
||||
{
|
||||
byte[] DypherTextBArray;
|
||||
string Result;
|
||||
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
|
||||
rsa.FromXmlString(xmlPrivateKey);
|
||||
DypherTextBArray = rsa.Decrypt(DecryptString, false);
|
||||
Result = (new UnicodeEncoding()).GetString(DypherTextBArray);
|
||||
return Result;
|
||||
|
||||
}
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region RSA数字签名
|
||||
#region 获取Hash描述表
|
||||
|
||||
/// <summary>
|
||||
/// 获取Hash描述表
|
||||
/// </summary>
|
||||
/// <param name="m_strSource">待签名的字符串</param>
|
||||
/// <param name="HashData">Hash描述</param>
|
||||
/// <returns></returns>
|
||||
public bool GetHash(string m_strSource, ref byte[] HashData)
|
||||
{
|
||||
//从字符串中取得Hash描述
|
||||
byte[] Buffer;
|
||||
HashAlgorithm MD5 = HashAlgorithm.Create("MD5");
|
||||
Buffer = System.Text.Encoding.GetEncoding("GB2312").GetBytes(m_strSource);
|
||||
HashData = MD5.ComputeHash(Buffer);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取Hash描述表
|
||||
/// </summary>
|
||||
/// <param name="m_strSource">待签名的字符串</param>
|
||||
/// <param name="strHashData">Hash描述</param>
|
||||
/// <returns></returns>
|
||||
public bool GetHash(string m_strSource, ref string strHashData)
|
||||
{
|
||||
|
||||
//从字符串中取得Hash描述
|
||||
byte[] Buffer;
|
||||
byte[] HashData;
|
||||
HashAlgorithm MD5 = HashAlgorithm.Create("MD5");
|
||||
Buffer = System.Text.Encoding.Default.GetBytes(m_strSource);
|
||||
HashData = MD5.ComputeHash(Buffer);
|
||||
|
||||
strHashData = Convert.ToBase64String(HashData);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取Hash描述表
|
||||
/// </summary>
|
||||
/// <param name="objFile">待签名的文件</param>
|
||||
/// <param name="strHashData">Hash描述</param>
|
||||
/// <returns></returns>
|
||||
public bool GetHash(System.IO.FileStream objFile, ref string strHashData)
|
||||
{
|
||||
|
||||
//从文件中取得Hash描述
|
||||
byte[] HashData;
|
||||
HashAlgorithm MD5 = HashAlgorithm.Create("MD5");
|
||||
HashData = MD5.ComputeHash(objFile);
|
||||
objFile.Close();
|
||||
|
||||
strHashData = Convert.ToBase64String(HashData);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
#endregion
|
||||
#region RSA签名
|
||||
/// <summary>
|
||||
/// RSA签名
|
||||
/// </summary>
|
||||
/// <param name="p_strKeyPrivate">私钥</param>
|
||||
/// <param name="HashbyteSignature">待签名Hash描述</param>
|
||||
/// <param name="EncryptedSignatureData">签名后的值</param>
|
||||
/// <returns></returns>
|
||||
public bool SignatureFormatter(string p_strKeyPrivate, byte[] HashbyteSignature, ref byte[] EncryptedSignatureData)
|
||||
{
|
||||
|
||||
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
|
||||
|
||||
RSA.FromXmlString(p_strKeyPrivate);
|
||||
RSAPKCS1SignatureFormatter RSAFormatter = new RSAPKCS1SignatureFormatter(RSA);
|
||||
//设置签名的算法为MD5
|
||||
RSAFormatter.SetHashAlgorithm("MD5");
|
||||
//执行签名
|
||||
EncryptedSignatureData = RSAFormatter.CreateSignature(HashbyteSignature);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// RSA签名
|
||||
/// </summary>
|
||||
/// <param name="p_strKeyPrivate">私钥</param>
|
||||
/// <param name="HashbyteSignature">待签名Hash描述</param>
|
||||
/// <param name="m_strEncryptedSignatureData">签名后的值</param>
|
||||
/// <returns></returns>
|
||||
public bool SignatureFormatter(string p_strKeyPrivate, byte[] HashbyteSignature, ref string m_strEncryptedSignatureData)
|
||||
{
|
||||
|
||||
byte[] EncryptedSignatureData;
|
||||
|
||||
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
|
||||
|
||||
RSA.FromXmlString(p_strKeyPrivate);
|
||||
RSAPKCS1SignatureFormatter RSAFormatter = new RSAPKCS1SignatureFormatter(RSA);
|
||||
//设置签名的算法为MD5
|
||||
RSAFormatter.SetHashAlgorithm("MD5");
|
||||
//执行签名
|
||||
EncryptedSignatureData = RSAFormatter.CreateSignature(HashbyteSignature);
|
||||
|
||||
m_strEncryptedSignatureData = Convert.ToBase64String(EncryptedSignatureData);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// RSA签名
|
||||
/// </summary>
|
||||
/// <param name="p_strKeyPrivate">私钥</param>
|
||||
/// <param name="m_strHashbyteSignature">待签名Hash描述</param>
|
||||
/// <param name="EncryptedSignatureData">签名后的值</param>
|
||||
/// <returns></returns>
|
||||
public bool SignatureFormatter(string p_strKeyPrivate, string m_strHashbyteSignature, ref byte[] EncryptedSignatureData)
|
||||
{
|
||||
|
||||
byte[] HashbyteSignature;
|
||||
|
||||
HashbyteSignature = Convert.FromBase64String(m_strHashbyteSignature);
|
||||
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
|
||||
|
||||
RSA.FromXmlString(p_strKeyPrivate);
|
||||
RSAPKCS1SignatureFormatter RSAFormatter = new RSAPKCS1SignatureFormatter(RSA);
|
||||
//设置签名的算法为MD5
|
||||
RSAFormatter.SetHashAlgorithm("MD5");
|
||||
//执行签名
|
||||
EncryptedSignatureData = RSAFormatter.CreateSignature(HashbyteSignature);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// RSA签名
|
||||
/// </summary>
|
||||
/// <param name="p_strKeyPrivate">私钥</param>
|
||||
/// <param name="m_strHashbyteSignature">待签名Hash描述</param>
|
||||
/// <param name="m_strEncryptedSignatureData">签名后的值</param>
|
||||
/// <returns></returns>
|
||||
public bool SignatureFormatter(string p_strKeyPrivate, string m_strHashbyteSignature, ref string m_strEncryptedSignatureData)
|
||||
{
|
||||
|
||||
byte[] HashbyteSignature;
|
||||
byte[] EncryptedSignatureData;
|
||||
|
||||
HashbyteSignature = Convert.FromBase64String(m_strHashbyteSignature);
|
||||
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
|
||||
|
||||
RSA.FromXmlString(p_strKeyPrivate);
|
||||
RSAPKCS1SignatureFormatter RSAFormatter = new RSAPKCS1SignatureFormatter(RSA);
|
||||
//设置签名的算法为MD5
|
||||
RSAFormatter.SetHashAlgorithm("MD5");
|
||||
//执行签名
|
||||
EncryptedSignatureData = RSAFormatter.CreateSignature(HashbyteSignature);
|
||||
|
||||
m_strEncryptedSignatureData = Convert.ToBase64String(EncryptedSignatureData);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
#endregion
|
||||
#region RSA 签名验证
|
||||
|
||||
/// <summary>
|
||||
/// 签名验证
|
||||
/// </summary>
|
||||
/// <param name="p_strKeyPublic">公钥</param>
|
||||
/// <param name="HashbyteDeformatter">Hash描述</param>
|
||||
/// <param name="DeformatterData">签名后的结果</param>
|
||||
/// <returns></returns>
|
||||
public bool SignatureDeformatter(string p_strKeyPublic, byte[] HashbyteDeformatter, byte[] DeformatterData)
|
||||
{
|
||||
|
||||
System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider();
|
||||
|
||||
RSA.FromXmlString(p_strKeyPublic);
|
||||
System.Security.Cryptography.RSAPKCS1SignatureDeformatter RSADeformatter = new System.Security.Cryptography.RSAPKCS1SignatureDeformatter(RSA);
|
||||
//指定解密的时候HASH算法为MD5
|
||||
RSADeformatter.SetHashAlgorithm("MD5");
|
||||
|
||||
if (RSADeformatter.VerifySignature(HashbyteDeformatter, DeformatterData))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 签名验证
|
||||
/// </summary>
|
||||
/// <param name="p_strKeyPublic">公钥</param>
|
||||
/// <param name="p_strHashbyteDeformatter">Hash描述</param>
|
||||
/// <param name="DeformatterData">签名后的结果</param>
|
||||
/// <returns></returns>
|
||||
public bool SignatureDeformatter(string p_strKeyPublic, string p_strHashbyteDeformatter, byte[] DeformatterData)
|
||||
{
|
||||
|
||||
byte[] HashbyteDeformatter;
|
||||
|
||||
HashbyteDeformatter = Convert.FromBase64String(p_strHashbyteDeformatter);
|
||||
|
||||
System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider();
|
||||
|
||||
RSA.FromXmlString(p_strKeyPublic);
|
||||
System.Security.Cryptography.RSAPKCS1SignatureDeformatter RSADeformatter = new System.Security.Cryptography.RSAPKCS1SignatureDeformatter(RSA);
|
||||
//指定解密的时候HASH算法为MD5
|
||||
RSADeformatter.SetHashAlgorithm("MD5");
|
||||
|
||||
if (RSADeformatter.VerifySignature(HashbyteDeformatter, DeformatterData))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 签名验证
|
||||
/// </summary>
|
||||
/// <param name="p_strKeyPublic">公钥</param>
|
||||
/// <param name="HashbyteDeformatter">Hash描述</param>
|
||||
/// <param name="p_strDeformatterData">签名后的结果</param>
|
||||
/// <returns></returns>
|
||||
public bool SignatureDeformatter(string p_strKeyPublic, byte[] HashbyteDeformatter, string p_strDeformatterData)
|
||||
{
|
||||
|
||||
byte[] DeformatterData;
|
||||
|
||||
System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider();
|
||||
|
||||
RSA.FromXmlString(p_strKeyPublic);
|
||||
System.Security.Cryptography.RSAPKCS1SignatureDeformatter RSADeformatter = new System.Security.Cryptography.RSAPKCS1SignatureDeformatter(RSA);
|
||||
//指定解密的时候HASH算法为MD5
|
||||
RSADeformatter.SetHashAlgorithm("MD5");
|
||||
|
||||
DeformatterData = Convert.FromBase64String(p_strDeformatterData);
|
||||
|
||||
if (RSADeformatter.VerifySignature(HashbyteDeformatter, DeformatterData))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 签名验证
|
||||
/// </summary>
|
||||
/// <param name="p_strKeyPublic">公钥</param>
|
||||
/// <param name="p_strHashbyteDeformatter">Hash描述</param>
|
||||
/// <param name="p_strDeformatterData">签名后的结果</param>
|
||||
/// <returns></returns>
|
||||
public bool SignatureDeformatter(string p_strKeyPublic, string p_strHashbyteDeformatter, string p_strDeformatterData)
|
||||
{
|
||||
|
||||
byte[] DeformatterData;
|
||||
byte[] HashbyteDeformatter;
|
||||
|
||||
HashbyteDeformatter = Convert.FromBase64String(p_strHashbyteDeformatter);
|
||||
System.Security.Cryptography.RSACryptoServiceProvider RSA = new System.Security.Cryptography.RSACryptoServiceProvider();
|
||||
|
||||
RSA.FromXmlString(p_strKeyPublic);
|
||||
System.Security.Cryptography.RSAPKCS1SignatureDeformatter RSADeformatter = new System.Security.Cryptography.RSAPKCS1SignatureDeformatter(RSA);
|
||||
//指定解密的时候HASH算法为MD5
|
||||
RSADeformatter.SetHashAlgorithm("MD5");
|
||||
|
||||
DeformatterData = Convert.FromBase64String(p_strDeformatterData);
|
||||
|
||||
if (RSADeformatter.VerifySignature(HashbyteDeformatter, DeformatterData))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// ASCII字典排序
|
||||
/// </summary>
|
||||
public class ASCIISort : IComparer
|
||||
{
|
||||
/// <summary>
|
||||
/// 创建新的ASCIISort实例
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static ASCIISort Create()
|
||||
{
|
||||
return new ASCIISort();
|
||||
}
|
||||
|
||||
public int Compare(object x,object y)
|
||||
{
|
||||
#if NET45
|
||||
byte[] xBytes = System.Text.Encoding.Default.GetBytes(x.ToString());
|
||||
byte[] yBytes = System.Text.Encoding.Default.GetBytes(y.ToString());
|
||||
#else
|
||||
byte[] xBytes = System.Text.Encoding.ASCII.GetBytes(x.ToString());
|
||||
byte[] yBytes = System.Text.Encoding.ASCII.GetBytes(y.ToString());
|
||||
#endif
|
||||
int xLength = xBytes.Length;
|
||||
int yLength = yBytes.Length;
|
||||
int minLength = Math.Min(xLength, yLength);
|
||||
|
||||
for (int i = 0; i < minLength; i++)
|
||||
{
|
||||
var xByte = xBytes[i];
|
||||
var yByte = yBytes[i];
|
||||
if (xByte > yByte)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else if (xByte < yByte)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (xLength == yLength)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (xLength > yLength)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// HashTable和object互转
|
||||
/// </summary>
|
||||
public class HashTableHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Hashtable转object实体对象
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="source"></param>
|
||||
/// <returns></returns>
|
||||
public static T Hashtable2Object<T>(Hashtable source)
|
||||
{
|
||||
T obj = Activator.CreateInstance<T>();
|
||||
object tv;
|
||||
|
||||
PropertyInfo[] ps = obj.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
|
||||
foreach (PropertyInfo p in ps)
|
||||
{
|
||||
if (source.ContainsKey(p.Name))
|
||||
{
|
||||
tv = source[p.Name];
|
||||
|
||||
if (p.PropertyType.IsArray)//数组类型,单独处理
|
||||
{
|
||||
p.SetValue(obj, tv, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (String.IsNullOrEmpty(tv.ToString()))//空值
|
||||
tv = p.PropertyType.IsValueType ? Activator.CreateInstance(p.PropertyType) : null;//值类型
|
||||
else
|
||||
tv = System.ComponentModel.TypeDescriptor.GetConverter(p.PropertyType).ConvertFromString(tv.ToString());//创建对象
|
||||
|
||||
p.SetValue(obj, tv, null);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 实体对象Object转HashTable
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="obj"></param>
|
||||
/// <returns></returns>
|
||||
public static Hashtable Object2Hashtable(object obj)
|
||||
{
|
||||
Hashtable hash = new Hashtable();
|
||||
|
||||
PropertyInfo[] ps = obj.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
|
||||
foreach (PropertyInfo p in ps)
|
||||
{
|
||||
hash.Add(p.Name, p.GetValue(obj));
|
||||
}
|
||||
|
||||
return hash;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,452 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
public class Validate
|
||||
{
|
||||
private static Regex RegNumber = new Regex("^[0-9]+$");
|
||||
private static Regex RegNumberSign = new Regex("^[+-]?[0-9]+$");
|
||||
private static Regex RegDecimal = new Regex("^[0-9]+[.]?[0-9]+$");
|
||||
private static Regex RegDecimalSign = new Regex("^[+-]?[0-9]+[.]?[0-9]+$"); //等价于^[+-]?\d+[.]?\d+$
|
||||
private static Regex RegEmail = new Regex(@"^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$");//w 英文字母或数字的字符串,和 [a-zA-Z0-9] 语法一样
|
||||
private static Regex RegCHZN = new Regex("[\u4e00-\u9fa5]");
|
||||
|
||||
#region 用户名密码格式
|
||||
|
||||
/// <summary>
|
||||
/// 返回字符串真实长度, 1个汉字长度为2
|
||||
/// </summary>
|
||||
/// <returns>字符长度</returns>
|
||||
public static int GetStringLength(string stringValue)
|
||||
{
|
||||
return Encoding.Default.GetBytes(stringValue).Length;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检测用户名格式是否有效
|
||||
/// </summary>
|
||||
/// <param name="userName"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsValidUserName(string userName)
|
||||
{
|
||||
int userNameLength = GetStringLength(userName);
|
||||
if (userNameLength >= 4 && userNameLength <= 20 && Regex.IsMatch(userName, @"^([\u4e00-\u9fa5A-Za-z_0-9]{0,})$"))
|
||||
{ // 判断用户名的长度(4-20个字符)及内容(只能是汉字、字母、下划线、数字)是否合法
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 密码有效性
|
||||
/// </summary>
|
||||
/// <param name="password"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsValidPassword(string password)
|
||||
{
|
||||
return Regex.IsMatch(password, @"^[A-Za-z_0-9]{6,16}$");
|
||||
}
|
||||
#endregion
|
||||
/// <summary>
|
||||
/// 验证车架号、发动机号
|
||||
/// </summary>
|
||||
/// <param name="Vin_Reg"></param>
|
||||
/// <returns></returns>
|
||||
public static bool CheckVinReg(string Vin_Reg)
|
||||
{
|
||||
return Regex.IsMatch(Vin_Reg, @"^([A-H]|[J-N]|[P-Z]|[0-9]){6,16}$");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证车架号VIN是否合法
|
||||
/// </summary>
|
||||
/// <param name="vin"></param>
|
||||
/// <returns></returns>
|
||||
public static bool CheckVin(string vin)
|
||||
{
|
||||
if (vin == null || vin.Length != 17) return false;
|
||||
int symbol, weight, verify, sum = 0;
|
||||
bool isRepeat = true;
|
||||
if (vin[8] >= 48 && vin[8] <= 57)
|
||||
verify = vin[8] - 48;//0到9
|
||||
else if (vin[8] == 88)
|
||||
verify = 10;//X
|
||||
else
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < vin.Length; i++)
|
||||
{
|
||||
if (i < 7)
|
||||
weight = 8 - i;
|
||||
else if (i > 8)
|
||||
weight = 18 - i;
|
||||
else if (i == 7)
|
||||
weight = 10;
|
||||
else
|
||||
continue;
|
||||
|
||||
if (vin[i] >= 48 && vin[i] <= 57)
|
||||
symbol = vin[i] - 48;//0-9
|
||||
else if (vin[i] >= 65 && vin[i] <= 72)
|
||||
symbol = vin[i] - 64;//A-H
|
||||
else if (vin[i] >= 74 && vin[i] <= 82 && vin[i] != 79 && vin[i] != 81)
|
||||
symbol = vin[i] - 73;//J-R不含O,Q
|
||||
else if (vin[i] >= 83 && vin[i] <= 90)
|
||||
symbol = vin[i] - 81;//S-Z
|
||||
else
|
||||
return false;
|
||||
sum += symbol * weight;
|
||||
|
||||
if (isRepeat && i > 0) isRepeat = vin[i] == vin[i - (i != 9 ? 1 : 2)];
|
||||
}
|
||||
|
||||
if (isRepeat) return false;
|
||||
return verify == sum % 11;
|
||||
}
|
||||
/// <summary>
|
||||
/// 验证车牌号是否合法
|
||||
/// </summary>
|
||||
/// <param name="vehicleNumber">车牌号</param>
|
||||
/// <returns></returns>
|
||||
public static bool IsVehicleNumber(string vehicleNumber)
|
||||
{
|
||||
bool result = false;
|
||||
if (vehicleNumber.Length == 7 || vehicleNumber.Length == 8)
|
||||
{
|
||||
string express = @"^(([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z](([0-9]{5}[DF])|([DF]([A-HJ-NP-Z0-9])[0-9]{4})))|([京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领][A-Z][A-HJ-NP-Z0-9]{4}[A-HJ-NP-Z0-9挂学警港澳使领]))$";
|
||||
return Regex.IsMatch(vehicleNumber.ToUpper(), express);
|
||||
}
|
||||
return result;
|
||||
|
||||
|
||||
}
|
||||
#region 数字字符串检查
|
||||
|
||||
/// <summary>
|
||||
/// int有效性
|
||||
/// </summary>
|
||||
/// <param name="val"></param>
|
||||
/// <returns></returns>
|
||||
static public bool IsValidInt(string val)
|
||||
{
|
||||
return Regex.IsMatch(val, @"^[1-9]\d*\.?[0]*$");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否数字字符串
|
||||
/// </summary>
|
||||
/// <param name="inputData">输入字符串</param>
|
||||
/// <returns></returns>
|
||||
public static bool IsNumber(string inputData)
|
||||
{
|
||||
Match m = RegNumber.Match(inputData);
|
||||
return m.Success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否数字字符串 可带正负号
|
||||
/// </summary>
|
||||
/// <param name="inputData">输入字符串</param>
|
||||
/// <returns></returns>
|
||||
public static bool IsNumberSign(string inputData)
|
||||
{
|
||||
Match m = RegNumberSign.Match(inputData);
|
||||
return m.Success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否是浮点数
|
||||
/// </summary>
|
||||
/// <param name="inputData">输入字符串</param>
|
||||
/// <returns></returns>
|
||||
public static bool IsDecimal(string inputData)
|
||||
{
|
||||
Match m = RegDecimal.Match(inputData);
|
||||
return m.Success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否是浮点数 可带正负号
|
||||
/// </summary>
|
||||
/// <param name="inputData">输入字符串</param>
|
||||
/// <returns></returns>
|
||||
public static bool IsDecimalSign(string inputData)
|
||||
{
|
||||
Match m = RegDecimalSign.Match(inputData);
|
||||
return m.Success;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 中文检测
|
||||
|
||||
/// <summary>
|
||||
/// 检测是否有中文字符
|
||||
/// </summary>
|
||||
/// <param name="inputData"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsHasCHZN(string inputData)
|
||||
{
|
||||
Match m = RegCHZN.Match(inputData);
|
||||
return m.Success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检测含有中文字符串的实际长度
|
||||
/// </summary>
|
||||
/// <param name="str">字符串</param>
|
||||
public static int GetCHZNLength(string inputData)
|
||||
{
|
||||
System.Text.ASCIIEncoding n = new System.Text.ASCIIEncoding();
|
||||
byte[] bytes = n.GetBytes(inputData);
|
||||
|
||||
int length = 0; // l 为字符串之实际长度
|
||||
for (int i = 0; i <= bytes.Length - 1; i++)
|
||||
{
|
||||
if (bytes[i] == 63) //判断是否为汉字或全脚符号
|
||||
{
|
||||
length++;
|
||||
}
|
||||
length++;
|
||||
}
|
||||
return length;
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 常用格式
|
||||
|
||||
/// <summary>
|
||||
/// 验证身份证是否合法 15 和 18位两种
|
||||
/// </summary>
|
||||
/// <param name="idCard">要验证的身份证</param>
|
||||
public static bool IsIdCard(string idCard)
|
||||
{
|
||||
if (string.IsNullOrEmpty(idCard))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (idCard.Length == 15)
|
||||
{
|
||||
return Regex.IsMatch(idCard, @"^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$");
|
||||
}
|
||||
else if (idCard.Length == 18)
|
||||
{
|
||||
return Regex.IsMatch(idCard, @"^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[A-Z])$", RegexOptions.IgnoreCase);
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否是邮件地址
|
||||
/// </summary>
|
||||
/// <param name="inputData">输入字符串</param>
|
||||
/// <returns></returns>
|
||||
public static bool IsEmail(string inputData)
|
||||
{
|
||||
Match m = RegEmail.Match(inputData);
|
||||
return m.Success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 邮编有效性
|
||||
/// </summary>
|
||||
/// <param name="zip"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsValidZip(string zip)
|
||||
{
|
||||
Regex rx = new Regex(@"^\d{6}$", RegexOptions.None);
|
||||
Match m = rx.Match(zip);
|
||||
return m.Success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 固定电话有效性
|
||||
/// </summary>
|
||||
/// <param name="phone"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsValidPhone(string phone)
|
||||
{
|
||||
Regex rx = new Regex(@"^(\(\d{3,4}\)|\d{3,4}-)?\d{7,8}$", RegexOptions.None);
|
||||
Match m = rx.Match(phone);
|
||||
return m.Success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 手机有效性
|
||||
/// </summary>
|
||||
/// <param name="strMobile"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsValidMobile(string mobile)
|
||||
{
|
||||
if (string.IsNullOrEmpty(mobile))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
Regex rx = new Regex(@"^(13|15|16|17|18|19)\d{9}$", RegexOptions.None);
|
||||
Match m = rx.Match(mobile);
|
||||
return m.Success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 电话有效性(固话和手机 )
|
||||
/// </summary>
|
||||
/// <param name="strVla"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsValidPhoneAndMobile(string number)
|
||||
{
|
||||
Regex rx = new Regex(@"^(\(\d{3,4}\)|\d{3,4}-)?\d{7,8}$|^(13|15)\d{9}$", RegexOptions.None);
|
||||
Match m = rx.Match(number);
|
||||
return m.Success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Url有效性
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <returns></returns>
|
||||
static public bool IsValidURL(string url)
|
||||
{
|
||||
return Regex.IsMatch(url, @"^(http|https|ftp)\://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(:[a-zA-Z0-9]*)?/?([a-zA-Z0-9\-\._\?\,\'/\\\+&%\$#\=~])*[^\.\,\)\(\s]$");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// IP有效性
|
||||
/// </summary>
|
||||
/// <param name="ip"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsValidIP(string ip)
|
||||
{
|
||||
return Regex.IsMatch(ip, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// domain 有效性
|
||||
/// </summary>
|
||||
/// <param name="host">域名</param>
|
||||
/// <returns></returns>
|
||||
public static bool IsValidDomain(string host)
|
||||
{
|
||||
Regex r = new Regex(@"^\d+$");
|
||||
if (host.IndexOf(".") == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return r.IsMatch(host.Replace(".", string.Empty)) ? false : true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断是否为base64字符串
|
||||
/// </summary>
|
||||
/// <param name="str"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsBase64String(string str)
|
||||
{
|
||||
return Regex.IsMatch(str, @"[A-Za-z0-9\+\/\=]");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 验证字符串是否是GUID
|
||||
/// </summary>
|
||||
/// <param name="guid">字符串</param>
|
||||
/// <returns></returns>
|
||||
public static bool IsGuid(string guid)
|
||||
{
|
||||
if (string.IsNullOrEmpty(guid))
|
||||
return false;
|
||||
|
||||
return Regex.IsMatch(guid, "[A-F0-9]{8}(-[A-F0-9]{4}){3}-[A-F0-9]{12}|[A-F0-9]{32}", RegexOptions.IgnoreCase);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 日期检查
|
||||
|
||||
/// <summary>
|
||||
/// 判断输入的字符是否为日期
|
||||
/// </summary>
|
||||
/// <param name="strValue"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsDate(string strValue)
|
||||
{
|
||||
return Regex.IsMatch(strValue, @"^((\d{2}(([02468][048])|([13579][26]))[\-\/\s]?((((0?[13578])|(1[02]))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\-\/\s]?((0?[1-9])|([1-2][0-9])))))|(\d{2}(([02468][1235679])|([13579][01345789]))[\-\/\s]?((((0?[13578])|(1[02]))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\-\/\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\-\/\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断输入的字符是否为日期,如2004-07-12 14:25|||1900-01-01 00:00|||9999-12-31 23:59
|
||||
/// </summary>
|
||||
/// <param name="strValue"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsDateHourMinute(string strValue)
|
||||
{
|
||||
return Regex.IsMatch(strValue, @"^(19[0-9]{2}|[2-9][0-9]{3})-((0(1|3|5|7|8)|10|12)-(0[1-9]|1[0-9]|2[0-9]|3[0-1])|(0(4|6|9)|11)-(0[1-9]|1[0-9]|2[0-9]|30)|(02)-(0[1-9]|1[0-9]|2[0-9]))\x20(0[0-9]|1[0-9]|2[0-3])(:[0-5][0-9]){1}$");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 其他
|
||||
|
||||
/// <summary>
|
||||
/// 检查字符串最大长度,返回指定长度的串
|
||||
/// </summary>
|
||||
/// <param name="sqlInput">输入字符串</param>
|
||||
/// <param name="maxLength">最大长度</param>
|
||||
/// <returns></returns>
|
||||
public static string CheckMathLength(string inputData, int maxLength)
|
||||
{
|
||||
if (inputData != null && inputData != string.Empty)
|
||||
{
|
||||
inputData = inputData.Trim();
|
||||
if (inputData.Length > maxLength)//按最大长度截取字符串
|
||||
{
|
||||
inputData = inputData.Substring(0, maxLength);
|
||||
}
|
||||
}
|
||||
return inputData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 转换成 HTML code
|
||||
/// </summary>
|
||||
/// <param name="str">string</param>
|
||||
/// <returns>string</returns>
|
||||
public static string Encode(string str)
|
||||
{
|
||||
str = str.Replace("&", "&");
|
||||
str = str.Replace("'", "''");
|
||||
str = str.Replace("\"", """);
|
||||
str = str.Replace(" ", " ");
|
||||
str = str.Replace("<", "<");
|
||||
str = str.Replace(">", ">");
|
||||
str = str.Replace("\n", "<br>");
|
||||
return str;
|
||||
}
|
||||
/// <summary>
|
||||
///解析html成 普通文本
|
||||
/// </summary>
|
||||
/// <param name="str">string</param>
|
||||
/// <returns>string</returns>
|
||||
public static string Decode(string str)
|
||||
{
|
||||
str = str.Replace("<br>", "\n");
|
||||
str = str.Replace(">", ">");
|
||||
str = str.Replace("<", "<");
|
||||
str = str.Replace(" ", " ");
|
||||
str = str.Replace(""", "\"");
|
||||
return str;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
using System;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
public class VerifyCode
|
||||
{
|
||||
/// <summary>
|
||||
/// 生成验证码
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
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("Elent_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
|
||||
{
|
||||
ms.Dispose();
|
||||
g.Dispose();
|
||||
bmp.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
/// <summary>
|
||||
/// 分页信息
|
||||
/// </summary>
|
||||
public class Pagination
|
||||
{
|
||||
/// <summary>
|
||||
/// 每页行数
|
||||
/// </summary>
|
||||
public int rows { get; set; }
|
||||
/// <summary>
|
||||
/// 当前页
|
||||
/// </summary>
|
||||
public int page { get; set; }
|
||||
/// <summary>
|
||||
/// 排序列
|
||||
/// </summary>
|
||||
public string sidx { get; set; }
|
||||
/// <summary>
|
||||
/// 排序类型
|
||||
/// </summary>
|
||||
public string sord { get; set; }
|
||||
/// <summary>
|
||||
/// 总记录数
|
||||
/// </summary>
|
||||
public int records { get; set; }
|
||||
/// <summary>
|
||||
/// 当前页
|
||||
/// </summary>
|
||||
public int offset { get; set; }
|
||||
/// <summary>
|
||||
/// 显示数
|
||||
/// </summary>
|
||||
public int limit { 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class PaginationApi
|
||||
{
|
||||
/// <summary>
|
||||
/// 每页行数
|
||||
/// </summary>
|
||||
public int rows { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 当前页
|
||||
/// </summary>
|
||||
public int page { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 显示数
|
||||
/// </summary>
|
||||
public int pagesize { get; set; } = 10;
|
||||
}
|
||||
|
||||
public class QueryConditional
|
||||
{
|
||||
/// <summary>
|
||||
/// 查询参数名
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
/// <summary>
|
||||
/// 查询类型
|
||||
/// </summary>
|
||||
public int Type { get; set; }
|
||||
/// <summary>
|
||||
/// 值
|
||||
/// </summary>
|
||||
public string Value { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
public static class TreeSelect
|
||||
{
|
||||
public static string TreeSelectJson(this List<TreeSelectModel> data, string parent = "0")
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append("[");
|
||||
sb.Append(TreeSelectJson(data, parent, ""));
|
||||
sb.Append("]");
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
|
||||
public static string TreeSelectGuidJson(this List<TreeSelectModel> data)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.Append("[");
|
||||
sb.Append(TreeSelectJson(data, Guid.Empty.ToString(), ""));
|
||||
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" && parentId != Guid.Empty.ToString())
|
||||
{
|
||||
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("}{", "},{");
|
||||
}
|
||||
}
|
||||
|
||||
public class TreeSelectModel
|
||||
{
|
||||
public string id { get; set; }
|
||||
public string text { get; set; }
|
||||
public string parentId { get; set; }
|
||||
public object data { get; set; }
|
||||
public string url { get; set; }
|
||||
|
||||
public string icon { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
using Microsoft.AspNetCore.Http;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Nirvana.Common
|
||||
{
|
||||
public class WebHelper
|
||||
{
|
||||
#region cookie操作
|
||||
/// <summary>
|
||||
/// 写cookie值
|
||||
/// </summary>
|
||||
/// <param name="strName">名称</param>
|
||||
/// <param name="strValue">值</param>
|
||||
/// <param name="domain">域名</param>
|
||||
public static void WriteCookie(string strName, string strValue, string domain = "")
|
||||
{
|
||||
if (!string.IsNullOrEmpty(domain))
|
||||
{
|
||||
MyHttpContext.current.Response.Cookies.Append(strName, strValue, new Microsoft.AspNetCore.Http.CookieOptions
|
||||
{
|
||||
Domain = domain
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
MyHttpContext.current.Response.Cookies.Append(strName, strValue);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 写cookie值
|
||||
/// </summary>
|
||||
/// <param name="strName">名称</param>
|
||||
/// <param name="strValue">值</param>
|
||||
/// <param name="strValue">过期时间(分钟)</param>
|
||||
/// <param name="domain">域名</param>
|
||||
public static void WriteCookie(string strName, string strValue, int expires, string domain = "")
|
||||
{
|
||||
if (!string.IsNullOrEmpty(domain))
|
||||
{
|
||||
MyHttpContext.current.Response.Cookies.Append(strName, strValue, new Microsoft.AspNetCore.Http.CookieOptions
|
||||
{
|
||||
Domain = domain,
|
||||
Expires = DateTime.Now.AddMinutes(expires)
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
MyHttpContext.current.Response.Cookies.Append(strName, strValue, new Microsoft.AspNetCore.Http.CookieOptions
|
||||
{
|
||||
Expires = DateTime.Now.AddMinutes(expires)
|
||||
});
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 读cookie值
|
||||
/// </summary>
|
||||
/// <param name="strName">名称</param>
|
||||
/// <returns></returns>
|
||||
public static string GetCookie(string strName)
|
||||
{
|
||||
if (MyHttpContext.current.Request.Cookies != null && !string.IsNullOrEmpty(MyHttpContext.current.Request.Cookies[strName]))
|
||||
{
|
||||
return MyHttpContext.current.Request.Cookies[strName];
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除Cookie对象
|
||||
/// </summary>
|
||||
/// <param name="CookiesName">Cookie对象名称</param>
|
||||
public static void RemoveCookie(string CookiesName)
|
||||
{
|
||||
if (MyHttpContext.current.Request.Cookies != null && !string.IsNullOrEmpty(MyHttpContext.current.Request.Cookies[CookiesName]))
|
||||
{
|
||||
MyHttpContext.current.Response.Cookies.Delete(CookiesName);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Session操作
|
||||
/// <summary>
|
||||
/// 写Session
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Session键值的类型</typeparam>
|
||||
/// <param name="key">Session的键名</param>
|
||||
/// <param name="value">Session的键值</param>
|
||||
public static void WriteSession(string key, byte[] value)
|
||||
{
|
||||
if (key.IsEmpty())
|
||||
return;
|
||||
MyHttpContext.current.Session.Set(key, value);
|
||||
}
|
||||
/// <summary>
|
||||
/// 写Session
|
||||
/// </summary>
|
||||
/// <param name="key">Session的键名</param>
|
||||
/// <param name="value">Session的键值</param>
|
||||
public static void WriteSession(string key, string value)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
{
|
||||
byte[] bt = Encoding.Default.GetBytes(value);
|
||||
WriteSession(key, bt);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 读取Session的值
|
||||
/// </summary>
|
||||
/// <param name="key">Session的键名</param>
|
||||
/// <returns></returns>
|
||||
public static string GetSession(string key)
|
||||
{
|
||||
if (key.IsEmpty())
|
||||
return string.Empty;
|
||||
if (MyHttpContext.current.Session == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
var value = MyHttpContext.current.Session.GetString(key);
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 删除指定Session
|
||||
/// </summary>
|
||||
/// <param name="key">Session的键名</param>
|
||||
public static void RemoveSession(string key)
|
||||
{
|
||||
if (key.IsEmpty())
|
||||
return;
|
||||
MyHttpContext.current.Session.Remove(key);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,5 @@
|
|||
using Furion.DynamicApiController;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Nirvana.Common;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Waste.Application
|
||||
|
|
@ -19,11 +16,11 @@ namespace Waste.Application
|
|||
_accountService = accountService;
|
||||
}
|
||||
/// <summary>
|
||||
/// 测试接口
|
||||
/// 用户登录
|
||||
/// </summary>
|
||||
public async Task<int> GetTest()
|
||||
public async Task<ResultInfo> LoginAsync(LoginModel loginModel)
|
||||
{
|
||||
return await _accountService.LoginAsync(null);
|
||||
return await _accountService.LoginAsync(loginModel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,17 +1,80 @@
|
|||
using Furion.DependencyInjection;
|
||||
using Nirvana.Common;
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Waste.Domain;
|
||||
|
||||
namespace Waste.Application
|
||||
{
|
||||
public class AccountService : IAccountService, ITransient
|
||||
{
|
||||
public Task<int> LoginAsync(LoginModel model)
|
||||
private readonly ISqlSugarRepository<W_Account> repository;
|
||||
private readonly SqlSugarClient dbClient;
|
||||
public AccountService(ISqlSugarRepository<W_Account> sqlSugarRepository)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
repository = sqlSugarRepository;
|
||||
dbClient = repository.Context;
|
||||
}
|
||||
public async Task<ResultInfo> LoginAsync(LoginModel model)
|
||||
{
|
||||
//如果是系统维护人员
|
||||
if (OperatorProvider.Provider.IsSupperAdmin(model.username, model.pwd))
|
||||
{
|
||||
OperatorProvider.Provider.AddCurrent(new OperatorModel
|
||||
{
|
||||
AccountType = (int)AccountType.platform,
|
||||
UserId = Guid.Empty,
|
||||
IsSuper = true,
|
||||
BusinessId = Guid.Empty,
|
||||
LoginIPAddress = Net.Ip,
|
||||
LoginTime = DateTime.Now,
|
||||
RealName = "系统维护人员",
|
||||
RoleId = Guid.Empty,
|
||||
BusinessCode=""
|
||||
});
|
||||
return new ResultInfo { code = ResultState.SUCCESS, message = "登录成功" };
|
||||
}
|
||||
var userdata = await dbClient.Queryable<W_Account>().FirstAsync(x => x.UserName == model.username);
|
||||
if (userdata == null)
|
||||
{
|
||||
return new ResultInfo { code = ResultState.FAIL, message = "账户未找到" };
|
||||
}
|
||||
if (userdata.Status != 1)
|
||||
{
|
||||
return new ResultInfo { code = ResultState.FAIL, message = "账户已禁用" };
|
||||
}
|
||||
var password = Md5.md5(DESEncrypt.Encrypt(Md5.md5(model.pwd, 32).ToLower(), userdata.Secret).ToLower(), 32).ToLower();
|
||||
if (password != userdata.Password)
|
||||
{
|
||||
return new ResultInfo { code = ResultState.FAIL, message = "密码不正确" };
|
||||
}
|
||||
await dbClient.Updateable<W_Account>().SetColumns(x => new W_Account
|
||||
{
|
||||
LastVisitIP = Net.Ip,
|
||||
LastVisitTime = DateTime.Now
|
||||
}).Where(x => x.Id == userdata.Id).ExecuteCommandAsync();
|
||||
string businesscode = "";
|
||||
if(userdata.BusinessId != Guid.Empty)
|
||||
{
|
||||
var buss = await dbClient.Queryable<W_Business>().FirstAsync(x => x.Id == userdata.BusinessId);
|
||||
businesscode = buss != null ? buss.Code : "";
|
||||
}
|
||||
//记录登录信息到cookie和session
|
||||
OperatorModel logindata = new OperatorModel
|
||||
{
|
||||
UserId = userdata.Id,
|
||||
RoleId = userdata.RoleId,
|
||||
AccountType = userdata.AccountType,
|
||||
BusinessId = userdata.BusinessId,
|
||||
IsSuper = false,
|
||||
LoginIPAddress = Net.Ip,
|
||||
LoginTime = DateTime.Now,
|
||||
RealName = userdata.RealName,
|
||||
BusinessCode= businesscode
|
||||
};
|
||||
OperatorProvider.Provider.AddCurrent(logindata);
|
||||
return new ResultInfo { code = ResultState.SUCCESS, message = "登录成功"};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
using Furion.DataEncryption;
|
||||
using Furion.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Waste.Application
|
||||
{
|
||||
public class AuthorizationManager : IAuthorizationManager, ITransient
|
||||
{
|
||||
/// <summary>
|
||||
/// 检查权限
|
||||
/// </summary>
|
||||
/// <param name="ResourceId"></param>
|
||||
/// <returns></returns>
|
||||
public bool CheckSecurity(string ResourceId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
/// <summary>
|
||||
/// 生成token
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public LoginSuccessInfo Encrypt(UserInfo userInfo)
|
||||
{
|
||||
var accesstoken = JWTEncryption.Encrypt(new Dictionary<string, object>() {
|
||||
{"UserId",userInfo.UserId },
|
||||
{"AccountType",userInfo.AccountType },
|
||||
{"BusinessId",userInfo.BusinessId },
|
||||
{"IsSuper",userInfo.IsSuper },
|
||||
{"RealName",userInfo.RealName },
|
||||
{"RoleId",userInfo.RoleId }
|
||||
});
|
||||
//刷新token,30天有效期
|
||||
var refreshToken = JWTEncryption.GenerateRefreshToken(accesstoken, 30);
|
||||
return new LoginSuccessInfo {
|
||||
token=accesstoken,
|
||||
refreshtoken=refreshToken
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
|
@ -14,14 +15,63 @@ namespace Waste.Application
|
|||
/// <summary>
|
||||
/// 用户名
|
||||
/// </summary>
|
||||
[Required(ErrorMessage ="请先输入用户名")]
|
||||
public string username { get; set; }
|
||||
/// <summary>
|
||||
/// 密码
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "请先输入密码")]
|
||||
public string pwd { get; set; }
|
||||
/// <summary>
|
||||
/// 验证码
|
||||
/// </summary>
|
||||
public string code { get; set; } = "";
|
||||
}
|
||||
/// <summary>
|
||||
/// 账户登录成功之后的信息
|
||||
/// </summary>
|
||||
public class UserInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 账户类型
|
||||
/// </summary>
|
||||
public int AccountType { get; set; }
|
||||
/// <summary>
|
||||
/// 用户ID
|
||||
/// </summary>
|
||||
public Guid UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户实际名称
|
||||
/// </summary>
|
||||
public string RealName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 角色ID
|
||||
/// </summary>
|
||||
public Guid RoleId { get; set; }
|
||||
/// <summary>
|
||||
/// 是否为超级管理员
|
||||
/// </summary>
|
||||
public bool IsSuper { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// 关联的商户ID
|
||||
/// </summary>
|
||||
public Guid BusinessId { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 登录成功之后的返回信息
|
||||
/// </summary>
|
||||
public class LoginSuccessInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 访问token
|
||||
/// </summary>
|
||||
public string token { get; set; }
|
||||
/// <summary>
|
||||
/// 刷新token
|
||||
/// </summary>
|
||||
public string refreshtoken { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,10 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Nirvana.Common;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Waste.Application
|
||||
{
|
||||
public interface IAccountService
|
||||
{
|
||||
Task<int> LoginAsync(LoginModel model);
|
||||
Task<ResultInfo> LoginAsync(LoginModel model);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,24 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
namespace Waste.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// 权限管理
|
||||
/// </summary>
|
||||
public interface IAuthorizationManager
|
||||
{
|
||||
/// <summary>
|
||||
/// 生成token
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
LoginSuccessInfo Encrypt(UserInfo userInfo);
|
||||
/// <summary>
|
||||
/// 检查token
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
bool CheckSecurity(string ResourceId);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
using Furion;
|
||||
using Nirvana.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Waste.Application
|
||||
{
|
||||
public class BaseInfoService
|
||||
{
|
||||
public static string CDNURL = App.Configuration["CDNURL"];
|
||||
|
||||
public static OperatorModel currentUser = OperatorProvider.Provider.GetCurrent();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
using Furion.DynamicApiController;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Nirvana.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Waste.Domain;
|
||||
|
||||
namespace Waste.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// 商户管理
|
||||
/// </summary>
|
||||
public class BusinessAppService : IDynamicApiController
|
||||
{
|
||||
private readonly IBusinessService _businessService;
|
||||
private static readonly string LoginUserKey = Configs.GetString("LoginProviderKey");
|
||||
private readonly IHttpContextAccessor _httpContextAccessor;
|
||||
|
||||
public BusinessAppService(IBusinessService businessService, IHttpContextAccessor httpContextAccessor)
|
||||
{
|
||||
_businessService = businessService;
|
||||
_httpContextAccessor = httpContextAccessor;
|
||||
}
|
||||
/// <summary>
|
||||
/// 商户列表
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<PageParms<BusinessList>> GetListAsync(QueryParams param)
|
||||
{
|
||||
return await _businessService.GetListAsync(param);
|
||||
}
|
||||
/// <summary>
|
||||
/// 商户列表,不包含管理员
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<PageParms<BusinessList>> GetListNoAdminAsync(QueryParams param)
|
||||
{
|
||||
return await _businessService.GetListAsync(param,true);
|
||||
}
|
||||
/// <summary>
|
||||
/// 信息提交
|
||||
/// </summary>
|
||||
/// <param name="buss"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> SubmitFormAsync(BusinessInfo buss)
|
||||
{
|
||||
return await _businessService.SubmitFormAsync(buss);
|
||||
}
|
||||
/// <summary>
|
||||
/// 重置密码
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="pwd"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[QueryParameters]
|
||||
public async Task<ResultInfo> ResetPwdAsync(Guid id,string pwd)
|
||||
{
|
||||
return await _businessService.ResetPwdAsync(id,pwd);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改密码
|
||||
/// </summary>
|
||||
/// <param name="busienssPwd"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> ChangePwdAsync(BusienssPwd busienssPwd)
|
||||
{
|
||||
return await _businessService.ChangePwdAsync(busienssPwd);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 退出登录
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public ResultInfo OutLogin()
|
||||
{
|
||||
_httpContextAccessor.HttpContext.Session.Remove(LoginUserKey);
|
||||
OperatorProvider.Provider.RemoveCurrent();
|
||||
return new ResultInfo(ResultState.SUCCESS, "success");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,532 @@
|
|||
using Furion.DependencyInjection;
|
||||
using Furion.DistributedIDGenerator;
|
||||
using Furion.DynamicApiController;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Nirvana.Common;
|
||||
using Nirvana.Common.ApiBase;
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Waste.Domain;
|
||||
|
||||
namespace Waste.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// 商户管理
|
||||
/// </summary>
|
||||
public class BusinessService : BaseInfoService, IBusinessService, ITransient
|
||||
{
|
||||
private readonly ISqlSugarRepository<W_Business> repository;
|
||||
private readonly SqlSugarClient dbClient;
|
||||
|
||||
public BusinessService(ISqlSugarRepository<W_Business> sqlSugarRepository)
|
||||
{
|
||||
repository = sqlSugarRepository;
|
||||
dbClient = repository.Context;
|
||||
}
|
||||
/// <summary>
|
||||
/// 删除商户
|
||||
/// </summary>
|
||||
/// <param name="keyValue"></param>
|
||||
/// <returns></returns>
|
||||
public Task<ResultInfo> DeleteFormAsync(Guid keyValue)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
/// <summary>
|
||||
/// 详情
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<BusinessInfo> DetailAsync(Guid id)
|
||||
{
|
||||
var buss = await dbClient.Queryable<W_Business>().Select(x => new W_Business
|
||||
{
|
||||
Name = x.Name,
|
||||
Address = x.Address,
|
||||
Area = x.Area,
|
||||
City = x.City,
|
||||
Phone = x.Phone,
|
||||
Province = x.Province,
|
||||
Id = x.Id,
|
||||
Remark = x.Remark
|
||||
}).Where(x => x.Id == id).FirstAsync();
|
||||
var user = await repository.Change<W_Account>().Context.Queryable<W_Account>().FirstAsync(x => x.BusinessId == buss.Id);
|
||||
return new BusinessInfo
|
||||
{
|
||||
AccountType = user.AccountType,
|
||||
Name = buss.Name,
|
||||
Address = buss.Address,
|
||||
Area = buss.Area,
|
||||
City = buss.City,
|
||||
Phone = buss.Phone,
|
||||
Province = buss.Province,
|
||||
Remark = buss.Remark,
|
||||
Id = buss.Id
|
||||
};
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取所有商户
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<List<W_Business>> GetAllList(int status = -1)
|
||||
{
|
||||
var tempquery = dbClient.Queryable<W_Business>();
|
||||
if(status >= 0)
|
||||
{
|
||||
tempquery = tempquery.Where(x => x.Status == status);
|
||||
}
|
||||
if(currentUser.AccountType != (int)AccountType.platform)
|
||||
{
|
||||
tempquery = tempquery.Where(x => x.ParentId == currentUser.BusinessId || x.Id == currentUser.BusinessId);
|
||||
}
|
||||
else
|
||||
{
|
||||
tempquery = tempquery.Where(x => SqlFunc.Subqueryable<W_Account>().Where(e => e.AccountType == 1 && e.BusinessId == x.Id).Any());
|
||||
}
|
||||
return await tempquery.ToListAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 商户列表
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
/// <param name="noadmin">是否包含管理员,true-不包含,false-包含</param>
|
||||
/// <returns></returns>
|
||||
public async Task<PageParms<BusinessList>> GetListAsync(QueryParams param, bool noadmin = false)
|
||||
{
|
||||
RefAsync<int> totalnum = 0;
|
||||
var temquery = dbClient.Queryable<W_Business>();
|
||||
if (param.queryParam != null && param.queryParam.Count > 0)
|
||||
{
|
||||
List<IConditionalModel> conModels = new List<IConditionalModel>();
|
||||
param.queryParam.ForEach(x =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(x.Value))
|
||||
{
|
||||
conModels.Add(new ConditionalModel()
|
||||
{
|
||||
FieldName = x.Name,
|
||||
ConditionalType = (ConditionalType)x.Type,
|
||||
FieldValue = x.Value.Trim()
|
||||
});
|
||||
}
|
||||
});
|
||||
if (conModels.Count > 0)
|
||||
{
|
||||
temquery = temquery.Where(conModels);
|
||||
}
|
||||
}
|
||||
if (noadmin)
|
||||
{
|
||||
temquery = temquery.Where(x => SqlFunc.Subqueryable<W_Account>().Where(e => e.AccountType == 1 && e.BusinessId == x.Id).Any());
|
||||
}
|
||||
if (currentUser.AccountType != (int)AccountType.platform)
|
||||
{
|
||||
temquery = temquery.Where(x => x.ParentId == currentUser.BusinessId);
|
||||
}
|
||||
string sorts = string.Format("{0} {1}", param.sort, param.order);
|
||||
var query = await temquery.OrderBy(sorts)
|
||||
.Select(x=>new BusinessList {
|
||||
Id=x.Id,
|
||||
Address=x.Address,
|
||||
CreateTime=x.CreateTime,
|
||||
Status=x.Status,
|
||||
Name=x.Name,
|
||||
Phone=x.Phone
|
||||
})
|
||||
.Mapper((it, cache) =>
|
||||
{
|
||||
if (!noadmin)
|
||||
{
|
||||
var allrealdata = cache.Get(list => {
|
||||
var ids = list.Select(x => x.Id).ToList();
|
||||
return repository.Change<W_BusinessRealData>().Context.Queryable<W_BusinessRealData>().Where(x => ids.Contains(x.BusinessId)).ToList();
|
||||
});
|
||||
var realdata = allrealdata.FirstOrDefault(x => x.BusinessId == it.Id);
|
||||
if(realdata != null)
|
||||
{
|
||||
it.BusinessCnt = realdata.BusinessCnt;
|
||||
it.DevCnt = realdata.DevCnt;
|
||||
it.TodayDevActiveCnt = realdata.TodayDevActiveCnt;
|
||||
it.TodayCount = realdata.TodayCount;
|
||||
it.TodayWeight = realdata.TodayWeight;
|
||||
it.TodayPureWeight = realdata.TodayPureWeight;
|
||||
it.TotalCount = realdata.TotalCount;
|
||||
it.TotalWeight = realdata.TotalWeight;
|
||||
it.TotalPureWeight = realdata.TotalPureWeight;
|
||||
}
|
||||
}
|
||||
})
|
||||
.ToPageListAsync(param.offset, param.limit, totalnum);
|
||||
return new PageParms<BusinessList>
|
||||
{
|
||||
page = param.offset,
|
||||
Items = query,
|
||||
totalnum = totalnum,
|
||||
limit = param.limit
|
||||
};
|
||||
}
|
||||
/// <summary>
|
||||
/// 重置密码
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="pwd"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> ResetPwdAsync(Guid id, string pwd)
|
||||
{
|
||||
if (string.IsNullOrEmpty(pwd))
|
||||
{
|
||||
pwd = "123456";
|
||||
}
|
||||
if (!await dbClient.Queryable<W_Business>().AnyAsync(x => x.Id == id))
|
||||
{
|
||||
return new ResultInfo(ResultState.FAIL, "此商户未找到");
|
||||
}
|
||||
if (!await repository.Change<W_Account>().Context.Queryable<W_Account>().AnyAsync(x => x.BusinessId == id))
|
||||
{
|
||||
return new ResultInfo(ResultState.FAIL, "账户未找到");
|
||||
}
|
||||
var Secret = Md5.md5(Common.CreateNo(), 16).ToLower();
|
||||
var Password = Md5.md5(DESEncrypt.Encrypt(Md5.md5(pwd, 32).ToLower(), Secret).ToLower(), 32).ToLower();
|
||||
await repository.Change<W_Account>().Context.Updateable<W_Account>().SetColumns(x => new W_Account
|
||||
{
|
||||
Secret = Secret,
|
||||
Password = Password
|
||||
}).Where(x => x.BusinessId == id).ExecuteCommandAsync();
|
||||
return new ResultInfo(ResultState.SUCCESS, "密码重置成功");
|
||||
}
|
||||
/// <summary>
|
||||
/// 修改密码
|
||||
/// </summary>
|
||||
/// <param name="busienssPwd"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> ChangePwdAsync(BusienssPwd busienssPwd)
|
||||
{
|
||||
if (busienssPwd.NewPwd != busienssPwd.ReNewPwd)
|
||||
{
|
||||
return new ResultInfo(ResultState.FAIL, "两次密码不一致");
|
||||
}
|
||||
var account = await repository.Change<W_Account>().Context.Queryable<W_Account>().FirstAsync(x => x.Id == currentUser.UserId);
|
||||
if (account == null)
|
||||
{
|
||||
return new ResultInfo(ResultState.FAIL, "账户未找到");
|
||||
}
|
||||
var oldpassword = Md5.md5(DESEncrypt.Encrypt(Md5.md5(busienssPwd.OldPwd, 32).ToLower(), account.Secret).ToLower(), 32).ToLower();
|
||||
if (oldpassword != account.Password)
|
||||
{
|
||||
return new ResultInfo(ResultState.FAIL, "旧密码错误");
|
||||
}
|
||||
var newpassword = Md5.md5(DESEncrypt.Encrypt(Md5.md5(busienssPwd.NewPwd, 32).ToLower(), account.Secret).ToLower(), 32).ToLower();
|
||||
await repository.Change<W_Account>().Context.Updateable<W_Account>().SetColumns(x => new W_Account
|
||||
{
|
||||
Password = newpassword
|
||||
}).Where(x => x.Id == account.Id).ExecuteCommandAsync();
|
||||
return new ResultInfo(ResultState.SUCCESS, "密码修改成功");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 信息提交
|
||||
/// </summary>
|
||||
/// <param name="buss"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> SubmitFormAsync(BusinessInfo buss)
|
||||
{
|
||||
buss.Province = buss.Province.ToStr();
|
||||
buss.City = buss.City.ToStr();
|
||||
buss.Area = buss.Area.ToStr();
|
||||
buss.Remark = buss.Remark.ToStr();
|
||||
buss.Phone = buss.Phone.ToStr();
|
||||
buss.Name = buss.Name.ToStr();
|
||||
buss.Address = buss.Address.ToStr();
|
||||
if (buss.AccountType <= 0 || buss.AccountType != (int)AccountType.platform)
|
||||
{
|
||||
buss.AccountType = (int)AccountType.agent;
|
||||
}
|
||||
Guid roleid = Guid.Parse("39FC70AA-652F-CE76-98A8-5C32D6E5D619");
|
||||
if (currentUser.AccountType == (int)AccountType.platform)
|
||||
{
|
||||
roleid = Guid.Parse("39FC70AA-1CDA-B9CD-5275-3D144841BEDD");
|
||||
}
|
||||
if (buss.Id != Guid.Empty)
|
||||
{
|
||||
if (await dbClient.Queryable<W_Business>().AnyAsync(x => x.Phone == buss.Phone && x.Id != buss.Id))
|
||||
{
|
||||
return new ResultInfo() { code = ResultState.FAIL, message = "手机号已注册!" };
|
||||
}
|
||||
if (await dbClient.Queryable<W_Account>().AnyAsync(x => x.Phone == buss.Phone && x.BusinessId != buss.Id))
|
||||
{
|
||||
return new ResultInfo() { code = ResultState.FAIL, message = "手机号已注册!" };
|
||||
}
|
||||
if (!await dbClient.Queryable<W_Business>().AnyAsync(x => x.Id == buss.Id))
|
||||
{
|
||||
return new ResultInfo() { code = ResultState.FAIL, message = "商户未找到!" };
|
||||
}
|
||||
await dbClient.Updateable<W_Business>().SetColumns(x => new W_Business
|
||||
{
|
||||
Address = buss.Address,
|
||||
Phone = buss.Phone,
|
||||
Name = buss.Name,
|
||||
Area = buss.Area,
|
||||
City = buss.City,
|
||||
Province = buss.Province,
|
||||
Remark = buss.Remark
|
||||
}).Where(x => x.Id == buss.Id).ExecuteCommandAsync();
|
||||
//更新登录账户,如果手机号有变动,则登录账户也变动
|
||||
if (currentUser.AccountType != (int)AccountType.platform)
|
||||
{
|
||||
await dbClient.Updateable<W_Account>().SetColumns(x => new W_Account
|
||||
{
|
||||
Phone = buss.Phone,
|
||||
RealName = buss.Name,
|
||||
UserName = buss.Phone
|
||||
}).Where(x => x.BusinessId == buss.Id).ExecuteCommandAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
await dbClient.Updateable<W_Account>().SetColumns(x => new W_Account
|
||||
{
|
||||
Phone = buss.Phone,
|
||||
RealName = buss.Name,
|
||||
UserName = buss.Phone,
|
||||
AccountType = buss.AccountType,
|
||||
RoleId = roleid
|
||||
}).Where(x => x.BusinessId == buss.Id).ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
return new ResultInfo(ResultState.SUCCESS, "修改成功");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (await dbClient.Queryable<W_Business>().AnyAsync(x => x.Phone == buss.Phone))
|
||||
{
|
||||
return new ResultInfo() { code = ResultState.FAIL, message = "手机号已注册!" };
|
||||
}
|
||||
if (await repository.Change<W_Account>().Context.Queryable<W_Account>().AnyAsync(x => x.Phone == buss.Phone))
|
||||
{
|
||||
return new ResultInfo() { code = ResultState.FAIL, message = "手机号已注册!" };
|
||||
}
|
||||
Guid parentid = Guid.Empty;
|
||||
string code = "";
|
||||
if (currentUser.AccountType != (int)AccountType.platform)
|
||||
{
|
||||
parentid = currentUser.BusinessId;
|
||||
var bcode = currentUser.BusinessCode;
|
||||
var len = bcode.Length;
|
||||
var maxcode = await dbClient.Queryable<W_Business>().Where(x => SqlFunc.StartsWith(x.Code, code) && SqlFunc.Length(x.Code) > len).MaxAsync(x => x.Code);
|
||||
var cnt = maxcode.Substring(maxcode.Length - 4).ToInt();
|
||||
code = GenCode(bcode, cnt);
|
||||
}
|
||||
else
|
||||
{
|
||||
var cnt = (await dbClient.Queryable<W_Business>().Where(x => SqlFunc.Length(x.Code) == 4).MaxAsync(x => x.Code)).ToInt();
|
||||
code = GenCode("", cnt);
|
||||
}
|
||||
var business = new W_Business
|
||||
{
|
||||
ParentId = parentid,
|
||||
Code = code,
|
||||
CreateTime = DateTime.Now,
|
||||
Status = (int)StatusType.Enabled,
|
||||
Address = buss.Address,
|
||||
Area = buss.Area,
|
||||
City = buss.City,
|
||||
Name = buss.Name,
|
||||
Phone = buss.Phone,
|
||||
Province = buss.Province,
|
||||
Remark = buss.Remark,
|
||||
Id = IDGen.NextID()
|
||||
};
|
||||
await dbClient.Insertable<W_Business>(business).ExecuteCommandAsync();
|
||||
//添加登录账户
|
||||
if (string.IsNullOrEmpty(buss.Password))
|
||||
{
|
||||
buss.Password = buss.Phone;
|
||||
}
|
||||
var UserSecretKey = Md5.md5(Common.CreateNo(), 16).ToLower();
|
||||
var Password = Md5.md5(DESEncrypt.Encrypt(Md5.md5(buss.Password, 32).ToLower(), UserSecretKey).ToLower(), 32).ToLower();
|
||||
await dbClient.Insertable<W_Account>(new W_Account
|
||||
{
|
||||
UserName = buss.Phone,
|
||||
RealName = buss.Name,
|
||||
Secret = UserSecretKey,
|
||||
BusinessId = business.Id,
|
||||
Password = Password,
|
||||
AccountType = buss.AccountType,
|
||||
CreateTime = DateTime.Now,
|
||||
Id = business.Id,
|
||||
LastVisitIP = "",
|
||||
Status = (int)StatusType.Enabled,
|
||||
LastVisitTime = null,
|
||||
Phone = buss.Phone,
|
||||
RoleId = roleid
|
||||
}).ExecuteCommandAsync();
|
||||
//插入或者更新实时数据
|
||||
await InsertOrUpdateRealDataAsync();
|
||||
if (currentUser.AccountType != (int)AccountType.platform)
|
||||
{
|
||||
await InsertOrUpdateRealDataAsync(currentUser.BusinessId);
|
||||
}
|
||||
return new ResultInfo(ResultState.SUCCESS, "添加成功");
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 生成用户code
|
||||
/// </summary>
|
||||
/// <param name="code">当前用户的code</param>
|
||||
/// <param name="cnt">名下用户数量</param>
|
||||
/// <returns></returns>
|
||||
private string GenCode(string code, int cnt)
|
||||
{
|
||||
var ccode = "0001";
|
||||
if (cnt < 9)
|
||||
{
|
||||
ccode = $"000{cnt + 1}";
|
||||
}
|
||||
else if (cnt >= 9 && cnt < 99)
|
||||
{
|
||||
ccode = $"00{cnt + 1}";
|
||||
}
|
||||
else if (cnt >= 99 && cnt < 999)
|
||||
{
|
||||
ccode = $"0{cnt + 1}";
|
||||
}
|
||||
else
|
||||
{
|
||||
ccode = $"{cnt + 1}";
|
||||
}
|
||||
if (!string.IsNullOrEmpty(code))
|
||||
{
|
||||
return $"{code}{ccode}";
|
||||
}
|
||||
return ccode;
|
||||
}
|
||||
/// <summary>
|
||||
/// 更新或者插入实时数据
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task InsertOrUpdateRealDataAsync()
|
||||
{
|
||||
//更新总体数据
|
||||
var tdbClient = repository.Change<W_RealData>().Context;
|
||||
int busiensscnt = await repository.Change<W_Business>().Context.Queryable<W_Business>().CountAsync();
|
||||
int devcnt = await dbClient.Queryable<W_Device>().CountAsync();
|
||||
int todaydevactivecnt = await dbClient.Queryable<W_Device>().Where(x => SqlFunc.DateIsSame(x.LastHeartTime, DateTime.Now)).CountAsync();
|
||||
var data = await tdbClient.Queryable<W_RealData>().FirstAsync();
|
||||
if (data == null)
|
||||
{
|
||||
var realdata = new W_RealData
|
||||
{
|
||||
Id = IDGen.NextID(),
|
||||
BusinessCnt = busiensscnt,
|
||||
DevCnt = devcnt,
|
||||
TodayCount = 0,
|
||||
TodayDevActiveCnt = todaydevactivecnt,
|
||||
TodayPureWeight = 0,
|
||||
TodayWeight = 0,
|
||||
TotalCount = 0,
|
||||
TotalPureWeight = 0,
|
||||
TotalWeight = 0
|
||||
};
|
||||
await tdbClient.Insertable<W_RealData>(realdata).ExecuteCommandAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
await tdbClient.Updateable<W_RealData>().SetColumns(x => new W_RealData
|
||||
{
|
||||
DevCnt = devcnt,
|
||||
BusinessCnt = busiensscnt,
|
||||
TodayDevActiveCnt = todaydevactivecnt
|
||||
}).Where(x => x.Id == data.Id).ExecuteCommandAsync();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 更新或者插入指定商户实时数据
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task InsertOrUpdateRealDataAsync(Guid BusinessId)
|
||||
{
|
||||
if (BusinessId != Guid.Empty)
|
||||
{
|
||||
var tdbClient = repository.Change<W_BusinessRealData>().Context;
|
||||
int todaydevactivecnt = await repository.Change<W_Device>().Context.Queryable<W_Device>().Where(x => x.Businessid == BusinessId && SqlFunc.DateIsSame(x.LastHeartTime, DateTime.Now)).CountAsync();
|
||||
int devcnt = await repository.Change<W_Device>().Context.Queryable<W_Device>().Where(x => x.Businessid == BusinessId).CountAsync();
|
||||
int businesscnt = await dbClient.Queryable<W_Business>().Where(x => x.ParentId == BusinessId).CountAsync();
|
||||
if (!await tdbClient.Queryable<W_BusinessRealData>().AnyAsync(x => x.BusinessId == BusinessId))
|
||||
{
|
||||
var realdata = new W_BusinessRealData
|
||||
{
|
||||
TodayDevActiveCnt = todaydevactivecnt,
|
||||
DevCnt = devcnt,
|
||||
BusinessId = BusinessId,
|
||||
Id = IDGen.NextID(),
|
||||
TodayCount = 0,
|
||||
TodayPureWeight = 0,
|
||||
TodayWeight = 0,
|
||||
TotalCount = 0,
|
||||
TotalPureWeight = 0,
|
||||
TotalWeight = 0,
|
||||
BusinessCnt = businesscnt
|
||||
};
|
||||
await tdbClient.Insertable<W_BusinessRealData>(realdata).ExecuteCommandAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
await tdbClient.Updateable<W_BusinessRealData>().SetColumns(x => new W_BusinessRealData
|
||||
{
|
||||
DevCnt = devcnt,
|
||||
TodayDevActiveCnt = todaydevactivecnt,
|
||||
BusinessCnt = businesscnt
|
||||
}).Where(x => x.BusinessId == BusinessId).ExecuteCommandAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 更新或者插入指定商户实时数据
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task InsertOrUpdateRealDataAsync(List<Guid> BusinessId)
|
||||
{
|
||||
if (BusinessId != null && BusinessId.Count > 0)
|
||||
{
|
||||
foreach (var item in BusinessId)
|
||||
{
|
||||
await InsertOrUpdateRealDataAsync(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取账户统计信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<W_RealData> GetTotalInfoAsync()
|
||||
{
|
||||
if (currentUser.AccountType != (int)AccountType.platform)
|
||||
{
|
||||
var data = await repository.Change<W_BusinessRealData>().Context.Queryable<W_BusinessRealData>().FirstAsync();
|
||||
if (data == null)
|
||||
return null;
|
||||
return new W_RealData
|
||||
{
|
||||
DevCnt = data.DevCnt,
|
||||
TodayDevActiveCnt = data.TodayDevActiveCnt,
|
||||
BusinessCnt = 0,
|
||||
TodayCount = data.TodayCount,
|
||||
TodayPureWeight = data.TodayPureWeight,
|
||||
TodayWeight = data.TodayWeight,
|
||||
TotalCount = data.TotalCount,
|
||||
TotalPureWeight = data.TotalPureWeight,
|
||||
TotalWeight = data.TotalWeight
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
var data = await repository.Change<W_RealData>().Context.Queryable<W_RealData>().FirstAsync();
|
||||
return data;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Waste.Domain;
|
||||
|
||||
namespace Waste.Application
|
||||
{
|
||||
public class BusinessInfo : W_Business
|
||||
{
|
||||
/// <summary>
|
||||
/// 密码
|
||||
/// </summary>
|
||||
public string Password { get; set; }
|
||||
/// <summary>
|
||||
/// 账户类型
|
||||
/// </summary>
|
||||
public int AccountType { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 修改密码
|
||||
/// </summary>
|
||||
public class BusienssPwd
|
||||
{
|
||||
/// <summary>
|
||||
/// 旧密码
|
||||
/// </summary>
|
||||
public string OldPwd { get; set; }
|
||||
/// <summary>
|
||||
/// 新密码
|
||||
/// </summary>
|
||||
public string NewPwd { get; set; }
|
||||
/// <summary>
|
||||
/// 确认新密码
|
||||
/// </summary>
|
||||
public string ReNewPwd { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 商户列表
|
||||
/// </summary>
|
||||
public class BusinessList:W_Business
|
||||
{
|
||||
/// <summary>
|
||||
/// 子商户数量
|
||||
/// </summary>
|
||||
public int BusinessCnt { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// 设备数量
|
||||
/// </summary>
|
||||
public int DevCnt { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// 今日活跃设备台数
|
||||
/// </summary>
|
||||
public int TodayDevActiveCnt { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// 今日测量数
|
||||
/// </summary>
|
||||
public int TodayCount { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// 今日重量
|
||||
/// </summary>
|
||||
public decimal TodayWeight { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// 今日净重
|
||||
/// </summary>
|
||||
public decimal TodayPureWeight { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// 累计测量数
|
||||
/// </summary>
|
||||
public int TotalCount { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// 累计重量
|
||||
/// </summary>
|
||||
public decimal TotalWeight { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// 累计净重
|
||||
/// </summary>
|
||||
public decimal TotalPureWeight { get; set; } = 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
using Nirvana.Common;
|
||||
using Nirvana.Common.ApiBase;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Waste.Domain;
|
||||
|
||||
namespace Waste.Application
|
||||
{
|
||||
public interface IBusinessService
|
||||
{
|
||||
Task<PageParms<BusinessList>> GetListAsync(QueryParams param,bool noadmin=false);
|
||||
Task<ResultInfo> SubmitFormAsync(BusinessInfo role);
|
||||
Task<ResultInfo> DeleteFormAsync(Guid keyValue);
|
||||
Task<BusinessInfo> DetailAsync(Guid id);
|
||||
Task<List<W_Business>> GetAllList(int status = 1);
|
||||
/// <summary>
|
||||
/// 重置密码
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="pwd"></param>
|
||||
/// <returns></returns>
|
||||
Task<ResultInfo> ResetPwdAsync(Guid id,string pwd);
|
||||
/// <summary>
|
||||
/// 修改密码
|
||||
/// </summary>
|
||||
/// <param name="busienssPwd"></param>
|
||||
/// <returns></returns>
|
||||
Task<ResultInfo> ChangePwdAsync(BusienssPwd busienssPwd);
|
||||
/// <summary>
|
||||
/// 更新或者插入实时数据
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task InsertOrUpdateRealDataAsync();
|
||||
/// <summary>
|
||||
/// 更新或者插入指定商户实时数据
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task InsertOrUpdateRealDataAsync(Guid BusinessId);
|
||||
|
||||
/// <summary>
|
||||
/// 更新或者插入指定商户实时数据
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task InsertOrUpdateRealDataAsync(List<Guid> BusinessId);
|
||||
/// <summary>
|
||||
/// 获取账户统计信息
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<W_RealData> GetTotalInfoAsync();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
using Furion.DynamicApiController;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Nirvana.Common;
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Waste.Domain;
|
||||
|
||||
namespace Waste.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备接口
|
||||
/// </summary>
|
||||
public class DeviceAppService:IDynamicApiController
|
||||
{
|
||||
private readonly IDeviceService _deviceService;
|
||||
public DeviceAppService(IDeviceService deviceService)
|
||||
{
|
||||
_deviceService = deviceService;
|
||||
}
|
||||
/// <summary>
|
||||
/// 设备列表
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<PageParms<DeviceList>> GetListAsync(QueryParams param)
|
||||
{
|
||||
return await _deviceService.GetListAsync(param);
|
||||
}
|
||||
/// <summary>
|
||||
/// 信息提交
|
||||
/// </summary>
|
||||
/// <param name="role"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> SubmitFormAsync(DeviceSubmit role)
|
||||
{
|
||||
return await _deviceService.SubmitFormAsync(role);
|
||||
}
|
||||
/// <summary>
|
||||
/// 批量操作
|
||||
/// </summary>
|
||||
/// <param name="deviceBatchModel"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> BatchSetAsync(DeviceBatchModel deviceBatchModel)
|
||||
{
|
||||
return await _deviceService.BatchSetAsync(deviceBatchModel);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,349 @@
|
|||
using Furion.DependencyInjection;
|
||||
using Furion.DistributedIDGenerator;
|
||||
using Furion.DynamicApiController;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Nirvana.Common;
|
||||
using Nirvana.Common.ApiBase;
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Waste.Domain;
|
||||
|
||||
namespace Waste.Application.Device
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备管理
|
||||
/// </summary>
|
||||
public class DeviceService : BaseInfoService, IDeviceService, ITransient
|
||||
{
|
||||
private readonly ISqlSugarRepository<W_Device> repository;
|
||||
private readonly SqlSugarClient dbClient;
|
||||
private readonly IBusinessService _businessService;
|
||||
|
||||
public DeviceService(ISqlSugarRepository<W_Device> sqlSugarRepository, IBusinessService businessService)
|
||||
{
|
||||
repository = sqlSugarRepository;
|
||||
dbClient = repository.Context;
|
||||
_businessService = businessService;
|
||||
}
|
||||
/// <summary>
|
||||
/// 设备批量操作
|
||||
/// </summary>
|
||||
/// <param name="deviceBatchModel"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> BatchSetAsync(DeviceBatchModel deviceBatchModel)
|
||||
{
|
||||
var emptyid = Guid.Empty;
|
||||
//设备所属商户列表
|
||||
var busslist = await dbClient.Queryable<W_Device>().Where(x => deviceBatchModel.codes.Contains(x.Id) && x.Businessid != emptyid).Select(x => x.Businessid).ToListAsync();
|
||||
if (deviceBatchModel.type == 1)
|
||||
{
|
||||
busslist.Add(deviceBatchModel.BusinessId);
|
||||
//如果是管理员分配
|
||||
if (currentUser.AccountType == (int)AccountType.platform)
|
||||
{
|
||||
|
||||
await dbClient.Updateable<W_Device>().SetColumns(x => new W_Device
|
||||
{
|
||||
Businessid = deviceBatchModel.BusinessId,
|
||||
ActiveTime = DateTime.Now,
|
||||
Status = (int)DeviceStatus.Run
|
||||
}).Where(x => deviceBatchModel.codes.Contains(x.Id)).ExecuteCommandAsync();
|
||||
await _businessService.InsertOrUpdateRealDataAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
await dbClient.Updateable<W_Device>().SetColumns(x => new W_Device
|
||||
{
|
||||
Businessid = deviceBatchModel.BusinessId
|
||||
}).Where(x => deviceBatchModel.codes.Contains(x.Id)).ExecuteCommandAsync();
|
||||
busslist.Add(currentUser.BusinessId);
|
||||
}
|
||||
await _businessService.InsertOrUpdateRealDataAsync(busslist);
|
||||
return new ResultInfo(ResultState.SUCCESS, "分配成功");
|
||||
}
|
||||
else
|
||||
{
|
||||
deviceBatchModel.BusinessId = currentUser.AccountType != (int)AccountType.platform ? currentUser.BusinessId : Guid.Empty;
|
||||
//如果是管理员回收
|
||||
if (currentUser.AccountType == (int)AccountType.platform)
|
||||
{
|
||||
await dbClient.Updateable<W_Device>().SetColumns(x => new W_Device
|
||||
{
|
||||
Businessid = deviceBatchModel.BusinessId,
|
||||
ActiveTime = null,
|
||||
Status = (int)DeviceStatus.WaitActive
|
||||
}).Where(x => deviceBatchModel.codes.Contains(x.Id)).ExecuteCommandAsync();
|
||||
await _businessService.InsertOrUpdateRealDataAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
await dbClient.Updateable<W_Device>().SetColumns(x => new W_Device
|
||||
{
|
||||
Businessid = deviceBatchModel.BusinessId
|
||||
}).Where(x => deviceBatchModel.codes.Contains(x.Id)).ExecuteCommandAsync();
|
||||
busslist.Add(currentUser.BusinessId);
|
||||
}
|
||||
await _businessService.InsertOrUpdateRealDataAsync(busslist);
|
||||
return new ResultInfo(ResultState.SUCCESS, "回收成功");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 详情
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<DeviceSubmit> DetailAsync(Guid id)
|
||||
{
|
||||
var devicedata = await dbClient.Queryable<W_Device>().FirstAsync(x => x.Id == id);
|
||||
var pltdata = await repository.Change<W_SZDevice>().Context.Queryable<W_SZDevice>().FirstAsync(x => x.DeviceId == devicedata.Id);
|
||||
return new DeviceSubmit
|
||||
{
|
||||
DeviceType = devicedata.DeviceType,
|
||||
Secret = pltdata != null ? pltdata.Secret : "",
|
||||
SecretHash = pltdata != null ? pltdata.SecretHash : "",
|
||||
Address = devicedata.Address,
|
||||
Area = devicedata.Area,
|
||||
City = devicedata.City,
|
||||
DevId = pltdata != null ? pltdata.DevId : "",
|
||||
Ecode = devicedata.Ecode,
|
||||
FacEcode = devicedata.FacEcode,
|
||||
Name = devicedata.Name,
|
||||
NetType = devicedata.NetType,
|
||||
Province = devicedata.Province,
|
||||
Tare = devicedata.Tare,
|
||||
Remark = devicedata.Remark,
|
||||
Id = devicedata.Id
|
||||
};
|
||||
}
|
||||
/// <summary>
|
||||
/// 设备列表
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<PageParms<DeviceList>> GetListAsync(QueryParams param)
|
||||
{
|
||||
RefAsync<int> totalnum = 0;
|
||||
var temquery = dbClient.Queryable<W_Device>();
|
||||
if (param.queryParam != null && param.queryParam.Count > 0)
|
||||
{
|
||||
List<IConditionalModel> conModels = new List<IConditionalModel>();
|
||||
param.queryParam.ForEach(x =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(x.Value))
|
||||
{
|
||||
conModels.Add(new ConditionalModel()
|
||||
{
|
||||
FieldName = x.Name,
|
||||
ConditionalType = (ConditionalType)x.Type,
|
||||
FieldValue = x.Value.Trim()
|
||||
});
|
||||
}
|
||||
});
|
||||
if (conModels.Count > 0)
|
||||
{
|
||||
temquery = temquery.Where(conModels);
|
||||
}
|
||||
}
|
||||
if (currentUser.AccountType != (int)AccountType.platform)
|
||||
{
|
||||
temquery = temquery.Where(x => x.Businessid == currentUser.BusinessId);
|
||||
}
|
||||
string sorts = string.Format("{0} {1}", param.sort, param.order);
|
||||
var query = await temquery.OrderBy(sorts)
|
||||
.Select(x => new DeviceList
|
||||
{
|
||||
Id = x.Id,
|
||||
Name = x.Name,
|
||||
Businessid = x.Businessid,
|
||||
Address = x.Address,
|
||||
Ecode = x.Ecode,
|
||||
FacEcode = x.FacEcode,
|
||||
CreateTime = x.CreateTime,
|
||||
DeviceType = x.DeviceType,
|
||||
LastHeartTime = x.LastHeartTime,
|
||||
NetType = x.NetType,
|
||||
Remark = x.Remark,
|
||||
Status = x.Status,
|
||||
InstallTime = x.InstallTime,
|
||||
ActiveTime = x.ActiveTime,
|
||||
Tare = x.Tare
|
||||
})
|
||||
.Mapper((it, cache) =>
|
||||
{
|
||||
var allbuss = cache.Get(list =>
|
||||
{
|
||||
var ids = list.Where(e => e.Businessid != Guid.Empty).Select(e => e.Businessid).ToList();
|
||||
return repository.Change<W_Business>().Context.Queryable<W_Business>().Where(e => ids.Contains(e.Id)).ToList();
|
||||
});
|
||||
var alldevicerealdata = cache.Get(list =>
|
||||
{
|
||||
var ids = list.Select(e => e.Id).ToList();
|
||||
return repository.Change<W_DeviceRealData>().Context.Queryable<W_DeviceRealData>().Where(e => ids.Contains(e.DeviceId)).ToList();
|
||||
});
|
||||
//判断网络是否在线
|
||||
if (it.LastHeartTime.HasValue && it.LastHeartTime.Value.AddMinutes(16) >= DateTime.Now)
|
||||
{
|
||||
it.NetStatus = (int)DeviceNetStatus.OnLine;
|
||||
}
|
||||
var devicerealdata = alldevicerealdata.FirstOrDefault(e => e.DeviceId == it.Id && e.BusinessId == it.Businessid);
|
||||
if (devicerealdata != null)
|
||||
{
|
||||
it.TodayCount = devicerealdata.TodayCount;
|
||||
it.TodayWeight = devicerealdata.TodayWeigth;
|
||||
it.TotalCount = devicerealdata.TotalCount;
|
||||
it.TotalWeight = devicerealdata.TotalWeight;
|
||||
}
|
||||
var alldevicedata = cache.Get(list =>
|
||||
{
|
||||
var ids = list.Select(e => e.Id).ToList();
|
||||
return repository.Change<W_DeviceData>().Context.Queryable<W_DeviceData>().Where(e => ids.Contains(e.DeviceId)).ToList();
|
||||
});
|
||||
var devicedata = alldevicedata.FirstOrDefault(e => e.DeviceId == it.Id);
|
||||
if (devicedata != null)
|
||||
{
|
||||
it.ICCID = devicedata.ICCID;
|
||||
it.IMEI = devicedata.IMEI;
|
||||
it.IMSI = devicedata.IMSI;
|
||||
it.LastBeatTime = devicedata.LastBeatTime;
|
||||
//判断网络是否在线
|
||||
if (devicedata.LastBeatTime.HasValue && devicedata.LastBeatTime.Value.AddMinutes(16) >= DateTime.Now)
|
||||
{
|
||||
it.NetStatus = (int)DeviceNetStatus.OnLine;
|
||||
}
|
||||
it.sign = (devicedata.Sign.ToDouble() / (6 * 1.0)).ToString("f1");
|
||||
}
|
||||
it.BusinessName = allbuss.FirstOrDefault(e => e.Id == it.Businessid)?.Name;
|
||||
})
|
||||
.ToPageListAsync(param.offset, param.limit, totalnum);
|
||||
return new PageParms<DeviceList>
|
||||
{
|
||||
page = param.offset,
|
||||
Items = query,
|
||||
totalnum = totalnum,
|
||||
limit = param.limit
|
||||
};
|
||||
}
|
||||
/// <summary>
|
||||
/// 信息提交
|
||||
/// </summary>
|
||||
/// <param name="role"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> SubmitFormAsync(DeviceSubmit role)
|
||||
{
|
||||
role.Name = role.Name.ToStr();
|
||||
role.FacEcode = role.FacEcode.ToStr();
|
||||
role.Ecode = role.Ecode.ToStr();
|
||||
role.Remark = role.Remark.ToStr();
|
||||
role.Province = role.Province.ToStr();
|
||||
role.City = role.City.ToStr();
|
||||
role.Area = role.Area.ToStr();
|
||||
role.Address = role.Address.ToStr();
|
||||
role.Secret = role.Secret.ToStr();
|
||||
role.SecretHash = role.SecretHash.ToStr();
|
||||
role.DevId = role.DevId.ToStr();
|
||||
if (role.Id != Guid.Empty)
|
||||
{
|
||||
//检查序列号是否已存在
|
||||
if (await dbClient.Queryable<W_Device>().AnyAsync(x => x.FacEcode == role.FacEcode && x.Id != role.Id))
|
||||
{
|
||||
return new ResultInfo() { code = ResultState.FAIL, message = "此序列号已存在!" };
|
||||
}
|
||||
//检查机器码是否已存在
|
||||
if (await dbClient.Queryable<W_Device>().AnyAsync(x => x.Ecode == role.Ecode && x.Id != role.Id))
|
||||
{
|
||||
return new ResultInfo() { code = ResultState.FAIL, message = "此设备码已存在!" };
|
||||
}
|
||||
await dbClient.Updateable<W_Device>().SetColumns(x => new W_Device
|
||||
{
|
||||
DeviceType = role.DeviceType,
|
||||
Address = role.Address,
|
||||
Area = role.Area,
|
||||
City = role.City,
|
||||
Ecode = role.Ecode,
|
||||
FacEcode = role.FacEcode,
|
||||
Name = role.Name,
|
||||
Remark = role.Remark,
|
||||
NetType = role.NetType,
|
||||
Province = role.Province,
|
||||
Tare = role.Tare
|
||||
}).Where(x => x.Id == role.Id).ExecuteCommandAsync();
|
||||
//更新平台信息
|
||||
var tdbclient = repository.Change<W_SZDevice>().Context;
|
||||
if (!await tdbclient.Queryable<W_SZDevice>().AnyAsync(x => x.DeviceId == role.Id))
|
||||
{
|
||||
await tdbclient.Insertable<W_SZDevice>(new W_SZDevice
|
||||
{
|
||||
DeviceId = role.Id,
|
||||
Secret = role.Secret,
|
||||
SecretHash = role.SecretHash,
|
||||
DevId = role.DevId
|
||||
}).ExecuteCommandAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
await tdbclient.Updateable<W_SZDevice>().SetColumns(x => new W_SZDevice
|
||||
{
|
||||
Secret = role.Secret,
|
||||
SecretHash = role.SecretHash,
|
||||
DevId = role.DevId
|
||||
}).Where(x => x.DeviceId == role.Id).ExecuteCommandAsync();
|
||||
}
|
||||
return new ResultInfo() { code = ResultState.SUCCESS, message = "修改成功!" };
|
||||
}
|
||||
else
|
||||
{
|
||||
//检查序列号是否已存在
|
||||
if (await dbClient.Queryable<W_Device>().AnyAsync(x => x.FacEcode == role.FacEcode))
|
||||
{
|
||||
return new ResultInfo() { code = ResultState.FAIL, message = "此序列号已存在!" };
|
||||
}
|
||||
//检查机器码是否已存在
|
||||
if (await dbClient.Queryable<W_Device>().AnyAsync(x => x.Ecode == role.Ecode))
|
||||
{
|
||||
return new ResultInfo() { code = ResultState.FAIL, message = "此设备码已存在!" };
|
||||
}
|
||||
role.CreateTime = DateTime.Now;
|
||||
role.Status = (int)DeviceStatus.WaitActive;
|
||||
role.Id = IDGen.NextID();
|
||||
await dbClient.Insertable<W_Device>(new W_Device
|
||||
{
|
||||
Id = role.Id,
|
||||
Status = role.Status,
|
||||
ActiveTime = role.ActiveTime,
|
||||
Address = role.Address,
|
||||
Area = role.Area,
|
||||
Businessid = role.Businessid,
|
||||
City = role.City,
|
||||
CreateTime = role.CreateTime,
|
||||
DeviceType = role.DeviceType,
|
||||
Ecode = role.Ecode,
|
||||
FacEcode = role.FacEcode,
|
||||
Remark = role.Remark,
|
||||
InstallTime = role.InstallTime,
|
||||
LastHeartTime = role.LastHeartTime,
|
||||
Name = role.Name,
|
||||
NetType = role.NetType,
|
||||
Province = role.Province,
|
||||
Tare = role.Tare
|
||||
}).ExecuteCommandAsync();
|
||||
//更新平台信息
|
||||
var tdbclient = repository.Change<W_SZDevice>().Context;
|
||||
await tdbclient.Insertable<W_SZDevice>(new W_SZDevice
|
||||
{
|
||||
DeviceId = role.Id,
|
||||
Secret = role.Secret,
|
||||
SecretHash = role.SecretHash,
|
||||
DevId = role.DevId
|
||||
}).ExecuteCommandAsync();
|
||||
|
||||
await _businessService.InsertOrUpdateRealDataAsync();
|
||||
return new ResultInfo() { code = ResultState.SUCCESS, message = "添加成功!" };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Waste.Domain;
|
||||
|
||||
namespace Waste.Application
|
||||
{
|
||||
|
||||
public class DeviceList : W_Device
|
||||
{
|
||||
/// <summary>
|
||||
/// 商户名称
|
||||
/// </summary>
|
||||
public string BusinessName { get; set; }
|
||||
/// <summary>
|
||||
/// ICCID
|
||||
/// </summary>
|
||||
public string ICCID { get; set; } = "";
|
||||
/// <summary>
|
||||
/// IMEI
|
||||
/// </summary>
|
||||
public string IMEI { get; set; } = "";
|
||||
/// <summary>
|
||||
/// IMSI
|
||||
/// </summary>
|
||||
public string IMSI { get; set; } = "";
|
||||
/// <summary>
|
||||
/// 今日测量次数
|
||||
/// </summary>
|
||||
public int TodayCount { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// 累计测量次数
|
||||
/// </summary>
|
||||
public int TotalCount { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// 今日测量重量
|
||||
/// </summary>
|
||||
public decimal TodayWeight { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// 累计测量重量
|
||||
/// </summary>
|
||||
public decimal TotalWeight { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// 最近心跳时间
|
||||
/// </summary>
|
||||
public DateTime? LastBeatTime { get; set; }
|
||||
/// <summary>
|
||||
/// 网络状态,0-离线,1-在线,规则:最新测量时间、最近心跳时间在16分钟之内则是在线
|
||||
/// </summary>
|
||||
public int NetStatus { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// 信号强度,分为5格信号,算法为:31/6
|
||||
/// </summary>
|
||||
public string sign { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 设备批量操作
|
||||
/// </summary>
|
||||
public class DeviceBatchModel
|
||||
{
|
||||
/// <summary>
|
||||
/// 服务商ID
|
||||
/// </summary>
|
||||
public Guid BusinessId { get; set; }
|
||||
/// <summary>
|
||||
/// 操作类型,1-分配,2-回收
|
||||
/// </summary>
|
||||
public int type { get; set; }
|
||||
/// <summary>
|
||||
/// 设备ID列表
|
||||
/// </summary>
|
||||
public List<Guid> codes { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 设备信息提交
|
||||
/// </summary>
|
||||
public class DeviceSubmit:W_Device
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备对应的SecretHash
|
||||
/// </summary>
|
||||
public string SecretHash { get; set; }
|
||||
/// <summary>
|
||||
/// 设备对应的DevId
|
||||
/// </summary>
|
||||
public string DevId { get; set; }
|
||||
/// <summary>
|
||||
/// 设备对应的Secret
|
||||
/// </summary>
|
||||
public string Secret { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
using Nirvana.Common;
|
||||
using Nirvana.Common.ApiBase;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Waste.Domain;
|
||||
|
||||
namespace Waste.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备管理
|
||||
/// </summary>
|
||||
public interface IDeviceService
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备列表
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
/// <returns></returns>
|
||||
Task<PageParms<DeviceList>> GetListAsync(QueryParams param);
|
||||
/// <summary>
|
||||
/// 设备信息提交
|
||||
/// </summary>
|
||||
/// <param name="role"></param>
|
||||
/// <returns></returns>
|
||||
Task<ResultInfo> SubmitFormAsync(DeviceSubmit role);
|
||||
/// <summary>
|
||||
/// 详情
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
Task<DeviceSubmit> DetailAsync(Guid id);
|
||||
/// <summary>
|
||||
/// 设备批量操作
|
||||
/// </summary>
|
||||
/// <param name="deviceBatchModel"></param>
|
||||
/// <returns></returns>
|
||||
Task<ResultInfo> BatchSetAsync(DeviceBatchModel deviceBatchModel);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,14 @@
|
|||
using Furion.DependencyInjection;
|
||||
using Furion.FriendlyException;
|
||||
using Microsoft.AspNetCore.Diagnostics;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Nirvana.Common;
|
||||
using Nirvana.Common.ApiBase;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
|
@ -11,16 +17,55 @@ namespace Waste.Application
|
|||
{
|
||||
public class LogExceptionHandler : IGlobalExceptionHandler, ISingleton
|
||||
{
|
||||
private readonly ILoggerService _loggerService;
|
||||
|
||||
public LogExceptionHandler(ILoggerService loggerService)
|
||||
{
|
||||
_loggerService = loggerService;
|
||||
}
|
||||
/// <summary>
|
||||
/// 全局异常处理提供器
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <returns></returns>
|
||||
public Task OnExceptionAsync(ExceptionContext context)
|
||||
public async Task OnExceptionAsync(ExceptionContext context)
|
||||
{
|
||||
// 写日志
|
||||
|
||||
return Task.CompletedTask;
|
||||
if (context != null)
|
||||
{
|
||||
var ex = context.HttpContext.Features.Get<IExceptionHandlerFeature>();
|
||||
//如果是用户取消的异常,则不必记录到日志
|
||||
if (context.HttpContext.RequestAborted.IsCancellationRequested && (ex is TaskCanceledException || ex is OperationCanceledException))
|
||||
{
|
||||
Console.WriteLine("用户取消了操作");
|
||||
context.HttpContext.Response.StatusCode = 200;
|
||||
var contentresult = new ContentResult();
|
||||
contentresult.Content = "操作已取消";
|
||||
context.Result = contentresult;
|
||||
}
|
||||
else
|
||||
{
|
||||
var request = context.HttpContext.Request;
|
||||
var action = request.Path.Value;
|
||||
var query_string = request.QueryString.Value;
|
||||
if (request.Method == "POST" && request.ContentLength > 0)
|
||||
{
|
||||
request.EnableBuffering();
|
||||
request.Body.Position = 0;
|
||||
using (var sr = new StreamReader(request.Body))
|
||||
{
|
||||
query_string = await sr.ReadToEndAsync();
|
||||
}
|
||||
}
|
||||
//记录日志
|
||||
var exs = context.Exception;
|
||||
_loggerService.AddErrorLogger(exs, query_string, action);
|
||||
context.HttpContext.Response.StatusCode = 200;
|
||||
var contentresult = new ContentResult();
|
||||
contentresult.Content= "系统异常";
|
||||
context.Result = contentresult;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,18 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Waste.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// 日志处理
|
||||
/// </summary>
|
||||
public interface ILoggerService
|
||||
{
|
||||
void AddLogger(string msg, int type);
|
||||
|
||||
void AddErrorLogger(Exception ex, string param = "", string program = "", int type = 1);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
using Furion.DependencyInjection;
|
||||
using Serilog;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Waste.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// 日志处理
|
||||
/// </summary>
|
||||
public class LoggerService : ILoggerService, ITransient
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
public LoggerService(ILogger logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
/// <summary>
|
||||
/// 添加日志
|
||||
/// </summary>
|
||||
/// <param name="ex"></param>
|
||||
/// <param name="param"></param>
|
||||
/// <param name="program"></param>
|
||||
/// <param name="type"></param>
|
||||
public void AddErrorLogger(Exception ex, string param = "", string program = "", int type = 1)
|
||||
{
|
||||
var msg = $"ex:{ex.Message}\r\nsource:{ex.Source}\r\nstack:{ex.StackTrace}\r\n";
|
||||
if (ex.InnerException != null)
|
||||
{
|
||||
msg = $"{msg}InnerException.Message:{ex.InnerException.Message}\r\nInnerException.Source:{ex.InnerException.Source}\r\nInnerException.StackTrace:{ex.InnerException.StackTrace}\r\n";
|
||||
}
|
||||
if (!string.IsNullOrEmpty(param))
|
||||
{
|
||||
msg = $"参数:{param}\r\n{msg}";
|
||||
}
|
||||
if (!string.IsNullOrEmpty(program))
|
||||
{
|
||||
msg = $"接口:{program}\r\n{msg}";
|
||||
}
|
||||
AddLogger(msg, type);
|
||||
}
|
||||
/// <summary>
|
||||
/// 添加日志
|
||||
/// </summary>
|
||||
/// <param name="msg"></param>
|
||||
/// <param name="type"></param>
|
||||
public void AddLogger(string msg, int type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case 1:
|
||||
_logger.Error(msg);
|
||||
break;
|
||||
case 2:
|
||||
_logger.Information(msg);
|
||||
break;
|
||||
case 3:
|
||||
_logger.Warning(msg);
|
||||
break;
|
||||
case 4:
|
||||
_logger.Debug(msg);
|
||||
break;
|
||||
case 5:
|
||||
_logger.Fatal(msg);
|
||||
break;
|
||||
default:
|
||||
_logger.Error(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
using Mapster;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Waste.Domain;
|
||||
|
||||
namespace Waste.Application
|
||||
{
|
||||
public class Mapper : IRegister
|
||||
{
|
||||
public void Register(TypeAdapterConfig config)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
using Furion.DynamicApiController;
|
||||
using Nirvana.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Waste.Application.PostInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 对接平台接口测试
|
||||
/// </summary>
|
||||
public class PostInfoAppService: IDynamicApiController
|
||||
{
|
||||
private readonly ISuZhouService _suZhouService;
|
||||
public PostInfoAppService(ISuZhouService suZhouService)
|
||||
{
|
||||
_suZhouService = suZhouService;
|
||||
}
|
||||
/// <summary>
|
||||
/// Hello接口GET测试
|
||||
/// </summary>
|
||||
/// <param name="greet"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> GetHelloAsync(string greet="hello")
|
||||
{
|
||||
return await _suZhouService.GetHelloAsync(greet);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Hello接口POST测试
|
||||
/// </summary>
|
||||
/// <param name="greet"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> PostHelloAsync(string greet = "hello")
|
||||
{
|
||||
return await _suZhouService.PostHelloAsync(greet);
|
||||
}
|
||||
/// <summary>
|
||||
/// 分页查询当前账号下存在的地产区域数据
|
||||
/// </summary>
|
||||
/// <param name="page"></param>
|
||||
/// <param name="size"></param>
|
||||
/// <param name="search"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> GetEstatesAsync(int page = 1, int size = 10, string search = "")
|
||||
{
|
||||
return await _suZhouService.GetEstatesAsync(page, size, search);
|
||||
}
|
||||
/// <summary>
|
||||
/// 添加地产区域信息
|
||||
/// </summary>
|
||||
/// <param name="estatesC2SDto"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> PostEstatesAsync(EstatesC2SDto estatesC2SDto)
|
||||
{
|
||||
return await _suZhouService.PostEstatesAsync(estatesC2SDto);
|
||||
}
|
||||
/// <summary>
|
||||
/// 查询地产区域信息
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> GetEstatesByIdAsync(string id)
|
||||
{
|
||||
return await _suZhouService.GetEstatesByIdAsync(id);
|
||||
}
|
||||
/// <summary>
|
||||
/// 向服务端推送测试用垃圾采集数据
|
||||
/// </summary>
|
||||
/// <param name="garbageC2SDto"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> PostGarbagesAsync(GarbageC2SDto garbageC2SDto)
|
||||
{
|
||||
return await _suZhouService.PostGarbagesAsync(garbageC2SDto);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,302 @@
|
|||
using MessagePack;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Waste.Application
|
||||
{
|
||||
|
||||
[MessagePackObject]
|
||||
public class SuZhouApiBaseDto
|
||||
{
|
||||
[Key("secret")]
|
||||
public string SecretHash { get; set; }
|
||||
|
||||
[Key("nonce")]
|
||||
public int Nonce { get; set; }
|
||||
|
||||
[Key("sign")]
|
||||
public string Signature { get; set; }
|
||||
|
||||
[Key("time")]
|
||||
public long TimeStamp { get; set; }
|
||||
|
||||
[Key("user")]
|
||||
public string UserId { get; set; }
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
public class SuZhouPostApiBaseDto
|
||||
{
|
||||
[Key("secret")]
|
||||
public string SecretHash { get; set; }
|
||||
|
||||
[Key("nonce")]
|
||||
public int Nonce { get; set; }
|
||||
|
||||
[Key("sign")]
|
||||
public string Signature { get; set; }
|
||||
|
||||
[Key("time")]
|
||||
public int TimeStamp { get; set; }
|
||||
/// <summary>
|
||||
/// 设备ID
|
||||
/// </summary>
|
||||
[Key("device")]
|
||||
public string DeviceId { get; set; }
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
public class SuZhouPostApiBaseDto<T> : SuZhouPostApiBaseDto
|
||||
{
|
||||
[Key("data")]
|
||||
public T Data { get; set; }
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
public class SuZhouApiBaseDto<T> : SuZhouApiBaseDto
|
||||
{
|
||||
[Key("data")]
|
||||
public T Data { get; set; }
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
public class EstatesBaseS2CDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 页码
|
||||
/// </summary>
|
||||
[Key("PageIndex")]
|
||||
public int PageIndex { get; set; }
|
||||
/// <summary>
|
||||
/// 总页数
|
||||
/// </summary>
|
||||
[Key("TotalPages")]
|
||||
public int TotalPages { get; set; }
|
||||
/// <summary>
|
||||
/// 总条数
|
||||
/// </summary>
|
||||
[Key("Itemcount")]
|
||||
public int Itemcount { get; set; }
|
||||
}
|
||||
[MessagePackObject]
|
||||
public class EstatesBaseS2CDto<T>:EstatesBaseS2CDto
|
||||
{
|
||||
[Key("Data")]
|
||||
public T Data { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 添加地产区域信息
|
||||
/// </summary>
|
||||
[MessagePackObject]
|
||||
public class EstatesC2SDto //客户端向服务端请求的DTO
|
||||
{
|
||||
/// <summary>
|
||||
/// 地产区域编码,不可重复, 长度限制2到32
|
||||
/// </summary>
|
||||
[Key("code")]
|
||||
public string Code { get; set; }
|
||||
/// <summary>
|
||||
/// 名称,长度限制2到32
|
||||
/// </summary>
|
||||
[Key("name")]
|
||||
public string Name { get; set; }
|
||||
/// <summary>
|
||||
/// 地址,长度限制4到128
|
||||
/// </summary>
|
||||
[Key("addr")]
|
||||
public string Addr { get; set; }
|
||||
/// <summary>
|
||||
/// 城市编码 ,例:320500000000(苏州)
|
||||
/// </summary>
|
||||
[Key("city")]
|
||||
public string City { get; set; }
|
||||
/// <summary>
|
||||
/// 区域编码 ,例:320507000000(相城)
|
||||
/// </summary>
|
||||
[Key("area")]
|
||||
public string Area { get; set; }
|
||||
/// <summary>
|
||||
/// 街道编码,例:320507105000(渭塘镇)
|
||||
/// </summary>
|
||||
[Key("street")]
|
||||
public string Street { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 添加地产区域返回信息
|
||||
/// </summary>
|
||||
[MessagePackObject]
|
||||
public class EstatesS2CDto//服务端向客户端返回结果的DTO
|
||||
{
|
||||
/// <summary>
|
||||
/// 地产区域ID
|
||||
/// </summary>
|
||||
[Key(0)] //服务端向客户端返回的DTO以元组形式编排参数,所以Key标注为index,从0开始.
|
||||
public string id { get; set; }
|
||||
/// <summary>
|
||||
/// 地产区域编码
|
||||
/// </summary>
|
||||
[Key(1)]
|
||||
public string code { get; set; }
|
||||
/// <summary>
|
||||
/// 地产区域所在地址
|
||||
/// </summary>
|
||||
[Key(2)]
|
||||
public string addr { get; set; }
|
||||
/// <summary>
|
||||
/// 城市编码
|
||||
/// </summary>
|
||||
[Key(3)]
|
||||
public string city { get; set; }
|
||||
/// <summary>
|
||||
/// 区域编码
|
||||
/// </summary>
|
||||
[Key(4)]
|
||||
public string area { get; set; }
|
||||
/// <summary>
|
||||
/// 街道编码
|
||||
/// </summary>
|
||||
[Key(5)]
|
||||
public string street { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加采集点信息
|
||||
/// </summary>
|
||||
[MessagePackObject]
|
||||
public class CollectC2SDto //客户端向服务端请求的DTO
|
||||
{
|
||||
/// <summary>
|
||||
/// 编码,不可重复, 长度限制2到32
|
||||
/// </summary>
|
||||
[Key("code")]
|
||||
public string Code { get; set; }
|
||||
/// <summary>
|
||||
/// 名称,长度限制2到32
|
||||
/// </summary>
|
||||
[Key("name")]
|
||||
public string Name { get; set; }
|
||||
/// <summary>
|
||||
/// 地址,长度限制4到128
|
||||
/// </summary>
|
||||
[Key("addr")]
|
||||
public string Addr { get; set; }
|
||||
/// <summary>
|
||||
/// 地产区域ID
|
||||
/// </summary>
|
||||
[Key("estate")]
|
||||
public string Estate { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 添加采集点返回信息
|
||||
/// </summary>
|
||||
[MessagePackObject]
|
||||
public class CollectS2CDto//服务端向客户端返回结果的DTO
|
||||
{
|
||||
/// <summary>
|
||||
/// 采集点ID
|
||||
/// </summary>
|
||||
[Key(0)] //服务端向客户端返回的DTO以元组形式编排参数,所以Key标注为index,从0开始.
|
||||
public string id { get; set; }
|
||||
/// <summary>
|
||||
/// 编码
|
||||
/// </summary>
|
||||
[Key(1)]
|
||||
public string code { get; set; }
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
[Key(2)]
|
||||
public string name { get; set; }
|
||||
/// <summary>
|
||||
/// 地址
|
||||
/// </summary>
|
||||
[Key(3)]
|
||||
public string addr { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 后台推送数据
|
||||
/// </summary>
|
||||
public class GarbagePltC2SDto: GarbageC2SDto
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备ID
|
||||
/// </summary>
|
||||
public string deviceid { get; set; }
|
||||
/// <summary>
|
||||
/// secret
|
||||
/// </summary>
|
||||
public string secret { get; set; }
|
||||
/// <summary>
|
||||
/// secrethash
|
||||
/// </summary>
|
||||
public string secrethash { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 向服务端推送测试用垃圾采集数据
|
||||
/// </summary>
|
||||
[MessagePackObject]
|
||||
public class GarbageC2SDto //客户端向服务端请求的DTO
|
||||
{
|
||||
/// <summary>
|
||||
/// 垃圾称重数据,64位浮点进度,单位为千克
|
||||
/// </summary>
|
||||
[Key("weight")]
|
||||
public double Weight { get; set; }
|
||||
/// <summary>
|
||||
/// 垃圾桶编码
|
||||
/// </summary>
|
||||
[Key("trash")]
|
||||
public string Trash { get; set; }
|
||||
/// <summary>
|
||||
/// 垃圾类型,缺省类型 : 0,厨余垃圾 : 1,可回收物 : 2,有害垃圾 : 3,其他垃圾 : 4
|
||||
/// </summary>
|
||||
[Key("type")]
|
||||
public int Type { get; set; }
|
||||
/// <summary>
|
||||
/// 数据扫描时间,UNIX时间戳
|
||||
/// </summary>
|
||||
[Key("scanningTime")]
|
||||
public int ScanningTime { get; set; }
|
||||
/// <summary>
|
||||
/// 设备状态,使用中 : 0:使用中,异常 : 1,检修 : 2,检修结束 : 3,启用 : 4,未知 : 5
|
||||
/// </summary>
|
||||
[Key("d_status")]
|
||||
public int DStatus { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Hello测试
|
||||
/// </summary>
|
||||
[MessagePackObject]
|
||||
public class HelloC2SDto //客户端向服务端请求的DTO
|
||||
{
|
||||
[Key("greet")]
|
||||
public string Greet { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Hello测试返回
|
||||
/// </summary>
|
||||
[MessagePackObject]
|
||||
public class HelloS2CDto //服务端向客户端返回结果的DTO
|
||||
{
|
||||
[Key(0)] //服务端向客户端返回的DTO以元组形式编排参数,所以Key标注为index,从0开始.
|
||||
public string Message { get; set; }
|
||||
|
||||
[Key(1)]
|
||||
public int Code { get; set; }
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
public class FailS2CDto //错误的时候服务端返回的数据
|
||||
{
|
||||
|
||||
[Key(0)]
|
||||
public string msg { get; set; }
|
||||
|
||||
[Key(1)] //服务端向客户端返回的DTO以元组形式编排参数,所以Key标注为index,从0开始.
|
||||
public int code { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
using Nirvana.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Waste.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// 苏州设备对接平台
|
||||
/// </summary>
|
||||
public interface ISuZhouService
|
||||
{
|
||||
/// <summary>
|
||||
/// Hello接口GET测试
|
||||
/// </summary>
|
||||
/// <param name="greet"></param>
|
||||
/// <returns></returns>
|
||||
Task<ResultInfo> GetHelloAsync(string greet);
|
||||
/// <summary>
|
||||
/// Hello接口Post测试
|
||||
/// </summary>
|
||||
/// <param name="greet"></param>
|
||||
/// <returns></returns>
|
||||
Task<ResultInfo> PostHelloAsync(string greet);
|
||||
/// <summary>
|
||||
/// 分页查询当前账号下存在的地产区域数据
|
||||
/// </summary>
|
||||
/// <param name="page"></param>
|
||||
/// <param name="size"></param>
|
||||
/// <param name="search"></param>
|
||||
/// <returns></returns>
|
||||
Task<ResultInfo> GetEstatesAsync(int page = 1, int size = 10, string search = "");
|
||||
/// <summary>
|
||||
/// 添加地产区域信息
|
||||
/// </summary>
|
||||
/// <param name="estatesC2SDto"></param>
|
||||
/// <returns></returns>
|
||||
Task<ResultInfo> PostEstatesAsync(EstatesC2SDto estatesC2SDto);
|
||||
/// <summary>
|
||||
/// 查询地产区域信息
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
Task<ResultInfo> GetEstatesByIdAsync(string id);
|
||||
/// <summary>
|
||||
/// 向服务端推送测试用垃圾采集数据
|
||||
/// </summary>
|
||||
/// <param name="garbageC2SDto"></param>
|
||||
/// <returns></returns>
|
||||
Task<ResultInfo> PostGarbagesAsync(GarbageC2SDto garbageC2SDto);
|
||||
|
||||
/// <summary>
|
||||
/// 向服务端推送测试用垃圾采集数据
|
||||
/// </summary>
|
||||
/// <param name="garbageC2SDto"></param>
|
||||
/// <returns></returns>
|
||||
Task<ResultInfo> PostGarbagesAsync(GarbagePltC2SDto garbageC2SDto);
|
||||
/// <summary>
|
||||
/// 删除地产区域
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
Task<ResultInfo> DeleteEstates(string id);
|
||||
|
||||
/// <summary>
|
||||
/// 删除采集点
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
Task<ResultInfo> DeleteCollect(string id);
|
||||
|
||||
/// <summary>
|
||||
/// 添加采集点
|
||||
/// </summary>
|
||||
/// <param name="estatesC2SDto"></param>
|
||||
/// <returns></returns>
|
||||
Task<ResultInfo> PostCollectAsync(CollectC2SDto estatesC2SDto);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,451 @@
|
|||
using Furion;
|
||||
using Furion.DependencyInjection;
|
||||
using Furion.RemoteRequest.Extensions;
|
||||
using MessagePack;
|
||||
using Nirvana.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Waste.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// 苏州设备对接平台
|
||||
/// </summary>
|
||||
public class SuZhouService : ISuZhouService, ITransient
|
||||
{
|
||||
private static string ApiUrl = App.Configuration["SZDevPlatSetting:ApiUrl"];
|
||||
private static string UserId = App.Configuration["SZDevPlatSetting:UserId"];
|
||||
private static string ApiSecret = App.Configuration["SZDevPlatSetting:ApiSecret"];
|
||||
private static string ApiSecretHash = App.Configuration["SZDevPlatSetting:ApiSecretHash"];
|
||||
private readonly IHttpClientFactory _clientFactory;
|
||||
private readonly ILoggerService _loggerService;
|
||||
public SuZhouService(IHttpClientFactory clientFactory, ILoggerService loggerService)
|
||||
{
|
||||
_clientFactory = clientFactory;
|
||||
_loggerService = loggerService;
|
||||
}
|
||||
/// <summary>
|
||||
/// 分页查询当前账号下存在的地产区域数据
|
||||
/// </summary>
|
||||
/// <param name="page"></param>
|
||||
/// <param name="size"></param>
|
||||
/// <param name="search"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> GetEstatesAsync(int page = 1, int size = 10, string search = "")
|
||||
{
|
||||
|
||||
var url = $"{ApiUrl}/api/estates?page={page}&size={size}&search={search}";
|
||||
var response = await GetDataAsync(url, 1, "");
|
||||
var resdata = await response.Content.ReadAsByteArrayAsync();
|
||||
var s2c_dto = MessagePackSerializer.Deserialize<EstatesBaseS2CDto<EstatesS2CDto>>(resdata);
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
return new ResultInfo(ResultState.SUCCESS, "success", s2c_dto);
|
||||
}
|
||||
else
|
||||
{
|
||||
var msg = await response.Content.ReadAsStringAsync();
|
||||
return new ResultInfo(ResultState.FAIL, msg);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 查询地产区域信息
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> GetEstatesByIdAsync(string id)
|
||||
{
|
||||
var url = $"{ApiUrl}/api/estates/{id}";
|
||||
var response = await GetDataAsync(url, 1, "");
|
||||
var resdata = await response.Content.ReadAsByteArrayAsync();
|
||||
var s2c_dto = MessagePackSerializer.Deserialize<EstatesS2CDto>(resdata);
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
return new ResultInfo(ResultState.SUCCESS, "success", s2c_dto);
|
||||
}
|
||||
else
|
||||
{
|
||||
var msg = await response.Content.ReadAsStringAsync();
|
||||
return new ResultInfo(ResultState.FAIL, msg);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Hello接口GET测试
|
||||
/// </summary>
|
||||
/// <param name="greet"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> GetHelloAsync(string greet)
|
||||
{
|
||||
var url = $"{ApiUrl}/api/hello/{greet}";
|
||||
var response = await GetDataAsync(url, 2, greet);
|
||||
var resdata = await response.Content.ReadAsStringAsync();
|
||||
var returndata = "";
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
returndata = $"成功:{resdata}";
|
||||
}
|
||||
else
|
||||
{
|
||||
returndata = $"失败:{resdata}";
|
||||
}
|
||||
return new ResultInfo(ResultState.SUCCESS, "success", returndata);
|
||||
}
|
||||
/// <summary>
|
||||
/// 添加地产区域信息
|
||||
/// </summary>
|
||||
/// <param name="estatesC2SDto"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> PostEstatesAsync(EstatesC2SDto estatesC2SDto)
|
||||
{
|
||||
var url = $"{ApiUrl}/api/estates";
|
||||
string[] paramlist = new string[] {
|
||||
estatesC2SDto.Code,estatesC2SDto.Name,estatesC2SDto.Addr,estatesC2SDto.City,estatesC2SDto.Area,estatesC2SDto.Street
|
||||
};
|
||||
var response = await PostDataAsync(url, 1, estatesC2SDto, paramlist);
|
||||
var resdata = await response.Content.ReadAsByteArrayAsync();
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var s2c_dto = MessagePackSerializer.Deserialize<EstatesS2CDto>(resdata);
|
||||
return new ResultInfo(ResultState.SUCCESS, "success", s2c_dto.id);
|
||||
}
|
||||
else
|
||||
{
|
||||
var msg = await response.Content.ReadAsStringAsync();
|
||||
return new ResultInfo(ResultState.FAIL, msg);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 向服务端推送测试用垃圾采集数据
|
||||
/// </summary>
|
||||
/// <param name="garbageC2SDto"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> PostGarbagesAsync(GarbageC2SDto garbageC2SDto)
|
||||
{
|
||||
var url = $"{ApiUrl}/api/garbages";
|
||||
string[] paramlist = new string[] {
|
||||
garbageC2SDto.Weight.ToString(),garbageC2SDto.Trash,garbageC2SDto.Type.ToString(),garbageC2SDto.ScanningTime.ToString(),garbageC2SDto.DStatus.ToString()
|
||||
};
|
||||
int timestamp = GetTimestamp();
|
||||
int nonce = GetNonce();
|
||||
string sign = GetUserApiSign("8137VxS0S01eooVc", paramlist);
|
||||
var c2s_dto = new SuZhouPostApiBaseDto<GarbageC2SDto>
|
||||
{
|
||||
Data = garbageC2SDto,
|
||||
SecretHash = "1eca5f6af7d84fb3",
|
||||
Nonce = nonce,
|
||||
Signature = sign,
|
||||
TimeStamp = timestamp,
|
||||
DeviceId = "08d92039-6b06-4650-8691-f71d4aa52f0a"
|
||||
};
|
||||
var request = new HttpRequestMessage(HttpMethod.Post, url);
|
||||
var bytes = MessagePackSerializer.Serialize(c2s_dto);
|
||||
request.Content = new ByteArrayContent(bytes);
|
||||
request.Headers.Add("Accept", "application/x-msgpack");
|
||||
request.Content.Headers.Add("Content-Type", "application/x-msgpack");
|
||||
var client = _clientFactory.CreateClient();
|
||||
var response = await client.SendAsync(request);
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
return new ResultInfo(ResultState.SUCCESS, "success");
|
||||
}
|
||||
else
|
||||
{
|
||||
var msg = await response.Content.ReadAsStringAsync();
|
||||
return new ResultInfo(ResultState.FAIL, msg);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Hello接口Post测试
|
||||
/// </summary>
|
||||
/// <param name="greet"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> PostHelloAsync(string greet)
|
||||
{
|
||||
var url = $"{ApiUrl}/api/hello";
|
||||
var hello_dto = new HelloC2SDto
|
||||
{
|
||||
Greet = greet
|
||||
};
|
||||
var response = await PostDataAsync(url, 1, hello_dto, greet);
|
||||
var resdata = await response.Content.ReadAsByteArrayAsync();
|
||||
var s2c_dto = MessagePackSerializer.Deserialize<HelloS2CDto>(resdata);
|
||||
var returndata = "";
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
returndata = $"成功:{s2c_dto.Message},{s2c_dto.Code}";
|
||||
}
|
||||
else
|
||||
{
|
||||
returndata = $"失败:{s2c_dto.Message},{s2c_dto.Code}";
|
||||
}
|
||||
return new ResultInfo(ResultState.SUCCESS, "success", returndata);
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取时间戳
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static int GetTimestamp()
|
||||
{
|
||||
DateTime dateTimeStart = TimeZoneInfo.ConvertTimeToUtc(new DateTime(1970, 1, 1, 8, 0, 0));
|
||||
int timestamp = Convert.ToInt32((DateTime.Now - dateTimeStart).TotalSeconds);
|
||||
return timestamp;
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取随机数
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
private static int GetNonce()
|
||||
{
|
||||
var random = new Random();
|
||||
int nonce = random.Next(1, Int32.MaxValue);
|
||||
return nonce;
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取签名
|
||||
/// </summary>
|
||||
/// <param name="secret"></param>
|
||||
/// <param name="dataparams"></param>
|
||||
/// <returns></returns>
|
||||
private static string GetUserApiSign(string secret, params string[] dataparams)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
if (dataparams != null && dataparams.Length > 0)
|
||||
{
|
||||
foreach (var item in dataparams)
|
||||
{
|
||||
sb.Append(item);
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(secret))
|
||||
{
|
||||
sb.Append(secret);
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append(ApiSecret);
|
||||
}
|
||||
string str = sb.ToString();
|
||||
string sign = Md5.md5(str, 16).ToLower();
|
||||
return sign;
|
||||
}
|
||||
/// <summary>
|
||||
/// POST封装接口
|
||||
/// </summary>
|
||||
/// <param name="url">地址</param>
|
||||
/// <param name="type">1-返回参数为msgpack,2-返回参数为text</param>
|
||||
/// <param name="postdata">post的数据</param>
|
||||
/// <param name="data">加密参数</param>
|
||||
/// <returns></returns>
|
||||
private async Task<HttpResponseMessage> PostDataAsync(string url, int type, object postdata, params string[] data)
|
||||
{
|
||||
int timestamp = GetTimestamp();
|
||||
int nonce = GetNonce();
|
||||
string sign = GetUserApiSign("", data);
|
||||
var c2s_dto = new SuZhouApiBaseDto<object>
|
||||
{
|
||||
Data = postdata,
|
||||
SecretHash = ApiSecretHash,
|
||||
Nonce = nonce,
|
||||
Signature = sign,
|
||||
TimeStamp = timestamp,
|
||||
UserId = UserId
|
||||
};
|
||||
var request = new HttpRequestMessage(HttpMethod.Post, url);
|
||||
var bytes = MessagePackSerializer.Serialize(c2s_dto);
|
||||
request.Content = new ByteArrayContent(bytes);
|
||||
if (type == 2)
|
||||
{
|
||||
request.Headers.Add("Accept", "text/plain");
|
||||
}
|
||||
else
|
||||
{
|
||||
request.Headers.Add("Accept", "application/x-msgpack");
|
||||
}
|
||||
request.Content.Headers.Add("Content-Type", "application/x-msgpack");
|
||||
var client = _clientFactory.CreateClient();
|
||||
var response = await client.SendAsync(request);
|
||||
var testdata = await response.Content.ReadAsStringAsync();
|
||||
return response;
|
||||
}
|
||||
/// <summary>
|
||||
/// GET接口封装
|
||||
/// </summary>
|
||||
/// <param name="url">地址</param>
|
||||
/// <param name="type">1-返回参数为msgpack,2-返回参数为text</param>
|
||||
/// <param name="data">加密参数</param>
|
||||
/// <returns></returns>
|
||||
private async Task<HttpResponseMessage> GetDataAsync(string url, int type, params string[] data)
|
||||
{
|
||||
int timestamp = GetTimestamp();
|
||||
int nonce = GetNonce();
|
||||
string sign = GetUserApiSign("", data);
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, url);
|
||||
if (type == 2)
|
||||
{
|
||||
request.Headers.Add("Accept", "text/plain");
|
||||
}
|
||||
else
|
||||
{
|
||||
request.Headers.Add("Accept", "application/x-msgpack");
|
||||
}
|
||||
request.Headers.Add("secret", ApiSecretHash);
|
||||
request.Headers.Add("nonce", nonce.ToString());
|
||||
request.Headers.Add("time", timestamp.ToString());
|
||||
request.Headers.Add("user", UserId);
|
||||
request.Headers.Add("sign", sign);
|
||||
var client = _clientFactory.CreateClient();
|
||||
var response = await client.SendAsync(request);
|
||||
var testdata = await response.Content.ReadAsStringAsync();
|
||||
return response;
|
||||
}
|
||||
/// <summary>
|
||||
/// Delete接口封装
|
||||
/// </summary>
|
||||
/// <param name="url">地址</param>
|
||||
/// <param name="type">1-返回参数为msgpack,2-返回参数为text</param>
|
||||
/// <param name="data">加密参数</param>
|
||||
/// <returns></returns>
|
||||
private async Task<HttpResponseMessage> DeleteDataAsync(string url, int type, params string[] data)
|
||||
{
|
||||
int timestamp = GetTimestamp();
|
||||
int nonce = GetNonce();
|
||||
string sign = GetUserApiSign("", data);
|
||||
var request = new HttpRequestMessage(HttpMethod.Delete, url);
|
||||
if (type == 2)
|
||||
{
|
||||
request.Headers.Add("Accept", "text/plain");
|
||||
}
|
||||
else
|
||||
{
|
||||
request.Headers.Add("Accept", "application/x-msgpack");
|
||||
}
|
||||
request.Headers.Add("secret", ApiSecretHash);
|
||||
request.Headers.Add("nonce", nonce.ToString());
|
||||
request.Headers.Add("time", timestamp.ToString());
|
||||
request.Headers.Add("user", UserId);
|
||||
request.Headers.Add("sign", sign);
|
||||
var client = _clientFactory.CreateClient();
|
||||
var response = await client.SendAsync(request);
|
||||
var testdata = await response.Content.ReadAsStringAsync();
|
||||
return response;
|
||||
}
|
||||
/// <summary>
|
||||
/// 删除地产区域
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> DeleteEstates(string id)
|
||||
{
|
||||
var url = $"{ApiUrl}/api/estates/{id}";
|
||||
var response = await DeleteDataAsync(url, 2, id);
|
||||
var resdata = await response.Content.ReadAsByteArrayAsync();
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
return new ResultInfo(ResultState.SUCCESS, "删除成功");
|
||||
}
|
||||
else
|
||||
{
|
||||
var msg = await response.Content.ReadAsStringAsync();
|
||||
return new ResultInfo(ResultState.FAIL, msg);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 删除采集点
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> DeleteCollect(string id)
|
||||
{
|
||||
var url = $"{ApiUrl}/api/collectionpoints/{id}";
|
||||
var response = await DeleteDataAsync(url, 2, id);
|
||||
var resdata = await response.Content.ReadAsStringAsync();
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
return new ResultInfo(ResultState.SUCCESS, "删除成功");
|
||||
}
|
||||
else
|
||||
{
|
||||
return new ResultInfo(ResultState.FAIL, resdata);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 添加采集点
|
||||
/// </summary>
|
||||
/// <param name="estatesC2SDto"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> PostCollectAsync(CollectC2SDto estatesC2SDto)
|
||||
{
|
||||
var url = $"{ApiUrl}/api/CollectionPoints";
|
||||
string[] paramlist = new string[] {
|
||||
estatesC2SDto.Code,estatesC2SDto.Name,estatesC2SDto.Addr,estatesC2SDto.Estate
|
||||
};
|
||||
var response = await PostDataAsync(url, 1, estatesC2SDto, paramlist);
|
||||
var resdata = await response.Content.ReadAsByteArrayAsync();
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
var s2c_dto = MessagePackSerializer.Deserialize<CollectS2CDto>(resdata);
|
||||
return new ResultInfo(ResultState.SUCCESS, "success", s2c_dto.id);
|
||||
}
|
||||
else
|
||||
{
|
||||
var msg = await response.Content.ReadAsStringAsync();
|
||||
return new ResultInfo(ResultState.FAIL, msg);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 上传数据
|
||||
/// </summary>
|
||||
/// <param name="garbageC2SDto"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> PostGarbagesAsync(GarbagePltC2SDto garbageC2SDto)
|
||||
{
|
||||
var url = $"{ApiUrl}/api/garbages";
|
||||
string[] paramlist = new string[] {
|
||||
garbageC2SDto.Weight.ToString(),garbageC2SDto.Trash,garbageC2SDto.Type.ToString(),garbageC2SDto.ScanningTime.ToString(),garbageC2SDto.DStatus.ToString()
|
||||
};
|
||||
int timestamp = GetTimestamp();
|
||||
int nonce = GetNonce();
|
||||
string sign = GetUserApiSign(garbageC2SDto.secret, paramlist);
|
||||
var c2s_dto = new SuZhouPostApiBaseDto<GarbageC2SDto>
|
||||
{
|
||||
Data = new GarbageC2SDto
|
||||
{
|
||||
DStatus = garbageC2SDto.DStatus,
|
||||
ScanningTime = garbageC2SDto.ScanningTime,
|
||||
Trash = garbageC2SDto.Trash,
|
||||
Type = garbageC2SDto.Type,
|
||||
Weight = garbageC2SDto.Weight
|
||||
},
|
||||
SecretHash = garbageC2SDto.secrethash,
|
||||
Nonce = nonce,
|
||||
Signature = sign,
|
||||
TimeStamp = timestamp,
|
||||
DeviceId = garbageC2SDto.deviceid
|
||||
};
|
||||
var request = new HttpRequestMessage(HttpMethod.Post, url);
|
||||
var bytes = MessagePackSerializer.Serialize(c2s_dto);
|
||||
request.Content = new ByteArrayContent(bytes);
|
||||
request.Headers.Add("Accept", "application/x-msgpack");
|
||||
request.Content.Headers.Add("Content-Type", "application/x-msgpack");
|
||||
var client = _clientFactory.CreateClient();
|
||||
var response = await client.SendAsync(request);
|
||||
if (response.IsSuccessStatusCode)
|
||||
{
|
||||
//记录日志
|
||||
_loggerService.AddLogger($"测量信息上报成功:参数:{c2s_dto.ToJson()}", 3);
|
||||
return new ResultInfo(ResultState.SUCCESS, "success");
|
||||
}
|
||||
else
|
||||
{
|
||||
var msg = await response.Content.ReadAsStringAsync();
|
||||
//记录日志
|
||||
_loggerService.AddLogger($"测量信息上报失败:参数:{c2s_dto.ToJson()}\r\n返回值:{msg}", 3);
|
||||
return new ResultInfo(ResultState.FAIL, msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Waste.Domain;
|
||||
|
||||
namespace Waste.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// 统计列表
|
||||
/// </summary>
|
||||
public class ReportList : W_DeviceStatistics
|
||||
{
|
||||
/// <summary>
|
||||
/// 商户名称
|
||||
/// </summary>
|
||||
public string BusinessName { get; set; } = "";
|
||||
/// <summary>
|
||||
/// 设备名称
|
||||
/// </summary>
|
||||
public string DevName { get; set; } = "";
|
||||
/// <summary>
|
||||
/// 设备编号
|
||||
/// </summary>
|
||||
public string DevCode { get; set; } = "";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
using Nirvana.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Waste.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// 统计信息
|
||||
/// </summary>
|
||||
public interface IReportService
|
||||
{
|
||||
/// <summary>
|
||||
/// 统计列表
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
/// <returns></returns>
|
||||
Task<PageParms<ReportList>> GetListAsync(QueryParams param);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
using Furion.DynamicApiController;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Nirvana.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Waste.Application.ReportInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 统计报表
|
||||
/// </summary>
|
||||
public class ReportAppService : IDynamicApiController
|
||||
{
|
||||
private readonly IReportService _reportService;
|
||||
public ReportAppService(IReportService reportService)
|
||||
{
|
||||
_reportService = reportService;
|
||||
}
|
||||
/// <summary>
|
||||
/// 统计列表
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<PageParms<ReportList>> GetListAsync(QueryParams param)
|
||||
{
|
||||
return await _reportService.GetListAsync(param);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,108 @@
|
|||
using Furion.DependencyInjection;
|
||||
using Nirvana.Common;
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Waste.Domain;
|
||||
|
||||
namespace Waste.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// 统计管理
|
||||
/// </summary>
|
||||
public class ReportService : BaseInfoService, IReportService, ITransient
|
||||
{
|
||||
private readonly ISqlSugarRepository<W_DeviceStatistics> repository;
|
||||
private readonly SqlSugarClient dbClient;
|
||||
|
||||
public ReportService(ISqlSugarRepository<W_DeviceStatistics> sqlSugarRepository)
|
||||
{
|
||||
repository = sqlSugarRepository;
|
||||
dbClient = repository.Context;
|
||||
}
|
||||
/// <summary>
|
||||
/// 统计列表
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<PageParms<ReportList>> GetListAsync(QueryParams param)
|
||||
{
|
||||
RefAsync<int> totalnum = 0;
|
||||
var temquery = dbClient.Queryable<W_DeviceStatistics>();
|
||||
if (param.queryParam != null && param.queryParam.Count > 0)
|
||||
{
|
||||
List<IConditionalModel> conModels = new List<IConditionalModel>();
|
||||
param.queryParam.ForEach(x =>
|
||||
{
|
||||
x.Value = x.Value.ToStr();
|
||||
if (!string.IsNullOrEmpty(x.Value))
|
||||
{
|
||||
if(x.Name.ToLower() == "devname")
|
||||
{
|
||||
temquery = temquery.Where(e => SqlFunc.Subqueryable<W_Device>().Where(w => w.Name == x.Value && e.DevId == w.Id).Any());
|
||||
}
|
||||
else
|
||||
{
|
||||
conModels.Add(new ConditionalModel()
|
||||
{
|
||||
FieldName = x.Name,
|
||||
ConditionalType = (ConditionalType)x.Type,
|
||||
FieldValue = x.Value.Trim()
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
if (conModels.Count > 0)
|
||||
{
|
||||
temquery = temquery.Where(conModels);
|
||||
}
|
||||
}
|
||||
if (currentUser.AccountType != (int)AccountType.platform)
|
||||
{
|
||||
temquery = temquery.Where(x => x.Businessid == currentUser.BusinessId);
|
||||
}
|
||||
string sorts = string.Format("{0} {1}", param.sort, param.order);
|
||||
var query = await temquery.OrderBy(sorts)
|
||||
.Select(x => new ReportList
|
||||
{
|
||||
Id = x.Id,
|
||||
Businessid = x.Businessid,
|
||||
DevId = x.DevId,
|
||||
CreateTime = x.CreateTime,
|
||||
DayCount = x.DayCount,
|
||||
DayPureWeight = x.DayPureWeight,
|
||||
DayWeight = x.DayWeight,
|
||||
WasteType = x.WasteType
|
||||
})
|
||||
.Mapper((it, cache) =>
|
||||
{
|
||||
var allbus = cache.Get(list =>
|
||||
{
|
||||
var ids = list.Where(x => x.Businessid != Guid.Empty).Select(x => x.Businessid).ToList();
|
||||
return repository.Change<W_Business>().Context.Queryable<W_Business>().Where(e => ids.Contains(e.Id)).ToList();
|
||||
});
|
||||
var bus = allbus.FirstOrDefault(x => x.Id == it.Businessid);
|
||||
it.BusinessName = bus != null ? bus.Name : "";
|
||||
var alldev = cache.Get(list =>
|
||||
{
|
||||
var ids = list.Where(x => x.DevId != Guid.Empty).Select(x => x.DevId).ToList();
|
||||
return repository.Change<W_Device>().Context.Queryable<W_Device>().Where(e => ids.Contains(e.Id)).ToList();
|
||||
});
|
||||
var dev = alldev.FirstOrDefault(x => x.Id == it.DevId);
|
||||
it.DevName = dev != null ? dev.Name : "";
|
||||
it.DevCode = dev != null ? dev.Ecode : "";
|
||||
})
|
||||
.ToPageListAsync(param.offset, param.limit, totalnum);
|
||||
return new PageParms<ReportList>
|
||||
{
|
||||
page = param.offset,
|
||||
Items = query,
|
||||
totalnum = totalnum,
|
||||
limit = param.limit
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Waste.Domain;
|
||||
|
||||
namespace Waste.Application
|
||||
{
|
||||
public class ResultList : W_Result
|
||||
{
|
||||
/// <summary>
|
||||
/// 商户名称
|
||||
/// </summary>
|
||||
public string BusinessName { get; set; }
|
||||
/// <summary>
|
||||
/// 设备名称
|
||||
/// </summary>
|
||||
public string DeviceName { get; set; }
|
||||
/// <summary>
|
||||
/// 设备地址
|
||||
/// </summary>
|
||||
public string DeviceAddress { get; set; }
|
||||
/// <summary>
|
||||
/// 设备出厂序列号
|
||||
/// </summary>
|
||||
public string DeviceFacEcode { get; set; }
|
||||
/// <summary>
|
||||
/// 设备编号
|
||||
/// </summary>
|
||||
public string DeviceEcode { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// 上传的数据包体
|
||||
/// </summary>
|
||||
public class MyPackage
|
||||
{
|
||||
/// <summary>
|
||||
/// 固定头
|
||||
/// </summary>
|
||||
public string Key { get; set; } = "";
|
||||
/// <summary>
|
||||
/// 数据体长度
|
||||
/// </summary>
|
||||
public int Len { get; set; } = 0;
|
||||
/// <summary>
|
||||
/// IMEI
|
||||
/// </summary>
|
||||
public string IMEI { get; set; } = "";
|
||||
/// <summary>
|
||||
/// ICCID
|
||||
/// </summary>
|
||||
public string ICCID { get; set; } = "";
|
||||
/// <summary>
|
||||
/// IMSI
|
||||
/// </summary>
|
||||
public string IMSI { get; set; } = "";
|
||||
/// <summary>
|
||||
/// 信号强度
|
||||
/// </summary>
|
||||
public string GSLQ { get; set; } = "";
|
||||
/// <summary>
|
||||
/// 时间
|
||||
/// </summary>
|
||||
public string Time { get; set; }
|
||||
/// <summary>
|
||||
/// 经度
|
||||
/// </summary>
|
||||
public string Longitude { get; set; } = "";
|
||||
/// <summary>
|
||||
/// 纬度
|
||||
/// </summary>
|
||||
public string Latitude { get; set; } = "";
|
||||
/// <summary>
|
||||
/// 设备地区
|
||||
/// </summary>
|
||||
public string City { get; set; } = "";
|
||||
/// <summary>
|
||||
/// 设备详细地点
|
||||
/// </summary>
|
||||
public string Area { get; set; } = "";
|
||||
/// <summary>
|
||||
/// 垃圾类别
|
||||
/// </summary>
|
||||
public string WasteType { get; set; } = "";
|
||||
/// <summary>
|
||||
/// 重量,KG
|
||||
/// </summary>
|
||||
public string Weight { get; set; } = "0";
|
||||
/// <summary>
|
||||
/// 内容
|
||||
/// </summary>
|
||||
public string Body { get; set; } = "";
|
||||
/// <summary>
|
||||
/// 字符串结果
|
||||
/// </summary>
|
||||
public string Str { get; set; } = "";
|
||||
/// <summary>
|
||||
/// 是否是否通过校检,true-是,false-否
|
||||
/// </summary>
|
||||
public bool IsChecked { get; set; } = true;
|
||||
/// <summary>
|
||||
/// 是否为心跳包数据
|
||||
/// </summary>
|
||||
public bool IsHeart { get; set; } = false;
|
||||
/// <summary>
|
||||
/// 是否为有效测量
|
||||
/// </summary>
|
||||
public bool IsWeight { get; set; } = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
using Nirvana.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Waste.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// 投放记录
|
||||
/// </summary>
|
||||
public interface IResultService
|
||||
{
|
||||
/// <summary>
|
||||
/// 垃圾分类列表
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
/// <returns></returns>
|
||||
Task<PageParms<ResultList>> GetListAsync(QueryParams param);
|
||||
/// <summary>
|
||||
/// 添加记录
|
||||
/// </summary>
|
||||
/// <param name="myPackage"></param>
|
||||
/// <returns></returns>
|
||||
Task<ResultInfo> InsertResultAsync(MyPackage myPackage);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
using Furion.DynamicApiController;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Nirvana.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Waste.Application.ResultInfos
|
||||
{
|
||||
/// <summary>
|
||||
/// 投放记录
|
||||
/// </summary>
|
||||
public class ResultAppService:IDynamicApiController
|
||||
{
|
||||
private readonly IResultService _resultService;
|
||||
public ResultAppService(IResultService resultService)
|
||||
{
|
||||
_resultService = resultService;
|
||||
}
|
||||
/// <summary>
|
||||
/// 投放记录列表
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<PageParms<ResultList>> GetListAsync(QueryParams param)
|
||||
{
|
||||
return await _resultService.GetListAsync(param);
|
||||
}
|
||||
/// <summary>
|
||||
/// 添加记录
|
||||
/// </summary>
|
||||
/// <param name="myPackage"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> InsertResultAsync(MyPackage myPackage)
|
||||
{
|
||||
return await _resultService.InsertResultAsync(myPackage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,220 @@
|
|||
using Furion.DependencyInjection;
|
||||
using Furion.DistributedIDGenerator;
|
||||
using Nirvana.Common;
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Waste.Domain;
|
||||
|
||||
namespace Waste.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// 投放记录管理
|
||||
/// </summary>
|
||||
public class ResultService : BaseInfoService, IResultService, ITransient
|
||||
{
|
||||
private readonly ISqlSugarRepository<W_Result> repository;
|
||||
private readonly SqlSugarClient dbClient;
|
||||
private readonly ILoggerService _loggerService;
|
||||
private readonly ISuZhouService _suZhouService;
|
||||
|
||||
public ResultService(ISqlSugarRepository<W_Result> sqlSugarRepository, ILoggerService loggerService, ISuZhouService suZhouService)
|
||||
{
|
||||
repository = sqlSugarRepository;
|
||||
dbClient = repository.Context;
|
||||
_loggerService = loggerService;
|
||||
_suZhouService = suZhouService;
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取投放记录
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<PageParms<ResultList>> GetListAsync(QueryParams param)
|
||||
{
|
||||
RefAsync<int> totalnum = 0;
|
||||
var temquery = dbClient.Queryable<W_Result>();
|
||||
if (param.queryParam != null && param.queryParam.Count > 0)
|
||||
{
|
||||
List<IConditionalModel> conModels = new List<IConditionalModel>();
|
||||
param.queryParam.ForEach(x =>
|
||||
{
|
||||
var val = x.Value.ToStr();
|
||||
if (!string.IsNullOrEmpty(val))
|
||||
{
|
||||
if (x.Name.ToStr().ToLower() == "facecode")
|
||||
{
|
||||
temquery = temquery.Where(t => SqlFunc.Subqueryable<W_Device>().Where(e => e.Ecode == val && t.DeviceId == e.Id).Any());
|
||||
}
|
||||
else if (x.Name.ToStr().ToLower() == "name")
|
||||
{
|
||||
temquery = temquery.Where(t => SqlFunc.Subqueryable<W_Device>().Where(e => e.Name == val && t.DeviceId == e.Id).Any());
|
||||
}
|
||||
else
|
||||
{
|
||||
conModels.Add(new ConditionalModel()
|
||||
{
|
||||
FieldName = x.Name,
|
||||
ConditionalType = (ConditionalType)x.Type,
|
||||
FieldValue = val
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
if (conModels.Count > 0)
|
||||
{
|
||||
temquery = temquery.Where(conModels);
|
||||
}
|
||||
}
|
||||
if (currentUser.AccountType != (int)AccountType.platform)
|
||||
{
|
||||
temquery = temquery.Where(x => x.BusinessId == currentUser.BusinessId);
|
||||
}
|
||||
string sorts = string.Format("{0} {1}", param.sort, param.order);
|
||||
var query = await temquery.OrderBy(sorts)
|
||||
.Select(x => new ResultList
|
||||
{
|
||||
Id = x.Id,
|
||||
BusinessId = x.BusinessId,
|
||||
DeviceId = x.DeviceId,
|
||||
WasteType = x.WasteType,
|
||||
Tare = x.Tare,
|
||||
GrossWeight = x.GrossWeight,
|
||||
NetWeight = x.NetWeight,
|
||||
Registration = x.Registration,
|
||||
CreateTime = x.CreateTime
|
||||
})
|
||||
.Mapper((it, cache) =>
|
||||
{
|
||||
var allbus = cache.Get(list =>
|
||||
{
|
||||
var ids = list.Where(e => e.BusinessId != Guid.Empty).Select(e => e.BusinessId).ToList();
|
||||
return repository.Change<W_Business>().Context.Queryable<W_Business>().Where(e => ids.Contains(e.Id)).ToList();
|
||||
});
|
||||
it.BusinessName = allbus.FirstOrDefault(e => e.Id == it.BusinessId)?.Name;
|
||||
var alldev = cache.Get(list =>
|
||||
{
|
||||
var ids = list.Where(e => e.DeviceId != Guid.Empty).Select(e => e.DeviceId).ToList();
|
||||
return repository.Change<W_Device>().Context.Queryable<W_Device>().Where(e => ids.Contains(e.Id)).ToList();
|
||||
});
|
||||
var dev = alldev.FirstOrDefault(e => e.Id == it.DeviceId);
|
||||
if (dev != null)
|
||||
{
|
||||
it.DeviceName = dev.Name;
|
||||
it.DeviceFacEcode = dev.FacEcode;
|
||||
it.DeviceEcode = dev.Ecode;
|
||||
it.DeviceAddress = dev.Address;
|
||||
}
|
||||
})
|
||||
.ToPageListAsync(param.offset, param.limit, totalnum);
|
||||
return new PageParms<ResultList>
|
||||
{
|
||||
page = param.offset,
|
||||
Items = query,
|
||||
totalnum = totalnum,
|
||||
limit = param.limit
|
||||
};
|
||||
}
|
||||
/// <summary>
|
||||
/// 增加测量记录
|
||||
/// </summary>
|
||||
/// <param name="myPackage"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> InsertResultAsync(MyPackage myPackage)
|
||||
{
|
||||
//查找设备
|
||||
var device = await repository.Change<W_Device>().Context.Queryable<W_Device>().FirstAsync(x => myPackage.IMEI == x.Ecode);
|
||||
_loggerService.AddLogger($"接收到的数据,参数:{myPackage.ToJson()}", 2);
|
||||
if (device == null)
|
||||
{
|
||||
//记录日志
|
||||
_loggerService.AddLogger($"设备未找到,参数:{myPackage.ToJson()}", 3);
|
||||
return new ResultInfo(ResultState.FAIL, "设备未找到");
|
||||
}
|
||||
var devicedata = await repository.Change<W_DeviceData>().Context.Queryable<W_DeviceData>().FirstAsync(x => x.DeviceId == device.Id);
|
||||
var resultid = IDGen.NextID();
|
||||
DateTime time = DateTime.Now;
|
||||
if (myPackage.IsHeart)
|
||||
{
|
||||
if (string.IsNullOrEmpty(myPackage.Longitude) || myPackage.Longitude.ToDecimal() == 0) myPackage.Longitude = devicedata != null ? devicedata.Longitude : "0";
|
||||
if (string.IsNullOrEmpty(myPackage.Latitude) || myPackage.Latitude.ToDecimal() == 0) myPackage.Latitude = devicedata != null ? devicedata.Latitude : "0";
|
||||
}
|
||||
else
|
||||
{
|
||||
if (string.IsNullOrEmpty(myPackage.IMSI)) myPackage.IMSI = devicedata != null ? devicedata.IMSI : "";
|
||||
if (string.IsNullOrEmpty(myPackage.IMEI)) myPackage.IMEI = devicedata != null ? devicedata.IMEI : "";
|
||||
if (string.IsNullOrEmpty(myPackage.ICCID)) myPackage.ICCID = devicedata != null ? devicedata.ICCID : "";
|
||||
if (!string.IsNullOrEmpty(myPackage.Time) && myPackage.Time.Length == 14)
|
||||
{
|
||||
time = $"{myPackage.Time.Substring(0, 4)}-{myPackage.Time.Substring(4, 2)}-{myPackage.Time.Substring(6, 2)} {myPackage.Time.Substring(8, 2)}:{myPackage.Time.Substring(10, 2)}:{myPackage.Time.Substring(12, 2)}".ToDate();
|
||||
}
|
||||
}
|
||||
//检查设备是否为今天第一次上报
|
||||
bool isfrist = false;
|
||||
if (device.LastHeartTime.HasValue && device.LastHeartTime.Value.Date != DateTime.Now.Date)
|
||||
{
|
||||
isfrist = true;
|
||||
}
|
||||
//记录数据
|
||||
await dbClient.Ado.UseStoredProcedure().ExecuteCommandAsync("Proc_InsertResult", new
|
||||
{
|
||||
deviceid = device.Id,
|
||||
businessid = device.Businessid,
|
||||
resultid = resultid,
|
||||
imei = myPackage.IMEI,
|
||||
iccid = myPackage.ICCID,
|
||||
imsi = myPackage.IMSI,
|
||||
time = time,
|
||||
latitude = myPackage.Latitude,
|
||||
longitude = myPackage.Longitude,
|
||||
sign = myPackage.GSLQ,
|
||||
city = myPackage.City,
|
||||
area = myPackage.Area,
|
||||
wastetype = myPackage.WasteType,
|
||||
weigth = myPackage.Weight,
|
||||
isheart = myPackage.IsHeart,
|
||||
tare = device.Tare,
|
||||
isfrist = isfrist
|
||||
});
|
||||
//上传垃圾数据
|
||||
if (myPackage.IsWeight && myPackage.Weight.ToDecimal() >0)
|
||||
{
|
||||
var devicesecret = await repository.Change<W_SZDevice>().Context.Queryable<W_SZDevice>().FirstAsync(x => x.DeviceId == device.Id);
|
||||
if (devicesecret != null)
|
||||
{
|
||||
int timestamp = GetTimestamp(time);
|
||||
await _suZhouService.PostGarbagesAsync(new GarbagePltC2SDto
|
||||
{
|
||||
Weight = myPackage.Weight.ToDouble(),
|
||||
secret = devicesecret.Secret,
|
||||
secrethash = devicesecret.SecretHash,
|
||||
ScanningTime = timestamp,
|
||||
DStatus = 0,
|
||||
deviceid = devicesecret.DevId,
|
||||
Trash = "202101",
|
||||
Type = TrashType(myPackage.WasteType)
|
||||
});
|
||||
}
|
||||
}
|
||||
return new ResultInfo(ResultState.SUCCESS, "success");
|
||||
}
|
||||
private static int GetTimestamp(DateTime time)
|
||||
{
|
||||
DateTime dateTimeStart = TimeZoneInfo.ConvertTimeToUtc(new DateTime(1970, 1, 1, 8, 0, 0));
|
||||
int timestamp = Convert.ToInt32((time - dateTimeStart).TotalSeconds);
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
private int TrashType(string type)
|
||||
{
|
||||
if (type == "厨余垃圾") return 1;
|
||||
else if (type == "可回收物") return 2;
|
||||
else if (type == "有害垃圾") return 3;
|
||||
else if (type == "其他垃圾") return 4;
|
||||
else return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Waste.Domain;
|
||||
|
||||
namespace Waste.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// 角色信息提交
|
||||
/// </summary>
|
||||
public class RoleSubmitModel :W_Role
|
||||
{
|
||||
/// <summary>
|
||||
/// 菜单列表
|
||||
/// </summary>
|
||||
public List<Guid> permissionId { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
using Nirvana.Common;
|
||||
using Nirvana.Common.ApiBase;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Waste.Domain;
|
||||
|
||||
namespace Waste.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// 账户管理
|
||||
/// </summary>
|
||||
public interface IRoleService
|
||||
{
|
||||
Task<PageParms<W_Role>> GetListAsync(QueryParams param);
|
||||
Task<ResultInfo> SubmitFormAsync(RoleSubmitModel role);
|
||||
Task<ResultInfo> DeleteFormAsync(Guid keyValue);
|
||||
Task<RoleSubmitModel> DetailAsync(Guid id);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
using Furion.DependencyInjection;
|
||||
using Furion.DistributedIDGenerator;
|
||||
using Furion.DynamicApiController;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Nirvana.Common;
|
||||
using Nirvana.Common.ApiBase;
|
||||
using SqlSugar;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Waste.Domain;
|
||||
|
||||
namespace Waste.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// 账户管理
|
||||
/// </summary>
|
||||
public class RoleService : IRoleService, IDynamicApiController, ITransient
|
||||
{
|
||||
private readonly ISqlSugarRepository<W_Role> repository;
|
||||
private readonly SqlSugarClient dbClient;
|
||||
|
||||
public RoleService(ISqlSugarRepository<W_Role> sqlSugarRepository
|
||||
)
|
||||
{
|
||||
repository = sqlSugarRepository;
|
||||
dbClient = repository.Context;
|
||||
}
|
||||
/// <summary>
|
||||
/// 删除角色
|
||||
/// </summary>
|
||||
/// <param name="keyValue"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<ResultInfo> DeleteFormAsync(Guid keyValue)
|
||||
{
|
||||
await dbClient.Deleteable<W_Role>().Where(e => e.Id == keyValue).ExecuteCommandAsync();
|
||||
await repository.Change<W_RoleAuthorize>().Context.Deleteable<W_RoleAuthorize>().Where(e => e.RoleId == keyValue).ExecuteCommandAsync();
|
||||
return new ResultInfo { code = ResultState.SUCCESS, message = "删除成功", data = null };
|
||||
}
|
||||
/// <summary>
|
||||
/// 角色详情
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public async Task<RoleSubmitModel> DetailAsync(Guid id)
|
||||
{
|
||||
if (id == Guid.Empty)
|
||||
{
|
||||
return new RoleSubmitModel() { permissionId = new List<Guid>() };
|
||||
}
|
||||
var data = await dbClient.Queryable<W_Role>().FirstAsync(x => x.Id == id);
|
||||
return new RoleSubmitModel
|
||||
{
|
||||
Id = data.Id,
|
||||
EnCode = data.EnCode,
|
||||
Name = data.Name,
|
||||
Remark = data.Remark,
|
||||
permissionId = await repository.Change<W_RoleAuthorize>().Context.Queryable<W_RoleAuthorize>().Where(x => x.RoleId == id).Select(x => x.MenuId).ToListAsync()
|
||||
};
|
||||
}
|
||||
/// <summary>
|
||||
/// 角色列表
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<PageParms<W_Role>> GetListAsync(QueryParams param)
|
||||
{
|
||||
RefAsync<int> totalnum = 0;
|
||||
var temquery = dbClient.Queryable<W_Role>();
|
||||
if (param.queryParam != null && param.queryParam.Count > 0)
|
||||
{
|
||||
List<IConditionalModel> conModels = new List<IConditionalModel>();
|
||||
param.queryParam.ForEach(x =>
|
||||
{
|
||||
if (!string.IsNullOrEmpty(x.Value))
|
||||
{
|
||||
conModels.Add(new ConditionalModel()
|
||||
{
|
||||
FieldName = x.Name,
|
||||
ConditionalType = (ConditionalType)x.Type,
|
||||
FieldValue = x.Value.Trim()
|
||||
});
|
||||
}
|
||||
});
|
||||
if (conModels.Count > 0)
|
||||
{
|
||||
temquery = temquery.Where(conModels);
|
||||
}
|
||||
}
|
||||
string sorts = string.Format("{0} {1}", param.sort, param.order);
|
||||
var query = await temquery.OrderBy(sorts)
|
||||
.ToPageListAsync(param.offset, param.limit, totalnum);
|
||||
return new PageParms<W_Role>
|
||||
{
|
||||
page = param.offset,
|
||||
Items = query,
|
||||
totalnum = totalnum,
|
||||
limit = param.limit
|
||||
};
|
||||
}
|
||||
/// <summary>
|
||||
/// 信息提交
|
||||
/// </summary>
|
||||
/// <param name="role"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> SubmitFormAsync(RoleSubmitModel role)
|
||||
{
|
||||
if (role.Id == Guid.Empty)
|
||||
{
|
||||
role.Id = IDGen.NextID();
|
||||
role.CreateTime = DateTime.Now;
|
||||
role.Remark = role.Remark.ToStr();
|
||||
await dbClient.Insertable<W_Role>(role).ExecuteCommandAsync();
|
||||
}
|
||||
else
|
||||
{
|
||||
await dbClient.Updateable<W_Role>()
|
||||
.SetColumns(x => new W_Role
|
||||
{
|
||||
Name = role.Name,
|
||||
Remark = role.Remark
|
||||
})
|
||||
.Where(x => x.Id == role.Id).ExecuteCommandAsync();
|
||||
}
|
||||
|
||||
List<W_RoleAuthorize> roleAuthorizeEntitys = new List<W_RoleAuthorize>();
|
||||
foreach (var item in role.permissionId)
|
||||
{
|
||||
var itemId = item;
|
||||
W_RoleAuthorize roleAuthorizeEntity = new W_RoleAuthorize
|
||||
{
|
||||
CreateTime = DateTime.Now,
|
||||
RoleId = role.Id,
|
||||
MenuId = itemId
|
||||
};
|
||||
roleAuthorizeEntitys.Add(roleAuthorizeEntity);
|
||||
}
|
||||
await repository.Change<W_RoleAuthorize>().Context.Deleteable<W_RoleAuthorize>(t => t.RoleId == role.Id).ExecuteCommandAsync();
|
||||
if (roleAuthorizeEntitys.Count > 0)
|
||||
{
|
||||
await repository.Change<W_RoleAuthorize>().Context.Insertable<W_RoleAuthorize>(roleAuthorizeEntitys).ExecuteCommandAsync();
|
||||
}
|
||||
return new ResultInfo { code = ResultState.SUCCESS, message = "成功" };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Waste.Domain;
|
||||
|
||||
namespace Waste.Application
|
||||
{
|
||||
public class SZCollectList:W_SZCollect
|
||||
{
|
||||
/// <summary>
|
||||
/// 地产区域名称
|
||||
/// </summary>
|
||||
public string AddressName { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
using Nirvana.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Waste.Domain;
|
||||
|
||||
namespace Waste.Application
|
||||
{
|
||||
/// <summary>
|
||||
/// 苏州设备接入平台管理
|
||||
/// </summary>
|
||||
public interface ISZPltService
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取地产区域列表
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
/// <returns></returns>
|
||||
Task<PageParms<W_SZAddress>> GetAddressListAsync(QueryParams param);
|
||||
/// <summary>
|
||||
/// 获取地产区域所有列表
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<List<W_SZAddress>> GetAddressAllListAsync();
|
||||
/// <summary>
|
||||
/// 地产区域信息提交
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
Task<ResultInfo> SubmitAddressFormAsync(W_SZAddress data);
|
||||
/// <summary>
|
||||
/// 地产区域详情
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
Task<W_SZAddress> DetailAddressAsync(Guid id);
|
||||
/// <summary>
|
||||
/// 删除地产区域
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
Task<ResultInfo> DeleteAddressAsync(Guid id);
|
||||
|
||||
/// <summary>
|
||||
/// 获取采集点列表
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
/// <returns></returns>
|
||||
Task<PageParms<SZCollectList>> GetCollectListAsync(QueryParams param);
|
||||
|
||||
/// <summary>
|
||||
/// 采集点信息提交
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
Task<ResultInfo> SubmitCollectFormAsync(W_SZCollect data);
|
||||
|
||||
/// <summary>
|
||||
/// 采集点详情
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
Task<W_SZCollect> DetailCollectAsync(Guid id);
|
||||
/// <summary>
|
||||
/// 删除采集点
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
Task<ResultInfo> DeleteCollectAsync(Guid id);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
using Furion.DynamicApiController;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Nirvana.Common;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Waste.Domain;
|
||||
|
||||
namespace Waste.Application.SZPltInfo
|
||||
{
|
||||
public class SZPltAppService : IDynamicApiController
|
||||
{
|
||||
private readonly ISZPltService _sZPltService;
|
||||
|
||||
public SZPltAppService(ISZPltService sZPltService)
|
||||
{
|
||||
_sZPltService = sZPltService;
|
||||
}
|
||||
/// <summary>
|
||||
/// 获取地产区域列表
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<PageParms<W_SZAddress>> GetAddressListAsync(QueryParams param)
|
||||
{
|
||||
return await _sZPltService.GetAddressListAsync(param);
|
||||
}
|
||||
/// <summary>
|
||||
/// 地产区域信息提交
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> SubmitAddressFormAsync(W_SZAddress data)
|
||||
{
|
||||
return await _sZPltService.SubmitAddressFormAsync(data);
|
||||
}
|
||||
/// <summary>
|
||||
/// 删除地产区域
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[QueryParameters]
|
||||
public async Task<ResultInfo> DeleteAddressAsync(Guid id)
|
||||
{
|
||||
return await _sZPltService.DeleteAddressAsync(id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取采集点列表
|
||||
/// </summary>
|
||||
/// <param name="param"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<PageParms<SZCollectList>> GetCollectListAsync(QueryParams param)
|
||||
{
|
||||
return await _sZPltService.GetCollectListAsync(param);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 采集点信息提交
|
||||
/// </summary>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public async Task<ResultInfo> SubmitCollectFormAsync(W_SZCollect data)
|
||||
{
|
||||
return await _sZPltService.SubmitCollectFormAsync(data);
|
||||
}
|
||||
/// <summary>
|
||||
/// 删除采集点
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[QueryParameters]
|
||||
public async Task<ResultInfo> DeleteCollectAsync(Guid id)
|
||||
{
|
||||
return await _sZPltService.DeleteCollectAsync(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue