123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Text.RegularExpressions;
- using Platform.Common;
- using Platform.ServiceProxy.ServiceHelper;
- using Platform.Common.RunningParameters;
- using Platform.Common.LogSystem;
- using TellerSystem.ServiceProxy.Ext;
- using TellerSystem.ServiceProxy.Ext.ServiceHelper;
- using System.Diagnostics;
- using TellerSystem.Communication.SocketListener;
- using System.IO;
-
- namespace TellerSystem.Communication.Package
- {
- /// <summary>
- /// 交易处理相关操作
- /// </summary>
- class MsgPackage
- {
- //报文处理接口对象
- public static Dictionary<PackageType, IPackage> PackageList = new Dictionary<PackageType, IPackage>
- {
- {PackageType.Msg858301,Msg858301.GetInstance()},
- {PackageType.Msg858302,Msg858302.GetInstance()},
- {PackageType.Msg858304,Msg858304.GetInstance()},
- {PackageType.MsgXml01,MsgXml01.GetInstance()}
- };
-
- /// <summary>
- /// 交易处理
- /// </summary>
- /// <param name="msg">报文对象</param>
- /// <param name="transit">callserver,callagn,calltips</param>
- /// <returns></returns>
- public static bool Trade(Message msg, PackageType packageType, string transit)
- {
- //组包后数据
- byte[] integrateData;
- //交易整体数据
- byte[] totalData;
- //通讯返回数据
- byte[] returnData;
- byte[] fileData = new byte[0];
- bool retunValue = false;
-
- //根据当前报文类型实例化报文处理对象
- if (!PackageList.ContainsKey(packageType))
- {
- PlatformLogger.TradeErrorInfo("MsgPackage.Trade:不支持的报文类型!-->" + packageType.ToString(), null);
- return false;
- }
- try
- {
- //根据当前报文类型实例化报文处理对象,
- var package = PackageList[packageType];
- //GetPackageInstance(transit);
- //组包
- integrateData = package.Integrate(msg);
- //通讯
- var fileName = msg.Fd3.Replace(" ", "") + msg.Fd10.Replace(" ", "");
- Stopwatch watch = new Stopwatch();
- watch.Start();
- List<byte[]> list;
- if (ServiceSettings.IsRecordPrintData)
- {
- //登记通讯报文类型
- string msgType = msg.IsMainTrade ? packageType.ToString() : string.Empty;
- try
- {
- list = TradeHandle.DoTrade(transit, integrateData, msg.Fd3, fileName, PlatformSettings.Encoding.GetBytes(Message.Cconv(msg.FileData)), null, msg.SerialNumber, msgType);//生僻字转义:文件组包处理
- }
- catch { list = null; }
- //当主交易通讯情况,未返回数据,需要查询记录,尝试进行补偿
- if (msg.IsMainTrade && (list == null || list.Count == 0))
- {
- //考虑到网络波动,需尝试3次
- for (int i = 0; i < 3; i++)
- {
- try
- {
- var data = PrintManagerHandle.GetPrintExtDataById(msg.SerialNumber);
- if (data != null)
- {
- PlatformLogger.SystemInfo("MsgPackage:主通讯补偿成功!" + msg.SerialNumber);
- list = new List<byte[]> { data.Message };
- if (data.MsgFile != null && data.MsgFile.Length > 0) list.Add(data.MsgFile);
- break;
- }
- }
- catch (Exception ex) { PlatformLogger.SystemErrorInfo("MsgPackage:主通讯补偿失败!" + msg.SerialNumber, ex); }
- System.Threading.Thread.Sleep(200);
- }
- //登记入库
- TradeHandle.WriteImportantLog("主通讯触发补偿", msg.SerialNumber, ((list != null && list.Count > 0) ? "成功" : "失败"), "DoTrade", "2", string.Join(",", SocketManager.GetLocalIpAddressList()));
- }
- }
- else
- {
- list = TradeHandle.DoTrade(transit, integrateData, msg.Fd3, fileName, PlatformSettings.Encoding.GetBytes(Message.Cconv(msg.FileData)), null, msg.SerialNumber);
- }
- watch.Stop();
- if (watch.ElapsedMilliseconds > 2000)
- TradeHandle.WriteImportantLog("通讯时间统计", watch.ElapsedMilliseconds.ToString(), msg.Fd16, "DoTrade", "2", string.Join(",", SocketManager.GetLocalIpAddressList()));
- //重置主交易标识
- msg.IsMainTrade = false;
- returnData = list[0];
- //处理文件附件
- if (list.Count > 1)
- {
- fileData = list[1];
- }
- byte fileDataFlag = 0;
- if (returnData != null && returnData.Length > 0)
- {
- if (returnData.Length < 20)
- PlatformLogger.SystemErrorInfo(string.Format("MsgPackage:返回报文长度太短,无法获取附件标志!", returnData.Length), new Exception());
- fileDataFlag = returnData[20];
- }
- else
- {
- //通讯出现异常,需要添加错误码
- msg.Fd12 = "COMM";
- return false;
- }
- //重置附件发送标志
- msg.FileFlag = false;
- totalData = new byte[returnData.Length + fileData.Length];
- Array.Copy(returnData, 0, totalData, 0, returnData.Length);
- Array.Copy(fileData, 0, totalData, returnData.Length, fileData.Length);
- //解包
- retunValue = package.Analyze(msg, totalData);
-
-
- }
- catch (Exception ex)
- {
- //写错误信息
- PlatformLogger.SystemErrorInfo("Trade: 函数出错. ", ex);
- return false;
- }
- return retunValue;
- }
-
- #region 报文处理相关功能函数
-
- /// <summary>
- /// 加密,解密函数
- /// 加密:flg=1 解密:flg=0
- /// </summary>
- /// <param name="myData"></param>
- /// <param name="key"></param>
- /// <param name="flg"></param>
- /// <returns></returns>
- public static bool Encrypt(byte[] myData, byte[] key, int flg)
- {
- //TODO:焦作项目不用做数据加密,暂时写死
- if (true) return true;
-
- int klen;
- klen = key.Length;
- string value;
- try
- {
- for (int i = 0; i < myData.Length; i++)
- {
- //加密
- if (flg == 1)
- { //溢出情况
- if ((myData[i] + key[i % klen]) > 255)
- {
- value = Convert.ToString((myData[i]) + key[i % klen], 2);
- myData[i] = Convert.ToByte(Convert.ToInt32(value.Substring(value.Length - 8, 8), 2));
- }
- //正常情况
- else
- {
- myData[i] = Convert.ToByte(myData[i] + key[i % klen]);
- }
- }
- //解密
- else
- {
- //溢出情况
- if (myData[i] < key[i % klen])
- {
- value = Convert.ToString((myData[i]), 2).PadLeft(8, '0');
- value = "1" + value;
- myData[i] = Convert.ToByte(Convert.ToInt32(value, 2) - key[i % klen]);
- }
- //正常情况
- else
- {
- myData[i] = Convert.ToByte(myData[i] - key[i % klen]);
- }
- }
- }
- }
- catch (Exception ex)
- {
- //写错误信息
- PlatformLogger.SystemErrorInfo("加密解密出错!", ex);
- throw;
- }
- return true;
- }
-
- /// <summary>
- /// 复制对象的属性值
- /// </summary>
- /// <param name="obj">复制目标对象</param>
- /// <param name="source">复制源对象</param>
- public static void Clone(Message obj, Message source)
- {
- System.Reflection.PropertyInfo[] tmp = obj.GetType().GetProperties();
-
- //复制所有的属性
- for (int i = 0; i < tmp.Length; i++)
- {
- tmp[i].SetValue(obj, tmp[i].GetValue(source, null), null);
- }
- //复制所有的filed
- }
-
-
- /// <summary>
- /// 字节数组修复为GDK编码规则
- /// </summary>
- /// <param name="data"></param>
- public static void CheckByte(byte[] data)
- {
- byte[] tmpData = null;
- string tmpStr = string.Empty;
- if (data == null || data.Length == 0)
- return;
- for (int i = 0; i < data.Length; i++)
- {
- //如果是ascii码字符,直接跳过
- if (data[i] < 128)
- continue;
- //added by liuyong 2010-4-16 start
- else
- {
- if ((i + 1) >= data.Length)
- continue;
- tmpData = new byte[2];
- tmpData[0] = data[i];
- tmpData[1] = data[i + 1];
-
- tmpStr = PlatformSettings.Encoding.GetString(tmpData);
- //全角字符且不是汉字则不进行转换
- if (IsSbc(tmpStr) && !IsChinese(tmpStr))
- {
- i++;
- continue;
- }
- }
- //added by liuyong 2010-4-16 end
- if (data[i] >= 0x81 && data[i] <= 0xa0)//GBK/3高位区间 129-160
- {
- if ((i + 1) >= data.Length)
- continue;
- if (data[i + 1] < 0x40 || data[i + 1] > 0xfe) //64 254
- {
- data[i] = 61;
- continue;
- }
- i++;
- }
- else if (data[i] >= 0xa1 && data[i] <= 0xa9)//GBK/1 高位区间 161-169
- {
- if ((i + 1) >= data.Length)
- continue;
- if (data[i + 1] < 0xa1 || data[i + 1] > 0xef) //161 239
- {
- data[i] = 61;
- continue;
- }
- i++;
- }
- else if (data[i] >= 0xaa && data[i] <= 0xfe)//GBK/4高位区间 170-254
- {
- if ((i + 1) >= data.Length)
- continue;
- if (data[i + 1] < 0x40) //64
- {
- data[i] = 61;
- continue;
- }
- else if (data[i + 1] > 0xa0) //160
- {
- //GBK/2高位区间
- if ((data[i] >= 0xb0 && data[i] <= 0xf7)) //176-247
- {
- //低位错误,证明是随机字符,高低位同时修复161 254
- if (data[i + 1] < 0xa1 || data[i + 1] > 0xfe)
- {
- data[i] = 61;
- continue;
- }
- }
- }
- i++;
- }
- else //错误乱码直接修复
- {
- data[i] = 61;
- }
- }
- }
-
- /// <summary>
- /// 判断字符串是否是全角字符
- /// </summary>
- /// <param name="str"></param>
- /// <returns></returns>
- private static bool IsSbc(string str)
- {
- bool blRet = false;
- if (2 * str.Length == Encoding.Default.GetByteCount(str))
- {
- blRet = true;
- }
- else
- {
- blRet = false;
- }
- return blRet;
- }
-
- /// <summary>
- /// 判断是否为中文
- /// </summary>
- /// <param name="word"></param>
- /// <returns></returns>
- private static bool IsChinese(string word)
- {
- Regex rx = null;
- if (string.IsNullOrEmpty(word))
- return false;
-
- rx = new Regex("^[\u4e00-\u9fa5]$");
-
- if (rx.IsMatch(word))
- return true;
- else
- return false;
- }
-
- #endregion
-
- }
- }
|