///-----------------------------------------------------------------------
///
/// 程式代號: DBService
/// 程式名稱: DBService
/// 程式說明:
/// 起始作者: Nelson
/// 起始日期: 2016/09/03 17:03:37
/// 最新修改人: Hercules
/// 最新修日期: 2017/05/15 12:24:49
///
///-----------------------------------------------------------------------
namespace CounsellorBL
{
using CounsellorBL.BLStructure;
using CounsellorBL.Helper;
using CounsellorBL.Common;
using Microsoft.Extensions.Caching.Memory;
using MonumentDefine;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using OT.COM.ArsenalDB;
using OT.COM.LogisticsUtil;
using OT.COM.SignalerMessage;
using SoldierData.EnterprizeV4;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using static CounsellorBL.Common.EntityBaseExtension;
using static OT.COM.ArsenalDB.EntityBase;
using Microsoft.Extensions.Caching.Distributed;
///
/// 類別名稱:DBService
/// 類別說明:
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
public abstract partial class DBService : ServiceBase
{
public delegate string DG_GenerateEditCommand(CRequestMessage i_crmInput, JArray i_jaData, tb_sys_session i_sSessionUser, out List o_lcCmds, List i_saQryContainKeys,
[System.Runtime.CompilerServices.CallerLineNumber] int i_nCodeLine = 0,
[System.Runtime.CompilerServices.CallerMemberName] string i_sMemberName = "",
[System.Runtime.CompilerServices.CallerFilePath] string i_sSourcePath = "");
public delegate string DG_GenerateReadCommand(CRequestMessage i_crmInput, JArray i_jaData, tb_sys_session i_sSessionUser, out Command o_cCmd,
[System.Runtime.CompilerServices.CallerLineNumber] int i_nCodeLine = 0,
[System.Runtime.CompilerServices.CallerMemberName] string i_sMemberName = "",
[System.Runtime.CompilerServices.CallerFilePath] string i_sSourcePath = "");
public delegate string DG_ExportFile(CRequestMessage i_crmInput, JArray i_jaData, tb_sys_session i_sSessionUser, out string o_sFilePath, List i_saQryContainKeys,
[System.Runtime.CompilerServices.CallerLineNumber] int i_nCodeLine = 0,
[System.Runtime.CompilerServices.CallerMemberName] string i_sMemberName = "",
[System.Runtime.CompilerServices.CallerFilePath] string i_sSourcePath = "");
protected delegate string DG_EditPostCommand(ArsenalInterface ai, EntityBase i_oOldInst, EntityBase i_oNewInst, out List o_lcAddition,
[System.Runtime.CompilerServices.CallerLineNumber] int i_nCodeLine = 0,
[System.Runtime.CompilerServices.CallerMemberName] string i_sMemberName = "",
[System.Runtime.CompilerServices.CallerFilePath] string i_sSourcePath = "");
protected delegate string DG_ModifyCreateInstance(CRequestMessage i_crm, ref object io_oInst);
protected List ldgUpdate_PostCommand { get; } = new List();
protected List ldgModifyCreateInstance { get; } = new List();
///
///
///
///
///
///
///
/// In most case, return QueryResponse
///
public delegate string DG_PostHandleReadData(CRequestMessage i_crmInput, ArsenalInterface i_aiArsenal, Command i_cCmd, JArray i_jaData, tb_sys_session i_sSessionUser, out object o_oReault,
[System.Runtime.CompilerServices.CallerLineNumber] int i_nCodeLine = 0,
[System.Runtime.CompilerServices.CallerMemberName] string i_sMemberName = "",
[System.Runtime.CompilerServices.CallerFilePath] string i_sSourcePath = "");
public delegate string DG_GenCacheKey(CRequestMessage i_crmInput, out List o_lsKeys,
[System.Runtime.CompilerServices.CallerLineNumber] int i_nCodeLine = 0,
[System.Runtime.CompilerServices.CallerMemberName] string i_sMemberName = "",
[System.Runtime.CompilerServices.CallerFilePath] string i_sSourcePath = "");
public abstract string MainTable
{
get;
}
///
/// 定義連線檢查提醒信間隔時間
///
public const int CONNECTIONBOUNDARY_NOTIFY_PERIOD = 10; // 10 Minutes
///
/// 類別成員、類別屬性說明:cdbm
///
protected Dictionary dicDBMeta { get; private set; }
protected DG_ExportFile dgGetExportPath { get; set; }
protected DG_GenerateEditCommand dgImportCommandGenerator { get; set; }
protected DG_GenCacheKey dgGenCacheKey { get; set; }
public List EditMustConditionKeys { get; protected set; } = new List() { BLWording.UID };
///
/// 類別名稱:checkDBLock
/// 類別說明:DB Lock檢核用資料結構
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
protected class checkDBLock
{
///
/// 類別成員、類別屬性說明:預期檢核的ROWID
///
public string RowID
{
get; set;
}
///
/// 類別成員、類別屬性說明:預期檢核的更新時間
///
public DateTime? UpdateTime
{
get; set;
}
}
private string _MainTableName = null;
///
/// 類別成員、類別屬性說明:DBService
///
protected DBService()
: base()
{
//
if (Command.SingleConnection != null)
{
Command.SetupSingleConnection(CustomizeDBMgr.SingleConnection);
}
}
protected static Type _GetEntityType(string i_sEntityName)
{
return ClassHelper.GetTypeByFullNameEndWithTerm(i_sEntityName);
}
///
/// Gets the name of the main table for db lock
///
/// Type
/// Formated name
public string GetMainTableName(Type i_tType)
{
if (_MainTableName == null && i_tType != null)
{
string sRes = $"{i_tType.FullName}";
_MainTableName = sRes.Substring(sRes.IndexOf('.', StringComparison.OrdinalIgnoreCase) + 1);
}
return _MainTableName;
}
///
/// 函式名稱:GetMasterDBTableInfo
/// 函式說明:產生資料表Meta Data含連線資訊
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
/// 資料表類別
/// 資料表Meta Data
///
public TableInfo GetMasterDBTableInfo(Type i_t)
{
return new TableInfo()
{
TargetTable = i_t,
DBMeta = dicDBMeta
};
}
///
/// 函式名稱:getEntity
/// 函式說明:
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
///
///
/// 參數說明
///
///
/// 回傳
///
protected static string getEntity(string i_sEntityName, out object o_ebEntity)
{
return ClassHelper.GetInstByFullNameEndWithTerm(i_sEntityName, out o_ebEntity); //錯誤時回傳No Type 或Create Type Fail錯誤
}
public tb_sys_session SetupGuestSession(CRequestMessage i_crmInput)
{
string GUESTTOKEN = "guest";
tb_sys_session sRes = null;
do
{
if (i_crmInput == null)
{
break;
}
if (this.OriRequest == null)
{
this.OriRequest = i_crmInput;
}
if (i_crmInput.customparam == null)
{
i_crmInput.customparam = new Dictionary();
}
this.OriRequest.token = string.IsNullOrEmpty(i_crmInput.token) ? GUESTTOKEN : i_crmInput.token;
IMemoryCache imc = GetMemoryCache();
if (imc == null)
{
throw new NullReferenceException(MethodBase.GetCurrentMethod() + "." + nameof(imc) + "is NULL");
}
lock (imc)
{
if (!imc.TryGetValue(BLWording.TOKENMAP, out ConcurrentDictionary dicMap))
{
dicMap = new ConcurrentDictionary();
imc.Set(BLWording.TOKENMAP, dicMap);
}
string sToken = GUESTTOKEN;
if (!dicMap.ContainsKey(sToken))
{
tb_sys_session sFake = _getQuestSession("Admin");
sFake.uid = GUESTTOKEN;
dicMap.TryAdd(sToken, sFake);
}
else
{
dicMap[sToken].update_date = DateTime.Now;
}
i_crmInput.customparam[BLWording.SESSION_USER] = dicMap[sToken];
}
sRes = i_crmInput.customparam[BLWording.SESSION_USER] as tb_sys_session;
} while (false);
return sRes;
}
protected string getSessionByToken(string i_sToken, out tb_sys_session o_sSession)
{
string sMsg = null;
tb_sys_session sCur = null;
do
{
IMemoryCache imc = GetMemoryCache();
if (imc != null)
{
lock (imc)
{
string sTempMsg = null;
if (!imc.TryGetValue(BLWording.TOKENMAP, out ConcurrentDictionary dicMap))
{
dicMap = new ConcurrentDictionary();
imc.Set(BLWording.TOKENMAP, dicMap);
}
else
{
if (dicMap.ContainsKey(i_sToken))
{
tb_sys_session sessionTemp = dicMap[i_sToken];
if (sessionTemp.update_date.AddMinutes(1) > DateTime.Now)
{
sCur = sessionTemp.Clone() as tb_sys_session;
sTempMsg = "pass";
}
else
{
if (i_sToken == "guest")
{
Logger.Info("session timeout");
sCur = sessionTemp.Clone() as tb_sys_session;
sTempMsg = "pass";
}
dicMap.TryRemove(i_sToken, out _);
}
}
}
if (i_sToken == "guest")
{
Logger.Info("token guest sTempMsg = " + sTempMsg + " dicMap = " + dicMap);
}
if (sTempMsg != "pass")
{
int nExpMinute = Convert.ToInt32(CustomizeDBMgr.SettingData[BLWording.TOKEN_EXP_MINUTE], CultureInfo.CurrentCulture);
tb_sys_session sDisplay = new tb_sys_session();
sDisplay.SetFullDirty();
tb_sys_session sCond = new tb_sys_session() { uid = i_sToken };
Command cSelectSeesion = Command.SetupSelectCmd(sDisplay, sCond);
cSelectSeesion.ReadLevel = Command.EReadLevel.ERL_DIRTY;
ArsenalInterface ai = ArsenalDBMgr.GetInst(cSelectSeesion, null);
sCur = ai.RunQuerySingleORM(cSelectSeesion);
if (null == sCur)
{
sMsg = MessageWording.SESSION_NOT_EXIST; //SESSION_NO_SESSION
if (i_sToken == "guest")
{
sMsg = "Messaging Error";
}
break;
}
if (nExpMinute < DateTime.Now.Subtract(sCur.update_date).TotalMinutes)
{
sMsg = MessageWording.SESSION_EXPIRED; //SESSION_EXPIRED SESSION過期
break;
}
dicMap.TryAdd(sCur.uid, sCur);
}
}
}
}
while (false);
o_sSession = sCur;
return sMsg;
}
///
/// 函式名稱:_checkTokenValid
/// 函式說明:Session Validation
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
///
///
///
///
protected CResponseMessage checkTokenValid(string i_sToken, bool i_bRenewExpireTime = false)
{
DateTime dtNow = DateTime.Now;
CResponseMessage crm = null;
string sMsg;
do
{
sMsg = getSessionByToken(i_sToken, out tb_sys_session sCur);
if (sMsg != null)
{
break;
}
if (i_bRenewExpireTime)
{
/*tb_sys_session sModifyData = new tb_sys_session() { update_date = dtNow };
sCur.update_date = dtNow;
WhereNode wnUpdate = new WhereNode(tb_sys_session.CN_UID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_sys_session), i_sToken);
Command cUpdate = Command.SetupUpdateCmd(sModifyData, wnUpdate);
ArsenalInterface ai = ArsenalDBMgr.GetInst(cUpdate, GetDefaultSystemColumnInfo());
ai.RunEditSingleCmd(cUpdate);*/
IMemoryCache imc = GetMemoryCache();
if (imc != null)
{
lock (imc)
{
if (!imc.TryGetValue(BLWording.TOKENMAP, out ConcurrentDictionary dicMap))
{
dicMap = new ConcurrentDictionary();
imc.Set(BLWording.TOKENMAP, dicMap);
}
if (dicMap.ContainsKey(sCur.uid))
{
dicMap[sCur.uid] = sCur;
}
else
{
dicMap.TryAdd(sCur.uid, sCur);
}
}
}
}
crm = new CResponseMessage() { result = EResponseResult.RR_TRUE };
crm.param.Add(BLWording.SESSION_USER, sCur);
}
while (false);
if (null != sMsg)
{
crm = new CErrorResponseMessage(sMsg);
}
return crm;
}
///
/// 函式名稱:checkTokenWithCRequestMessage
/// 函式說明:
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
///
///
///
///
public CResponseMessage CheckTokenWithCRequestMessage(CRequestMessage i_crm, out Dictionary o_oDicData)
{
CResponseMessage crm = null;
string sMsg = null;
Dictionary dicFormData = new Dictionary();
do
{
if (i_crm == null)
{
sMsg = MessageWording.PARAM_NOT_EXPECTED;
break;
}
foreach (string sKey in i_crm.param.Keys)
{
dicFormData.Add(sKey, i_crm.param[sKey]);
}
if (i_crm.token == null)
{
sMsg = MessageWording.TOKEN_MISS; //NO TOKEN
break;
}
crm = this.checkTokenValid(i_crm.token, true);
}
while (false);
if (null != sMsg)
{
crm = new CErrorResponseMessage(sMsg, i_crm);
}
o_oDicData = dicFormData;
return crm;
}
///
/// 函式名稱:MakeSelectJoinByBlocks
/// 函式說明:產生
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
///
///
///
/// 回傳
///
public static string MakeSelectJoinByBlocks(QueryJsonElementCollection i_qjelBlocks, out Command o_cSelect)
{
Command cTemp = null;
string sMsg;
do
{
List i_lBlocks = i_qjelBlocks;
if (i_lBlocks == null || i_lBlocks.Count == 0)
{
sMsg = MessageWording.BLOCK_MISS; //NO BLOCK
break;
}
convertWherenode(ref i_lBlocks);
QueryJson qj = new QueryJson();
sMsg = qj.AddBlock(i_lBlocks.ToArray());
if (sMsg != null)
{
break;
}
sMsg = qj.MakeCommand(
new TableInfo()
{
TargetTable = _GetEntityType(i_lBlocks[0].table)
}, out cTemp);
if (sMsg != null)
{
break;
}
// For Select Insert porting
if (i_lBlocks[0].SelectInsertTable != null)
{
cTemp.ChangeCmdType(Command.EC_Type.ECT_SELECTINSERT);
}
cTemp.ReadLevel = Command.EReadLevel.ERL_DIRTY;
}
while (false);
o_cSelect = cTemp;
return sMsg;
}
///
/// 函式名稱:convertWherenode
/// 函式說明:
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
///
/// 參數說明
///
///
/// 回傳
///
protected static void convertWherenode(ref List io_data)
{
if (io_data != null)
{
for (int i = 0; i < io_data.Count; i++)
{
QueryJsonElement qjs = io_data[i];
Type t = _GetEntityType(qjs.table);
qjs.databaseinfo = t.FullName.Split('.')[1];
WhereNode wnDicwherecolsCompile = Command.whereDictionary2WhereNode(t, qjs.dicwherecols);
if (qjs.wherecols == null)
{
qjs.wherecols = wnDicwherecolsCompile;
}
else
{
if (wnDicwherecolsCompile != null)
{
qjs.wherecols = new WhereNode(WhereNode.ENodeOperation.ENO_AND, qjs.wherecols, wnDicwherecolsCompile);
}
}
}
}
}
///
/// 函式名稱:CreateExcel
/// 函式說明:
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
///
///
///
///
///
///
public static bool CreateExcel(DataTable i_dtData, CRequestMessage i_crm, out string o_sFilePath, bool i_blAutoSizeColumn = true)
{
bool bStatus = false;
int iCurentRow = 0;
string sFilePath = null;
string sFileName = null;
do
{
if (i_dtData == null)
{
break;
}
int iMaxCol = i_dtData.Columns.Count;
HSSFWorkbook workbook = new HSSFWorkbook();//初始化匯出Excel物件
ISheet sheet = workbook.CreateSheet("sheet1");//設定sheet1的顯示名稱
ICellStyle style = workbook.CreateCellStyle();//創建單元格的樣式
style.BorderBottom = BorderStyle.Thin;
style.BorderLeft = BorderStyle.Thin;
style.BorderRight = BorderStyle.Thin;
style.BorderTop = BorderStyle.Thin;
IRow dataRow = sheet.CreateRow(0);
//獲取前段設定的表頭
Dictionary items = null;
if (i_crm != null && i_crm.param.ContainsKey(BLWording.ITEMS))
{
JObject joItems = i_crm.param[BLWording.ITEMS] as JObject;
items = joItems.ToObject>();
}
//填充表头
if (items != null)
{
List lstRemoveCol = new List();
foreach (DataColumn col in i_dtData.Columns)
{
if (items.Keys.Contains(col.ColumnName))
{
ICell cell = dataRow.CreateCell(i_dtData.Columns.IndexOf(col) - lstRemoveCol.Count);//減去移除的欄位個數
col.ColumnName = items[col.ColumnName];
cell.CellStyle = style;
cell.SetCellValue(col.ColumnName);
}
else
{
lstRemoveCol.Add(col);
iMaxCol--;
}
}
foreach (DataColumn col in lstRemoveCol)
{
i_dtData.Columns.Remove(col);
}
iCurentRow++;
}
else //填充欄位名稱
{
dataRow = sheet.CreateRow(iCurentRow);
iCurentRow++;
foreach (DataColumn dc in i_dtData.Columns)
{
ICell cell = dataRow.CreateCell(i_dtData.Columns.IndexOf(dc));
cell.CellStyle = style;
cell.SetCellValue(dc.ColumnName);
}
}
//填充內容
foreach (DataRow dr in i_dtData.Rows)
{
dataRow = sheet.CreateRow(iCurentRow);
iCurentRow++;
foreach (DataColumn dc in i_dtData.Columns)
{
ICell cell = dataRow.CreateCell(i_dtData.Columns.IndexOf(dc));
cell.CellStyle = style;
cell.SetCellValue(dr[dc].ToString() ?? "");
}
}
//自適應
if (i_blAutoSizeColumn)
{
for (int col = 0; col <= iMaxCol; col++)
{
sheet.AutoSizeColumn(col, true);
}
}
sFilePath = SystemSettingHelper.FileFolder(SystemSettingHelper.EPath.EP_FILETMP);
sFileName = _fetchString(i_crm, "filename");
sFileName = (sFileName ?? "") + DateTime.Now.ToString("yyyyMMddHHmmss", CultureInfo.CurrentCulture) + ".xls";
string sSeverPath = System.IO.Path.Combine(ServiceBase.RootPath, sFilePath);
string sFileFullName = System.IO.Path.Combine(sSeverPath, sFileName);
if (!Directory.Exists(sSeverPath))
{
Directory.CreateDirectory(sSeverPath);
}
//保存
using FileStream fs = new FileStream(sFileFullName, FileMode.Create, FileAccess.Write);
workbook.Write(fs);
bStatus = true;
}
while (false);
o_sFilePath = System.IO.Path.Combine(sFilePath, sFileName);
return bStatus;
}
///
/// 函式名稱:CreateExcelFiles
/// 函式說明:
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
///
///
///
///
///
///
///
///
///
public static bool CreateExcelFiles(List> i_dicData, CRequestMessage i_crm, out string o_sFilePath)
{
string sFilePath = null;
string sFileName = null;
bool bStatus = false;
int imaxcell = 0;
do
{
if (i_dicData == null)
{
break;
}
Dictionary items = null;
HSSFWorkbook workbook = new HSSFWorkbook();
ISheet sheet = workbook.CreateSheet("sheet1");
ICellStyle style = workbook.CreateCellStyle();
style.BorderBottom = BorderStyle.Thin;
style.BorderLeft = BorderStyle.Thin;
style.BorderRight = BorderStyle.Thin;
style.BorderTop = BorderStyle.Thin;
IRow dataRow = sheet.CreateRow(0);
if (i_crm == null)
{
break;
}
if (i_crm.param.ContainsKey(BLWording.ITEMS))
{
JObject joItems = i_crm.param[BLWording.ITEMS] as JObject;
items = joItems.ToObject>();
}
// Workarond: Forward capbility for DBService.ExcelEntity
if (items == null && i_crm.param.ContainsKey(BLWording.DATA))
{
if (!(i_crm.param[BLWording.DATA] is JObject dic))
{
break;
}
if (!(dic[BLWording.ITEMS] is JObject joItems))
{
break;
}
items = joItems.ToObject>();
}
//填充表头
if (items != null)
{
int index = 0;
foreach (string sKey in items.Keys)
{
object sValue = items[sKey];
string s = sValue.ToString() ?? "";
if (!string.IsNullOrEmpty(s))
{
ICell cell = dataRow.CreateCell(index);
cell.CellStyle = style;
cell.SetCellValue(s);
index++;
}
}
}
//填充内容
string sJsonKey = _fetchString(i_crm, "sjsonkey");
string scartonkey = _fetchString(i_crm, "scartonkey");
sJsonKey ??= "";
scartonkey ??= "";
int cellIndex = 0;
foreach (Dictionary _list in i_dicData)
{
if (_list != null && items != null)
{
dataRow = sheet.CreateRow(dataRow.RowNum + 1);
imaxcell = cellIndex > imaxcell ? cellIndex : imaxcell;
cellIndex = 0;
foreach (string sKey in items.Keys)
{
if (_list.Keys.Contains(sKey))
{
object sValue = _list[sKey];
string s = sValue.ToString() ?? "";
if (sKey != sJsonKey)
{
ICell cell = dataRow.CreateCell(cellIndex);
cell.CellStyle = style;
if (sKey == scartonkey)
{
cell.SetCellValue((s == "0" ? "" : s));
}
else
{
cell.SetCellValue(s);
}
cellIndex++;
}
else
{
JObject jsonObj = (JObject)JsonConvert.DeserializeObject(s);
Dictionary jsonData = jsonObj.ToObject>();
foreach (string _sKey in jsonData.Keys)
{
if (_sKey.ToLower(CultureInfo.CurrentCulture).IndexOf("_scan_sval", StringComparison.OrdinalIgnoreCase) > -1)
{//整合性報表特殊處理(公用部分走上邊部分)
object sJson = jsonData[_sKey];
string sVal = sJson.ToString() ?? "";
ICell cell = dataRow.CreateCell(cellIndex);
cell.CellStyle = style;
cell.SetCellValue(sVal);
cellIndex++;
}
}
}
}
}
}
}
//自適應
for (int cellindex = 0; cellindex <= imaxcell; cellindex++)
{
sheet.AutoSizeColumn(cellindex, true);
}
sFilePath = Path.Combine("Uploads", "ExpExcel");
sFileName = _fetchString(i_crm, "filename");
sFileName = (sFileName ?? "") + DateTime.Now.ToString("yyyyMMddHHmmss", CultureInfo.CurrentCulture) + ".xls";
string sSeverPath = System.IO.Path.Combine(ServiceBase.RootPath, sFilePath);
string sFileFullName = Path.Combine(sSeverPath, sFileName);
if (!Directory.Exists(sSeverPath))
{
Directory.CreateDirectory(sSeverPath);
}
//保存
using FileStream fs = new FileStream(sFileFullName, FileMode.Create, FileAccess.Write);
workbook.Write(fs);
bStatus = true;
}
while (false);
o_sFilePath = sFilePath + sFileName;
return bStatus;
}
///
/// 函式名稱:getToExcelData
/// 函式說明:整合性報表案例1json字串處理
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
///
/// With given table name
///
///
/// 回傳
///
public static Dictionary getToExcelData(JArray i_jaData)
{
Dictionary dicData = i_jaData?.ToObject>();
if (dicData != null && dicData.Any())
{
List> lsDic = i_jaData.ToObject>>();
foreach (Dictionary dic in lsDic)
{
foreach (string sKey in dic.Keys)
{
if (sKey.ToLower(CultureInfo.CurrentCulture).IndexOf("_scan_sval", StringComparison.OrdinalIgnoreCase) > -1)
{
if (dicData[sKey] != null)
{
dicData[sKey] += ";" + dic[sKey];
}
else
{
dicData.Add(sKey, dic[sKey]);
}
}
}
}
}
return dicData;
}
public static ErrorPack GetLastErrorPack(Command i_c)
{
return i_c == null || i_c.IsSuccess ? new ErrorPack() : new ErrorPack(i_c.LastErrorCode, i_c.LastErrorMsg);
}
public static ErrorPack GetLastErrorPack(List i_lcCmds)
{
Command cFind = i_lcCmds.FirstOrDefault(c => !c.IsSuccess);
return cFind == null ? new ErrorPack() : new ErrorPack(cFind.LastErrorCode, cFind.LastErrorMsg);
}
public static CErrorResponseMessage GetErrorResponseMessage(ErrorPack i_ep)
{
CErrorResponseMessage crm = null;
if (i_ep != null && !i_ep.IsSucces)
{
crm = new CErrorResponseMessage(i_ep.ErrorCode, null);
crm.param[BLWording.ERROR_DESCRIPTION] = i_ep.ErrorMsg;
}
return crm;
}
///
/// 函式名稱:GetLastErrorCode
/// 函式說明:取得DB錯誤碼
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
/// SQL命令
/// DB錯誤碼
///
public static string GetLastErrorCode(Command i_cCmd)
{
return i_cCmd == null || i_cCmd.IsSuccess ? null : i_cCmd.LastErrorCode;
}
///
/// 函式名稱:GetLastErrorCode
/// 函式說明:取得第一組DB錯誤碼
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
/// SQL命令List
/// 第一組DB錯誤碼
///
public static string GetLastErrorCode(List i_lcCmds)
{
return i_lcCmds?.Find(c => !c.IsSuccess)?.LastErrorCode;
}
///
/// 函式名稱:GetLastErrorCode
/// 函式說明:取得DB錯誤碼
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
/// SQL命令
/// DB錯誤碼
///
public static string GetLastErrorMessage(Command i_cCmd)
{
return i_cCmd == null || i_cCmd.IsSuccess ? null : i_cCmd.LastErrorMsg;
}
///
/// 函式名稱:GetLastErrorCode
/// 函式說明:取得第一組DB錯誤碼
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
/// SQL命令List
/// 第一組DB錯誤碼
///
public static string GetLastErrorMessage(List i_lcCmds)
{
return i_lcCmds?.Find(c => !c.IsSuccess)?.LastErrorMsg;
}
///
/// 函式名稱:GetRequestOrder
/// 函式說明:
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
///
/// 參數說明
///
///
/// 回傳
///
public static List> GetRequestOrder(CRequestMessage i_crmInput)
{
List> ordercol = null;
object oOrdercol = _fetchString(i_crmInput, BLWording.ORDERCOL);
if (oOrdercol != null)
{
JToken token = JArray.Parse(oOrdercol.ToString());
if (token != null)
{
ordercol = token.ToObject>>();
}
}
return ordercol;
}
///
/// 函式名稱:GetQueryMasterFirstQJEDicwherecols
/// 函式說明: 一般用以提供QJE.dicwherecols
///
/// 前端Request
/// Master查詢條件Dictionary
///
public static Dictionary GetQueryMasterFirstQJEDicwherecols(CRequestMessage i_crmInput)
{
return GetQueryMasterFirstWhereData>(i_crmInput);
}
public static WhereNode GetQueryMasterFirstWhereNode(CRequestMessage i_crmInput)
{
Dictionary dicCondition = GetQueryMasterFirstQJEDicwherecols(i_crmInput);
return Command.whereDictionary2WhereNode(dicCondition);
}
///
/// 函式名稱:GetQueryMaster
/// 函式說明:Master查詢條件
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
/// 前端Request
/// Master查詢條件Dictionary
///
public static T GetQueryMasterFirstWhereData(CRequestMessage i_crmInput) where T : class
{
T dicData = null;
if (i_crmInput != null && i_crmInput.param != null && i_crmInput.param.ContainsKey(BLWording.QRY_MASTER))
{
JArray joData = i_crmInput.param[BLWording.QRY_MASTER] as JArray;
if (joData.Any())
{
dicData = joData[0][BLWording.WHEREDATA].ToObject();
}
}
return dicData;
}
///
/// 函式名稱:GetQueryMasterFirstWhereData
/// 函式說明:Master查詢條件
/// 前端Request
/// Master查詢條件Dictionary
///
public static Dictionary GetQueryMasterFirstWhereData(CRequestMessage i_crmInput)
{
return GetQueryMasterFirstWhereData>(i_crmInput);
}
///
/// 函式名稱:GetQueryDetail
/// 函式說明:Detail查詢條件
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
/// 前端Request
/// Detail查詢條件Dictionary
///
public static Dictionary GetQueryDetail(CRequestMessage i_crmInput)
{
Dictionary dicData = null;
if (i_crmInput != null && i_crmInput.param != null && i_crmInput.param.ContainsKey(BLWording.QRY_DETAIL))
{
JArray joData = i_crmInput.param[BLWording.QRY_DETAIL] as JArray;
if (joData.Any())
{
dicData = joData[0][BLWording.WHEREDATA].ToObject>();
}
}
return dicData;
}
#region DBLOCK
///
/// Generate lock commands
///
/// 前端Request
/// Generated commands
///
protected virtual string setupDBLockCommand(CRequestMessage i_crmInput, out List o_lcCmds)
{
List lCmds = new List();
string sMsg;
do
{
if (i_crmInput == null)
{
sMsg = MessageWording.PARAM_NOT_EXPECTED;
break;
}
sMsg = getSessionByToken(i_crmInput.token, out tb_sys_session sUser);
if (sMsg != null)
{
break;
}
foreach (JToken joItem in (i_crmInput.param[BLWording.ADD_MASTER] as JArray))
{
tb_sys_dblock o = new tb_sys_dblock()
{
program_uid = GetRequestProgramID(i_crmInput),
table_uid = MainTable,
lock_cust_desc = this.GetType().Name + " lock",
lock_ip = i_crmInput.clientip,
lock_hostname = i_crmInput.cleinthostsname,
lock_uid = joItem[BLWording.DATA][tb_sys_dblock.CN_LOCK_UID].ToString(),
lock_update_date = DateTime.Now,
lock_update_org_uid = sUser.update_org_uid,
lock_update_user_uid = sUser.update_user_uid
};
lCmds.Add(Command.SetupInsertCmd(o));
}
}
while (false);
o_lcCmds = lCmds;
return sMsg;
}
///
/// DBlock
///
/// 前端Request
/// 執行結果
public CResponseMessage DBlock(CRequestMessage i_crmInput)
{
ArsenalInterface.ManualTrans mt = GetManualTrans();
ArsenalInterface ai = null;
string sMsg;
do
{
sMsg = setupDBLockCommand(i_crmInput, out List lAddLock);
if (sMsg != null)
{
break;
}
ai = ArsenalDBMgr.GetInst(lAddLock[0], GetDefaultSystemColumnInfo());
if (lAddLock.Count != ai.RunEditCmds(lAddLock, mt))
{
sMsg = GetLastErrorCode(lAddLock);
if (sMsg == null)
{
sMsg = MessageWording.CREATE_FAIL;
}
break;
}
}
while (false);
CResponseMessage crmRes = null;
if (ai != null)
{
if (sMsg != null)
{
ai.Rollback(mt);
crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
}
else
{
ai.Commit(mt);
ai.CloseManualTrans(mt);
crmRes = new CSuccessResponseMessage(null, i_crmInput);
}
}
return crmRes;
}
///
/// 函式名稱:DBLockRefresh
/// 函式說明:刷新DB Lock資料的更新時間(以Token)
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
/// 前端Request
/// 執行結果
///
public CResponseMessage DBLockRefresh(CRequestMessage i_crmInput)
{
ArsenalInterface.ManualTrans mt = GetManualTrans();
ArsenalInterface ai = null;
string sMsg;
do
{
if (i_crmInput == null)
{
sMsg = MessageWording.PARAM_NOT_EXPECTED;
break;
}
List sKeys = new List { tb_sys_dblock.CN_LOCK_UID };
List lUpdLock = getUpdListCommand(i_crmInput, i_crmInput.param[BLWording.UPD_MASTER], tb_sys_dblock.TABLENAME, sKeys, out sMsg);
if (sMsg != null)
{
break;
}
ai = ArsenalDBMgr.GetInst(lUpdLock[0], GetDefaultSystemColumnInfo());
int nEffect = ai.RunEditCmds(lUpdLock, mt);
sMsg = GetLastErrorCode(lUpdLock);
if (sMsg != null)
{
break;
}
if (nEffect != lUpdLock.Count)
{
sMsg = MessageWording.DBLOCK_DATACHANGED;
break;
}
}
while (false);
CResponseMessage crmRes;
if (sMsg != null)
{
ai?.Rollback(mt);
crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
}
else
{
ai?.Commit(mt);
ai?.CloseManualTrans(mt);
crmRes = new CSuccessResponseMessage(null, i_crmInput);
}
return crmRes;
}
///
/// 函式名稱:DBLockUnlock
/// 函式說明:截除DB Lock資料(以Token)
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
/// 前端Request
/// 執行結果
///
///
public CResponseMessage DBLockUnlock(CRequestMessage i_crmInput)
{
ArsenalInterface.ManualTrans mt = GetManualTrans();
ArsenalInterface ai = null;
string sMsg;
do
{
if (i_crmInput == null)
{
sMsg = MessageWording.PARAM_NOT_EXPECTED;
break;
}
List sKeys = new List { tb_sys_dblock.CN_LOCK_UID };
List lDelLock = getDelListCommand(i_crmInput, i_crmInput.param[BLWording.DEL_MASTER], tb_sys_dblock.TABLENAME, sKeys, out sMsg);
if (sMsg != null)
{
break;
}
ai = ArsenalDBMgr.GetInst(lDelLock[0], GetDefaultSystemColumnInfo());
int nEffect = ai.RunEditCmds(lDelLock);
sMsg = GetLastErrorCode(lDelLock);
if (sMsg != null)
{
break;
}
if (nEffect != lDelLock.Count)
{
sMsg = MessageWording.DBLOCK_DATACHANGED;
break;
}
}
while (false);
CResponseMessage crmRes;
if (sMsg != null)
{
ai?.Rollback(mt);
crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
}
else
{
ai?.Commit(mt);
ai?.CloseManualTrans(mt);
crmRes = new CSuccessResponseMessage(null, i_crmInput);
}
return crmRes;
}
///
/// 函式名稱:DBLockCleanExpire
/// 函式說明:清除所有DB Lock資料(以Token)
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
/// 前端Request
/// 執行結果
///
protected CResponseMessage DBLockCleanExpire(CRequestMessage i_crmInput)
{
CResponseMessage crmRes = null;
string sMsg;
do
{
WhereNode wnCond1 = new WhereNode(tb_sys_dblock.CN_UPDATE_DATE, WhereNode.EColumnOperation.EOT_LT, typeof(tb_sys_dblock), DateTime.Now.AddMinutes(-5));
WhereNode wnCond2 = new WhereNode(tb_sys_dblock.CN_UPDATE_DATE, WhereNode.EColumnOperation.EOT_ISNULL, typeof(tb_sys_dblock));
WhereNode wnCond = new WhereNode(WhereNode.ENodeOperation.ENO_OR, wnCond1, wnCond2);
List lCmds = new List() {
Command.SetupDeleteCmd(wnCond)
};
ArsenalInterface ai = ArsenalDBMgr.GetInst(lCmds[0], GetDefaultSystemColumnInfo());
ai.RunEditCmds(lCmds);
sMsg = GetLastErrorCode(lCmds);
if (sMsg != null)
{
break;
}
crmRes = new CSuccessResponseMessage(null, i_crmInput);
}
while (false);
if (null != sMsg)
{
crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
}
return crmRes;
}
///
/// 函式名稱:generateDBLockInst
/// 函式說明:產生Lock資料並填入資料
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
/// 前端Request
/// 欲鎖定資料表名稱
/// 欲鎖定資料ROWID
/// Lock資料
///
protected tb_sys_dblock generateDBLockInst(CRequestMessage i_crmInput, string i_sTableName)
{
string sDept_id = OriRequest.customparam[BLWording.DEPT_ID].ToString();
string sUser_id = OriRequest.customparam[BLWording.USER_ID].ToString();
string sProgram_id = GetRequestProgramID(i_crmInput);
DateTime dtNow = DateTime.Now;
tb_sys_dblock dblRes = null;
if (i_crmInput != null)
{
dblRes = new tb_sys_dblock()
{
uid = i_crmInput.token,
program_uid = sProgram_id,
table_uid = i_sTableName,
update_org_uid = sDept_id,
create_org_uid = sDept_id,
create_user_uid = sUser_id,
update_user_uid = sUser_id,
update_date = dtNow,
create_date = dtNow
};
}
return dblRes;
}
protected static Dictionary> getDBLockCheck(object i_oData, string i_sLockTableName, Dictionary> i_dicTableColumnMapping = null)
{
string sUpdateColumnName = tb_sys_dblock.CN_UPDATE_DATE;
Dictionary> dicCheck = new Dictionary>();
if (i_oData is JArray ja)
{
if (i_dicTableColumnMapping != null && i_dicTableColumnMapping.ContainsKey(i_sLockTableName))
{
Dictionary dicColumnMapping = i_dicTableColumnMapping[i_sLockTableName];
if (dicColumnMapping != null && dicColumnMapping.ContainsKey(tb_sys_dblock.CN_UPDATE_DATE))
{
sUpdateColumnName = dicColumnMapping[tb_sys_dblock.CN_UPDATE_DATE];
}
}
List lch = new List();
foreach (JToken joData in ja)
{
string sRowID = joData[BLWording.WHEREDATA][tb_sys_dblock.CN_UID].ToString();
DateTime dtUpdateTime = DateTime.Parse(joData[BLWording.WHEREDATA][sUpdateColumnName].ToString(), CultureInfo.CurrentCulture);
lch.Add(new checkDBLock() { RowID = sRowID, UpdateTime = dtUpdateTime });
}
dicCheck.Add(i_sLockTableName, lch);
}
return dicCheck;
}
///
/// 函式名稱:deleteOneTableRows
/// 函式說明:單筆資料刪除
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
/// 資料表型態
/// 前端Request
/// 資料表名稱
/// 執行結果
///
protected CResponseMessage deleteOneTableRows(CRequestMessage i_crmInput, string i_sLockTableName, Dictionary> i_dicTableColumnMapping = null) where T : EntityBase, new()
{
return deleteOneTableRowsHandler(i_crmInput, BLWording.DEL_MASTER, i_sLockTableName, i_dicTableColumnMapping);
}
protected CResponseMessage deleteOneTableRowsDetail(CRequestMessage i_crmInput, string i_sLockTableName, Dictionary> i_dicTableColumnMapping = null) where T : EntityBase, new()
{
return deleteOneTableRowsHandler(i_crmInput, BLWording.DEL_DETAIL, i_sLockTableName, i_dicTableColumnMapping);
}
protected CResponseMessage deleteOneTableRowsHandler(CRequestMessage i_crmInput, string i_Key, string i_sLockTableName, Dictionary> i_dicTableColumnMapping = null) where T : EntityBase, new()
{
string sMsg = null;
CResponseMessage crmRes = null;
do
{
if (i_crmInput == null)
{
sMsg = MessageWording.PARAM_NOT_EXPECTED;
break;
}
DBLockCleanExpire(i_crmInput);
Type tType = typeof(T);
Dictionary> dicCheck;
dicCheck = getDBLockCheck(i_crmInput.param[i_Key], i_sLockTableName, i_dicTableColumnMapping);
List lsDeletRowIDs = new List();
List lc = dicCheck[i_sLockTableName];
foreach (checkDBLock c in lc)
{
lsDeletRowIDs.Add(c.RowID);
}
List lCmds = new List
{
Command.SetupDeleteCmd(
new WhereNode(tb_sys_dblock.CN_UID, WhereNode.EColumnOperation.EOT_IN, tType, lsDeletRowIDs.ToArray())),
// Remove DBLock
generateDBUnlockCmdAll(i_crmInput)
};
crmRes = checkDBLockAndRun(i_crmInput, dicCheck, lCmds, i_dicTableColumnMapping);
}
while (false);
if (null != sMsg)
{
crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
}
return crmRes;
}
///
/// 函式名稱:lockOneTableOneRow
/// 函式說明:單筆資料鎖定
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
/// 前端Request
/// 鎖定資料表名稱
/// 若為非null,
/// 執行結果
///
protected CResponseMessage lockOneTableOneRow(CRequestMessage i_crmInput, string i_key, string i_sLockTableName, bool i_bUnlock = false, List i_lsExceptTables = null,
Dictionary> i_dicTableColumnMapping = null)
{
string sMsg = null;
CResponseMessage crmRes = null;
QueryResponse qrRes = null;
do
{
if (i_crmInput == null)
{
sMsg = MessageWording.PARAM_NOT_EXPECTED;
break;
}
DBLockCleanExpire(i_crmInput);
if (i_bUnlock)
{
string sUpdateColumnName = (i_dicTableColumnMapping == null) ? tb_sys_dblock.CN_UPDATE_DATE : i_dicTableColumnMapping[i_sLockTableName][tb_sys_dblock.CN_UPDATE_DATE].ToString(CultureInfo.CurrentCulture);
Command cPrevDBLock_Data = Command.SetupSelectCmd(new tb_sys_dblock(), new tb_sys_dblock() { uid = i_crmInput.token, table_uid = i_sLockTableName });
ArsenalInterface ai = ArsenalDBMgr.GetInst(cPrevDBLock_Data, GetDefaultSystemColumnInfo());
tb_sys_dblock oDBLock = ai.RunQuerySingleORM(cPrevDBLock_Data);
ai.RunEditSingleCmd(generateDBUnlockCmdExceptTable(i_crmInput, i_lsExceptTables));
if (oDBLock != null)
{
QueryJsonElementCollection lBlocks = new QueryJsonElementCollection();
Dictionary dicCondition = new Dictionary();
QueryJsonElement qjeRowIDs = lBlocks.GetInst();
qjeRowIDs.table = i_sLockTableName;
qjeRowIDs.displaycols = new List() {
tb_sys_dblock.CN_UID,
sUpdateColumnName
};
dicCondition.Add(tb_sys_dblock.CN_UID, oDBLock.uid);
qjeRowIDs.dicwherecols = dicCondition;
lBlocks.Add(qjeRowIDs);
sMsg = MakeSelectJoinByBlocks(lBlocks, out Command cSelect);
if (sMsg != null)
{
break;
}
cSelect.UseSQLTrim = true;
cSelect.NeedCount = false;
QueryDataSet qdsRes = ai.RunQueryDataSet(cSelect);
qrRes = new QueryResponse(qdsRes);
}
}
if (!i_crmInput.param.ContainsKey(i_key))
{
sMsg = MessageWording.PARAM_NOT_EXPECTED; //找無詞彙代碼
break;
}
List lcChecks = getCheckDBLock(i_crmInput, i_key,
(i_dicTableColumnMapping != null && i_dicTableColumnMapping.ContainsKey(i_sLockTableName)) ? i_dicTableColumnMapping[i_sLockTableName] : null);
List lRunCmds = new List() { };
Command cInsert = Command.SetupInsertCmd(generateDBLockInst(i_crmInput, i_sLockTableName));
lRunCmds.Add(cInsert);
Dictionary> dictionary = new Dictionary>
{
{ i_sLockTableName, lcChecks }
};
Dictionary> dicCheck = dictionary;
crmRes = checkDBLockAndRun(i_crmInput, dicCheck, lRunCmds, i_dicTableColumnMapping);
if (qrRes != null)
{
crmRes.param.Add(BLWording.RECORD, qrRes);
if (i_dicTableColumnMapping != null)
{
crmRes.param.Add(BLWording.UPDATETYPE, i_dicTableColumnMapping[i_sLockTableName]);
}
}
}
while (false);
if (null != sMsg)
{
crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
}
return crmRes;
}
///
/// 函式名稱:generateDBUnlockCmdExceptTable
/// 函式說明:產生排除部分資料表的解鎖命令(常用於DBLockDetail)
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
/// 前端Request
/// 特例不刪除的資料表
/// 命令
///
protected static Command generateDBUnlockCmdExceptTable(CRequestMessage i_crmInput, List i_lsNotRemovedTables = null)
{
Command cRes = null;
if (i_crmInput != null)
{
WhereNode wnToken = new WhereNode(tb_sys_dblock.CN_UID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_sys_dblock), i_crmInput.token);
WhereNode wnConidtion;
if (i_lsNotRemovedTables == null)
{
wnConidtion = wnToken;
}
else
{
List lwnExcept = new List();
foreach (string sTableName in i_lsNotRemovedTables)
{
WhereNode wnExceptOneTableTableName = new WhereNode(tb_sys_dblock.CN_TABLE_UID, WhereNode.EColumnOperation.EOT_NEQ, typeof(tb_sys_dblock), sTableName);
lwnExcept.Add(wnExceptOneTableTableName);
}
WhereNode wnExceptAll = new WhereNode(WhereNode.ENodeOperation.ENO_AND, lwnExcept.ToArray());
wnConidtion = new WhereNode(WhereNode.ENodeOperation.ENO_AND, wnToken, wnExceptAll);
}
cRes = Command.SetupDeleteCmd(wnConidtion);
}
return cRes;
}
///
/// 函式名稱:generateDBUnlockCmdAll
/// 函式說明:產生資料表的解鎖命令
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
/// 前端Request
/// 命令
///
///
protected static Command generateDBUnlockCmdAll(CRequestMessage i_crmInput)
{
return i_crmInput != null ? Command.SetupDeleteCmd(new WhereNode(tb_sys_dblock.CN_UID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_sys_dblock), i_crmInput.token)) : null;
}
///
/// 函式名稱:checkDBLockAndRun
/// 函式說明:檢核,通過即執行命令。確保所有動作於同一Transaction
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
/// 前端Request
/// 所有檢核資料
/// 檢核通過要執行的命令
/// 執行結果
///
protected CResponseMessage checkDBLockAndRun(CRequestMessage i_crmInput, Dictionary> i_dicChecks, List i_lcCmds,
Dictionary> i_dicTableColumnMapping = null
)
{
string sMsg = null;
CResponseMessage crmRes = null;
ArsenalInterface.ManualTrans mt = GetManualTrans();
do
{
if (i_dicChecks == null)
{
sMsg = MessageWording.PARAM_NOT_EXPECTED;
break;
}
// Check UpdateTime避免資料已被修改過
foreach (string sLockTableName in i_dicChecks.Keys)
{
QueryJsonElementCollection lBlocks = new QueryJsonElementCollection();
QueryJsonElement qjeCheckUpdateTime = lBlocks.GetInst();
qjeCheckUpdateTime.table = sLockTableName;
qjeCheckUpdateTime.displaycols = new List() {
QueryJsonElement.COUNT(tb_sys_dblock.CN_UID)
};
List lwn = new List();
List lch = i_dicChecks[sLockTableName];
foreach (checkDBLock ch in lch)
{
if (ch.UpdateTime != null)
{
WhereNode wnUpdateDate = null;
if (i_dicTableColumnMapping != null && i_dicTableColumnMapping.ContainsKey(sLockTableName) &&
i_dicTableColumnMapping[sLockTableName].ContainsKey(tb_sys_dblock.CN_UPDATE_DATE)
)
{
wnUpdateDate = new WhereNode(i_dicTableColumnMapping[sLockTableName][tb_sys_dblock.CN_UPDATE_DATE],
WhereNode.EColumnOperation.EOT_EQ, typeof(tb_sys_dblock), ch.UpdateTime);
}
else
{
wnUpdateDate = new WhereNode(tb_sys_dblock.CN_UPDATE_DATE, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_sys_dblock), ch.UpdateTime);
}
lwn.Add(new WhereNode(WhereNode.ENodeOperation.ENO_AND,
new WhereNode(tb_sys_dblock.CN_UID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_sys_dblock), ch.RowID),
wnUpdateDate)
);
}
}
if (lwn.Count == 0)
{
continue;
}
qjeCheckUpdateTime.wherecols = new WhereNode(WhereNode.ENodeOperation.ENO_OR, lwn.ToArray());
lBlocks.Add(qjeCheckUpdateTime);
sMsg = MakeSelectJoinByBlocks(lBlocks, out Command cSelect);
if (sMsg != null)
{
break;
}
ArsenalInterface ai = ArsenalDBMgr.GetInst(cSelect, GetDefaultSystemColumnInfo());
QueryDataSet qdsUpdateCount = ai.RunQueryDataSet(cSelect, mt);
sMsg = DBService.GetLastErrorCode(cSelect);
if (sMsg != null)
{
break;
}
object oCount = QueryJsonElement.GetFirstValue(qdsUpdateCount);
if (oCount == null || Convert.ToInt32(oCount, CultureInfo.CurrentCulture) != lch.Count)
{
sMsg = MessageWording.DBLOCK_DATACHANGED;
break;
}
}
if (sMsg != null)
{
break;
}
// 檢查&上鎖
QueryJsonElementCollection lBlocksCheckAndLock = new QueryJsonElementCollection();
QueryJsonElement qjeRowIDs = lBlocksCheckAndLock.GetInst();
qjeRowIDs.table = tb_sys_dblock.TABLENAME;
qjeRowIDs.displaycols = new List() {
tb_sys_dblock.CN_UID
};
List lwnCheckAndLock = new List();
foreach (string sLockTableName in i_dicChecks.Keys)
{
List lch = i_dicChecks[sLockTableName];
if (lch.Count == 0)
{
continue;
}
foreach (checkDBLock ch in lch)
{
lwnCheckAndLock.Add(new WhereNode(WhereNode.ENodeOperation.ENO_AND,
new WhereNode(tb_sys_dblock.CN_TABLE_UID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_sys_dblock), sLockTableName),
new WhereNode(tb_sys_dblock.CN_UID, WhereNode.EColumnOperation.EOT_EQ, typeof(tb_sys_dblock), ch.RowID)
));
}
}
qjeRowIDs.wherecols = new WhereNode(WhereNode.ENodeOperation.ENO_OR, lwnCheckAndLock.ToArray());
lBlocksCheckAndLock.Add(qjeRowIDs);
sMsg = MakeSelectJoinByBlocks(lBlocksCheckAndLock, out Command cSelectCheckAndLock);
if (sMsg != null)
{
break;
}
cSelectCheckAndLock.UseUpdateFor = true;
QueryDataSet qdsUpdateCountCheckAndLock = mt.aiDB.RunQueryDataSet(cSelectCheckAndLock, mt);
sMsg = GetLastErrorCode(cSelectCheckAndLock);
if (sMsg != null)
{
break;
}
if (qdsUpdateCountCheckAndLock.Total != 0)
{
sMsg = MessageWording.DBLOCK_ALREADYLOCKED;
break;
}
mt.aiDB.RunEditCmds(i_lcCmds, mt);
sMsg = GetLastErrorCode(i_lcCmds);
if (sMsg != null)
{
break;
}
crmRes = new CSuccessResponseMessage(null, i_crmInput);
}
while (false);
if (sMsg != null)
{
mt.aiDB.Rollback(mt);
crmRes = new CErrorResponseMessage(sMsg, i_crmInput);
}
else
{
mt.aiDB.Commit(mt);
}
mt.aiDB.CloseManualTrans(mt);
return crmRes;
}
///
/// 函式名稱:getCheckDBLocks
/// 函式說明:
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
///
///
///
///
protected static List getCheckDBLocks(CRequestMessage i_crmInput, string i_key)
{
List lchdbLock = new List();
if (i_crmInput != null && i_key != null)
{
JArray ja = i_crmInput.param[i_key] as JArray;
foreach (JToken joDataRaw in ja)
{
Dictionary dictionary = joDataRaw.ToObject>();
JToken joData;
if (dictionary.ContainsKey(BLWording.WHEREDATA))
{
joData = joDataRaw[BLWording.WHEREDATA];
}
else
{
joData = joDataRaw;
}
string sRowID = joData[tb_sys_dblock.CN_UID].ToString();
DateTime dtUpdateTime = DateTime.Parse(joData[tb_sys_dblock.CN_UPDATE_DATE].ToString(), CultureInfo.CurrentCulture);
lchdbLock.Add(new checkDBLock() { RowID = sRowID, UpdateTime = dtUpdateTime });
}
}
return lchdbLock;
}
///
/// 函式名稱:getOneCheckDBLock
/// 函式說明:
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
///
///
///
/// 參數說明
///
///
/// 回傳
///
protected static List getCheckDBLock(CRequestMessage i_crmInput, string i_key, Dictionary i_dicColumnMapping = null)
{
List lcRes = new List();
if (i_crmInput != null && i_key != null && i_crmInput.param != null)
{
JArray ja = i_crmInput.param[i_key] as JArray;
foreach (JToken joDataRaw in ja)
{
Dictionary dictionary = joDataRaw.ToObject>();
JToken joData;
if (dictionary.ContainsKey(BLWording.WHEREDATA))
{
joData = joDataRaw[BLWording.WHEREDATA];
}
else
{
joData = joDataRaw;
}
string sRowID = joData[tb_sys_dblock.CN_UID].ToString();
string sUpdateColumnName = tb_sys_dblock.CN_UPDATE_DATE;
if (i_dicColumnMapping != null && i_dicColumnMapping.ContainsKey(tb_sys_dblock.CN_UPDATE_DATE))
{
sUpdateColumnName = i_dicColumnMapping[tb_sys_dblock.CN_UPDATE_DATE];
}
DateTime dtUpdateTime = DateTime.Parse(joData[sUpdateColumnName].ToString(), CultureInfo.CurrentCulture);
lcRes.Add(new checkDBLock() { RowID = sRowID, UpdateTime = dtUpdateTime });
}
}
return lcRes;
}
#endregion DBLOCK
///
/// 函式名稱:GetManualTrans
/// 函式說明:
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
///
///
///
///
///
public ArsenalInterface.ManualTrans GetManualTrans() where T : EntityBase, new()
{
ArsenalInterface.ManualTrans mtRes;
ArsenalInterface.ManualTrans mtTemp;
Command command = Command.SetupSelectCmd(new T());
ArsenalInterface ai = ArsenalDBMgr.GetInst(command, GetDefaultSystemColumnInfo());
mtTemp = ai.GetManualTrans(command);
mtTemp.aiDB = ai;
mtTemp.Command = command;
mtRes = mtTemp;
return mtRes;
}
///
/// 函式名稱:EntityToDic
/// 函式說明:
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
///
/// 參數說明
///
///
/// 回傳
///
public static Dictionary EntityToDic(EntityBase i_eb)
{
Dictionary dicRes = new Dictionary();
if (i_eb != null)
{
Type t = i_eb.GetType();
foreach (PropertyInfo pi in t.GetProperties())
{
dicRes.Add(pi.Name, pi.GetValue(i_eb, null));
}
}
return dicRes;
}
///
/// 函式名稱:GetFileUploadInfo
/// 函式說明:
/// 起始作者:
/// 起始日期:
/// 最新修改人:
/// 最新修改日:
///
///
/// 參數說明
///
///
/// 回傳
///
public override FileUploadInfo GetFileUploadInfo()
{
return new FileUploadInfo()
{
Logger = Logger,
RootPath = RootPath
};
}
///
/// 函式名稱:GetRealPropertyName
/// 函式說明: 由ORM定義的CN_名稱 Ex. label_no.CN_LABEL_NO反譯 實際屬性名稱
/// 起始作者: Hercules
/// 起始日期: 2018/02/02
/// 最新修改人: Hercules
/// 最新修改日: 2018/02/02
///
/// View Model Type
/// 欄位名稱
///
public static string GetRealPropertyName(Type i_t, string i_sName)
{
string sName = null;
if (i_t != null)
{
PropertyInfo[] pis = i_t.GetProperties();
foreach (PropertyInfo pi in pis)
{
ColumnMiscAttribute cma = EntityUtil.GetPropertyAttribute(pi);
if (cma == null || cma.Data == null)
{
continue;
}
if (cma.Data.COLUMN_NAME == i_sName)
{
sName = pi.Name;
break;
}
}
}
return sName;
}
protected static List> getQryParameterList(CRequestMessage i_crmInput)
{
return i_crmInput != null && i_crmInput.param != null && i_crmInput.param.ContainsKey(BLWording.QRY_MASTER) ? getParameterList(i_crmInput.param[BLWording.QRY_MASTER]) : null;
}
protected static List> getParameterList(object i_dicData)
{
List> lDicRes = new List>();
if (i_dicData is JArray)
{
JArray jaData = i_dicData as JArray;
foreach (JToken jo in jaData)
{
lDicRes.Add(jo.ToObject>());
}
}
return lDicRes;
}
#region getQryListCommand
///
/// 函式名稱:getQryListCommand
/// 函式說明:獲取批次查詢Command
/// 起始作者:Justin
/// 起始日期:2016/10/05
/// 最新修改人:Justin
/// 最新修改日:2016/10/05
///
///
///
///
///
///
///
/// 參數說明i_crm(Object):所需查詢資料...
/// 參數說明i_sTbName:Tabel名稱
/// 參數說明o_sMsg:錯誤訊息
///
///
/// 回傳 lcCmds(Object):新增狀態相關訊息
///
protected static List getQryListCommand(
JArray i_jaDataArray, string i_sTbName, out string o_sMsg, Dictionary> i_aliascols = null, bool i_distinct = false,
bool i_bUseFullSelect = false, List i_lColumnName = null, EColumnFilter i_ecfFilter = EColumnFilter.ES_NO_CREATE)
{
string sMsg = null;
List lcCmds = new List();
foreach (JObject jtDataItem in i_jaDataArray.OfType())
{
sMsg = getEntity(i_sTbName, out object tbData); //傳出來一個物件
EntityBase ebSelect = tbData as EntityBase;
if (i_bUseFullSelect)
{
ebSelect.SetFullDirtyEx(i_ecfFilter);
}
else
{
if (i_lColumnName != null)
{
ebSelect.SetDirty(i_lColumnName.ToArray());
}
}
if (null != sMsg)
{
sMsg = MessageWording.PARAM_NOT_EXPECTED; //參數錯誤
break;
}
Dictionary dicCond = null;
if (jtDataItem.ContainsKey(BLWording.WHEREDATA))
{
dicCond = jtDataItem[BLWording.WHEREDATA].ToObject>();
}
Dictionary dicFullTextCond = null;
if (jtDataItem.ContainsKey(BLWording.FULLTEXT_PATTERN))
{
string sFullTextPattern = jtDataItem[BLWording.FULLTEXT_PATTERN].ToString().Trim();
if (sFullTextPattern.Length > 0)
{
dicFullTextCond = new Dictionary();
foreach (string sKey in ebSelect.Dirty)
{
if (!dicFullTextCond.ContainsKey(sKey))
{
dicFullTextCond[sKey] = $"{sFullTextPattern}";
}
}
}
}
List> ordercols = null;
if (jtDataItem.ContainsKey(BLWording.ORDERDATA))
{
List> lDic = jtDataItem[BLWording.ORDERDATA].ToObject>>();
List> ltss = new List>();
lDic.ForEach(f =>
{
string sKey = f.Keys.First();
ltss.Add(Tuple.Create(sKey, f[sKey]));
});
ordercols = ltss;
}
else
{
PropertyInfo pi = ebSelect.GetType().GetProperties().FirstOrDefault(f => f.Name == BLWording.CREATE_DATE);
if (pi != null)
{
ordercols = new List>() { new Tuple(BLWording.CREATE_DATE, BLWording.ORDER_DESC) };
}
}
Command c = Command.SetupSelectCmdByParam(ebSelect, dicCond, ordercols, i_aliascols, i_distinct, i_dicFullTextSearch: dicFullTextCond);
c.NeedCount = true;
lcCmds.Add(c);
}
o_sMsg = sMsg;
return lcCmds;
}
#endregion getQryListCommand
///
/// For Create/Copy Assignment
///
///
///
///
///
///
protected static string valueAssignment(CRequestMessage i_crmInput, EntityBase ebInsert, JObject jdata, out List o_lcCmds, Dictionary i_dicAddData = null, bool i_bIsCreate = false)
{
string sMsg = null;
List lcCmds = null;
do
{
if (i_crmInput == null || ebInsert == null)
{
sMsg = MessageWording.PARAM_NOT_EXPECTED;
break;
}
List lcCmdsTemp = new List();
Dictionary dicInput = new Dictionary();
IDictionary dicDataProperty = jdata;
if (dicDataProperty == null)
{
sMsg = MessageWording.PARAM_NOT_EXPECTED; //參數錯誤
break;
}
PropertyInfo[] pis = ebInsert.GetType().GetProperties();
foreach (JProperty property in jdata.Properties())
{
JToken jv = property.Value;
if (!pis.Any(f => f.Name == property.Name))
{
continue;
}
if (jv is JArray jaAllUploads)
{
string sFolderPath = generateUploadFolderPath("files");
StringBuilder sbUIDs = new StringBuilder();
Dictionary dicUpload = jaAllUploads[0].ToObject>();
UploadFiles uf = new UploadFiles()
{
UploadName = dicUpload[BLWording.NAME].ToString(),
};
string sBase64 = (string)dicUpload[BLWording.BSTRING];
int nIdx = sBase64.IndexOf(',', StringComparison.OrdinalIgnoreCase);
uf.FileMeta = sBase64.Substring(0, nIdx);
byte[] bRawData = Convert.FromBase64String(sBase64.Substring(nIdx + 1));
string sSubFolderPath = Path.Combine(sFolderPath,
(i_crmInput.customparam[BLWording.SESSION_USER] as tb_sys_session).update_user_uid);
if (!Directory.Exists(sSubFolderPath))
{
Directory.CreateDirectory(sSubFolderPath);
}
string sFilePath = Path.Combine(sSubFolderPath,
string.Format(CultureInfo.CurrentCulture, "{0}{1}", DateTime.Now.ToString("yyyyMMddHHMMssfff", CultureInfo.CurrentCulture), Path.GetExtension(dicUpload[BLWording.NAME].ToString())));
System.IO.File.WriteAllBytes(sFilePath, bRawData);
uf.FilePath = sFilePath;
string sUid = Guid.NewGuid().ToString();
lcCmdsTemp.Add(Command.SetupInsertCmd(new tb_sys_uploadlog()
{
uid = sUid,
module = i_crmInput.module,
name = dicUpload[BLWording.NAME].ToString(),
path = sFilePath.Substring(RootPath.Length)
}));
if (sbUIDs.Length == 0)
{
sbUIDs.Append(sUid);
}
else
{
sbUIDs.Append($";{sUid}");
}
if (sbUIDs.Length != 0)
{
dicInput.Add(property.Name, sbUIDs.ToString()); // for exception
}
}
else
{
dicInput.Add(property.Name, jv.Value());
}
}
if (i_dicAddData != null)
{
foreach (string sKey in i_dicAddData.Keys)
{
if (dicInput.ContainsKey(sKey))
{
dicInput[sKey] = i_dicAddData[sKey];
}
else
{
dicInput.Add(sKey, i_dicAddData[sKey]);
}
}
}
// Foolproof
if (i_bIsCreate)
{
if (dicInput.ContainsKey(BLWording.UID))
{
if (dicInput[BLWording.UID].ToString() == BLWording.CREATEUID)
{
dicInput[BLWording.UID] = Guid.NewGuid().ToString();
}
}
else
{
dicInput.Add(BLWording.UID, Guid.NewGuid().ToString());
}
}
if (i_bIsCreate &&
dicInput.ContainsKey(BLWording.UID) &&
dicInput[BLWording.UID].ToString() == BLWording.CREATEUID)
{
dicInput.Remove(BLWording.UID);
}
Dictionary dicFillRes = ebInsert.FillData(dicInput, EFillDataPolicy.EFDP_OVERRIDE);
if (0 != dicFillRes.Count)
{
sMsg = MessageWording.PARAM_NOT_EXPECTED; //參數錯誤
break;
}
lcCmds = lcCmdsTemp;
}
while (false);
o_lcCmds = lcCmds;
return sMsg;
}
#region getAddListCommand
///
/// 函式名稱:getAddListCommand
/// 函式說明:獲取批次新增Command
/// 起始作者:John
/// 起始日期:2016/06/04
/// 最新修改人:John
/// 最新修改日:2016/06/14
///
///
///
///
///
/// 參數說明i_crm(Object):所需新增資料...
/// 參數說明i_sTbName:Tabel名稱
/// 參數說明o_sMsg:錯誤訊息
///
///
/// 回傳 lcCmds(Object):新增狀態相關訊息
///
protected List getAddListCommand(CRequestMessage i_crmInput, object i_oAllItems, string i_sTbName, out string o_sMsg)
{
string sMsg = null;
List lcCmds = new List();
if (i_oAllItems is JArray jaItems)
{
foreach (JToken jtkItem in jaItems)
{
Dictionary dicItem = jtkItem.ToObject>();
if (dicItem == null)
{
continue;
}
sMsg = getEntity(i_sTbName, out object oInsert);
if (null != sMsg)
{
sMsg = MessageWording.PARAM_NOT_EXPECTED; //參數錯誤
break;
}
EntityBase ebInsert = oInsert as EntityBase;
sMsg = valueAssignment(i_crmInput, ebInsert, dicItem[BLWording.DATA] as JObject, out List o_lcAddInsert, i_bIsCreate: true);
if (sMsg != null)
{
break;
}
if (ldgModifyCreateInstance.Any())
{
foreach (DG_ModifyCreateInstance mci in ldgModifyCreateInstance)
{
sMsg = mci(i_crmInput, ref oInsert);
if (sMsg != null)
{
break;
}
}
if (sMsg != null)
{
break;
}
}
// Log
sMsg = getManualLog(i_crmInput, dicItem, BLWording.LOG_ACTION_NAME_INSERTSQL, out Command cLog);
if (sMsg != null)
{
break;
}
if (cLog != null)
{
lcCmds.Add(cLog);
}
if (o_lcAddInsert != null && o_lcAddInsert.Count > 0)
{
lcCmds.AddRange(o_lcAddInsert);
}
Command c = Command.SetupInsertCmd(ebInsert);
lcCmds.Add(c);
}
}
o_sMsg = sMsg;
return lcCmds;
}
#endregion getAddListCommand
#region getUpdListCommand
///
/// 函式名稱:getUpdListCommand
/// 函式說明:獲取批次修改Command
/// 起始作者:John
/// 起始日期:2016/06/04
/// 最新修改人:John
/// 最新修改日:2016/06/14
///
///
///
///
///
///
///
/// 參數說明i_crm(Object):所需修改資料...
/// 參數說明i_sTbName:Tabel名稱
/// 參數說明o_sMsg:錯誤訊息
///
///
/// 回傳 lcCmds(Object):修改狀態相關訊息
///
protected List getUpdListCommand(CRequestMessage i_crmInput, object i_oItems, string i_sTbName, List i_saUpdKeys, out string o_sMsg)
{
string sMsg = null;
List lcCmds = new List();
if (i_oItems is JArray)
{
ArsenalInterface ai = null;
JArray jaItems = i_oItems as JArray;
foreach (JToken jtkItem in jaItems)
{
Dictionary dicItem = jtkItem.ToObject>();
if (!dicItem.ContainsKey(BLWording.WHEREDATA))
{
sMsg = MessageWording.PARAM_NOT_EXPECTED; //參數錯誤
break;
}
sMsg = getEntity(i_sTbName, out object oData);
if (null != sMsg)
{
sMsg = MessageWording.PARAM_NOT_EXPECTED; //參數錯誤
break;
}
Type tRun = oData.GetType();
EntityBase ebData = oData as EntityBase;
sMsg = valueAssignment(i_crmInput, ebData, dicItem[BLWording.DATA] as JObject, out List o_lcAddInsert);
if (sMsg != null)
{
break;
}
if (o_lcAddInsert != null && o_lcAddInsert.Count > 0)
{
lcCmds.AddRange(o_lcAddInsert);
}
sMsg = getManualLog(i_crmInput, dicItem, BLWording.LOG_ACTION_NAME_UPDATESQL, out Command cLog);
if (sMsg != null)
{
break;
}
if (cLog != null)
{
lcCmds.Add(cLog);
}
sMsg = generateWhereNode(dicItem, i_saUpdKeys, tRun, out WhereNode wnWhere);
if (sMsg != null)
{
break;
}
Command c = Command.SetupUpdateCmd(ebData, wnWhere);
lcCmds.Add(c);
if (ldgUpdate_PostCommand.Any())
{
generateWhereNode(dicItem, i_saUpdKeys, tRun, out WhereNode wnWherePost);
sMsg = getEntity(i_sTbName, out object oDataPost);
if (sMsg != null)
{
break;
}
EntityBase ebDataPost = oDataPost as EntityBase;
ebDataPost.SetFullDirty();
Command cSelectPost = Command.SetupSelectCmd(ebDataPost, wnWherePost);
if (ai == null)
{
ai = ArsenalDBMgr.GetInst(cSelectPost);
}
List