641 lines
21 KiB
641 lines
21 KiB
///-----------------------------------------------------------------------
|
|
/// <copyright file="ServiceBase.cs" company="Origtek">
|
|
/// 程式代號: ServiceBase
|
|
/// 程式名稱: ServiceBase
|
|
/// 程式說明:
|
|
/// 起始作者: Nelson
|
|
/// 起始日期: 2016/09/03 17:03:37
|
|
/// 最新修改人: Hercules
|
|
/// 最新修日期: 2017/05/15 12:24:49
|
|
/// </copyright>
|
|
///-----------------------------------------------------------------------
|
|
#region 程式異動記錄
|
|
/// xx.YYYY/MM/DD VER AUTHOR COMMENTS(說明修改的內容)
|
|
/// 01.2016/09/20 1.000 Justin.liu 底層訊息標準化(RV.385)
|
|
/// 02.2016/10/04 1.001 Hercules For Phase2 Develop(RV.574)
|
|
/// 03.2016/12/13 1.002 Hercules 移除Warning(RV.2014)
|
|
/// 04.2016/12/17 1.003 Hercules 實作1-1-1版號(RV.2105)
|
|
/// 05.2016/12/29 1.004 Hercules 上傳元件後端(RV.2310)
|
|
/// 06.2017/03/09 1.005 Hercules Commit DB LOCK底層(RV.3065)
|
|
/// 07.2017/05/09 1.006 Rexxar.eng bse Upload(RV.4198)
|
|
/// 08.2017/05/12 1.007 Rexxar.eng UploadFile(RV.4270)
|
|
/// 09.2017/05/12 1.008 Rexxar.eng UploadFile(RV.4272)
|
|
/// 10.2017/05/15 1.009 Hercules 檔案上傳 獨立成Helper(RV.4293)
|
|
#endregion
|
|
|
|
namespace CounsellorBL
|
|
{
|
|
using CounsellorBL.BLStructure;
|
|
using CounsellorBL.Common;
|
|
using log4net;
|
|
using Microsoft.Extensions.Caching.Distributed;
|
|
using Microsoft.Extensions.Caching.Memory;
|
|
using MonumentDefine;
|
|
using Newtonsoft.Json;
|
|
using Newtonsoft.Json.Linq;
|
|
using OT.COM.ArsenalDB;
|
|
using OT.COM.SignalerMessage;
|
|
using SoldierData.EnterprizeV4;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Net;
|
|
using System.Reflection;
|
|
using System.Runtime.Serialization.Formatters.Binary;
|
|
using System.Text;
|
|
using static CounsellorBL.Common.EntityBaseExtension;
|
|
|
|
|
|
/// <summary>
|
|
/// 類別名稱:ServiceBase
|
|
/// 類別說明:
|
|
/// 起始作者:
|
|
/// 起始日期:
|
|
/// 最新修改人:
|
|
/// 最新修改日:
|
|
/// </summary>
|
|
public class ServiceBase
|
|
{
|
|
private static string _LocalIP = null;
|
|
protected static string LocalIP
|
|
{
|
|
get
|
|
{
|
|
if (_LocalIP == null)
|
|
{
|
|
_LocalIP = GetLocalIPAddress();
|
|
}
|
|
return _LocalIP;
|
|
}
|
|
}
|
|
/// <summary>
|
|
/// 類別成員、類別屬性說明:Logger
|
|
/// </summary>
|
|
protected ILog Logger
|
|
{
|
|
get
|
|
{
|
|
if (_inst == null)
|
|
{
|
|
_inst = LogManager.GetLogger(this.GetType());
|
|
}
|
|
return _inst;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 類別成員、類別屬性說明:_inst
|
|
/// </summary>
|
|
private ILog _inst = null;
|
|
|
|
|
|
/// <summary>
|
|
/// 類別成員、類別屬性說明:OriRequest
|
|
/// </summary>
|
|
public CRequestMessage OriRequest { get; set; }
|
|
/// <summary>
|
|
/// 類別成員、類別屬性說明:SERVICE
|
|
/// </summary>
|
|
public const string SERVICE = "service";
|
|
|
|
/// <summary>
|
|
/// 類別成員、類別屬性說明:_dicInitData
|
|
/// </summary>
|
|
protected Dictionary<string, object> _dicInitData { get; private set; }
|
|
|
|
/// <summary>
|
|
/// 類別成員、類別屬性說明:RootPath
|
|
/// </summary>
|
|
public static string RootPath { get; set; } = AppDomain.CurrentDomain.BaseDirectory;
|
|
/// <summary>
|
|
/// 函式名稱:SetRootPath
|
|
/// 函式說明:
|
|
/// 起始作者:
|
|
/// 起始日期:
|
|
/// 最新修改人:
|
|
/// 最新修改日:
|
|
/// </summary>
|
|
/// <param name="i_sRootPath">
|
|
/// 參數說明
|
|
/// </param>
|
|
/// <returns>
|
|
/// 回傳
|
|
/// </returns>
|
|
public static void SetRootPath(string i_sRootPath)
|
|
{
|
|
RootPath = i_sRootPath;
|
|
}
|
|
#region 1-1-1
|
|
/// <summary>
|
|
/// 類別成員、類別屬性說明:1-1-1 JS路徑
|
|
/// </summary>
|
|
protected virtual string JSPath => "NOT SET";
|
|
|
|
/// <summary>
|
|
/// 類別成員、類別屬性說明:1-1-1 HTML路徑
|
|
/// </summary>
|
|
protected virtual string HTMLPath => "NOT SET";
|
|
|
|
/// <summary>
|
|
/// 類別成員、類別屬性說明:1-1-1 JS Version
|
|
/// </summary>
|
|
protected string JSVersion => _getVersion(JSPath, "g_JSRevisionVersioin");
|
|
|
|
/// <summary>
|
|
/// 類別成員、類別屬性說明:1-1-1 JS Version
|
|
/// </summary>
|
|
protected string HTMLVersion => _getVersion(HTMLPath, "g_HTMLRevisionVersioin");
|
|
|
|
/// <summary>
|
|
/// 類別成員、類別屬性說明:取得Service版本號
|
|
/// </summary>
|
|
protected string ServiceVersion => ParseServiceVersion();
|
|
/// <summary>
|
|
/// 函式名稱:_getVersion
|
|
/// 函式說明:
|
|
/// 起始作者:
|
|
/// 起始日期:
|
|
/// 最新修改人:
|
|
/// 最新修改日:
|
|
/// </summary>
|
|
/// <param name="i_sPath"></param>
|
|
/// <param name="i_sPattern">
|
|
/// 參數說明
|
|
/// </param>
|
|
/// <returns>
|
|
/// 回傳
|
|
/// </returns>
|
|
private static string _getVersion(string i_sPath, string i_sPattern)
|
|
{
|
|
string sRes = "-1";
|
|
|
|
|
|
do
|
|
{
|
|
if (i_sPath == "NOT SET")
|
|
{
|
|
break;
|
|
}
|
|
|
|
string sPath = System.IO.Path.Combine(RootPath, i_sPath);
|
|
if (!System.IO.File.Exists(sPath))
|
|
{
|
|
break;
|
|
}
|
|
|
|
string sContent = System.IO.File.ReadAllText(sPath);
|
|
int nIdx = sContent.LastIndexOf(i_sPattern, StringComparison.OrdinalIgnoreCase);
|
|
if (nIdx == -1)
|
|
{
|
|
break;
|
|
}
|
|
|
|
int nVersionStart = sContent.IndexOf('"', nIdx);
|
|
|
|
if (nVersionStart == -1)
|
|
{
|
|
nVersionStart = sContent.IndexOf('\'', nIdx);
|
|
if (nVersionStart == -1)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
nVersionStart++;
|
|
|
|
int nVersionEnd = sContent.IndexOf('"', nVersionStart);
|
|
|
|
if (nVersionEnd == -1)
|
|
{
|
|
nVersionEnd = sContent.IndexOf('\'', nVersionStart);
|
|
if (nVersionEnd == -1)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
sRes = sContent[nVersionStart..nVersionEnd];
|
|
}
|
|
while (false);
|
|
|
|
return sRes;
|
|
}
|
|
/// <summary>
|
|
/// 函式名稱:ParseServiceVersion
|
|
/// 函式說明:取得Service版本號
|
|
/// 起始作者:
|
|
/// 起始日期:
|
|
/// 最新修改人:
|
|
/// 最新修改日:
|
|
/// </summary>
|
|
/// <param name="參數名稱">
|
|
/// 參數說明
|
|
/// </param>
|
|
/// <returns>版號。 -1表示沒有取得版本號</returns>
|
|
/// <summary>
|
|
protected string ParseServiceVersion()
|
|
{
|
|
string sRes = "-1";
|
|
|
|
PropertyInfo pi = this.GetType().GetProperty("ServiceRevisionVersion");
|
|
|
|
if (pi != null)
|
|
{
|
|
object oValue = pi.GetValue(this, null);
|
|
|
|
if (oValue != null)
|
|
{
|
|
sRes = oValue.ToString();
|
|
}
|
|
}
|
|
|
|
return sRes;
|
|
}
|
|
|
|
|
|
#endregion 1-1-1
|
|
|
|
/// <summary>
|
|
/// 函式名稱:Entry
|
|
/// 函式說明:
|
|
/// 起始作者:
|
|
/// 起始日期:
|
|
/// 最新修改人:
|
|
/// 最新修改日:
|
|
/// </summary>
|
|
/// <param name="i_crm">
|
|
/// 參數說明
|
|
/// </param>
|
|
/// <returns>
|
|
/// 回傳
|
|
/// </returns>
|
|
public CResponseMessage Entry(CRequestMessage i_crm)
|
|
{
|
|
string sMsg = null;
|
|
CResponseMessage crm = null;
|
|
|
|
|
|
do
|
|
{
|
|
try
|
|
{
|
|
if (i_crm == null)
|
|
{
|
|
sMsg = MessageWording.PARAM_NOT_EXPECTED;
|
|
break;
|
|
}
|
|
SoldierData.EnterprizeV4.tb_sys_session userSession = null;
|
|
// Find Native Method
|
|
string sFunctionName = i_crm.method;
|
|
|
|
MethodInfo mi = this.GetType().GetMethod(sFunctionName);
|
|
if (null == mi)
|
|
{
|
|
sMsg = MessageWording.METHOD_NO_MATCH; //NO MATCH METHOD
|
|
break;
|
|
}
|
|
#if DEBUG
|
|
System.Diagnostics.Debug.Write($"Process {this.GetType().Name}::{sFunctionName}");
|
|
#endif
|
|
AuthAttribute auClass = EntityUtil.GetClassAttribute<AuthAttribute>(this.GetType());
|
|
object[] oaAttr = mi.GetCustomAttributes(true);
|
|
|
|
|
|
bool bCheck = true;
|
|
|
|
if (auClass != null)
|
|
{
|
|
bCheck = auClass.TokenCheck;
|
|
}
|
|
|
|
|
|
if (oaAttr != null)
|
|
{
|
|
foreach (AuthAttribute oAttr in oaAttr)
|
|
{
|
|
if (oAttr is AuthAttribute aa)
|
|
{
|
|
bCheck = oAttr.TokenCheck;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (bCheck)
|
|
{
|
|
|
|
if (this is DBService dbsCur)
|
|
{
|
|
CResponseMessage crmToken = dbsCur.CheckTokenWithCRequestMessage(i_crm, out Dictionary<string, object> _);
|
|
|
|
if (EResponseResult.RR_FALSE == crmToken.result)
|
|
{
|
|
sMsg = crmToken.msg;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
userSession = crmToken.param[BLWording.SESSION_USER] as SoldierData.EnterprizeV4.tb_sys_session;
|
|
i_crm.customparam.Add(BLWording.SESSION_USER, userSession);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
DBService dbsCur = this as DBService;
|
|
dbsCur?.SetupGuestSession(i_crm);
|
|
}
|
|
|
|
// Make sure that reflection service method can only input CRequestMessage, output CResponseMessage!!
|
|
// Even default parameter is also not allowed!
|
|
crm = ((Func<CRequestMessage, CResponseMessage>)Delegate.CreateDelegate(typeof(Func<CRequestMessage, CResponseMessage>), this, mi))(i_crm);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.Error(new StringBuilder().Append("StackTrace: " + ex.StackTrace + ", Exception Information: " + ex.ToString()).ToString());
|
|
}
|
|
}
|
|
while (false);
|
|
|
|
|
|
if (null != sMsg)
|
|
{
|
|
crm = new CErrorResponseMessage(sMsg, i_crm);
|
|
}
|
|
|
|
return crm;
|
|
}
|
|
/// <summary>
|
|
/// 函式名稱:MakeDebugFullDump
|
|
/// 函式說明:
|
|
/// 起始作者:
|
|
/// 起始日期:
|
|
/// 最新修改人:
|
|
/// 最新修改日:
|
|
/// </summary>
|
|
/// <param name="i_sMsg"></param>
|
|
/// <param name="i_crm">
|
|
/// 參數說明
|
|
/// </param>
|
|
/// <returns>
|
|
/// 回傳
|
|
/// </returns>
|
|
public static string MakeDebugFullDump(string i_sMsg, CRequestMessage i_crm)
|
|
{
|
|
string sRes = Environment.NewLine;
|
|
|
|
sRes += "**** Start Dump **************************" + Environment.NewLine;
|
|
sRes += string.Format(CultureInfo.CurrentCulture, "Custom Message:{0}", i_sMsg) + Environment.NewLine;
|
|
sRes += string.Format(CultureInfo.CurrentCulture, "Parameter Json:{0}", JsonConvert.SerializeObject(i_crm)) + Environment.NewLine;
|
|
sRes += "Call Stack Dump:" + Environment.NewLine;
|
|
sRes += Environment.StackTrace + Environment.NewLine;
|
|
sRes += "*****End Dump *************************" + Environment.NewLine;
|
|
|
|
return sRes;
|
|
}
|
|
/// <summary>
|
|
/// 函式名稱:JProperty2Dic
|
|
/// 函式說明:
|
|
/// 起始作者:
|
|
/// 起始日期:
|
|
/// 最新修改人:
|
|
/// 最新修改日:
|
|
/// </summary>
|
|
/// <param name="i_jpData"></param>
|
|
/// <param name="io_dicData">
|
|
/// 參數說明
|
|
/// </param>
|
|
/// <returns>
|
|
/// 回傳
|
|
/// </returns>
|
|
public static string JProperty2Dic(JObject i_jpData, ref Dictionary<string, object> io_dicData)
|
|
{
|
|
string sRes = null;
|
|
Dictionary<string, object> dicRes = new Dictionary<string, object>();
|
|
|
|
if (i_jpData != null)
|
|
{
|
|
foreach (JProperty property in i_jpData.Properties())
|
|
{
|
|
JToken jv = property.Value;
|
|
dicRes.Add(property.Name, jv.Value<string>());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sRes = MessageWording.PARAM_NOT_EXPECTED;
|
|
}
|
|
|
|
io_dicData = dicRes;
|
|
return sRes;
|
|
}
|
|
|
|
public virtual FileUploadInfo GetFileUploadInfo()
|
|
{
|
|
return new FileUploadInfo()
|
|
{
|
|
Logger = Logger,
|
|
RootPath = RootPath
|
|
};
|
|
}
|
|
|
|
protected static EColumnFilter getQueryCustomerFilter(CRequestMessage i_crmInput)
|
|
{
|
|
EColumnFilter ecfRes = EColumnFilter.ES_NO;
|
|
|
|
if (i_crmInput != null && i_crmInput.customparam != null && i_crmInput.customparam.ContainsKey(BLWording.COLUMN_FILTER))
|
|
{
|
|
ecfRes = (EColumnFilter)Enum.Parse(typeof(EColumnFilter),
|
|
i_crmInput.customparam[BLWording.COLUMN_FILTER].ToString());
|
|
}
|
|
|
|
return ecfRes;
|
|
}
|
|
|
|
public IMemoryCache GetMemoryCache()
|
|
{
|
|
IMemoryCache imc = null;
|
|
|
|
if (OriRequest != null && OriRequest.system_param.ContainsKey(typeof(ControllDataPack).Name))
|
|
{
|
|
ControllDataPack cdp = OriRequest.system_param[typeof(ControllDataPack).Name] as ControllDataPack;
|
|
if (cdp.MemoryCache != null)
|
|
{
|
|
imc = cdp.MemoryCache;
|
|
}
|
|
}
|
|
|
|
return imc;
|
|
}
|
|
|
|
//public IDistributedCache GetDistributedCache()
|
|
//{
|
|
// IDistributedCache imc = null;
|
|
|
|
// if (OriRequest != null && OriRequest.system_param.ContainsKey(typeof(ControllDataPack).Name))
|
|
// {
|
|
// ControllDataPack cdp = OriRequest.system_param[typeof(ControllDataPack).Name] as ControllDataPack;
|
|
// if (cdp.MemoryCache != null)
|
|
// {
|
|
// imc = cdp.DistributedCache;
|
|
// }
|
|
// }
|
|
|
|
// return imc;
|
|
//}
|
|
|
|
|
|
|
|
protected byte[] ObjectToByteArray(object obj)
|
|
{
|
|
var binaryFormatter = new BinaryFormatter();
|
|
using (var memoryStream = new MemoryStream())
|
|
{
|
|
binaryFormatter.Serialize(memoryStream, obj);
|
|
return memoryStream.ToArray();
|
|
}
|
|
}
|
|
|
|
protected T ByteArrayToObject<T>(byte[] bytes)
|
|
{
|
|
using (var memoryStream = new MemoryStream())
|
|
{
|
|
var binaryFormatter = new BinaryFormatter();
|
|
memoryStream.Write(bytes, 0, bytes.Length);
|
|
memoryStream.Seek(0, SeekOrigin.Begin);
|
|
var obj = binaryFormatter.Deserialize(memoryStream);
|
|
return (T)obj;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 函式名稱:_fetchString
|
|
/// 函式說明:
|
|
/// 起始作者:
|
|
/// 起始日期:
|
|
/// 最新修改人:
|
|
/// 最新修改日:
|
|
/// </summary>
|
|
/// <param name="i_crmInput"></param>
|
|
/// <param name="i_sKey">
|
|
/// 參數說明
|
|
/// </param>
|
|
/// <returns>
|
|
/// 回傳
|
|
/// </returns>
|
|
protected static string _fetchString(CRequestMessage i_crmInput, string i_sKey)
|
|
{
|
|
return i_crmInput != null ? _fetchString(i_crmInput.param, i_sKey) : null;
|
|
}
|
|
/// <summary>
|
|
/// 函式名稱:_fetchString
|
|
/// 函式說明:
|
|
/// 起始作者:
|
|
/// 起始日期:
|
|
/// 最新修改人:
|
|
/// 最新修改日:
|
|
/// </summary>
|
|
/// <param name="i_dic"></param>
|
|
/// <param name="i_sKey">
|
|
/// 參數說明
|
|
/// </param>
|
|
/// <returns>
|
|
/// 回傳
|
|
/// </returns>
|
|
protected static string _fetchString(Dictionary<string, object> i_dic, string i_sKey)
|
|
{
|
|
string sRes = null;
|
|
|
|
if (i_dic != null && i_dic.ContainsKey(i_sKey))
|
|
{
|
|
object obj = i_dic[i_sKey];
|
|
if (null != obj)
|
|
{
|
|
sRes = obj.ToString();
|
|
}
|
|
}
|
|
return sRes;
|
|
}
|
|
|
|
|
|
|
|
public static string GetLocalIPAddress()
|
|
{
|
|
var host = Dns.GetHostEntry(Dns.GetHostName());
|
|
string sIPRes = null;
|
|
foreach (var ip in host.AddressList)
|
|
{
|
|
if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
|
|
{
|
|
sIPRes = ip.ToString();
|
|
}
|
|
}
|
|
return sIPRes;
|
|
}
|
|
|
|
protected static string getCommonParameter(CRequestMessage i_crmInput, string i_sRequestType, out JArray o_jaDataArray, out tb_sys_session o_sUserSession, bool i_bIsRequestTypeNeed = true)
|
|
{
|
|
string sMsg = null;
|
|
JArray jaDataArray = null;
|
|
tb_sys_session sUserSession = null;
|
|
|
|
// Leave exception for caller function
|
|
do
|
|
{
|
|
if (i_crmInput == null)
|
|
{
|
|
sMsg = MessageWording.PARAM_NOT_EXPECTED;
|
|
break;
|
|
}
|
|
|
|
if (i_sRequestType != null)
|
|
{
|
|
bool bFind = true;
|
|
if (i_crmInput.param == null ||
|
|
!i_crmInput.param.ContainsKey(i_sRequestType) ||
|
|
!(i_crmInput.param[i_sRequestType] is JArray))
|
|
{
|
|
bFind = false;
|
|
if (i_bIsRequestTypeNeed)
|
|
{
|
|
sMsg = MessageWording.PARAM_NOT_EXPECTED;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (bFind)
|
|
{
|
|
jaDataArray = i_crmInput.param[i_sRequestType] as JArray;
|
|
}
|
|
}
|
|
|
|
if (i_crmInput.customparam != null &&
|
|
i_crmInput.customparam.ContainsKey(BLWording.SESSION_USER))
|
|
{
|
|
sUserSession = i_crmInput.customparam[BLWording.SESSION_USER] as tb_sys_session;
|
|
}
|
|
}
|
|
while (false);
|
|
|
|
o_jaDataArray = jaDataArray ?? throw new NullReferenceException(nameof(jaDataArray) + ", " + MessageWording.PARAM_NOT_EXPECTED);
|
|
o_sUserSession = sUserSession ?? throw new NullReferenceException(nameof(sUserSession) + ", " + MessageWording.PARAM_NOT_EXPECTED);
|
|
|
|
return sMsg;
|
|
}
|
|
|
|
public static string GetRequestProgramID(CRequestMessage i_crmInput)
|
|
{
|
|
object oProgramID = i_crmInput != null && i_crmInput.customparam != null && i_crmInput.customparam.ContainsKey(BLWording.PROGRAMID) ? i_crmInput.customparam[BLWording.PROGRAMID] : null;
|
|
return oProgramID?.ToString();
|
|
}
|
|
|
|
public static string GetRequestMessage(Dictionary<string, object> i_dic)
|
|
{
|
|
object oMessage = i_dic != null && i_dic.ContainsKey(BLWording.MESSAGE) ? i_dic[BLWording.MESSAGE] : null;
|
|
return oMessage?.ToString();
|
|
}
|
|
}
|
|
|
|
|
|
}
|