mirror of
https://gitee.com/opencc/ccflow.git
synced 2025-12-06 16:09:11 +08:00
更新版本
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
using BP.DA;
|
||||
using BP.Difference;
|
||||
using BP.En;
|
||||
using BP.Sys;
|
||||
using BP.Web;
|
||||
using BP.WF;
|
||||
using BP.WF.HttpHandler;
|
||||
using BP.WF.Template;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Data;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using BP.WF.DTS;
|
||||
using System.Security.Cryptography;
|
||||
using BP.Tools;
|
||||
using DocumentFormat.OpenXml.ExtendedProperties;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using BP.Port;
|
||||
using System.Collections.Generic;
|
||||
using BP.WF.CCFast.Third.GoView;
|
||||
using NPOI.Util;
|
||||
using NPOI.SS.Util;
|
||||
using NPOI.HPSF;
|
||||
using NetTaste;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System.IO;
|
||||
using System.Text.Json.Nodes;
|
||||
using DocumentFormat.OpenXml.Drawing.Charts;
|
||||
using static CCFlow.NetCore.DataUser.API.Controllers.APIController;
|
||||
using DataTable = System.Data.DataTable;
|
||||
using DocumentFormat.OpenXml.Office2016.Drawing.ChartDrawing;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System.Linq;
|
||||
using BP.App.NetCore.GZSZ;
|
||||
|
||||
/**
|
||||
* 广州审图
|
||||
*/
|
||||
namespace CCFlow.NetCore.DataUser.API.Controllers
|
||||
{
|
||||
[Route("WF/[controller]/[Action]")]
|
||||
[ApiController]
|
||||
public class GZSZController : ControllerBase
|
||||
{
|
||||
|
||||
/**
|
||||
* 修改历史数据
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
[HttpGet, HttpPost]
|
||||
public object UpdateHisData(int num)
|
||||
{
|
||||
GZ_CommTS gz = new GZ_CommTS();
|
||||
gz.UpdateHisData(num);
|
||||
return "修改成功";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ using System.Collections;
|
||||
using System.Data;
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using BP.WF;
|
||||
|
||||
namespace CCFlow.NetCore.DataUser.API.Controllers
|
||||
{
|
||||
|
||||
@@ -1,496 +0,0 @@
|
||||
using BP.CCFast.Portal.WindowExt;
|
||||
using BP.DA;
|
||||
using BP.Difference;
|
||||
using BP.En;
|
||||
using BP.Port;
|
||||
using BP.Star;
|
||||
using BP.Web;
|
||||
using BP.WF;
|
||||
using BP.WF.Admin;
|
||||
using BP.WF.Template;
|
||||
using DocumentFormat.OpenXml.Spreadsheet;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Data;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Log = BP.DA.Log;
|
||||
|
||||
namespace CCFlow.NetCore.DataUser.API.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// Star股票系统API接口
|
||||
/// 对外发布的接口,需要用户名密码登录获取token后才能访问数据
|
||||
/// </summary>
|
||||
[Route("Star/[controller]/[Action]")]
|
||||
[ApiController]
|
||||
public class StarMockController : BPController
|
||||
{
|
||||
#region 业务接口
|
||||
/// <summary>
|
||||
/// 执行统计
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <param name="stockNo"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet, HttpPost]
|
||||
public object MockStand_TongJi(string token, string stockNo)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Token验证
|
||||
if (DataType.IsNullOrEmpty(token))
|
||||
return Return_Info(500, "未提供访问令牌,请先登录", null);
|
||||
|
||||
// 通过token登录
|
||||
try
|
||||
{
|
||||
Dev2Interface.Port_LoginByToken(token);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Return_Info(401, "Token验证失败,请重新登录: " + ex.Message, null);
|
||||
}
|
||||
|
||||
|
||||
string safeStockNo = stockNo.Replace("'", "''");
|
||||
string sql = $"SELECT MockStandSta, COUNT(*) AS N FROM Star_MockStand WHERE StockNo='{safeStockNo}' GROUP BY MockStandSta";
|
||||
DataTable dt = DBAccess.RunSQLReturnTable(sql);
|
||||
|
||||
// 初始化各状态数量
|
||||
int count0 = 0; // 未执行
|
||||
int count1 = 0; // 已完成
|
||||
int count2 = 0; // 执行中
|
||||
int count3 = 0; // 执行失败
|
||||
|
||||
// 遍历查询结果,统计各状态数量
|
||||
if (dt != null && dt.Rows.Count > 0)
|
||||
{
|
||||
foreach (DataRow row in dt.Rows)
|
||||
{
|
||||
int mockStandSta = Convert.ToInt32(row["MockStandSta"] ?? 0);
|
||||
int count = Convert.ToInt32(row["N"] ?? 0);
|
||||
|
||||
switch (mockStandSta)
|
||||
{
|
||||
case 0:
|
||||
count0 = count;
|
||||
break;
|
||||
case 1:
|
||||
count1 = count;
|
||||
break;
|
||||
case 2:
|
||||
count2 = count;
|
||||
break;
|
||||
case 3:
|
||||
count3 = count;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 返回JSON格式的统计数据
|
||||
var result = new
|
||||
{
|
||||
code = 200,
|
||||
message = "统计成功",
|
||||
data = new
|
||||
{
|
||||
未执行 = count0,
|
||||
已完成 = count1,
|
||||
执行中 = count2,
|
||||
执行失败 = count3
|
||||
}
|
||||
};
|
||||
|
||||
string str = BP.Tools.Json.ToJson(result);
|
||||
return Return_Info(200, "执行成功", str);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Return_Info(500, "执行失败: " + ex.Message, null);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 执行Mock 单个股票,单个策略
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <param name="stockNo">股票编号</param>
|
||||
/// <param name="standMyPK">策略编号</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet, HttpPost]
|
||||
public object MockStand(string token, string stockNo, string standMyPK)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Token验证
|
||||
if (DataType.IsNullOrEmpty(token))
|
||||
return Return_Info(500, "未提供访问令牌,请先登录", null);
|
||||
|
||||
// 通过token登录
|
||||
try
|
||||
{
|
||||
Dev2Interface.Port_LoginByToken(token);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Return_Info(401, "Token验证失败,请重新登录: " + ex.Message, null);
|
||||
}
|
||||
Stock stock = new Stock(stockNo);
|
||||
// standNo 可能是 MyPK 或 StrategyNo,先尝试作为 MyPK,如果失败则作为 StrategyNo 查询
|
||||
Stand stand = new Stand(standMyPK);
|
||||
|
||||
Handler_Star handler = new Handler_Star();
|
||||
handler.AddPara("stockNo", stockNo);
|
||||
handler.AddPara("StandMyPK", stand.MyPK);
|
||||
string result = handler.Stock_ExecuteMockSingle();
|
||||
|
||||
//返回执行结果.
|
||||
MockStand ms = new MockStand(stockNo + "_" + stand.MyPK);
|
||||
|
||||
return Return_Info(200, "执行成功", ms.ToJson());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Return_Info(500, "执行失败: " + ex.Message, null);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 执行同步
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <param name="stockNo"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet, HttpPost]
|
||||
public object Stock_DTS(string token, string stockNo)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Token验证
|
||||
if (DataType.IsNullOrEmpty(token))
|
||||
return Return_Info(500, "未提供访问令牌,请先登录", null);
|
||||
|
||||
// 通过token登录
|
||||
try
|
||||
{
|
||||
Dev2Interface.Port_LoginByToken(token);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Return_Info(401, "Token验证失败,请重新登录: " + ex.Message, null);
|
||||
}
|
||||
Stock stock = new Stock(stockNo);
|
||||
|
||||
Handler_Star handler = new Handler_Star();
|
||||
string str = handler.Stock_DTSOneExt(stock);
|
||||
|
||||
return Return_Info(200, "执行成功", str);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
BP.DA.Log.DebugWriteError($"执行失败: {ex.Message}");
|
||||
return Return_Info(500, "执行失败: " + ex.Message, null);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 获得模拟的数据
|
||||
/// </summary>
|
||||
/// <param name="token"></param>
|
||||
/// <param name="stockNo"></param>
|
||||
/// <returns></returns>
|
||||
[HttpGet, HttpPost]
|
||||
public object MockStand_Init(string token, string stockNo)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Token验证
|
||||
if (DataType.IsNullOrEmpty(token))
|
||||
return Return_Info(500, "未提供访问令牌,请先登录", null);
|
||||
|
||||
// 通过token登录
|
||||
try
|
||||
{
|
||||
Dev2Interface.Port_LoginByToken(token);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Return_Info(401, "Token验证失败,请重新登录: " + ex.Message, null);
|
||||
}
|
||||
|
||||
Stock stock = new Stock(stockNo);
|
||||
|
||||
//1. 删除不存在的策略数据.
|
||||
string sql = "DELETE FROM Star_MockStand WHERE StockNo='" + stockNo + "'";
|
||||
sql += " AND StandMyPK NOT IN (SELECT MyPK FROM Star_Stand) ";
|
||||
DBAccess.RunSQL(sql);
|
||||
|
||||
//2. 查询出来,没有的
|
||||
Stands stands = new Stands();
|
||||
sql = "SELECT MyPK FROM Star_Stand WHERE MyPK NOT IN( SELECT StandMyPK FROM Star_MockStand WHERE StockNo ='" + stockNo + "') ";
|
||||
stands.RetrieveInSQL(sql);
|
||||
|
||||
//3. 生成数据.
|
||||
MockStand ms = new MockStand();
|
||||
foreach (Stand stand in stands)
|
||||
{
|
||||
ms.StockNo = stock.No;
|
||||
ms.StockName = stock.Name;
|
||||
ms.StandName = stand.Name;
|
||||
ms.StockLocal = stock.StockLocal;
|
||||
ms.StandMyPK = stand.MyPK;
|
||||
ms.StandName = stand.Name;
|
||||
|
||||
ms.StrategyNo = stand.StrategyNo;
|
||||
ms.StrategyName = stand.StrategyName;
|
||||
ms.StrategyKLineType = stand.StrategyKLineType;
|
||||
|
||||
ms.MyPK = stock.No + "_" + stand.MyPK;
|
||||
ms.Insert();
|
||||
}
|
||||
return Return_Info(200, "成功", null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Return_Info(500, "执行失败: " + ex.Message, null);
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 执行单个策略规格的模拟
|
||||
/// </summary>
|
||||
/// <param name="token">访问令牌</param>
|
||||
/// <param name="stockNo">股票编号</param>
|
||||
/// <param name="standMyPK">策略规格主键</param>
|
||||
/// <returns>执行结果</returns>
|
||||
[HttpGet, HttpPost]
|
||||
public object Stock_ExecuteMockSingle(string token, string stockNo, string standMyPK)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Token验证
|
||||
if (DataType.IsNullOrEmpty(token))
|
||||
return Return_Info(500, "未提供访问令牌,请先登录", null);
|
||||
|
||||
// 通过token登录
|
||||
try
|
||||
{
|
||||
Dev2Interface.Port_LoginByToken(token);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Return_Info(401, "Token验证失败,请重新登录: " + ex.Message, null);
|
||||
}
|
||||
|
||||
Handler_Star handler = new Handler_Star();
|
||||
handler.AddPara("token", token);
|
||||
handler.AddPara("stockNo", stockNo);
|
||||
handler.AddPara("standMyPK", standMyPK);
|
||||
string result = handler.Stock_ExecuteMockSingle();
|
||||
|
||||
// 判断结果是否包含错误
|
||||
bool isError = result.Contains("失败") || result.Contains("错误") ||
|
||||
result.Contains("不能为空") || result.Contains("不存在");
|
||||
|
||||
if (isError)
|
||||
{
|
||||
return Return_Info(500, result, null);
|
||||
}
|
||||
|
||||
return Return_Info(200, result, null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
BP.DA.Log.DebugWriteError($"执行失败: {ex.Message}");
|
||||
return Return_Info(500, "执行失败: " + ex.Message, null);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 股票数据同步(后台线程执行)
|
||||
/// </summary>
|
||||
/// <param name="token">访问令牌</param>
|
||||
/// <param name="stockNo">股票编号</param>
|
||||
/// <returns>执行结果</returns>
|
||||
[HttpGet, HttpPost]
|
||||
public object Stock_SyncData(string token, string stockNo)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Token验证
|
||||
if (DataType.IsNullOrEmpty(token))
|
||||
return Return_Info(500, "未提供访问令牌,请先登录", null);
|
||||
|
||||
// 通过token登录
|
||||
try
|
||||
{
|
||||
Dev2Interface.Port_LoginByToken(token);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Return_Info(401, "Token验证失败,请重新登录: " + ex.Message, null);
|
||||
}
|
||||
|
||||
//执行数据同步的方法,这里需要,用AddPara方法 ,传入参数。
|
||||
Handler_Star handler = new Handler_Star();
|
||||
handler.AddPara("token", token);
|
||||
handler.AddPara("stockNo", stockNo);
|
||||
string result = handler.Stock_SyncData();
|
||||
|
||||
// 判断结果是否包含错误
|
||||
bool isError = result.Contains("失败") || result.Contains("错误") ||
|
||||
result.Contains("不能为空");
|
||||
|
||||
if (isError)
|
||||
{
|
||||
return Return_Info(500, result, null);
|
||||
}
|
||||
|
||||
return Return_Info(200, result, null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.DebugWriteError($"执行失败: {ex.Message}");
|
||||
return Return_Info(500, "执行失败: " + ex.Message, null);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算并更新股票的最优解策略
|
||||
/// </summary>
|
||||
/// <param name="token">访问令牌</param>
|
||||
/// <param name="No">股票编号</param>
|
||||
/// <returns>执行结果</returns>
|
||||
[HttpGet, HttpPost]
|
||||
public object Stock_CalculateOptimalStrategy(string token, string No)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Token验证
|
||||
if (DataType.IsNullOrEmpty(token))
|
||||
return Return_Info(500, "未提供访问令牌,请先登录", null);
|
||||
|
||||
// 通过token登录
|
||||
try
|
||||
{
|
||||
Dev2Interface.Port_LoginByToken(token);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Return_Info(401, "Token验证失败,请重新登录: " + ex.Message, null);
|
||||
}
|
||||
|
||||
Handler_Star handler = new Handler_Star();
|
||||
handler.AddPara("No", No);
|
||||
string result = handler.Stock_CalculateOptimalStrategy();
|
||||
|
||||
// 判断结果是否包含错误
|
||||
bool isError = result.Contains("失败") || result.Contains("错误") ||
|
||||
result.Contains("不能为空") || result.Contains("不存在");
|
||||
|
||||
if (isError)
|
||||
{
|
||||
return Return_Info(500, result, null);
|
||||
}
|
||||
|
||||
return Return_Info(200, result, null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.DebugWriteError($"计算最优解失败: {ex.Message}");
|
||||
return Return_Info(500, $"计算最优解失败: {ex.Message}", null);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 更新股票状态
|
||||
/// </summary>
|
||||
/// <param name="token">访问令牌</param>
|
||||
/// <param name="stockNo">股票编号</param>
|
||||
/// <param name="stockSta">股票状态:0=不启用, 1=投产, 2=模拟验证中</param>
|
||||
/// <returns>执行结果</returns>
|
||||
[HttpGet, HttpPost]
|
||||
public object Stock_UpdateStatus(string token, string stockNo, int stockSta)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Token验证
|
||||
if (DataType.IsNullOrEmpty(token))
|
||||
return Return_Info(500, "未提供访问令牌,请先登录", null);
|
||||
|
||||
// 通过token登录
|
||||
try
|
||||
{
|
||||
Dev2Interface.Port_LoginByToken(token);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Return_Info(401, "Token验证失败,请重新登录: " + ex.Message, null);
|
||||
}
|
||||
|
||||
Handler_Star handler = new Handler_Star();
|
||||
handler.AddPara("token", token);
|
||||
handler.AddPara("stockNo", stockNo);
|
||||
handler.AddPara("stockSta", stockSta.ToString());
|
||||
string result = handler.Stock_UpdateStatus();
|
||||
|
||||
// 判断结果是否包含错误
|
||||
bool isError = result.Contains("失败") || result.Contains("错误") ||
|
||||
result.Contains("不能为空");
|
||||
|
||||
if (isError)
|
||||
{
|
||||
return Return_Info(500, result, null);
|
||||
}
|
||||
|
||||
return Return_Info(200, result, null);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.DebugWriteError($"更新股票状态失败: {ex.Message}");
|
||||
return Return_Info(500, $"更新股票状态失败: {ex.Message}", null);
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 辅助方法
|
||||
|
||||
/// <summary>
|
||||
/// 测试接口是否可用(无需Token)
|
||||
/// </summary>
|
||||
/// <returns>服务状态</returns>
|
||||
[HttpGet, HttpPost]
|
||||
public object Ping()
|
||||
{
|
||||
return Return_Info(200, "Star API服务正常", new
|
||||
{
|
||||
version = "1.0.0",
|
||||
serverTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
|
||||
service = "Star Stock API"
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取当前版本信息(无需Token)
|
||||
/// 用于客户端检查更新
|
||||
/// </summary>
|
||||
/// <returns>版本信息</returns>
|
||||
[HttpGet, HttpPost]
|
||||
public object GetVersion()
|
||||
{
|
||||
return Return_Info(200, "获取版本成功", new
|
||||
{
|
||||
version = "1.0.0",
|
||||
clientVersion = "1.0.0",
|
||||
updateUrl = "http://localhost:56146/DataUser/StarMock.zip",
|
||||
updateTime = "2025-10-26",
|
||||
updateDesc = "StarPilot v1.0.0 - 初始版本",
|
||||
forceUpdate = true, // 是否强制更新
|
||||
minVersion = "1.0.0" // 最低支持版本
|
||||
});
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,6 +322,7 @@ namespace CCFlow.NetCore.DataUser.API.Controllers
|
||||
lock (WF_Comm.frmVSTOTemplateLock)
|
||||
BP.WF.Dev2Interface.Port_LoginByToken(token);
|
||||
|
||||
|
||||
DataSet ds = new DataSet();
|
||||
MapData mapData = new MapData(frmID);
|
||||
DataTable mapDataTable = mapData.ToDataTableField("Sys_MapData");
|
||||
@@ -408,6 +409,7 @@ namespace CCFlow.NetCore.DataUser.API.Controllers
|
||||
return "err@参数不能为空";
|
||||
}
|
||||
BP.WF.Dev2Interface.Port_LoginByToken(token);
|
||||
|
||||
IFormFile file = HttpContextHelper.RequestFiles(0);
|
||||
|
||||
byte[] buffer = new byte[file.Length];
|
||||
@@ -480,6 +482,7 @@ namespace CCFlow.NetCore.DataUser.API.Controllers
|
||||
{
|
||||
IFormFile file = HttpContextHelper.RequestFiles(0);
|
||||
BP.WF.Dev2Interface.Port_LoginByToken(token);
|
||||
|
||||
if (file == null || file.Length == 0)
|
||||
throw new Exception("err@文件数据bytes没有传递过来.");
|
||||
|
||||
@@ -545,6 +548,7 @@ namespace CCFlow.NetCore.DataUser.API.Controllers
|
||||
//执行登录.
|
||||
BP.WF.Dev2Interface.Port_LoginByToken(token);
|
||||
|
||||
|
||||
GenerWorkFlow gwf = new GenerWorkFlow(workID);
|
||||
|
||||
//获得消息.
|
||||
@@ -1225,7 +1229,7 @@ namespace CCFlow.NetCore.DataUser.API.Controllers
|
||||
{
|
||||
try
|
||||
{
|
||||
//Dev2Interface.Port_LoginByToken(token);
|
||||
//BP.WF.Dev2Interface.Port_LoginByToken(token);
|
||||
//此处为字段中文转拼音,设置为最大20个字符,edited by liuxc,2017-9-25
|
||||
string str = BP.Sys.CCFormAPI.ParseStringToPinyinField(name, flag, true, 20);
|
||||
return Return_Info(200, "成功", str);
|
||||
|
||||
@@ -63,8 +63,7 @@ namespace CCFlow
|
||||
builder.WithOrigins("http://10.38.0.79:30156",
|
||||
"http://localhost:3000",
|
||||
"http://localhost:3393",
|
||||
"http://localhost:6080",
|
||||
"http://127.0.0.1:3393",
|
||||
"http://127.0.0.1:3393",
|
||||
"http://192.168.1.7:8087") // 指定前端地址
|
||||
.AllowAnyHeader() // 用于支持http头中带token的认证
|
||||
.AllowAnyMethod() // 跨域时,浏览器会发一个OPTIONS请求。这儿也可以用.WithHeaders来指定具体的Http方法
|
||||
|
||||
@@ -4,7 +4,7 @@ https://go.microsoft.com/fwlink/?LinkID=208121.
|
||||
-->
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<History>True|2025-11-05T07:02:18.7047734Z||;True|2025-11-05T14:45:40.7216826+08:00||;True|2025-10-24T15:21:51.5147185+08:00||;True|2024-11-04T10:49:22.3439780+08:00||;True|2024-11-02T15:30:32.4493531+08:00||;True|2024-10-31T11:59:28.6642920+08:00||;True|2024-10-08T09:36:17.8010764+08:00||;False|2024-10-08T09:35:41.2564843+08:00||;True|2024-09-23T10:25:32.3661449+08:00||;True|2024-09-20T10:18:18.3623728+08:00||;True|2024-09-18T09:23:54.2366096+08:00||;True|2024-09-18T09:20:13.6313145+08:00||;True|2024-09-10T08:59:03.3615113+08:00||;True|2024-09-06T17:12:20.6511430+08:00||;True|2024-09-06T17:11:47.0125481+08:00||;True|2024-09-03T16:16:15.9895220+08:00||;True|2024-09-03T16:15:13.1769002+08:00||;True|2024-08-26T09:50:17.8879731+08:00||;True|2024-08-19T18:17:19.2685669+08:00||;True|2024-08-17T14:41:01.7202982+08:00||;True|2024-08-17T14:20:02.7322151+08:00||;True|2024-08-17T10:37:11.6370780+08:00||;True|2024-08-16T16:32:28.4506212+08:00||;True|2024-08-16T14:27:03.8626125+08:00||;True|2024-08-16T10:25:16.4322486+08:00||;True|2024-08-16T09:58:58.5530777+08:00||;True|2024-08-15T23:33:56.1737136+08:00||;True|2024-08-15T23:26:54.7595429+08:00||;True|2024-08-15T16:31:01.8402297+08:00||;True|2024-08-15T16:25:06.8337675+08:00||;True|2024-08-15T16:20:30.1035707+08:00||;True|2024-08-15T16:15:23.0017935+08:00||;True|2024-08-15T16:14:06.6106725+08:00||;True|2024-08-15T16:12:43.3544482+08:00||;True|2024-08-15T16:11:17.9301252+08:00||;True|2024-08-15T16:09:53.3238193+08:00||;True|2024-08-15T16:07:46.1388207+08:00||;True|2024-08-15T16:02:13.7608193+08:00||;True|2024-08-15T15:47:05.9594330+08:00||;True|2024-08-15T15:33:00.6545868+08:00||;True|2024-08-15T15:23:26.1171247+08:00||;True|2024-08-15T15:21:56.0150016+08:00||;True|2024-08-15T15:21:36.9296801+08:00||;True|2024-08-15T15:20:06.6029405+08:00||;True|2024-08-15T15:17:43.4263365+08:00||;True|2024-08-15T15:13:50.3381323+08:00||;True|2024-08-15T15:10:43.9408787+08:00||;True|2024-08-15T14:45:00.3779697+08:00||;True|2024-08-15T14:41:18.2346769+08:00||;True|2024-08-15T14:40:50.9397723+08:00||;True|2024-08-15T14:19:15.3844761+08:00||;True|2024-08-15T14:11:17.9180694+08:00||;True|2024-08-15T11:58:58.9103250+08:00||;True|2024-08-15T11:52:45.1310040+08:00||;True|2024-08-15T11:40:55.0247636+08:00||;True|2024-08-14T17:57:12.1001520+08:00||;True|2023-07-10T10:46:32.3936546+08:00||;True|2023-02-10T11:04:06.9187348+08:00||;True|2023-02-08T17:07:57.1599828+08:00||;True|2023-01-16T18:00:58.8027043+08:00||;True|2023-01-16T16:57:42.0128462+08:00||;True|2023-01-13T16:19:54.2694025+08:00||;True|2023-01-12T18:45:34.3556424+08:00||;True|2023-01-12T16:26:06.1117663+08:00||;True|2023-01-12T16:19:24.4642741+08:00||;True|2023-01-12T16:06:01.7639094+08:00||;True|2023-01-12T15:14:48.7525821+08:00||;False|2023-01-12T15:12:54.8911185+08:00||;False|2023-01-12T15:11:43.2429571+08:00||;False|2023-01-12T14:40:05.8520549+08:00||;False|2023-01-12T14:39:40.0972234+08:00||;True|2023-01-12T12:08:08.1313782+08:00||;False|2023-01-12T12:07:16.5121334+08:00||;True|2023-01-11T10:41:39.2725002+08:00||;True|2022-08-18T09:29:32.0440022+08:00||;False|2022-08-18T09:26:44.9335531+08:00||;False|2022-08-18T09:26:19.6424677+08:00||;</History>
|
||||
<History>True|2025-11-10T03:49:14.4433633Z||;True|2025-11-10T09:15:58.6766552+08:00||;True|2025-11-10T09:15:28.5199845+08:00||;True|2025-11-10T09:15:23.6119709+08:00||;False|2025-11-10T09:14:23.2673454+08:00||;True|2025-11-10T09:07:43.0128822+08:00||;True|2025-11-10T09:07:12.9193876+08:00||;True|2025-11-05T15:02:18.7047734+08:00||;True|2025-11-05T14:45:40.7216826+08:00||;True|2025-10-24T15:21:51.5147185+08:00||;True|2024-11-04T10:49:22.3439780+08:00||;True|2024-11-02T15:30:32.4493531+08:00||;True|2024-10-31T11:59:28.6642920+08:00||;True|2024-10-08T09:36:17.8010764+08:00||;False|2024-10-08T09:35:41.2564843+08:00||;True|2024-09-23T10:25:32.3661449+08:00||;True|2024-09-20T10:18:18.3623728+08:00||;True|2024-09-18T09:23:54.2366096+08:00||;True|2024-09-18T09:20:13.6313145+08:00||;True|2024-09-10T08:59:03.3615113+08:00||;True|2024-09-06T17:12:20.6511430+08:00||;True|2024-09-06T17:11:47.0125481+08:00||;True|2024-09-03T16:16:15.9895220+08:00||;True|2024-09-03T16:15:13.1769002+08:00||;True|2024-08-26T09:50:17.8879731+08:00||;True|2024-08-19T18:17:19.2685669+08:00||;True|2024-08-17T14:41:01.7202982+08:00||;True|2024-08-17T14:20:02.7322151+08:00||;True|2024-08-17T10:37:11.6370780+08:00||;True|2024-08-16T16:32:28.4506212+08:00||;True|2024-08-16T14:27:03.8626125+08:00||;True|2024-08-16T10:25:16.4322486+08:00||;True|2024-08-16T09:58:58.5530777+08:00||;True|2024-08-15T23:33:56.1737136+08:00||;True|2024-08-15T23:26:54.7595429+08:00||;True|2024-08-15T16:31:01.8402297+08:00||;True|2024-08-15T16:25:06.8337675+08:00||;True|2024-08-15T16:20:30.1035707+08:00||;True|2024-08-15T16:15:23.0017935+08:00||;True|2024-08-15T16:14:06.6106725+08:00||;True|2024-08-15T16:12:43.3544482+08:00||;True|2024-08-15T16:11:17.9301252+08:00||;True|2024-08-15T16:09:53.3238193+08:00||;True|2024-08-15T16:07:46.1388207+08:00||;True|2024-08-15T16:02:13.7608193+08:00||;True|2024-08-15T15:47:05.9594330+08:00||;True|2024-08-15T15:33:00.6545868+08:00||;True|2024-08-15T15:23:26.1171247+08:00||;True|2024-08-15T15:21:56.0150016+08:00||;True|2024-08-15T15:21:36.9296801+08:00||;True|2024-08-15T15:20:06.6029405+08:00||;True|2024-08-15T15:17:43.4263365+08:00||;True|2024-08-15T15:13:50.3381323+08:00||;True|2024-08-15T15:10:43.9408787+08:00||;True|2024-08-15T14:45:00.3779697+08:00||;True|2024-08-15T14:41:18.2346769+08:00||;True|2024-08-15T14:40:50.9397723+08:00||;True|2024-08-15T14:19:15.3844761+08:00||;True|2024-08-15T14:11:17.9180694+08:00||;True|2024-08-15T11:58:58.9103250+08:00||;True|2024-08-15T11:52:45.1310040+08:00||;True|2024-08-15T11:40:55.0247636+08:00||;True|2024-08-14T17:57:12.1001520+08:00||;True|2023-07-10T10:46:32.3936546+08:00||;True|2023-02-10T11:04:06.9187348+08:00||;True|2023-02-08T17:07:57.1599828+08:00||;True|2023-01-16T18:00:58.8027043+08:00||;True|2023-01-16T16:57:42.0128462+08:00||;True|2023-01-13T16:19:54.2694025+08:00||;True|2023-01-12T18:45:34.3556424+08:00||;True|2023-01-12T16:26:06.1117663+08:00||;True|2023-01-12T16:19:24.4642741+08:00||;True|2023-01-12T16:06:01.7639094+08:00||;True|2023-01-12T15:14:48.7525821+08:00||;False|2023-01-12T15:12:54.8911185+08:00||;False|2023-01-12T15:11:43.2429571+08:00||;False|2023-01-12T14:40:05.8520549+08:00||;False|2023-01-12T14:39:40.0972234+08:00||;True|2023-01-12T12:08:08.1313782+08:00||;False|2023-01-12T12:07:16.5121334+08:00||;True|2023-01-11T10:41:39.2725002+08:00||;True|2022-08-18T09:29:32.0440022+08:00||;False|2022-08-18T09:26:44.9335531+08:00||;False|2022-08-18T09:26:19.6424677+08:00||;</History>
|
||||
<_PublishTargetUrl>D:\workspace\svn\.netcore发布</_PublishTargetUrl>
|
||||
<LastFailureDetails />
|
||||
</PropertyGroup>
|
||||
|
||||
@@ -4,11 +4,10 @@
|
||||
<section name="nlog" type="NLog.Config.ConfigSectionHandler, NLog" />
|
||||
</configSections>
|
||||
<appSettings>
|
||||
|
||||
<!--本地演示环境数据库链接-->
|
||||
<add key="AppCenterDSN" value="SslMode=none;Data Source=localhost;Port=3306;Persist Security info=True;Initial Catalog=数据库名称;User ID=数据库账号;Password=数据库密码;Charset=utf8"/>
|
||||
<add key="AppCenterDBType" value="MySQL"/>
|
||||
<add key="CCBPMRunModel" value="0"/>
|
||||
|
||||
<add key="appcenterdsn" value="sslmode=none;data source=localhost;port=4316;persist security info=true;initial catalog=XXX;user id=XXX;password=XXXX;charset=utf8;allow user variables=true;"/>
|
||||
<add key="appcenterdbtype" value="MySQL"/>
|
||||
<add key="ccbpmrunmodel" value="0"/>
|
||||
|
||||
<!--0 -->
|
||||
<add key="TokenModel" value="0"/>
|
||||
@@ -83,16 +82,23 @@
|
||||
<!-- 前端输入的加密AES的Key 默认为:lCCqkL1BfSwt2M@5 -->
|
||||
<add key="IsEncryptionKey" value="lCCqkL1BfSwt2M@5"/>
|
||||
|
||||
<!-- 用户登录密码组合类型 0:无 1: 8-20位字符,必须包含大小写字母、数字。在密码中不得包含用户名 -->
|
||||
<add key="PassWordComposeType" value="1"/>
|
||||
<!-- 用户第一次登录时是否强制要求修改密码 0:否 1:是 -->
|
||||
<add key="IsPassWordChangeBYFirstLogin" value="1"/>
|
||||
<!-- 用户登录密码修改时的校验类型 0:无 1: 至少包含8个字符;必须为大小写字母、数字和符号的组合;不得包含帐户名、实际姓名全拼或缩写;不能出现连续数字(3位及以上) -->
|
||||
<add key="PassWordComposeType" value="0"/>
|
||||
<!-- 用户登录密码中不能包含的敏感词,PassWordComposeType=1时检测,多个逗号分隔(忽略大小写) -->
|
||||
<add key="PassWordComposeTypeSensitiveWords" value="pass,password,root"/>
|
||||
|
||||
<!-- 用户第一次登录或使用初始密码时是否强制要求修改密码 0:否 1:是 -->
|
||||
<add key="IsPassWordChangeBYFirstLogin" value="0"/>
|
||||
<!-- 用户的操作日志是否记录数据库(登录,访问,删除,权限修改以及其他操作) 0:否 1:是-->
|
||||
<add key="IsEnableLog" value="0"/>
|
||||
|
||||
|
||||
|
||||
<!-- 用户信息显示格式 @0=UserID,UserName@1=UserNo,@2=UserName 0=zhangsa,张三. 1=zhangsan, 2=张三. -->
|
||||
<add key="UserInfoShowModel" value="0" />
|
||||
|
||||
<!-- 是否:debug状态. 0 表示不是, 1 是,如果系统发布后,请将此修改成0,以提高执行效率。 -->
|
||||
<add key="IsDebug" value="0" />
|
||||
<add key="IsDebug" value="1" />
|
||||
|
||||
<!-- 是否:自动测试模式. 0-不是, 1 -是,注意:系统发布后,勿必将此修改成0,否则可能影响部分功能使用(2017-09-08暂时仅影响VSTO插件功能)。 -->
|
||||
<add key="IsAutoTesting" value="0" />
|
||||
|
||||
@@ -4,6 +4,11 @@
|
||||
<name>CCFlow</name>
|
||||
</assembly>
|
||||
<members>
|
||||
<member name="M:CCFlow.NetCore.DataUser.API.Controllers.GZSZController.UpdateHisData(System.Int32)">
|
||||
修改历史数据
|
||||
@return
|
||||
@throws Exception
|
||||
</member>
|
||||
<member name="M:CCFlow.NetCore.DataUser.API.Controllers.APIController.Return_Info(System.Int32,System.String,System.String)">
|
||||
<summary>
|
||||
返回信息格式
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
|
||||
/*
|
||||
/*
|
||||
简介:负责存取数据的类
|
||||
创建时间:2002-10
|
||||
最后修改时间:2004-2-1 ccb
|
||||
@@ -27,6 +26,9 @@ using Kdbndp;
|
||||
using BP.Difference;
|
||||
using KdbndpTypes;
|
||||
using NPOI.SS.Formula.Functions;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Common;
|
||||
|
||||
namespace BP.DA
|
||||
{
|
||||
@@ -36,6 +38,33 @@ namespace BP.DA
|
||||
/// </summary>
|
||||
public class DBAccess
|
||||
{
|
||||
// 用于控制对同一表的并发访问,避免死锁
|
||||
// Key: 表名(小写),Value: SemaphoreSlim 信号量(允许最多1个并发,即串行化)
|
||||
private static System.Collections.Generic.Dictionary<string, System.Threading.SemaphoreSlim> _tableSemaphores =
|
||||
new System.Collections.Generic.Dictionary<string, System.Threading.SemaphoreSlim>();
|
||||
private static readonly object _semaphoreLock = new object();
|
||||
|
||||
/// <summary>
|
||||
/// 获取或创建表对应的信号量,用于控制并发访问
|
||||
/// </summary>
|
||||
private static System.Threading.SemaphoreSlim GetTableSemaphore(string tableName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(tableName))
|
||||
return null;
|
||||
|
||||
string key = tableName.ToLower();
|
||||
lock (_semaphoreLock)
|
||||
{
|
||||
if (!_tableSemaphores.ContainsKey(key))
|
||||
{
|
||||
// 每个表最多允许3个并发,在避免死锁和提高吞吐量之间取得平衡
|
||||
// 对于DELETE操作,由于通常针对不同的行(不同的StandMyPK),允许有限并发是安全的
|
||||
_tableSemaphores[key] = new System.Threading.SemaphoreSlim(3, 3);
|
||||
}
|
||||
return _tableSemaphores[key];
|
||||
}
|
||||
}
|
||||
|
||||
public static string GenerMD5(string str, bool islower = false)
|
||||
{
|
||||
if (islower == true)
|
||||
@@ -100,7 +129,7 @@ namespace BP.DA
|
||||
BP.DA.DBAccess.RunSQL(sql);
|
||||
}
|
||||
|
||||
public static void UpdateTableColumnType(string tableName, string colName,string dataType,SFDBSrc sfdbsrc)
|
||||
public static void UpdateTableColumnType(string tableName, string colName, string dataType, SFDBSrc sfdbsrc)
|
||||
{
|
||||
//判断数据库中表单是否存在
|
||||
if (sfdbsrc.IsExitsTableCol(tableName, colName) == false || sfdbsrc.IsView(tableName, sfdbsrc.HisDBType) == true)
|
||||
@@ -111,7 +140,7 @@ namespace BP.DA
|
||||
switch (sfdbsrc.HisDBType)
|
||||
{
|
||||
case DBType.MSSQL:
|
||||
sql = "SELECT data_type as FTYPE FROM information_schema.columns where table_name='" + tableName + "' AND column_name='"+colName+"'";
|
||||
sql = "SELECT data_type as FTYPE FROM information_schema.columns where table_name='" + tableName + "' AND column_name='" + colName + "'";
|
||||
break;
|
||||
case DBType.Oracle:
|
||||
case DBType.DM:
|
||||
@@ -119,10 +148,10 @@ namespace BP.DA
|
||||
case DBType.KingBaseR6:
|
||||
case DBType.KingBaseR8:
|
||||
case DBType.GBASE8CByOracle:
|
||||
sql = "SELECT DATA_TYPE as FTYPE FROM all_tab_columns WHERE table_name = upper('" + tableName + "') AND UPPER(COLUMN_NAME)='" + colName.ToUpper() ;
|
||||
sql = "SELECT DATA_TYPE as FTYPE FROM all_tab_columns WHERE table_name = upper('" + tableName + "') AND UPPER(COLUMN_NAME)='" + colName.ToUpper();
|
||||
break;
|
||||
case DBType.MySQL:
|
||||
sql = "SELECT DATA_TYPE FTYPE FROM information_schema.columns WHERE table_name='" + tableName + "' AND column_name='"+colName+"' and TABLE_SCHEMA='" + sfdbsrc.GetTableSchema() + "'";
|
||||
sql = "SELECT DATA_TYPE FTYPE FROM information_schema.columns WHERE table_name='" + tableName + "' AND column_name='" + colName + "' and TABLE_SCHEMA='" + sfdbsrc.GetTableSchema() + "'";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -151,7 +180,7 @@ namespace BP.DA
|
||||
}
|
||||
|
||||
}
|
||||
toType = dataType.Equals("String") ? " VARCHAR(20)" : " INT";
|
||||
toType = dataType.Equals("String") ? " VARCHAR(20)" : " INT";
|
||||
if (dataType.Equals("String") || dataType.Equals("Int"))
|
||||
sfdbsrc.RunSQL("alter table " + tableName + " ALTER column " + colName + toType);
|
||||
|
||||
@@ -194,7 +223,7 @@ namespace BP.DA
|
||||
/// <summary>
|
||||
/// 获得数据表字段描述的SQL
|
||||
/// </summary>
|
||||
public static string SQLOfTableFieldDesc(string table,DBType dbType)
|
||||
public static string SQLOfTableFieldDesc(string table, DBType dbType)
|
||||
{
|
||||
if (dbType == DBType.MSSQL)
|
||||
return "SELECT column_name as FName,data_type as FType,CHARACTER_MAXIMUM_LENGTH as FLen from information_schema.columns where table_name='" + table + "'";
|
||||
@@ -234,7 +263,7 @@ namespace BP.DA
|
||||
/// </summary>
|
||||
/// <param name="table"></param>
|
||||
/// <returns></returns>
|
||||
public static string SQLOfTableFieldYueShu(string table,DBType dbType)
|
||||
public static string SQLOfTableFieldYueShu(string table, DBType dbType)
|
||||
{
|
||||
if (dbType == DBType.MSSQL)
|
||||
return "SELECT b.name, a.name FName from sysobjects b join syscolumns a on b.id = a.cdefault where a.id = object_id('" + table + "') ";
|
||||
@@ -549,14 +578,14 @@ namespace BP.DA
|
||||
MySqlCommand cm = new MySqlCommand();
|
||||
cm.Connection = cn;
|
||||
cm.CommandType = CommandType.Text;
|
||||
|
||||
|
||||
//if (tableName == "Sys_FrmPrintTemplate")
|
||||
//{
|
||||
// cm.CommandText = "UPDATE " + tableName + " SET NodeID=1 WHERE " + tablePK + " =@PKVal";
|
||||
// }
|
||||
// else {
|
||||
cm.CommandText = "UPDATE " + tableName + " SET " + saveToFileField + "=@FlowJsonFile WHERE " + tablePK + " =@PKVal";
|
||||
// }
|
||||
// cm.CommandText = "UPDATE " + tableName + " SET NodeID=1 WHERE " + tablePK + " =@PKVal";
|
||||
// }
|
||||
// else {
|
||||
cm.CommandText = "UPDATE " + tableName + " SET " + saveToFileField + "=@FlowJsonFile WHERE " + tablePK + " =@PKVal";
|
||||
// }
|
||||
|
||||
|
||||
MySqlParameter spFile = new MySqlParameter("FlowJsonFile", MySqlDbType.Blob);
|
||||
@@ -661,7 +690,8 @@ namespace BP.DA
|
||||
public static void SaveFileToDB(string fullFileName, string tableName, string tablePK, string pkVal, string saveToFileField)
|
||||
{
|
||||
FileInfo fi = new FileInfo(fullFileName);
|
||||
if (fi.Exists) {
|
||||
if (fi.Exists)
|
||||
{
|
||||
FileStream fs = fi.OpenRead();
|
||||
byte[] bytes = new byte[fs.Length];
|
||||
fs.Read(bytes, 0, Convert.ToInt32(fs.Length));
|
||||
@@ -852,10 +882,10 @@ namespace BP.DA
|
||||
{
|
||||
string sql = "";
|
||||
/*如果没有此列,就自动创建此列.*/
|
||||
|
||||
|
||||
sql = "ALTER TABLE " + tableName + " ADD " + fileSaveField + " blob ";
|
||||
|
||||
|
||||
|
||||
sql = "ALTER TABLE " + tableName + " ADD " + fileSaveField + " blob ";
|
||||
|
||||
|
||||
DBAccess.RunSQL(sql);
|
||||
return null;
|
||||
@@ -878,7 +908,8 @@ namespace BP.DA
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (dr != null) { dr.Close(); };
|
||||
if (dr != null) { dr.Close(); }
|
||||
;
|
||||
cm.Dispose();
|
||||
cn.Dispose();
|
||||
}
|
||||
@@ -940,7 +971,8 @@ namespace BP.DA
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (dr != null) { dr.Close(); };
|
||||
if (dr != null) { dr.Close(); }
|
||||
;
|
||||
cm.Dispose();
|
||||
cn.Dispose();
|
||||
}
|
||||
@@ -994,7 +1026,8 @@ namespace BP.DA
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (dr != null) { dr.Close(); };
|
||||
if (dr != null) { dr.Close(); }
|
||||
;
|
||||
cm.Dispose();
|
||||
conn.Dispose();
|
||||
}
|
||||
@@ -1046,7 +1079,8 @@ namespace BP.DA
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (dr != null) { dr.Close(); };
|
||||
if (dr != null) { dr.Close(); }
|
||||
;
|
||||
cm.Dispose();
|
||||
cn.Dispose();
|
||||
}
|
||||
@@ -1097,7 +1131,8 @@ namespace BP.DA
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (dr != null) { dr.Close(); };
|
||||
if (dr != null) { dr.Close(); }
|
||||
;
|
||||
cm.Dispose();
|
||||
cn.Dispose();
|
||||
}
|
||||
@@ -1147,7 +1182,8 @@ namespace BP.DA
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (dr != null) { dr.Close(); };
|
||||
if (dr != null) { dr.Close(); }
|
||||
;
|
||||
cm.Dispose();
|
||||
cn.Dispose();
|
||||
}
|
||||
@@ -1725,7 +1761,7 @@ namespace BP.DA
|
||||
}
|
||||
else
|
||||
{
|
||||
DBAccess.RunSQL("ALTER TABLE " + tableName + " ADD " + columnName + " NVARCHAR(20) DEFAULT '" + defaultVal + "' NULL ");
|
||||
DBAccess.RunSQL("ALTER TABLE " + tableName + " ADD " + columnName + " NVARCHAR(20) DEFAULT '" + defaultVal + "' NULL ");
|
||||
}
|
||||
break;
|
||||
case DataType.AppInt:
|
||||
@@ -1757,7 +1793,7 @@ namespace BP.DA
|
||||
/// </summary>
|
||||
/// <param name="tableName"></param>
|
||||
/// <returns>FIELD-字段名称;TYPE-字段类型</returns>
|
||||
public static DataTable getTableFieldType(string tableName,SFDBSrc sfdbSrc)
|
||||
public static DataTable getTableFieldType(string tableName, SFDBSrc sfdbSrc)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -1824,7 +1860,7 @@ namespace BP.DA
|
||||
" JOIN user_ind_columns ic ON i.index_name = ic.index_name" +
|
||||
" WHERE i.table_name = '" + table.ToUpper() + "' AND ic.column_name = '" + fieldName.ToUpper() + "'" +
|
||||
" ORDER BY i.index_name";
|
||||
dt = DBAccess.RunSQLReturnTable(sql);
|
||||
dt = DBAccess.RunSQLReturnTable(sql);
|
||||
if (dt.Rows.Count != 0)
|
||||
{
|
||||
string indexName = dt.Rows[0][0].ToString();
|
||||
@@ -1837,7 +1873,7 @@ namespace BP.DA
|
||||
sql = "SELECT i.name ,i.type_desc,i.is_unique,i.is_primary_key,ic.is_included_column FROM sys.indexes i" +
|
||||
" INNER JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id" +
|
||||
" INNER JOIN sys.columns c ON ic.object_id = c.object_id AND ic.column_id = c.column_id" +
|
||||
" INNER JOIN sys.tables t ON i.object_id = t.object_id WHERE t.name = '"+ table + "' AND c.name = '"+ fieldName + "' ";
|
||||
" INNER JOIN sys.tables t ON i.object_id = t.object_id WHERE t.name = '" + table + "' AND c.name = '" + fieldName + "' ";
|
||||
dt = DBAccess.RunSQLReturnTable(sql);
|
||||
if (dt.Rows.Count != 0)
|
||||
{
|
||||
@@ -2068,26 +2104,29 @@ namespace BP.DA
|
||||
|
||||
#region 索引管理
|
||||
|
||||
public static void DropIndex(string table, string idxName)
|
||||
public static void DropIndex(string table, string idxName)
|
||||
{
|
||||
string sql = "";
|
||||
switch (AppCenterDBType)
|
||||
{
|
||||
case DBType.HGDB:
|
||||
sql = "DROP INDEX IF EXISTS " + idxName;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
try{
|
||||
if(!sql.Equals("")){
|
||||
DBAccess.RunSQL(sql);
|
||||
}
|
||||
}catch (Exception ex)
|
||||
{
|
||||
switch (AppCenterDBType)
|
||||
{
|
||||
case DBType.HGDB:
|
||||
sql = "DROP INDEX IF EXISTS " + idxName;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
try
|
||||
{
|
||||
if (!sql.Equals(""))
|
||||
{
|
||||
DBAccess.RunSQL(sql);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
public static void CreatIndex(string table, string fields)
|
||||
{
|
||||
string myFields = fields.Replace(",", "_");
|
||||
@@ -2243,33 +2282,20 @@ namespace BP.DA
|
||||
switch (AppCenterDBType)
|
||||
{
|
||||
case DBType.MSSQL:
|
||||
result = RunSQL_200705_SQL(sql, paras);
|
||||
break;
|
||||
case DBType.Oracle:
|
||||
case DBType.GBASE8CByOracle:
|
||||
result = RunSQL_200705_Ora(sql.Replace("]", "").Replace("[", ""), paras);
|
||||
break;
|
||||
case DBType.MySQL:
|
||||
result = RunSQL_200705_MySQL(sql, paras);
|
||||
break;
|
||||
case DBType.PostgreSQL:
|
||||
case DBType.HGDB:
|
||||
result = RunSQL_201902_PSQL(sql, paras);
|
||||
break;
|
||||
case DBType.UX:
|
||||
result = RunSQL_201902_UXQL(sql, paras);
|
||||
break;
|
||||
case DBType.DM:
|
||||
result = RunSQL_20191230_DM(sql, paras);
|
||||
break;
|
||||
case DBType.KingBaseR3:
|
||||
case DBType.KingBaseR6:
|
||||
case DBType.KingBaseR8:
|
||||
result = RunSQL_201902_KingBase(sql.Replace("]", "").Replace("[", ""), paras);
|
||||
result = RunSQL_2025(sql, paras);
|
||||
break;
|
||||
case DBType.Oracle:
|
||||
case DBType.GBASE8CByOracle:
|
||||
result = RunSQL_2025(sql.Replace("]", "").Replace("[", ""), paras);
|
||||
break;
|
||||
//case DBType.Informix:
|
||||
// result = RunSQL_201205_Informix(sql, paras);
|
||||
// break;
|
||||
default:
|
||||
throw new Exception("err@RunSQL发现未知的数据库连接类型!");
|
||||
}
|
||||
@@ -2418,15 +2444,8 @@ namespace BP.DA
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
paras.SQL = sql;
|
||||
string msg = "";
|
||||
if (paras.Count == 0)
|
||||
msg = "SQL=" + sql + ",异常信息:" + ex.Message;
|
||||
else
|
||||
msg = "SQL=" + paras.SQLNoPara + ",异常信息:" + ex.Message;
|
||||
|
||||
BP.DA.Log.DebugWriteError(msg);
|
||||
throw new Exception(msg);
|
||||
DealExeSQLException(ex, sql, paras);
|
||||
return -1;
|
||||
}
|
||||
finally
|
||||
{
|
||||
@@ -2436,6 +2455,20 @@ namespace BP.DA
|
||||
conn.Dispose();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 处理执行SQL异常
|
||||
/// </summary>
|
||||
/// <param name="ex"></param>
|
||||
/// <param name="sql"></param>
|
||||
/// <param name="paras"></param>
|
||||
/// <exception cref="Exception"></exception>
|
||||
private static void DealExeSQLException(Exception ex, string sql, Paras paras)
|
||||
{
|
||||
string msg = "执行SQL:" + sql + ",参数:" + paras.ToString() + ",异常:" + ex.Message;
|
||||
BP.DA.Log.DebugWriteError(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
private static int RunSQL_201902_UXQL(string sql, Paras paras)
|
||||
{
|
||||
if (1 == 1)
|
||||
@@ -2630,82 +2663,376 @@ namespace BP.DA
|
||||
conn.Close();
|
||||
}
|
||||
}
|
||||
|
||||
#region 处理mysql conn的缓存.
|
||||
private static Hashtable _ConnHTOfMySQL = null;
|
||||
public static Hashtable ConnHTOfMySQL
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_ConnHTOfMySQL == null || _ConnHTOfMySQL.Count <= 0)
|
||||
{
|
||||
_ConnHTOfMySQL = new Hashtable();
|
||||
int numConn = 10;
|
||||
for (int i = 0; i < numConn; i++)
|
||||
{
|
||||
MySqlConnection conn = new MySqlConnection(BP.Difference.SystemConfig.AppCenterDSN);
|
||||
conn.Open(); //打开连接.
|
||||
_ConnHTOfMySQL.Add("Conn" + i, conn);
|
||||
}
|
||||
}
|
||||
return _ConnHTOfMySQL;
|
||||
}
|
||||
}
|
||||
#endregion 处理mysql conn的缓存.
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// RunSQL_200705_MySQL
|
||||
/// 从SQL语句中提取表名(用于表锁)
|
||||
/// </summary>
|
||||
/// <param name="sql"></param>
|
||||
/// <param name="paras"></param>
|
||||
/// <returns></returns>
|
||||
private static int RunSQL_200705_MySQL(string sql, Paras paras)
|
||||
/// <param name="sql">SQL语句</param>
|
||||
/// <returns>表名,如果未找到则返回null</returns>
|
||||
private static string ExtractTableNameFromSQL(string sql)
|
||||
{
|
||||
MySqlConnection connOfMySQL = new MySqlConnection(BP.Difference.SystemConfig.AppCenterDSN);
|
||||
if (connOfMySQL.State != System.Data.ConnectionState.Open)
|
||||
if (string.IsNullOrEmpty(sql))
|
||||
return null;
|
||||
|
||||
// 移除注释和多余空格
|
||||
string cleanSql = sql.Trim();
|
||||
// 移除SQL注释
|
||||
cleanSql = System.Text.RegularExpressions.Regex.Replace(cleanSql, @"--.*", "");
|
||||
cleanSql = System.Text.RegularExpressions.Regex.Replace(cleanSql, @"/\*.*?\*/", "", System.Text.RegularExpressions.RegexOptions.Singleline);
|
||||
|
||||
// 匹配 DELETE FROM table_name
|
||||
var deleteMatch = System.Text.RegularExpressions.Regex.Match(cleanSql, @"DELETE\s+FROM\s+([^\s\(]+)", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
|
||||
if (deleteMatch.Success)
|
||||
{
|
||||
connOfMySQL.ConnectionString = BP.Difference.SystemConfig.AppCenterDSN;
|
||||
connOfMySQL.Open();
|
||||
string tableName = deleteMatch.Groups[1].Value.Trim();
|
||||
// 移除可能的反引号、方括号等
|
||||
tableName = tableName.Trim('`', '[', ']');
|
||||
if (!string.IsNullOrEmpty(tableName))
|
||||
return tableName;
|
||||
}
|
||||
|
||||
// 匹配 UPDATE table_name
|
||||
var updateMatch = System.Text.RegularExpressions.Regex.Match(cleanSql, @"UPDATE\s+([^\s\(]+)", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
|
||||
if (updateMatch.Success)
|
||||
{
|
||||
string tableName = updateMatch.Groups[1].Value.Trim();
|
||||
tableName = tableName.Trim('`', '[', ']');
|
||||
if (!string.IsNullOrEmpty(tableName))
|
||||
return tableName;
|
||||
}
|
||||
|
||||
// 匹配 INSERT INTO table_name
|
||||
var insertMatch = System.Text.RegularExpressions.Regex.Match(cleanSql, @"INSERT\s+(?:INTO\s+)?([^\s\(]+)", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
|
||||
if (insertMatch.Success)
|
||||
{
|
||||
string tableName = insertMatch.Groups[1].Value.Trim();
|
||||
tableName = tableName.Trim('`', '[', ']');
|
||||
if (!string.IsNullOrEmpty(tableName))
|
||||
return tableName;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
private static int RunSQL_2025(string sql, Paras paras)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(sql))
|
||||
return 0;
|
||||
|
||||
DBType dbType = AppCenterDBType;
|
||||
string originalSql = sql;
|
||||
|
||||
string primaryTableName = ExtractTableNameFromSQL(originalSql);
|
||||
System.Threading.SemaphoreSlim tableSemaphore = GetTableSemaphore(primaryTableName);
|
||||
|
||||
int maxRetries = 5;
|
||||
int baseRetryDelay = 50;
|
||||
Random random = new Random();
|
||||
Exception lastException = null;
|
||||
|
||||
IEnumerable<Para> effectiveParasEnumerable;
|
||||
string normalizedSql = NormalizeSqlForProvider(originalSql, paras, dbType, out effectiveParasEnumerable);
|
||||
List<Para> effectiveParas = effectiveParasEnumerable?.ToList() ?? new List<Para>();
|
||||
|
||||
if (tableSemaphore != null && !tableSemaphore.Wait(60000))
|
||||
throw new Exception($"获取表锁超时(60秒): {primaryTableName}, SQL: {originalSql}");
|
||||
|
||||
try
|
||||
{
|
||||
MySqlCommand cmd = new MySqlCommand(sql, connOfMySQL);
|
||||
cmd.CommandType = CommandType.Text;
|
||||
|
||||
if (paras != null)
|
||||
for (int attempt = 0; attempt < maxRetries; attempt++)
|
||||
{
|
||||
foreach (Para para in paras)
|
||||
using (DbConnection connection = CreateDbConnection(dbType))
|
||||
using (DbCommand command = connection.CreateCommand())
|
||||
{
|
||||
MySqlParameter oraP = new MySqlParameter(para.ParaName, para.val);
|
||||
cmd.Parameters.Add(oraP);
|
||||
command.CommandText = normalizedSql;
|
||||
command.CommandType = CommandType.Text;
|
||||
|
||||
foreach (Para para in effectiveParas)
|
||||
{
|
||||
command.Parameters.Add(CreateDbParameter(para, dbType));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (connection.State != ConnectionState.Open)
|
||||
connection.Open();
|
||||
|
||||
int result = command.ExecuteNonQuery();
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
lastException = ex;
|
||||
|
||||
if (!IsTransientError(ex, dbType) || attempt == maxRetries - 1)
|
||||
throw new Exception($"err@RunSQL_200705_MySQL({dbType}): {ex.Message} SQL={originalSql}", ex);
|
||||
|
||||
System.Threading.Thread.Sleep(CalculateRetryDelay(attempt, baseRetryDelay, random));
|
||||
}
|
||||
finally
|
||||
{
|
||||
command.Parameters.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
return cmd.ExecuteNonQuery();
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
throw new Exception("err@RunSQL_200705_MySQL:" + ex.Message + "@SQL:" + sql);
|
||||
|
||||
if (lastException != null)
|
||||
throw new Exception($"err@RunSQL_200705_MySQL({dbType}): 经过{maxRetries}次重试后仍失败: {lastException.Message} SQL={originalSql}", lastException);
|
||||
|
||||
throw new Exception($"err@RunSQL_200705_MySQL({dbType}): 执行失败,未知错误 SQL={originalSql}");
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (connOfMySQL != null)
|
||||
if (tableSemaphore != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (connOfMySQL.State == System.Data.ConnectionState.Open)
|
||||
{
|
||||
connOfMySQL.Close();
|
||||
}
|
||||
tableSemaphore.Release();
|
||||
}
|
||||
catch { }
|
||||
finally
|
||||
catch
|
||||
{
|
||||
connOfMySQL.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string NormalizeSqlForProvider(string sql, Paras paras, DBType dbType, out IEnumerable<Para> effectiveParas)
|
||||
{
|
||||
string normalized = sql ?? string.Empty;
|
||||
List<Para> parameters = new List<Para>();
|
||||
|
||||
if (paras != null)
|
||||
{
|
||||
foreach (Para para in paras)
|
||||
{
|
||||
parameters.Add(para);
|
||||
}
|
||||
}
|
||||
|
||||
if (dbType != DBType.MSSQL)
|
||||
{
|
||||
normalized = normalized.Replace("[", string.Empty).Replace("]", string.Empty);
|
||||
}
|
||||
|
||||
if (dbType == DBType.Oracle || dbType == DBType.GBASE8CByOracle)
|
||||
{
|
||||
string trimmed = normalized.Trim();
|
||||
if (trimmed.EndsWith(";"))
|
||||
{
|
||||
normalized = $"begin {trimmed} end;";
|
||||
}
|
||||
|
||||
if (paras != null && paras.Count > 0)
|
||||
{
|
||||
List<Para> filtered = new List<Para>();
|
||||
string dbVarStr = SystemConfig.AppCenterDBVarStr;
|
||||
|
||||
foreach (Para para in paras)
|
||||
{
|
||||
object val = para.val;
|
||||
bool isNullOrEmpty = val == null || val == DBNull.Value || string.IsNullOrEmpty(val.ToString());
|
||||
if (isNullOrEmpty)
|
||||
{
|
||||
normalized = normalized.Replace("=" + dbVarStr + para.ParaName, " IS NULL ");
|
||||
normalized = normalized.Replace("<>" + dbVarStr + para.ParaName, " IS NOT NULL ");
|
||||
}
|
||||
else
|
||||
{
|
||||
filtered.Add(para);
|
||||
}
|
||||
}
|
||||
|
||||
parameters = filtered;
|
||||
}
|
||||
}
|
||||
|
||||
effectiveParas = parameters;
|
||||
return normalized;
|
||||
}
|
||||
|
||||
private static DbConnection CreateDbConnection(DBType dbType)
|
||||
{
|
||||
string dsn = SystemConfig.AppCenterDSN;
|
||||
switch (dbType)
|
||||
{
|
||||
case DBType.MySQL:
|
||||
return new MySqlConnection(dsn);
|
||||
case DBType.MSSQL:
|
||||
return new SqlConnection(dsn);
|
||||
case DBType.Oracle:
|
||||
case DBType.GBASE8CByOracle:
|
||||
return new OracleConnection(dsn);
|
||||
case DBType.PostgreSQL:
|
||||
case DBType.HGDB:
|
||||
return new NpgsqlConnection(dsn);
|
||||
case DBType.DM:
|
||||
return new DmConnection(dsn);
|
||||
case DBType.KingBaseR3:
|
||||
case DBType.KingBaseR6:
|
||||
case DBType.KingBaseR8:
|
||||
return new KdbndpConnection(dsn);
|
||||
case DBType.UX:
|
||||
return new NuxsqlConnection(dsn);
|
||||
default:
|
||||
throw new NotSupportedException($"err@RunSQL_200705_MySQL: 尚未实现 {dbType} 的执行逻辑");
|
||||
}
|
||||
}
|
||||
|
||||
private static DbParameter CreateDbParameter(Para para, DBType dbType)
|
||||
{
|
||||
if (para == null)
|
||||
throw new ArgumentNullException(nameof(para));
|
||||
|
||||
object value = para.val ?? DBNull.Value;
|
||||
|
||||
switch (dbType)
|
||||
{
|
||||
case DBType.MSSQL:
|
||||
{
|
||||
SqlParameter parameter = new SqlParameter(para.ParaName, value)
|
||||
{
|
||||
DbType = para.DAType
|
||||
};
|
||||
if (para.Size > 0)
|
||||
parameter.Size = para.Size;
|
||||
return parameter;
|
||||
}
|
||||
case DBType.MySQL:
|
||||
{
|
||||
MySqlParameter parameter = new MySqlParameter(para.ParaName, value)
|
||||
{
|
||||
DbType = para.DAType
|
||||
};
|
||||
if (para.Size > 0)
|
||||
parameter.Size = para.Size;
|
||||
return parameter;
|
||||
}
|
||||
case DBType.PostgreSQL:
|
||||
case DBType.HGDB:
|
||||
{
|
||||
NpgsqlParameter parameter = new NpgsqlParameter(para.ParaName, value)
|
||||
{
|
||||
DbType = para.DAType
|
||||
};
|
||||
if (para.Size > 0)
|
||||
parameter.Size = para.Size;
|
||||
return parameter;
|
||||
}
|
||||
case DBType.UX:
|
||||
{
|
||||
Nuxsql.NuxsqlParameter parameter = new Nuxsql.NuxsqlParameter(para.ParaName, value)
|
||||
{
|
||||
DbType = para.DAType
|
||||
};
|
||||
if (para.Size > 0)
|
||||
parameter.Size = para.Size;
|
||||
return parameter;
|
||||
}
|
||||
case DBType.DM:
|
||||
{
|
||||
DmParameter parameter = new DmParameter(para.ParaName, value == DBNull.Value ? DBNull.Value : value.ToString())
|
||||
{
|
||||
DbType = para.DAType
|
||||
};
|
||||
return parameter;
|
||||
}
|
||||
case DBType.KingBaseR3:
|
||||
case DBType.KingBaseR6:
|
||||
case DBType.KingBaseR8:
|
||||
{
|
||||
KdbndpParameter parameter = new KdbndpParameter(para.ParaName, value)
|
||||
{
|
||||
DbType = para.DAType
|
||||
};
|
||||
if (para.Size > 0)
|
||||
parameter.Size = para.Size;
|
||||
return parameter;
|
||||
}
|
||||
case DBType.Oracle:
|
||||
case DBType.GBASE8CByOracle:
|
||||
{
|
||||
OracleParameter parameter = new OracleParameter(para.ParaName, para.DATypeOfOra);
|
||||
parameter.Size = para.Size;
|
||||
|
||||
if (para.DATypeOfOra == OracleDbType.Varchar2 && Convert.IsDBNull(para.val))
|
||||
{
|
||||
parameter.Value = DBNull.Value;
|
||||
return parameter;
|
||||
}
|
||||
|
||||
if (para.DATypeOfOra == OracleDbType.Clob && DataType.IsNullOrEmpty(para.val as string) == true)
|
||||
parameter.Value = DBNull.Value;
|
||||
else
|
||||
parameter.Value = para.val;
|
||||
parameter.DbType = para.DAType;
|
||||
|
||||
return parameter;
|
||||
}
|
||||
default:
|
||||
throw new NotSupportedException($"err@RunSQL_200705_MySQL: 尚未实现 {dbType} 的参数绑定");
|
||||
}
|
||||
}
|
||||
|
||||
private static bool IsTransientError(Exception ex, DBType dbType)
|
||||
{
|
||||
if (ex == null)
|
||||
return false;
|
||||
|
||||
string message = ex.Message?.ToLowerInvariant() ?? string.Empty;
|
||||
|
||||
if (message.Contains("deadlock") || message.Contains("lock wait timeout") || message.Contains("timeout") ||
|
||||
message.Contains("try restarting transaction") || message.Contains("could not serialize access") ||
|
||||
message.Contains("connection reset") || message.Contains("connection refused") ||
|
||||
message.Contains("broken pipe"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (dbType)
|
||||
{
|
||||
case DBType.MSSQL:
|
||||
if (message.Contains("deadlock victim") || message.Contains("could not obtain lock"))
|
||||
return true;
|
||||
break;
|
||||
case DBType.MySQL:
|
||||
if (message.Contains("lock wait timeout") || message.Contains("deadlock found"))
|
||||
return true;
|
||||
break;
|
||||
case DBType.PostgreSQL:
|
||||
case DBType.HGDB:
|
||||
case DBType.UX:
|
||||
if (message.Contains("could not serialize access due to concurrent update") || message.Contains("deadlock detected"))
|
||||
return true;
|
||||
break;
|
||||
case DBType.Oracle:
|
||||
case DBType.GBASE8CByOracle:
|
||||
if (message.Contains("ora-00060") || message.Contains("ora-00054"))
|
||||
return true;
|
||||
break;
|
||||
case DBType.DM:
|
||||
if (message.Contains("dm-4007") || message.Contains("dm-00642") || message.Contains("lock timeout"))
|
||||
return true;
|
||||
break;
|
||||
case DBType.KingBaseR3:
|
||||
case DBType.KingBaseR6:
|
||||
case DBType.KingBaseR8:
|
||||
if (message.Contains("could not serialize access"))
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ex.InnerException != null)
|
||||
return IsTransientError(ex.InnerException, dbType);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static int CalculateRetryDelay(int attempt, int baseRetryDelay, Random random)
|
||||
{
|
||||
int exponentialDelay = baseRetryDelay * (1 << attempt);
|
||||
int jitter = random.Next(0, exponentialDelay + 1);
|
||||
return exponentialDelay + jitter;
|
||||
}
|
||||
|
||||
private static int RunSQL_200705_Ora(string sql, Paras paras)
|
||||
{
|
||||
if (sql.EndsWith(";") == true)
|
||||
@@ -2745,11 +3072,11 @@ namespace BP.DA
|
||||
cmd.Parameters.Add(oraP);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
else
|
||||
oraP.Value = para.val;
|
||||
}
|
||||
|
||||
|
||||
|
||||
oraP.DbType = para.DAType;
|
||||
cmd.Parameters.Add(oraP);
|
||||
@@ -2972,7 +3299,8 @@ namespace BP.DA
|
||||
if (para.val == null || para.val.ToString().Equals(""))
|
||||
{
|
||||
selectSQL = selectSQL.Replace("=:" + para.ParaName, " Is Null ");
|
||||
}else
|
||||
}
|
||||
else
|
||||
{
|
||||
paras.Add(para);
|
||||
}
|
||||
@@ -3023,7 +3351,7 @@ namespace BP.DA
|
||||
{
|
||||
|
||||
SqlConnection conn = new SqlConnection(BP.Difference.SystemConfig.AppCenterDSN);
|
||||
if (conn.State != ConnectionState.Open)
|
||||
if (conn.State != System.Data.ConnectionState.Open)
|
||||
conn.Open();
|
||||
SqlDataAdapter ada = new SqlDataAdapter(sql, conn);
|
||||
ada.SelectCommand.CommandType = CommandType.Text;
|
||||
@@ -4051,7 +4379,7 @@ namespace BP.DA
|
||||
public static bool IsExits(string sql)
|
||||
{
|
||||
if (sql.ToUpper().Contains("SELECT") == false)
|
||||
return DBAccess.IsExitsObject(sql);
|
||||
return DBAccess.IsExitsObject(sql);
|
||||
|
||||
// throw new Exception("@非法的查询语句:" + sql);
|
||||
|
||||
|
||||
@@ -1322,7 +1322,7 @@ namespace BP.Difference
|
||||
/// </summary>
|
||||
public static string IsEnableUserLog()
|
||||
{
|
||||
return SystemConfig.GetValByKey("IsEnableUserLog", "0");
|
||||
return SystemConfig.GetValByKey("IsEnableLog", "0");
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1086,6 +1086,12 @@ namespace BP.En
|
||||
string val = this.GetValStrByKey(key);
|
||||
return DataType.ParseSysDate2DateTime(val);
|
||||
}
|
||||
public DateTime GetValDateTimeByKey(string key)
|
||||
{
|
||||
string val = this.GetValStrByKey(key);
|
||||
return DataType.ParseSysDate2DateTime(val);
|
||||
}
|
||||
|
||||
|
||||
public bool GetValBooleanByKey(string key, bool defval)
|
||||
{
|
||||
|
||||
@@ -808,7 +808,7 @@ namespace BP.Port
|
||||
pass2 = AESHelper.AESDecrypt(pass2, key);
|
||||
if (!isCharacterAndNumber(pass2))
|
||||
{
|
||||
return "err@新密码必须含大小写字母及数字;不得含用户名;长度限制8-20个字符";
|
||||
return "err@新密码必须含大小写字母、数字及特殊符号;不得含用户名、登录账号;长度限制8-20个字符及不能有敏感字符;不能出现连续数字(3位及以上)";
|
||||
}
|
||||
|
||||
//BCrypt加密类型
|
||||
@@ -826,19 +826,78 @@ namespace BP.Port
|
||||
return "执行成功.";
|
||||
}
|
||||
/**
|
||||
* 密码强度:0 无 1:8-20位字符,必须包含大小写字母、数字。在密码中不得包含用户名
|
||||
*/
|
||||
* 密码强度:0:无 1:8-20个字符,必须为大小写字母、数字和符号的组合,不得包含帐户名、实际姓名全拼或缩写
|
||||
* 不能出现连续数字(3位及以上)
|
||||
*/
|
||||
//public bool isCharacterAndNumber(string password)
|
||||
//{
|
||||
// String type = SystemConfig.GetPassWordComposeType();
|
||||
// //8-20位字符,必须包含大小写字母、数字。在密码中不得包含用户名
|
||||
// if (type.Equals("1"))
|
||||
// {
|
||||
// string pattern = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d).{8,20}$";
|
||||
// if (password.Contains(this.No) || !Regex.IsMatch( password,pattern))
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// return true;
|
||||
//}
|
||||
public bool isCharacterAndNumber(string password)
|
||||
{
|
||||
String type = SystemConfig.GetPassWordComposeType();
|
||||
//8-20位字符,必须包含大小写字母、数字。在密码中不得包含用户名
|
||||
string type = SystemConfig.GetPassWordComposeType();
|
||||
if (type.Equals("1"))
|
||||
{
|
||||
string pattern = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d).{8,20}$";
|
||||
if (password.Contains(this.No) || !Regex.IsMatch( password,pattern))
|
||||
string userName = this.Name;
|
||||
// 全拼
|
||||
string userNamePinYin = NPinyin.Pinyin.GetPinyin(userName);
|
||||
// 全拼首字母
|
||||
string userNamePinYinHead = NPinyin.Pinyin.GetInitials(userName);
|
||||
|
||||
// 必须是8-20位,包含大小写字母和数字
|
||||
string pattern = @"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,20}$";
|
||||
// 8-20个字符,必须为大小写字母、数字,不得包含帐户名、实际姓名全拼或缩写的判断
|
||||
if (password.Contains(userNamePinYin) ||
|
||||
password.Contains(userNamePinYinHead) ||
|
||||
password.Contains(this.No) ||
|
||||
!Regex.IsMatch(password, pattern))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 必须包含特殊符号
|
||||
bool hasSpecialChar = false;
|
||||
string specialChars = "!@#$%^&*()_+-=[]{};':\"|,.<>/?";
|
||||
foreach (char c in password)
|
||||
{
|
||||
if (specialChars.Contains(c.ToString()))
|
||||
{
|
||||
hasSpecialChar = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!hasSpecialChar)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 敏感词判断
|
||||
string sensitiveWords = SystemConfig.GetValByKey("PassWordComposeTypeSensitiveWords", "");
|
||||
if (!string.IsNullOrEmpty(sensitiveWords))
|
||||
{
|
||||
foreach (string str in sensitiveWords.Split(','))
|
||||
{
|
||||
if (password.Contains(str))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 不能出现连续数字(3位及以上)
|
||||
Regex continuousNumbers = new Regex(@"\d{3,}");
|
||||
bool isContinuousNumbers = !continuousNumbers.IsMatch(password);
|
||||
return isContinuousNumbers;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -229,9 +229,14 @@ namespace BP.Sys
|
||||
|
||||
protected override bool beforeInsert()
|
||||
{
|
||||
/**
|
||||
* 日志的标志
|
||||
* 登录 退出 访问 删除
|
||||
*/
|
||||
|
||||
//是否开启日志记录
|
||||
string IsEnableUserLog = SystemConfig.IsEnableUserLog();
|
||||
if (IsEnableUserLog.Equals("0") && !this.LogFlag.Equals("登录") && !this.LogFlag.Equals("退出") && !this.LogFlag.Contains("删除"))
|
||||
if (IsEnableUserLog.Equals("0"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -244,57 +249,53 @@ namespace BP.Sys
|
||||
this.IP=BP.Difference.Glo.GetIP;
|
||||
}
|
||||
|
||||
if ( this.LogFlag.Equals("登录") || this.LogFlag.Equals("退出") || this.LogFlag.Equals("访问") || this.LogFlag.Contains("删除"))
|
||||
|
||||
if (DataType.IsNullOrEmpty(BP.Web.WebUser.No) == true)
|
||||
{
|
||||
if (DataType.IsNullOrEmpty(BP.Web.WebUser.No) == true)
|
||||
this.EmpNo = "访客";
|
||||
this.EmpName = "访客";
|
||||
this.LogFlag = "访问";
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Docs=WebUser.Token;
|
||||
}
|
||||
//退出时
|
||||
// 1.宽泛模式,根据toke 删除 port_token 对应数据
|
||||
//2.严谨模式时,根据no 修改 wf_emp 表的Atpara 字段 online=0
|
||||
if (this.LogFlag.Equals("退出"))
|
||||
{
|
||||
//严谨模式,saas模式只有宽泛模式
|
||||
if (SystemConfig.TokenModel == 1 && SystemConfig.CCBPMRunModel != CCBPMRunModel.SAAS)
|
||||
{
|
||||
this.EmpNo = "访客";
|
||||
this.EmpName = "访客";
|
||||
this.LogFlag = "访问";
|
||||
string sql="select Atpara from wf_emp where No='"+ WebUser.No + "'";
|
||||
string rdata= DBAccess.RunSQLReturnString(sql);
|
||||
rdata = rdata.Replace("Online=1", "Online=0");
|
||||
sql = "update wf_emp set Atpara='"+ rdata + "' where No='" + WebUser.No + "'";
|
||||
DBAccess.RunSQL(sql);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Docs=WebUser.Token;
|
||||
}
|
||||
//退出时
|
||||
// 1.宽泛模式,根据toke 删除 port_token 对应数据
|
||||
//2.严谨模式时,根据no 修改 wf_emp 表的Atpara 字段 online=0
|
||||
if (this.LogFlag.Equals("退出"))
|
||||
{
|
||||
//严谨模式,saas模式只有宽泛模式
|
||||
if (SystemConfig.TokenModel == 1 && SystemConfig.CCBPMRunModel != CCBPMRunModel.SAAS)
|
||||
{
|
||||
string sql="select Atpara from wf_emp where No='"+ WebUser.No + "'";
|
||||
string rdata= DBAccess.RunSQLReturnString(sql);
|
||||
rdata = rdata.Replace("Online=1", "Online=0");
|
||||
sql = "update wf_emp set Atpara='"+ rdata + "' where No='" + WebUser.No + "'";
|
||||
DBAccess.RunSQL(sql);
|
||||
}
|
||||
else
|
||||
{
|
||||
String sql = "delete from port_token where mypk='" + WebUser.Token + "'";
|
||||
DBAccess.RunSQL(sql);
|
||||
}
|
||||
}
|
||||
else
|
||||
{ //访客,登录 记录ip详情
|
||||
try
|
||||
{
|
||||
string jsonString = SystemUtil.GetCityByIp();
|
||||
// 将 JSON 字符串转换为对象
|
||||
dynamic json = JsonConvert.DeserializeObject(jsonString);
|
||||
this.IP = json.ip;
|
||||
this.Locatinon = json.pro + " " + json.city;
|
||||
this.Brower = SystemUtil.GetBrowser();
|
||||
this.OS = SystemUtil.GetOperatingSystem();
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
|
||||
}
|
||||
String sql = "delete from port_token where mypk='" + WebUser.Token + "'";
|
||||
DBAccess.RunSQL(sql);
|
||||
}
|
||||
}
|
||||
|
||||
//访客,登录 记录ip详情
|
||||
try
|
||||
{
|
||||
string jsonString = SystemUtil.GetCityByIp();
|
||||
// 将 JSON 字符串转换为对象
|
||||
dynamic json = JsonConvert.DeserializeObject(jsonString);
|
||||
this.IP = json.ip;
|
||||
this.Locatinon = json.pro + " " + json.city;
|
||||
this.Brower = SystemUtil.GetBrowser();
|
||||
this.OS = SystemUtil.GetOperatingSystem();
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
|
||||
}
|
||||
return base.beforeInsert();
|
||||
}
|
||||
|
||||
|
||||
@@ -3856,7 +3856,7 @@ namespace BP.WF
|
||||
return DB_GenerWillReturnNodes_DealDT(dt, gwf.FlowNo);
|
||||
}
|
||||
|
||||
WorkNode mywnP = wn.GetPreviousWorkNode();
|
||||
WorkNode mywnP = wn.GetPreviousWorkNode("WorkReturn");
|
||||
|
||||
|
||||
if (nd.TodolistModel == TodolistModel.Order)
|
||||
@@ -5049,10 +5049,26 @@ namespace BP.WF
|
||||
Token tk = new Token();
|
||||
isExist = tk.IsExit("EmpNo", no);
|
||||
}
|
||||
if (!isExist)
|
||||
//判断是否初始密码
|
||||
Object type = SystemConfig.GetIsPasswordEncryptionType();
|
||||
//初始密码
|
||||
string yspass = "123";
|
||||
string pass = DBAccess.RunSQLReturnString("select Pass from port_emp WHERE No='" + no + "'");
|
||||
//BCrypt加密类型
|
||||
if (type.ToString().Equals("2"))
|
||||
{
|
||||
yspass = BP.Tools.Cryptography.HashPassword(yspass);
|
||||
}
|
||||
//MD5加密类型
|
||||
if (type.ToString().Equals("1"))
|
||||
{
|
||||
yspass = BP.Tools.Cryptography.MD5_Encrypt(yspass);
|
||||
}
|
||||
if (!isExist || pass.Equals(yspass))
|
||||
{
|
||||
WebUser.IsFirstLogin = true;
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* 判断是否需要强制改密码
|
||||
|
||||
@@ -7912,13 +7912,13 @@ namespace BP.WF.HttpHandler
|
||||
|
||||
#region 前台SQL转移处理
|
||||
|
||||
public string RunSQL_Init()
|
||||
{
|
||||
string sql = GetRequestVal("SQL");
|
||||
DBAccess.RunSQLReturnTable(sql);
|
||||
DataTable dt = new DataTable();
|
||||
return BP.Tools.Json.ToJson(dt);
|
||||
}
|
||||
//public string RunSQL_Init()
|
||||
//{
|
||||
// string sql = GetRequestVal("SQL");
|
||||
// DBAccess.RunSQLReturnTable(sql);
|
||||
// DataTable dt = new DataTable();
|
||||
// return BP.Tools.Json.ToJson(dt);
|
||||
//}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
@@ -5491,26 +5491,26 @@ namespace BP.WF.HttpHandler
|
||||
#endregion 常用词汇结束
|
||||
|
||||
#region 前台SQL转移处理
|
||||
public string RunSQL_Init()
|
||||
{
|
||||
string sql = GetRequestVal("SQL");
|
||||
string dbSrc = this.GetRequestVal("DBSrc");
|
||||
DataTable dt = null;
|
||||
if (DataType.IsNullOrEmpty(dbSrc) == false && dbSrc.Equals("local") == false)
|
||||
{
|
||||
SFDBSrc sfdb = new SFDBSrc(dbSrc);
|
||||
dt = sfdb.RunSQLReturnTable(sql);
|
||||
}
|
||||
else
|
||||
{
|
||||
dt = DBAccess.RunSQLReturnTable(sql);
|
||||
}
|
||||
if (sql.ToUpper().Contains("PORT_EMP") == true && (dt.Columns.Contains("Pass") || dt.Columns.Contains("PASS") || dt.Columns.Contains("pass") || dt.Columns.Contains("PWS")))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return BP.Tools.Json.ToJson(dt);
|
||||
}
|
||||
//public string RunSQL_Init()
|
||||
//{
|
||||
// string sql = GetRequestVal("SQL");
|
||||
// string dbSrc = this.GetRequestVal("DBSrc");
|
||||
// DataTable dt = null;
|
||||
// if (DataType.IsNullOrEmpty(dbSrc) == false && dbSrc.Equals("local") == false)
|
||||
// {
|
||||
// SFDBSrc sfdb = new SFDBSrc(dbSrc);
|
||||
// dt = sfdb.RunSQLReturnTable(sql);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// dt = DBAccess.RunSQLReturnTable(sql);
|
||||
// }
|
||||
// if (sql.ToUpper().Contains("PORT_EMP") == true && (dt.Columns.Contains("Pass") || dt.Columns.Contains("PASS") || dt.Columns.Contains("pass") || dt.Columns.Contains("PWS")))
|
||||
// {
|
||||
// return "";
|
||||
// }
|
||||
// return BP.Tools.Json.ToJson(dt);
|
||||
//}
|
||||
#endregion
|
||||
|
||||
// 您的应用ID
|
||||
|
||||
@@ -2303,7 +2303,7 @@ namespace BP.WF.HttpHandler
|
||||
if (i == 0)
|
||||
return "该流程的工作已删除,请联系管理员.WorkID=" + this.WorkID;
|
||||
if (gwf.IsOver == true)
|
||||
return "该流程工作已经结束,不需要重复发送";
|
||||
return "该流程工作已经结束";
|
||||
|
||||
Int64 workid = this.WorkID;
|
||||
//如果包含subWorkID
|
||||
|
||||
@@ -1148,21 +1148,21 @@ namespace BP.WF.HttpHandler
|
||||
int currNodeID = gwf.NodeID;
|
||||
//获取未来处理人的节点
|
||||
Node nd = new Node(currNodeID);
|
||||
GERpt rptGe = nd.HisFlow.HisGERpt;
|
||||
rptGe.OID = this.WorkID;
|
||||
rptGe.RetrieveFromDBSources();
|
||||
if (nd.ItIsStartNode)
|
||||
{
|
||||
Work wk = nd.HisWork;
|
||||
wk.OID=this.WorkID;
|
||||
wk.Retrieve();
|
||||
WorkNode wn = new WorkNode(wk, nd);
|
||||
wn.rptGe = nd.HisFlow.HisGERpt;
|
||||
wn.rptGe.OID=this.WorkID;
|
||||
wn.rptGe = rptGe;
|
||||
//执行计算未来处理人.
|
||||
FullSA fsa = new FullSA();
|
||||
fsa.DoIt2023(wn);
|
||||
}
|
||||
GERpt rptGe = nd.HisFlow.HisGERpt;
|
||||
rptGe.OID = this.WorkID;
|
||||
rptGe.RetrieveFromDBSources();
|
||||
|
||||
Node hisNode = nd;
|
||||
//获取当前节点的抄送节点
|
||||
nodeIDs += GetFutureCCNodes(nd, rptGe, nodeIDs);
|
||||
|
||||
@@ -10229,7 +10229,7 @@ namespace BP.WF
|
||||
/// 如果没有找到转向他的节点,就返回,当前的工作.
|
||||
/// </summary>
|
||||
/// <returns>得当他的上一步工作</returns>
|
||||
public WorkNode GetPreviousWorkNode()
|
||||
public WorkNode GetPreviousWorkNode(string workSource= "WorkUnSend")
|
||||
{
|
||||
// 如果没有找到转向他的节点,就返回,当前的工作.
|
||||
if (this.HisNode.ItIsStartNode)
|
||||
@@ -10247,16 +10247,16 @@ namespace BP.WF
|
||||
|
||||
//首先获取实际发送节点,不存在时再使用from节点.
|
||||
DataTable dt = DBAccess.RunSQLReturnTable(sql);
|
||||
if (dt != null && dt.Rows.Count > 0)
|
||||
foreach(DataRow dr in dt.Rows)
|
||||
{
|
||||
nodeid = int.Parse(dt.Rows[0]["NDFrom"].ToString());
|
||||
if (dt.Rows[0]["Tag"] != null && dt.Rows[0]["Tag"].ToString().Contains("SendNode=") == true)
|
||||
nodeid = int.Parse(dr["NDFrom"].ToString());
|
||||
string tag = dr["Tag"] != null ? dr["Tag"].ToString() : "";
|
||||
if (DataType.IsNullOrEmpty(tag) == false && tag.Contains("SendNode=") == true)
|
||||
{
|
||||
string tag = dt.Rows[0]["Tag"].ToString();
|
||||
string[] strs = tag.Split('@');
|
||||
foreach (string str in strs)
|
||||
{
|
||||
if (str == null || str.Equals("") || str.Contains("SendNode=") == false)
|
||||
if (DataType.IsNullOrEmpty(str) || str.Contains("SendNode=") == false)
|
||||
continue;
|
||||
string[] mystr = str.Split('=');
|
||||
if (mystr.Length == 2)
|
||||
@@ -10265,9 +10265,15 @@ namespace BP.WF
|
||||
if (string.IsNullOrEmpty(sendNode) == false && sendNode.Equals("0") == false)
|
||||
{
|
||||
nodeid = int.Parse(sendNode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (workSource.Equals("WorkUnSend"))
|
||||
break;
|
||||
if (nodeid != this.HisNode.NodeID)
|
||||
break;
|
||||
nodeid = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user