Browse Source

feat: 增加移动支付

zhengjie 1 year ago
parent
commit
854659b893

+ 62 - 0
Business/IMobilePay.cs

@@ -0,0 +1,62 @@
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PTMedicalInsurance.Business
+{
+    interface IMobilePay
+    {
+        /// <summary>
+        /// 【6101】解析医保电子凭证二维码
+        /// </summary>
+        /// <param name="inParam"></param>
+        /// <returns></returns>
+        JObject parseEcCode(string inParam);
+
+        /// <summary>
+        /// 【6201】费用明细上传
+        /// </summary>
+        /// <param name="inParam"></param>
+        /// <returns></returns>
+        JObject uploadFeeDetails(string inParam);
+
+        /// <summary>
+        /// 【6202】支付下单
+        /// </summary>
+        /// <param name="inParam"></param>
+        /// <returns></returns>
+        JObject payOrder(string inParam);
+
+        /// <summary>
+        /// 【6203】医保退费
+        /// </summary>
+        /// <param name="inParam"></param>
+        /// <returns></returns>
+        JObject cancelPay(string inParam);
+
+        /// <summary>
+        /// 【6204】医保订单信息同步(医保订单异步通知接口,应由服务端实现)
+        /// </summary>
+        /// <param name="inParam"></param>
+        /// <returns></returns>
+        JObject orderNotify(string inParam);
+
+        /// <summary>
+        /// 【6301】医保订单结算结果查询
+        /// </summary>
+        /// <param name="inParam"></param>
+        /// <returns></returns>
+        JObject orderQuery(string inParam);
+
+        /// <summary>
+        /// 【6302】医保结算结果通知
+        /// </summary>
+        /// <param name="inParam"></param>
+        /// <returns></returns>
+        JObject payNotify(string inParam);
+
+    }
+}

+ 1588 - 0
Business/MobilePay.cs

@@ -0,0 +1,1588 @@
+using Newtonsoft.Json.Linq;
+using PTMedicalInsurance.Common;
+using PTMedicalInsurance.Helper;
+using PTMedicalInsurance.Variables;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PTMedicalInsurance.Business
+{
+    class MobilePay
+    {
+        private HisIrisServices hIS = new HisIrisServices();
+        private MIIrisServices mIS = new MIIrisServices();
+        private CenterBusiness cBus = new CenterBusiness();
+        private InvokeHelper invoker = new InvokeHelper();
+        private Patients MPat;
+        private Settlements MSettl;
+        private JArray jaFee;
+        //
+        //private string fixmedins_code;//定点医疗服务机构编码
+        //private string yhappid;//渠道ID
+        //private string orgId;//电子凭证机构号
+
+        //前端传过来的入参,从这里面取值
+        private JObject joParam;
+        private JObject joInsuAdmObj;
+
+        public MobilePay(string inpar, out string errMsg)
+        {
+            errMsg = "";
+            try
+            {
+                JObject joInpar = JObject.Parse(inpar);
+                joParam = JObject.Parse(JsonHelper.getDestValue(joInpar, "params[0]"));
+                joInsuAdmObj = JObject.Parse(JsonHelper.getDestValue(joInpar, "insuAdmObj"));
+                setPatientByInPar();
+                setSettlementsByInPar();
+            }
+            catch (Exception ex)
+            {
+                errMsg = "MobilePay异常:" + ex.Message;
+            }
+
+        }
+
+        private JObject OutpatientReg()
+        {
+            string diagnoses;
+            if (hIS.getPatDiagnoses(Global.pat, out diagnoses) != 0)
+            {
+                return JsonHelper.setExceptionJson(-1, "挂号", "获取诊断异常" + diagnoses);
+            }
+            JObject joHisRtnInfo = JObject.Parse(diagnoses);
+
+            JObject joRegInpar = new JObject();
+            string occurTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
+            joRegInpar.Add("psn_no", Global.pat.psn_no);
+            joRegInpar.Add("insutype", Global.pat.insuType);
+            joRegInpar.Add("begntime", JsonHelper.getDestValue(joHisRtnInfo, "mdtrtinfo.begntime"));//挂号时间 occurTime
+            joRegInpar.Add("mdtrt_cert_type", "02");//就诊凭证类型
+            joRegInpar.Add("mdtrt_cert_no", MPat.certNO);//就诊凭证编号
+
+            joRegInpar.Add("ipt_otp_no", Global.pat.adm_Dr);
+            joRegInpar.Add("atddr_no", JsonHelper.getDestValue(joHisRtnInfo, "mdtrtinfo.atddr_no"));
+            joRegInpar.Add("dr_name", JsonHelper.getDestValue(joHisRtnInfo, "mdtrtinfo.chfpdr_name"));
+            joRegInpar.Add("dept_code", JsonHelper.getDestValue(joHisRtnInfo, "mdtrtinfo.adm_dept_codg"));
+            joRegInpar.Add("dept_name", JsonHelper.getDestValue(joHisRtnInfo, "mdtrtinfo.adm_dept_name"));
+            joRegInpar.Add("caty", "72");
+            JObject joReg = new JObject();
+            joReg.Add("data", joRegInpar);
+
+            JObject jo2201Rtn = invoker.invokeCenterService(TradeEnum.OutpatientRegistration, joReg);
+            string errMsg = "";
+            if (JsonHelper.parseCenterRtnValue(jo2201Rtn, out errMsg) != 0)
+            {
+                return JsonHelper.setExceptionJson(-1, "医保挂号", errMsg);
+            }
+            else
+            {
+                Global.pat.mdtrtID = JsonHelper.getDestValue(jo2201Rtn, "output.data.mdtrt_id");
+            }
+
+            return jo2201Rtn;
+        }
+        public int MobilePaySettlement(out string outPar)
+        {
+            string errMsg, patInfo, M6201Inpar, M6202Inpar;
+            //M6201Rtn, M6202Rtn,M6301Inpar,M6301Rtn;
+            outPar = "";
+            try
+            {
+
+                if (GetPatientInfo(out errMsg) != 0)
+                {
+                    outPar = errMsg;
+                    return -1;
+                }
+                patInfo = errMsg;
+                JObject jo1194Rtn = invoker.invokeCenterService(TradeEnum.PatientInfo, JObject.Parse(patInfo));
+                if (JsonHelper.parseCenterRtnValue(jo1194Rtn, out errMsg) != 0)
+                {
+                    outPar = errMsg;
+                    return -1;
+                }
+                setPatientInsuInfo(jo1194Rtn);
+
+                //2201
+                //JObject jo2201Rtn = OutpatientReg();
+
+                if (Get6201Inpar(out errMsg) != 0)
+                {
+                    outPar = errMsg;
+                    return -1;
+                }
+                M6201Inpar = errMsg;
+                JObject joM6201Rtn = invoker.invokeMPService("6201", errMsg);
+                if (JsonHelper.parseMPRtnValue(joM6201Rtn, out errMsg) != 0)
+                {
+                    outPar = errMsg;
+                    return -1;
+                }
+                JObject joEncData = JObject.Parse(errMsg);
+
+                Global.writeLog("返回值:" + errMsg);
+                //设置
+                setPatientBy6201Rtn(joEncData);
+                //存入MI 患者表,登记表,费用表
+                if (saveToMi(out errMsg) != 0)
+                {
+                    outPar = errMsg;
+                    return -1;
+                }
+                //M6202
+                if (Get6202Inpar(JObject.Parse(M6201Inpar), out errMsg) != 0)
+                {
+                    outPar = errMsg;
+                    return -1;
+                }
+                M6202Inpar = errMsg;
+                JObject joM6202Rtn = invoker.invokeMPService("6202", M6202Inpar);
+                if (JsonHelper.parseMPRtnValue(joM6202Rtn, out errMsg) != 0)
+                {
+                    outPar = errMsg;
+                    return -1;
+                }
+                joEncData = JObject.Parse(errMsg);
+                Global.writeLog(JsonHelper.Compress(joEncData));
+                //设置
+                setSettlementsBy6202Rtn(joEncData);
+                MSettl.confirmFlag = 0;
+                //存入MI 结算表
+                if (saveSettlement(out errMsg) != 0)
+                {
+                    outPar = errMsg;
+                    return -1;
+                }
+                //6301查询具体明细信息
+                //if (Get6301Inpar(out errMsg) != 0)
+                //{
+                //    outPar = errMsg;
+                //    return -1;
+                //}
+                //M6301Inpar = errMsg;
+                //JObject joM6301Rtn = invoker.invokeMPService("6301", eh.encrypt(M6301Inpar));
+                //if (JsonHelper.parseMPRtnValue(joM6301Rtn, out errMsg) != 0)
+                //{
+                //    outPar = errMsg;
+                //    return -1;
+                //}
+                //joEncData = JObject.Parse(eh.decrypt(errMsg));
+                //JObject joSettlInfo = JObject.Parse(JsonHelper.getDestValue(joEncData, "extData.SETLINFO"));
+                //Global.writeLog(JsonHelper.Compress(joEncData));
+                ////设置
+                //setSettlementsBy6301Rtn(joSettlInfo);
+                ////存入MI 结算表
+                //if (saveSettlement(out errMsg) != 0)
+                //{
+                //    outPar = errMsg;
+                //}
+                //返回给HIS后端 
+                JObject joPreSettl = JObject.Parse(JsonHelper.getDestValue(joEncData, "extData.preSetl"));
+                //JObject joTmp = JObject.Parse(JsonHelper.getDestValue(joM6201Rtn, "encData"));
+                JObject joTmp = new JObject();
+                joTmp.Add("insutype", MPat.insuType);
+                joTmp.Add("psn_no", MPat.psn_no);
+                joTmp.Add("insuplc_admdvs", MPat.insuplc_admdvs);
+                joTmp.Add("mdtrtId", MPat.mdtrtID);
+                joTmp.Add("mdtrt_id", MPat.mdtrtID);
+                joPreSettl.Add("setl_id", MPat.payOrdId);
+                joTmp.Add("mdtrt_cert_type", JsonHelper.getDestValue(joPreSettl, "mdtrt_cert_type"));
+                joTmp.Add("mdtrt_cert_no", JsonHelper.getDestValue(joPreSettl, "certno"));
+                joTmp.Add("med_type", JsonHelper.getDestValue(joPreSettl, "med_type"));
+
+                if (returnMPSettlementInfo(joTmp, joPreSettl, out errMsg) != 0)
+                {
+                    outPar = errMsg;
+                    return -1;
+                }
+                //返回给HIS前端
+                outPar = errMsg;
+                return 0;
+            }
+            catch (Exception ex)
+            {
+                outPar = ex.Message;
+                return -1;
+            }
+        }
+        public int MobilePayConfirmSettlement(out string outPar)
+        {
+            string errMsg, M6301Inpar;
+            outPar = "";
+            try
+            {
+                //EncryptHelper eh = new EncryptHelper();
+                //6301查询具体明细信息
+                if (Get6301Inpar(out errMsg) != 0)
+                {
+                    outPar = errMsg;
+                    return -1;
+                }
+                M6301Inpar = errMsg;
+                JObject joM6301Rtn = invoker.invokeMPService("6301", M6301Inpar);
+                if (JsonHelper.parseMPRtnValue(joM6301Rtn, out errMsg) != 0)
+                {
+                    outPar = errMsg;
+                    return -1;
+                }
+                JObject joEncData = JObject.Parse((errMsg));
+                Global.writeLog(JsonHelper.Compress(joEncData));
+                //设置
+                setSettlementsBy6301Rtn(joEncData);
+                MSettl.confirmFlag = 1;
+                //存入MI 结算表
+                if (updateSettlement(out errMsg) != 0)
+                {
+                    outPar = errMsg;
+                    return -1;
+                }
+                else
+                {
+                    //返回给HIS前端
+                    outPar = JsonHelper.setExceptionJson(0, "云医保平台", "确认成功!").ToString();
+                    return 0;
+                }
+
+            }
+            catch (Exception ex)
+            {
+                outPar = ex.Message;
+                return -1;
+            }
+        }
+        public int MobilePayCancelSettlement(out string outPar)
+        {
+            string errMsg;
+            outPar = "";
+            try
+            {
+
+                /**目前从微信那边处理退费
+                                if (Get6203Inpar(out errMsg) != 0)
+                                {
+
+                                }
+                                YH6203Inpar = errMsg;
+                                JObject jo6203Rtn = invoker.invokeMPService("6203", M6203Inpar);
+                                //M6202
+                                if (ParseCenterRtnValue(jo6203Rtn, out errMsg) != 0)
+                                {
+
+                                }
+                                else
+                                {
+                                    string newSettlID = JsonHelper.getDestValue(jo6203Rtn,"");
+                                    //撤销医保平台结算数据
+                                    cancleSettlement(newSettlID,out errMsg);
+                                    //撤销医保平台费用,登记,
+                                }
+                    **/
+                //处理撤销数据
+
+                if (cancleSettlement(MPat.settlID, out errMsg) != 0)
+                {
+                    outPar = errMsg;
+                    return -1;
+                }
+                else
+                {
+                    outPar = errMsg;
+                    return 0;
+                }
+            }
+            catch (Exception ex)
+            {
+                return -1;
+            }
+        }
+
+        #region 赋值MPat,Msettle结构体
+        public void setPatientByInPar()
+        {
+            MPat.adm_Dr = int.Parse(JsonHelper.getDestValue(joParam, "admID"));
+            Global.pat.adm_Dr = MPat.adm_Dr;
+            MPat.recordID = JsonHelper.getDestValue(joParam, "recordID");
+            MPat.billID = JsonHelper.getDestValue(joParam, "billID");
+            MPat.medType = JsonHelper.getDestValue(joInsuAdmObj, "medType");
+            MPat.certType = JsonHelper.getDestValue(joInsuAdmObj, "mdtrtCertType");
+            MPat.token = JsonHelper.getDestValue(joInsuAdmObj, "ecToken");
+            MPat.payAuthNo = JsonHelper.getDestValue(joInsuAdmObj, "payAuthNo");
+            MPat.uldLatlnt = JsonHelper.getDestValue(joInsuAdmObj, "uldLatlnt");
+            MPat.payOrdId = JsonHelper.getDestValue(joInsuAdmObj, "payOrdId");
+            MPat.mdtrtID = JsonHelper.getDestValue(joInsuAdmObj, "mdtrt_id");
+            MPat.settlID = JsonHelper.getDestValue(joInsuAdmObj, "setl_id");
+            Global.pat.mdtrtID = MPat.mdtrtID;
+        }
+        public void setPatientBy6201Rtn(JObject jo)
+        {
+            MPat.payOrdId = JsonHelper.getDestValue(jo, "payOrdId");
+            MPat.payToken = JsonHelper.getDestValue(jo, "payToken");
+            //MPat.psn_no = JsonHelper.getDestValue(jo, "psn_no");
+            //MPat.insuType = JsonHelper.getDestValue(jo, "insutype");
+            //MPat.insuplc_admdvs = JsonHelper.getDestValue(jo, "insuplc_admdvs");
+            MPat.mdtrtID = JsonHelper.getDestValue(jo, "extData.mdtrtId");
+        }
+        //{"errorCode":0,"errorMessage":"","result":{"patName":"张振","patBirthdate":"1993-02-07","patSex":"男","credCode":"01","credNo":"522226199302073619"}}
+        public void setPatientByHisBaseInfo(JObject jo)
+        {
+            MPat.name = JsonHelper.getDestValue(jo, "result.patName");
+            MPat.brdy = JsonHelper.getDestValue(jo, "result.patBirthdate");
+            MPat.gend = JsonHelper.getDestValue(jo, "result.patSex");
+            MPat.age = JsonHelper.getDestValue(jo, "result.Age");
+            MPat.naty = JsonHelper.getDestValue(jo, "result.naty");
+            MPat.certNO = JsonHelper.getDestValue(jo, "result.credNo");
+            MPat.IDNO = MPat.certNO;
+            MPat.certType = JsonHelper.getDestValue(jo, "result.credCode");
+        }
+
+        public void setPatientByMiRegInfo(JObject jo)
+        {
+            MPat.name = JsonHelper.getDestValue(jo, "data.PatientName");
+            MPat.psn_no = JsonHelper.getDestValue(jo, "data.PersonalNO");
+            MPat.certNO = JsonHelper.getDestValue(jo, "data.CertificateNO");
+            MPat.IDNO = MPat.certNO;
+            MPat.certType = JsonHelper.getDestValue(jo, "data.CertificateType");
+            MPat.payToken = JsonHelper.getDestValue(jo, "data.payToken");
+            MPat.insuplc_admdvs = JsonHelper.getDestValue(jo, "data.InsuranceAreaCode");
+        }
+
+        public void setPatientInsuInfo(JObject jo)
+        {
+            MPat.insuplc_admdvs = JsonHelper.getDestValue(jo, "output.insuinfo[0].insuplc_admdvs");
+            MPat.psn_no = JsonHelper.getDestValue(jo, "output.baseinfo.psn_no");
+            MPat.insuType = JsonHelper.getDestValue(jo, "output.insuinfo[0].insutype");
+            Global.pat.insuplc_admdvs = MPat.insuplc_admdvs;
+            Global.pat.psn_no = MPat.psn_no;
+            Global.pat.insuType = MPat.insuType;
+        }
+
+        public void setPatientByDiagnoseInfo(JObject jo)
+        {
+            MPat.admAttendDoctorNO = JsonHelper.getDestValue(jo, "atddr_no");
+            MPat.admDiagCode = JsonHelper.getDestValue(jo, "dscg_maindiag_code");
+            MPat.admDiagName = JsonHelper.getDestValue(jo, "dscg_maindiag_name");
+            MPat.AdmInDepCode = JsonHelper.getDestValue(jo, "adm_dept_codg");
+        }
+
+        public void setSettlementsBy6202Rtn(JObject jo)
+        {
+            MSettl.settlID = JsonHelper.getDestValue(jo, "payOrdId");
+            MPat.payOrdId = MSettl.settlID;
+            MSettl.ordStas = JsonHelper.getDestValue(jo, "ordStas");
+            MSettl.sumamt = getDecimalFee(jo, "feeSumamt");
+            MSettl.personCashPay = getDecimalFee(jo, "ownPayAmt");
+            MSettl.accountPaySumamt = getDecimalFee(jo, "psnAcctPay");
+            MSettl.fundPaySumamt = getDecimalFee(jo, "fundPay");
+            MSettl.deposit = getDecimalFee(jo, "deposit");
+            MSettl.clearingOrgan = JsonHelper.getDestValue(jo, "extData.preSetl.clr_optins");
+            MSettl.clearingType = JsonHelper.getDestValue(jo, "extData.preSetl.clr_type");
+            MSettl.clearingWay = JsonHelper.getDestValue(jo, "extData.preSetl.clr_way");
+            MSettl.civilserviceAllowancePay = getDecimalFee(jo, "extData.preSetl.cvlserv_pay");
+            MSettl.ownPayAmount = getDecimalFee(jo, "extData.preSetl.fulamt_ownpay_amt");
+            MSettl.overLimitAmountmt = getDecimalFee(jo, "extData.preSetl.overlmt_selfpay");
+            MSettl.preSelfPayAmount = getDecimalFee(jo, "extData.preSetl.preselfpay_amt");
+            MSettl.inPolicyRangeAmount = getDecimalFee(jo, "extData.preSetl.inscp_scp_amt");
+            MSettl.actualPayDeductible = getDecimalFee(jo, "extData.preSetl.act_pay_dedc");
+            MSettl.healthInsurancePay = getDecimalFee(jo, "extData.preSetl.hifp_pay");
+            MSettl.healthInsuranceRatio = getDecimalFee(jo, "extData.preSetl.pool_prop_selfpay");
+            MSettl.enterpriseSupplementPay = getDecimalFee(jo, "extData.preSetl.hifes_pay");
+            MSettl.seriousIllnessPay = getDecimalFee(jo, "extData.preSetl.hifmi_pay");
+            MSettl.largeExpensesSupplementPay = getDecimalFee(jo, "extData.preSetl.hifob_pay");
+            MSettl.medicalAssistPay = getDecimalFee(jo, "extData.preSetl.maf_pay");
+            MSettl.hospitalPartAmount = getDecimalFee(jo, "extData.preSetl.hosp_part_amt");
+            MSettl.otherPay = getDecimalFee(jo, "extData.preSetl.oth_pay");
+            MSettl.personPaySumamt = getDecimalFee(jo, "extData.preSetl.psn_part_amt");
+            MSettl.balance = getDecimalFee(jo, "extData.preSetl.balc");
+            MSettl.accountMutualAidAmount = getDecimalFee(jo, "extData.preSetl.acct_mulaid_pay");
+        }
+
+        public void setSettlementsBy6301Rtn(JObject joRtn)
+        {
+            JObject jo = JObject.Parse(JsonHelper.getDestValue(joRtn, "extData.setlinfo"));
+
+            MPat.settlID = JsonHelper.getDestValue(jo, "setlId");
+            MPat.psn_no = JsonHelper.getDestValue(jo, "psnNo");
+            MPat.naty = JsonHelper.getDestValue(jo, "naty");
+            MPat.name = JsonHelper.getDestValue(jo, "psnName");
+            MPat.age = JsonHelper.getDestValue(jo, "age");
+            MPat.gend = JsonHelper.getDestValue(jo, "gend");
+            MPat.certNO = JsonHelper.getDestValue(jo, "certno");
+            MPat.brdy = JsonHelper.getDestValue(jo, "brdy");
+            MPat.insuType = JsonHelper.getDestValue(jo, "insutype");
+            MPat.psn_type = JsonHelper.getDestValue(jo, "psnType");
+            MPat.mdtrtcertType = JsonHelper.getDestValue(jo, "mdtrtCertType");
+            MPat.medType = JsonHelper.getDestValue(jo, "medType");
+            MPat.insuplc_admdvs = JsonHelper.getDestValue(joRtn, "extData.insuplcAdmdvs");
+
+            MPat.payOrdId = JsonHelper.getDestValue(joRtn, "payOrdId");
+            MSettl.ordStas = JsonHelper.getDestValue(joRtn, "ordStas");
+            MSettl.sumamt = getDecimalFee(joRtn, "feeSumamt");
+
+            MSettl.personCashPay = getDecimalFee(jo, "psnCashPay");
+            MSettl.accountPaySumamt = getDecimalFee(jo, "acctPay");
+            MSettl.fundPaySumamt = getDecimalFee(jo, "fundPaySumamt");
+
+            //MSettl.deposit = getDecimalFee(jo, "deposit");
+            MSettl.clearingOrgan = JsonHelper.getDestValue(jo, "clrOptins");
+            MSettl.clearingType = JsonHelper.getDestValue(jo, "clrType");
+            MSettl.clearingWay = JsonHelper.getDestValue(jo, "clrWay");
+            MSettl.civilserviceAllowancePay = getDecimalFee(jo, "cvlservPay");
+            MSettl.ownPayAmount = getDecimalFee(jo, "fulamtOwnpayAmt");
+            MSettl.overLimitAmountmt = getDecimalFee(jo, "overlmtSelfpay");
+            MSettl.preSelfPayAmount = getDecimalFee(jo, "preselfpayAmt");
+            MSettl.inPolicyRangeAmount = getDecimalFee(jo, "inscpScpAmt");
+            MSettl.actualPayDeductible = getDecimalFee(jo, "actPayDedc");
+            MSettl.healthInsurancePay = getDecimalFee(jo, "hifpPay");
+            MSettl.healthInsuranceRatio = getDecimalFee(jo, "poolPropSelfpay");
+            MSettl.enterpriseSupplementPay = getDecimalFee(jo, "hifesPay");
+            MSettl.seriousIllnessPay = getDecimalFee(jo, "hifmiPay");
+            MSettl.largeExpensesSupplementPay = getDecimalFee(jo, "hifobPay");
+            MSettl.medicalAssistPay = getDecimalFee(jo, "mafPay");
+            MSettl.hospitalPartAmount = getDecimalFee(jo, "hospPartAmt");
+            MSettl.otherPay = getDecimalFee(jo, "othPay");
+            MSettl.personPaySumamt = getDecimalFee(jo, "psnPartAmt");
+            MSettl.balance = getDecimalFee(jo, "balc");
+            MSettl.accountMutualAidAmount = getDecimalFee(jo, "acctMulaidPay");
+        }
+
+        public void setSettlementsByInPar()
+        {
+            MSettl.clearingWay = JsonHelper.getDestValue(joInsuAdmObj, "psnSetlway");
+            MSettl.settlID = JsonHelper.getDestValue(joInsuAdmObj, "payOrdId");
+        }
+        #endregion
+
+        #region 组织入参
+        public int GetPatientInfo(out string outparam)
+        {
+            string errMsg = "";
+            outparam = "";
+            try
+            {
+                JObject joInpar = new JObject();
+                //查询患者基本信息
+                if (hIS.GetHisPatBaseInfo(out errMsg) != 0)
+                {
+                    outparam = errMsg;
+                    return -1;
+                }
+                setPatientByHisBaseInfo(JObject.Parse(errMsg));
+                //入参
+                joInpar.Add("mdtrt_cert_type", "02");//就诊凭证类型
+                joInpar.Add("mdtrt_cert_no", MPat.certNO);//就诊凭证编号
+                joInpar.Add("card_sn", "");//卡识别码
+                joInpar.Add("begntime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));//开始时间  获取历史参保信息时传入
+                joInpar.Add("psn_cert_type", "01");//就诊凭证类型为“ 02” 时默认传 01 代表身份 证,其他证件类型按实际上传
+                joInpar.Add("certno", MPat.certNO);//证件号码
+                joInpar.Add("psn_name", MPat.name);//姓名
+                JObject joData = new JObject();
+                joData.Add("data", joInpar);
+                outparam = joData.ToString();
+                return 0;
+            }
+            catch (Exception ex)
+            {
+                outparam = "GetPatientInfo:" + ex.Message;
+                return -1;
+            }
+            finally
+            {
+                Global.writeLog("GetPatientInfo", "", outparam);
+            }
+        }
+
+        //组织M6201入参
+        public int Get6201Inpar(out string outparam)
+        {
+            string errMsg = "";
+            outparam = "";
+            try
+            {
+                JObject joInpar = new JObject();
+                //查询患者基本信息
+                if (hIS.GetHisPatBaseInfo(out errMsg) != 0)
+                {
+                    outparam = errMsg;
+                    return -1;
+                }
+                setPatientByHisBaseInfo(JObject.Parse(errMsg));
+                JObject joPatBaseInfo = JObject.Parse(JsonHelper.getDestValue(JObject.Parse(errMsg), "result"));
+                //获取诊断
+                if (getDiagnoses(out errMsg) != 0)
+                {
+                    outparam = errMsg;
+                    return -1;
+                }
+                JObject joDiagnoses = JObject.Parse(errMsg);
+                JArray jaDiseinfoList = JArray.Parse(JsonHelper.getDestValue(joDiagnoses, "diseinfoList"));
+                JObject joMdtrtinfo = JObject.Parse(JsonHelper.getDestValue(joDiagnoses, "mdtrtinfo"));
+                setPatientByDiagnoseInfo(joMdtrtinfo);
+                //获取费用
+                if (GetFee(out errMsg) != 0)
+                {
+                    outparam = errMsg;
+                    return -1;
+                }
+                JObject joFee = JObject.Parse(errMsg);
+                JArray jaFeedetailList = JArray.Parse(JsonHelper.getDestValue(joFee, "feedetailList"));
+                for (int i = 0; i < jaFeedetailList.Count; i++)
+                {
+                    JObject joTmp = new JObject();
+                    joTmp.Add("act_purc_pric", jaFeedetailList[i]["pric"]);
+                    joTmp.Add("sin_dos", jaFeedetailList[i]["sinDosDscr"]);
+                    //joTmp.Add("medins_list_name", jaFeedetailList[i]["medListName"]);
+                    //((JObject)jaFeedetailList[i]).Property("chrgBchno").Remove();
+                    //((JObject)jaFeedetailList[i]).Property("diseCodg").Remove();
+                    ((JObject)jaFeedetailList[i]).Property("rxno").Remove();
+                    //((JObject)jaFeedetailList[i]).Property("feeOcurTime").Remove();
+                    ((JObject)jaFeedetailList[i]).Property("sinDosDscr").Remove();
+                    ((JObject)jaFeedetailList[i]).Property("usedFrquDscr").Remove();
+                    ((JObject)jaFeedetailList[i]).Property("prdDays").Remove();
+                    ((JObject)jaFeedetailList[i]).Property("medcWayDscr").Remove();
+                    //((JObject)jaFeedetailList[i]).Property("bilgDeptCodg").Remove();
+                    ((JObject)jaFeedetailList[i]).Property("acordDeptCodg").Remove();
+                    ((JObject)jaFeedetailList[i]).Property("acordDeptName").Remove();
+                    ((JObject)jaFeedetailList[i]).Property("ordersDrCode").Remove();
+                    ((JObject)jaFeedetailList[i]).Property("ordersDrName").Remove();
+                    ((JObject)jaFeedetailList[i]).Property("tcmdrugUsedWay").Remove();
+                    ((JObject)jaFeedetailList[i]).Property("etipFlag").Remove();
+                    ((JObject)jaFeedetailList[i]).Property("etipHospCode").Remove();
+                    ((JObject)jaFeedetailList[i]).Property("dscgTkdrugFlag").Remove();
+                    ((JObject)jaFeedetailList[i]).Property("matnFeeFlag").Remove();
+                    ((JObject)jaFeedetailList[i]).Property("initFeedetlSn").Remove();
+                    ((JObject)jaFeedetailList[i]).Property("medType").Remove();
+                    ((JObject)jaFeedetailList[i]).Property("memo").Remove();
+                    //((JObject)jaFeedetailList[i]).Property("expContent").Remove();
+                    //((JObject)jaFeedetailList[i]).Property("medListName").Remove();
+                    //((JObject)jaFeedetailList[i]).Property("medListSpc").Remove();
+                    ((JObject)jaFeedetailList[i]).Property("combNo").Remove();
+                    //jaFeedetailList[i]["chrgBchno"] = MPat.adm_Dr.ToString();
+                    jaFeedetailList[i]["expContent"] = joTmp.ToString();
+                    jaFeedetailList[i]["medType"] = JsonHelper.getDestValue(joInsuAdmObj, "medType");
+                    jaFeedetailList[i]["psnNo"] = MPat.psn_no;
+                }
+                //入参
+                joInpar.Add("orgCodg", Global.inf.hospitalNO);//机构编码
+                //joInpar.Add("orgId",  "");//电子凭证机构号
+                joInpar.Add("psnNo", MPat.psn_no);//人员编号
+                joInpar.Add("insutype", MPat.insuType);//险种类型
+                joInpar.Add("medOrgOrd", MPat.recordID);//医疗机构订单号  前端传入
+                joInpar.Add("initRxOrd", JsonHelper.getDestValue(joInsuAdmObj, "initRxOrd"));//要续方的原处方流水 前端传入
+                joInpar.Add("rxCircFlag", JsonHelper.getDestValue(joInsuAdmObj, "rxCircFlag"));//电子处方流转标志 前端传入
+                MSettl.settlTime = Convert.ToDateTime(JsonHelper.getDestValue(joMdtrtinfo, "begntime"));
+                joInpar.Add("begntime", JsonHelper.getDestValue(joMdtrtinfo, "begntime"));//开始时间
+                joInpar.Add("idNo", JsonHelper.getDestValue(joPatBaseInfo, "credNo"));//证件号码
+                joInpar.Add("userName", JsonHelper.getDestValue(joPatBaseInfo, "patName"));//用户姓名
+                joInpar.Add("idType", JsonHelper.getDestValue(joPatBaseInfo, "credCode"));//证件类别
+                joInpar.Add("ecToken", JsonHelper.getDestValue(joInsuAdmObj, "ecToken"));//电子凭证授权ecToken 前端传入
+                joInpar.Add("insuCode", Global.inf.areaCode);//就诊参保地行政区划
+                joInpar.Add("iptOtpNo", JsonHelper.getDestValue(joMdtrtinfo, "ipt_no"));//住院/门诊号
+                joInpar.Add("atddrNo", JsonHelper.getDestValue(joMdtrtinfo, "atddr_no"));//医师编码
+                joInpar.Add("drName", JsonHelper.getDestValue(joMdtrtinfo, "chfpdr_name"));//医师姓名
+                joInpar.Add("deptCode", JsonHelper.getDestValue(joMdtrtinfo, "adm_dept_codg"));//科室编码
+                joInpar.Add("deptName", JsonHelper.getDestValue(joMdtrtinfo, "adm_dept_name"));//科室名称
+                joInpar.Add("caty", "A10");//科别
+                //joInpar.Add("mdtrtId", Global.pat.mdtrtID);//医保就诊ID
+                joInpar.Add("medType", MPat.medType);//医疗类别 前端传入
+                joInpar.Add("feeType", JsonHelper.getDestValue(joInsuAdmObj, "feeType"));//费用类型 前端传入
+                joInpar.Add("medfeeSumamt", JsonHelper.getDestValue(joFee, "medfeeSumamt"));//医疗费总额
+                joInpar.Add("acctUsedFlag", JsonHelper.getDestValue(joInsuAdmObj, "acctUsedFlag"));//个人账户使用标志 前端传入
+                joInpar.Add("mainCondDscr", JsonHelper.getDestValue(joMdtrtinfo, "mainCondDscr"));//主要病情描述
+                joInpar.Add("diseCodg", JsonHelper.getDestValue(joMdtrtinfo, "diseCodg"));//病种编码
+                joInpar.Add("diseName", JsonHelper.getDestValue(joMdtrtinfo, "diseName"));//病种名称
+                joInpar.Add("psnSetlway", JsonHelper.getDestValue(joInsuAdmObj, "psnSetlway"));//个人结算方式 前端传入
+                joInpar.Add("chrgBchno", JsonHelper.getDestValue(joFee, "chrgBchno"));//收费批次号
+                //joInpar.Add("pubHospRfomFlag", JsonHelper.getDestValue(joInsuAdmObj, "pubHospRfomFlag"));//公立医院改革标志
+                //joInpar.Add("invono", JsonHelper.getDestValue(joMdtrtinfo, "invono"));//发票号
+                //joInpar.Add("endtime", JsonHelper.getDestValue(joMdtrtinfo, "endtime"));//出院时间
+                //joInpar.Add("fulamtOwnpayAmt", JsonHelper.getDestValue(joMdtrtinfo, "fulamtOwnpayAmt"));//全自费金额
+                //joInpar.Add("overlmtSelfpay", JsonHelper.getDestValue(joMdtrtinfo, "overlmtSelfpay"));//超限价金额
+                //joInpar.Add("preselfpayAmt", JsonHelper.getDestValue(joMdtrtinfo, "preselfpayAmt"));//先行自付金额
+                //joInpar.Add("inscpScpAmt", JsonHelper.getDestValue(joMdtrtinfo, "inscpScpAmt"));//符合政策范围金额
+                //joInpar.Add("oprnOprtCode", JsonHelper.getDestValue(joMdtrtinfo, "oprnOprtCode"));//手术操作代码
+                //joInpar.Add("oprnOprtName", JsonHelper.getDestValue(joMdtrtinfo, "oprnOprtName"));//手术操作名称
+                //joInpar.Add("fpscNo", JsonHelper.getDestValue(joMdtrtinfo, "fpscNo"));//计划生育服务证号
+                //joInpar.Add("latechbFlag", JsonHelper.getDestValue(joMdtrtinfo, "latechbFlag"));//晚育标志
+                joInpar.Add("gesoVal", JsonHelper.getDestValue(joMdtrtinfo, "gesoVal"));//孕周数
+                joInpar.Add("fetts", JsonHelper.getDestValue(joMdtrtinfo, "fetts"));//胎次
+                joInpar.Add("fetusCnt", JsonHelper.getDestValue(joMdtrtinfo, "fetusCnt"));//胎儿数
+                //joInpar.Add("pretFlag", JsonHelper.getDestValue(joMdtrtinfo, "pretFlag"));//早产标志
+                //joInpar.Add("birctrlType", JsonHelper.getDestValue(joMdtrtinfo, "birctrlType"));//计划生育手术类别
+                //joInpar.Add("birctrlMatnDate", JsonHelper.getDestValue(joMdtrtinfo, "birctrlMatnDate"));//计划生育手术或生育日期
+                //joInpar.Add("copFlag", JsonHelper.getDestValue(joMdtrtinfo, "copFlag"));//伴有并发症标志
+                //joInpar.Add("dscgDeptCodg", JsonHelper.getDestValue(joMdtrtinfo, "dscgDeptCodg"));//出院科室编码
+                //joInpar.Add("dscgDeptName", JsonHelper.getDestValue(joMdtrtinfo, "dscgDeptName"));//出院科室名称
+                //joInpar.Add("dscgDed", JsonHelper.getDestValue(joMdtrtinfo, "dscgDed"));//出院床位
+                //joInpar.Add("dscgWay", JsonHelper.getDestValue(joMdtrtinfo, "dscgWay"));//离院方式
+                //joInpar.Add("dieDate", JsonHelper.getDestValue(joMdtrtinfo, "dieDate"));//死亡日期
+                joInpar.Add("matnType", JsonHelper.getDestValue(joMdtrtinfo, "matnType"));//生育类别
+                joInpar.Add("expContent", JsonHelper.getDestValue(joInsuAdmObj, "expContent"));//扩展参数 前端传入
+                //joInpar.Add("midSetlFlag", JsonHelper.getDestValue(joInsuAdmObj, "midSetlFlag"));//中途结算标志 前端传入
+                joInpar.Add("diseinfoList", jaDiseinfoList);//诊断或症状明细
+                joInpar.Add("feedetailList", jaFeedetailList);//费用明细
+                //joInpar.Add("admDiagDscr", JsonHelper.getDestValue(joMdtrtinfo, "admDiagDscr"));//入院诊断描述
+                //joInpar.Add("admDeptCodg", JsonHelper.getDestValue(joMdtrtinfo, "admDeptCodg"));//入院科室编码
+                //joInpar.Add("admDeptName", JsonHelper.getDestValue(joMdtrtinfo, "admDeptName"));//入院科室名称
+                //joInpar.Add("admBed", JsonHelper.getDestValue(joMdtrtinfo, "admBed"));//入院床位
+                joInpar.Add("payAuthNo", JsonHelper.getDestValue(joInsuAdmObj, "payAuthNo"));//支付授权码 前端传入
+                joInpar.Add("uldLatlnt", JsonHelper.getDestValue(joInsuAdmObj, "uldLatlnt"));//经纬度 前端传入
+                joInpar.Add("mdtrtCertType", JsonHelper.getDestValue(joInsuAdmObj, "mdtrtCertType"));//就诊凭证类型 前端传入
+                joInpar.Add("insuplcAdmdvs", MPat.insuplc_admdvs);//用户参保地行政区划
+
+                //JObject joData = new JObject();
+                //joData.Add("data",joInpar);
+                outparam = joInpar.ToString();
+                return 0;
+            }
+            catch (Exception ex)
+            {
+
+                outparam = "Get6201Inpar:" + ex.Message;
+                return -1;
+            }
+            finally
+            {
+                Global.writeLog("Get6201Inpar", "", outparam);
+            }
+        }
+
+        //获取入参,入参基本为类局部变量
+        public int Get6202Inpar(JObject joM6201Inpar, out string outparam)
+        {
+            outparam = "";
+            try
+            {
+                //获取其他入参
+                JObject joInpar = new JObject();
+                joInpar.Add("payAuthNo", MPat.payAuthNo);//支付授权码 前端传入
+                joInpar.Add("payOrdId", MPat.payOrdId);//待支付订单号 
+                joInpar.Add("payToken", MPat.payToken);//支付订单对应的token 
+                joInpar.Add("orgCodg", Global.inf.hospitalNO);//定点机构编码
+                joInpar.Add("orgBizSer", DateTime.Now.ToString("yyyyMMddHHmmssffff"));//业务流水号 前端传入
+                //joInpar.Add("ecAuthCode", "");
+                //joInpar.Add("ecChnlAppId", "");
+                //joInpar.Add("ecChnlUserId", "");
+                //joInpar.Add("mdtrtId", MPat.mdtrtID);
+                joInpar.Add("chrgBchno", JsonHelper.getDestValue(joM6201Inpar, "chrgBchno"));//收费批次号 
+                //joInpar.Add("feeType", JsonHelper.getDestValue(joM6201Inpar, "feeType"));//费用类别
+                //joInpar.Add("deposit", JsonHelper.getDestValue(joInsuAdmObj, "deposit"));//住院押金
+                //joInpar.Add("expContent", "");//扩展数据
+                //joInpar.Add("acctUsedFlag", "1");//个账使用标识
+                //JObject joData = new JObject();
+                //joData.Add("data", joInpar);
+                outparam = joInpar.ToString();
+                return 0;
+            }
+            catch (Exception ex)
+            {
+                outparam = "Get6202Inpar:" + ex.Message;
+                return -1;
+            }
+            finally
+            {
+                Global.writeLog("Get6202Inpar", "", outparam);
+            }
+        }
+
+        //组织M6203入参
+        public int Get6203Inpar(out string outparam)
+        {
+            string errMsg = "";
+            outparam = "";
+            try
+            {
+                JObject joInpar = new JObject();
+                //获取医保平台结算信息
+                if (QuerySettleInfo(out errMsg) != 0)
+                {
+                    outparam = errMsg;
+                    return -1;
+                }
+                JObject joRtn = JObject.Parse(errMsg);
+                JObject joSettl = JObject.Parse(JsonHelper.getDestValue(joRtn, "data"));
+
+                //入参
+                joInpar.Add("payOrdId", JsonHelper.getDestValue(joSettl, "SettlementID"));//支付订单号
+                joInpar.Add("appRefdSn", JsonHelper.getDestValue(joSettl, ""));//应用退款流水号
+                joInpar.Add("appRefdTime", JsonHelper.getDestValue(joSettl, ""));//应用退费时间
+                joInpar.Add("totlRefdAmt", JsonHelper.getDestValue(joSettl, "Sumamt"));//总退费金额
+                joInpar.Add("psnAcctRefdAmt", JsonHelper.getDestValue(joSettl, "AccountPaySumamt"));//医保个人账户支付
+                joInpar.Add("fundRefdAmt", JsonHelper.getDestValue(joSettl, "FundPaySumamt"));//基金支付
+                joInpar.Add("cashRefdAmt", JsonHelper.getDestValue(joInsuAdmObj, "PersonCashPay"));//现金退费金额
+                joInpar.Add("ecToken", MPat.token);//电子凭证授权Token  前端传入
+                joInpar.Add("refdType", "ALL");//退费类型  前端传入
+                joInpar.Add("expData", "");//扩展数据  前端传入
+                joInpar.Add("payAuthNo", MPat.payAuthNo);//支付授权码  前端传入
+
+                //JObject joData = new JObject();
+                //joData.Add("data", joInpar);
+                outparam = joInpar.ToString();
+                return 0;
+            }
+            catch (Exception ex)
+            {
+
+                outparam = "Get6203Inpar:" + ex.Message;
+                return -1;
+            }
+            finally
+            {
+                Global.writeLog("Get6203Inpar", "", outparam);
+            }
+        }
+
+        //获取入参,入参基本为类局部变量
+        public int Get6301Inpar(out string outparam)
+        {
+            outparam = "";
+            try
+            {
+                string errMsg;
+                //查询登记信息
+                if (mIS.queryRegisterInfo(4, out errMsg) != 0)
+                {
+                    outparam = errMsg;
+                    return -1;
+                }
+                setPatientByMiRegInfo(JObject.Parse(errMsg));
+                //获取其他入参
+                JObject joInpar = new JObject();
+                joInpar.Add("payOrdId", MPat.payOrdId);//待支付订单号 
+                joInpar.Add("payToken", MPat.payToken);//支付订单对应的token 
+                joInpar.Add("orgCodg", Global.inf.hospitalNO);//定点机构编码
+                joInpar.Add("idNo", MPat.IDNO);//业务流水号 前端传入
+                joInpar.Add("userName", MPat.name);
+                joInpar.Add("idType", "01");
+                joInpar.Add("expData", "");
+
+                //JObject joData = new JObject();
+                //joData.Add("data", joInpar);
+                outparam = joInpar.ToString();
+                return 0;
+            }
+            catch (Exception ex)
+            {
+                outparam = "Get6301Inpar:" + ex.Message;
+                return -1;
+            }
+            finally
+            {
+                Global.writeLog("Get6301Inpar", "", outparam);
+            }
+        }
+
+        public int Get6401Inpar(out string outparam)
+        {
+            string errMsg = "";
+            outparam = "";
+            try
+            {
+                JObject joInpar = new JObject();
+                //获取医保平台结算信息
+                if (QuerySettleInfo(out errMsg) != 0)
+                {
+                    outparam = errMsg;
+                    return -1;
+                }
+                JObject joRtn = JObject.Parse(errMsg);
+                JObject joSettl = JObject.Parse(JsonHelper.getDestValue(joRtn, "data"));
+
+                //入参
+                joInpar.Add("payOrdId", JsonHelper.getDestValue(joSettl, "SettlementID"));//支付订单号
+                joInpar.Add("appRefdSn", JsonHelper.getDestValue(joSettl, ""));//应用退款流水号
+                joInpar.Add("appRefdTime", JsonHelper.getDestValue(joSettl, ""));//应用退费时间
+                joInpar.Add("totlRefdAmt", JsonHelper.getDestValue(joSettl, "Sumamt"));//总退费金额
+                joInpar.Add("psnAcctRefdAmt", JsonHelper.getDestValue(joSettl, "AccountPaySumamt"));//医保个人账户支付
+                joInpar.Add("fundRefdAmt", JsonHelper.getDestValue(joSettl, "FundPaySumamt"));//基金支付
+                joInpar.Add("cashRefdAmt", JsonHelper.getDestValue(joInsuAdmObj, "PersonCashPay"));//现金退费金额
+                joInpar.Add("ecToken", MPat.token);//电子凭证授权Token  前端传入
+                joInpar.Add("refdType", "ALL");//退费类型  前端传入
+                joInpar.Add("expData", "");//扩展数据  前端传入
+                joInpar.Add("payAuthNo", MPat.payAuthNo);//支付授权码  前端传入
+
+                //JObject joData = new JObject();
+                //joData.Add("data", joInpar);
+                outparam = joInpar.ToString();
+                return 0;
+            }
+            catch (Exception ex)
+            {
+
+                outparam = "Get6203Inpar:" + ex.Message;
+                return -1;
+            }
+            finally
+            {
+                Global.writeLog("Get6203Inpar", "", outparam);
+            }
+        }
+
+        #endregion
+
+        #region 诊断
+        //获取诊断信息
+        public int getDiagnoses(out string errMsg)
+        {
+            errMsg = "";
+            try
+            {
+                //调用服务获取门诊诊断信息
+                string outparam = "";
+                if (hIS.getPatDiagnoses(MPat, out outparam) != 0)
+                {
+                    return -1;
+                }
+
+
+                JObject joRtn = JObject.Parse(outparam);
+                JObject joMdtrtInfo = JObject.Parse(JsonHelper.getDestValue(joRtn, "mdtrtinfo"));
+                JArray jaDiagnoses = JArray.Parse(JsonHelper.getDestValue(joRtn, "diseinfo"));
+
+                //组织门诊结算诊断入参
+                JArray jaRow = new JArray();
+                for (int i = 0; i < jaDiagnoses.Count; i++)
+                {
+                    JObject joTmp = new JObject();
+                    joTmp.Add("diagType", jaDiagnoses[i]["diag_type"]);//
+                    joTmp.Add("diagSrtNo", jaDiagnoses[i]["diag_srt_no"]);//
+                    joTmp.Add("diagCode", jaDiagnoses[i]["diag_code"]);//
+                    joTmp.Add("diagName", jaDiagnoses[i]["diag_name"]);//
+                    joTmp.Add("diagDept", jaDiagnoses[i]["diag_dept"]);//
+                    joTmp.Add("diseDorNo", jaDiagnoses[i]["dise_dor_no"]);//
+                    joTmp.Add("diseDorName", jaDiagnoses[i]["dise_dor_name"]);//
+                    joTmp.Add("diagTime", jaDiagnoses[i]["diag_time"]);//
+                    joTmp.Add("valiFlag", "1");//
+                    jaRow.Add(joTmp);
+                }
+                JObject joDiagRow = new JObject();
+                joDiagRow.Add("diseinfoList", jaRow);
+                joDiagRow.Add("mdtrtinfo", joMdtrtInfo);
+                outparam = joDiagRow.ToString();
+                errMsg = outparam;
+                return 0;
+            }
+            catch (Exception ex)
+            {
+                errMsg = "getDiagnoses:" + ex.Message;
+                return -1;
+            }
+        }
+        #endregion
+
+        #region 费用
+        private int GetFee(out string outparam)
+        {
+            string hisFee, chrgBchno = "";
+            JObject jo = new JObject();
+            JObject joRow = new JObject();
+            JArray jaRow = new JArray();
+            try
+            {
+                //获取HIS费用
+                if (hIS.getHisFee(MPat, out hisFee) != 0)
+                {
+                    outparam = hisFee;
+                    return -1;
+                }
+                JObject joFee = JObject.Parse(hisFee);
+                //处理
+                //调用医保平台转换HIS费用(转换医保编码等)
+                JObject joHisFee = JObject.Parse(hisFee);
+                if (mIS.convertHisFeeWithInsuCodeOfMobilePay(MPat, joHisFee, out outparam) != 0)
+                {
+                    return -1;
+                }
+
+                JArray jaFeeDetail = JArray.Parse(JsonHelper.getDestValue(JObject.Parse(outparam), "data"));
+                jaFee = (JArray)jaFeeDetail.DeepClone();
+                decimal sumFee = 0;
+                //转换
+                for (int i = 0; i < jaFeeDetail.Count; i++)
+                {
+                    decimal cnt = decimal.Parse(jaFeeDetail[i]["cnt"].ToString());
+                    decimal pric = decimal.Parse(jaFeeDetail[i]["pric"].ToString());
+                    decimal sumamt = decimal.Parse(jaFeeDetail[i]["det_item_fee_sumamt"].ToString());
+                    sumFee = sumFee + sumamt;
+
+                    JObject joTmp = new JObject();
+                    joTmp.Add("feedetlSn", jaFeeDetail[i]["feedetl_sn"]);//费用明细流水号
+                    //joTmp.Add("mdtrtId", Global.pat.mdtrtID);//医保就诊ID
+                    //joTmp.Add("psnNo", jaFeeDetail[i]["psnNo"]);//人员编号
+                    chrgBchno = jaFeeDetail[i]["chrg_bchno"].ToString();
+                    joTmp.Add("chrgBchno", jaFeeDetail[i]["chrg_bchno"]);//收费批次号
+                    joTmp.Add("diseCodg", "");//病种编码
+                    joTmp.Add("rxno", jaFeeDetail[i]["rxno"]);//处方号
+                    joTmp.Add("rxCircFlag", jaFeeDetail[i]["rx_circ_flag"]);//外购处方标志
+                    joTmp.Add("feeOcurTime", jaFeeDetail[i]["fee_ocur_time"]);//费用发生时间
+                    joTmp.Add("medListCodg", jaFeeDetail[i]["med_list_codg"]);//医疗目录编码
+                    joTmp.Add("medinsListCodg", jaFeeDetail[i]["medins_list_codg"]);//医药机构目录编码
+                    joTmp.Add("detItemFeeSumamt", sumamt.ToString("#0.00"));//明细项目费用总额
+                    joTmp.Add("cnt", cnt.ToString("#0.0000"));//数量
+                    joTmp.Add("pric", pric.ToString("#0.000000"));//单价
+                    joTmp.Add("sinDosDscr", jaFeeDetail[i]["sin_dos_dscr"]);//单次剂量描述
+                    joTmp.Add("usedFrquDscr", jaFeeDetail[i]["used_frqu_dscr"]);//使用频次描述
+                    joTmp.Add("prdDays", jaFeeDetail[i]["prd_days"]);//周期天数
+                    joTmp.Add("medcWayDscr", jaFeeDetail[i]["medc_way_dscr"]);//用药途径描述
+                    joTmp.Add("bilgDeptCodg", jaFeeDetail[i]["bilg_dept_codg"]);//开单科室编码
+                    joTmp.Add("bilgDeptName", jaFeeDetail[i]["bilg_dept_name"]);//开单科室名称
+                    joTmp.Add("bilgDrCodg", jaFeeDetail[i]["bilg_dr_codg"]);//开单医生编码
+                    joTmp.Add("bilgDrName", jaFeeDetail[i]["bilg_dr_name"]);//开单医师姓名
+                    joTmp.Add("acordDeptCodg", jaFeeDetail[i]["acord_dept_codg"]);//受单科室编码
+                    joTmp.Add("acordDeptName", jaFeeDetail[i]["acord_dept_name"]);//受单科室名称
+                    joTmp.Add("ordersDrCode", jaFeeDetail[i]["orders_dr_code"]);//受单医生编码
+                    joTmp.Add("ordersDrName", jaFeeDetail[i]["orders_dr_name"]);//受单医生姓名
+                    joTmp.Add("hospApprFlag", jaFeeDetail[i]["hosp_appr_flag"]);//医院审批标志
+                    joTmp.Add("tcmdrugUsedWay", jaFeeDetail[i]["tcmdrug_used_way"]);//中药使用方式
+                    joTmp.Add("etipFlag", jaFeeDetail[i]["etip_flag"]);//外检标志
+                    joTmp.Add("etipHospCode", jaFeeDetail[i]["etip_hosp_code"]);//外检医院编码
+                    joTmp.Add("dscgTkdrugFlag", jaFeeDetail[i]["dscg_tkdrug_flag"]);//出院带药标志
+                    joTmp.Add("matnFeeFlag", jaFeeDetail[i]["matn_fee_flag"]);//生育费用标志
+                    joTmp.Add("initFeedetlSn", jaFeeDetail[i]["init_feedetl_sn"]);//原费用流水号
+                    joTmp.Add("drordNo", jaFeeDetail[i]["drord_no"]);//医嘱号
+                    joTmp.Add("medType", jaFeeDetail[i]["med_type"]);//医疗类别
+                    joTmp.Add("memo", "");//备注
+                    joTmp.Add("expContent", jaFeeDetail[i]["expContent"]);//扩展字段
+                    joTmp.Add("medListName", jaFeeDetail[i]["medins_list_name"]);//医疗目录名称
+                    joTmp.Add("medListSpc", jaFeeDetail[i]["med_list_spc"]);//医疗目录规格
+                    joTmp.Add("combNo", jaFeeDetail[i]["comb_no"]);//组套编号
+
+                    jaRow.Add(joTmp);
+                }
+
+                jo.Add("medfeeSumamt", sumFee.ToString("#0.00"));
+                jo.Add("chrgBchno", chrgBchno);
+                jo.Add("feedetailList", jaRow);
+                outparam = jo.ToString();
+                return 0;
+
+            }
+            catch (Exception ex)
+            {
+                outparam = "获取费用异常:" + ex.Message;
+                Global.writeLog("GetFee", jo.ToString(), "获取费用异常:" + ex.Message);
+                return -1;
+            }
+        }
+
+        /// <summary>
+        /// 汇总医保返回的结算金额(按照HIS的原则汇总,后期HIS按照这个来进行勾稽关系判断)
+        /// </summary>
+        /// <param name="jo"></param>
+        /// <returns></returns>
+        public int sumInsuRtnSettlInfo(JObject jo, out JObject joSumFee, out string errMsg)
+        {
+            //            医疗费总额是患者在医药机构花费的所有诊疗、药品、耗材、服务设施等项目费用的总和 = 基金支付总额 + 个人负担总金额 + 其他(如医院负担金额);
+            //3、基金支付总额 = 基本医保统筹基金支出(含职工基本医疗保险、居民基本医疗保险)+补充医疗保险基金支出 (含覆盖全体参保人的居民大病保险和大额医疗费用补助、覆盖部分参保人的企业职工大额医疗费用补助和公务员医疗补助等)+医疗救助基金支出 + 其他支出(如伤残人员医疗保障基金支出);
+            //5、个人账户支出中包含账户共济支付金额
+
+            joSumFee = new JObject();
+            errMsg = "";
+            decimal ybAmt, psnAcctAmt, hospAmt, psnCashAmt, medFee;
+            try
+            {
+                ybAmt = 0; psnAcctAmt = 0; hospAmt = 0; psnCashAmt = 0; medFee = 0;
+                ybAmt = MSettl.fundPaySumamt;
+                psnAcctAmt = MSettl.accountPaySumamt;
+                psnCashAmt = MSettl.personCashPay;
+                hospAmt = MSettl.hospitalPartAmount;
+                medFee = MSettl.sumamt;
+
+                joSumFee.Add("sumamt", medFee);
+                joSumFee.Add("ybAmt", ybAmt);
+                joSumFee.Add("psnAcctAmt", psnAcctAmt);
+                joSumFee.Add("hospAmt", hospAmt);
+                joSumFee.Add("psnCashAmt", psnCashAmt);
+
+                if (medFee != (ybAmt + psnAcctAmt + psnCashAmt + hospAmt))
+                {
+                    errMsg = "ybAmt(" + ybAmt.ToString() + ")+" + "psnAcctAmt(" + psnAcctAmt.ToString() + ")+" + "psnCashAmt(" + psnCashAmt.ToString() + ")+" + "hospAmt(" + hospAmt.ToString() + ")" + "!=medFee(" + medFee.ToString() + ")";
+                    return -1;
+                }
+
+                return 0;
+            }
+            catch (Exception ex)
+            {
+                errMsg = ex.Message;
+                return 1;
+            }
+
+        }
+
+        /// <summary>
+        /// 获取结算费用的封装
+        /// </summary>
+        /// <param name="jo"></param>
+        /// <param name="path"></param>
+        /// <returns></returns>
+        private decimal getDecimalFee(JObject jo, string path)
+        {
+            try
+            {
+                string temp = JsonHelper.getDestValue(jo, path);
+                if (temp == "")
+                {
+                    return 0;
+                }
+                else
+                {
+                    return decimal.Parse(temp);
+                }
+            }
+            catch (Exception ex)
+            {
+                Global.writeLog("getFee异常:" + ex.Message);
+                return 0;
+            }
+        }
+
+        #endregion
+
+        #region 结算
+        /// <summary>
+        /// 返回移动支付结算信息给HIS
+        /// </summary>
+        /// <param name="joSetlInpar"></param>
+        /// <param name="joSetlinfo"></param>中心返回的信息
+        /// <param name="outParam"></param>
+        /// <returns></returns>
+        public int returnMPSettlementInfo(JObject joReg, JObject joSettl, out string outParam)
+        {
+            string errMsg;
+            try
+            {
+                JObject joSumFee = new JObject();
+                if (sumInsuRtnSettlInfo(joSettl, out joSumFee, out errMsg) != 0)
+                {
+                    outParam = "返回结算结果给HIS失败,请联系管理员!" + errMsg;
+                    return -1;
+                }
+
+                dynamic joTmp = new JObject();
+                joTmp.settleInfo = joSettl;
+                joTmp.updateUserID = Global.user.ID;
+                joTmp.regInfo = joReg;
+                joTmp.middleSettleFlag = "";
+                joTmp.interfaceDr = Global.inf.interfaceDr;
+                dynamic joHisInfo = new JObject();
+                joHisInfo.admID = MPat.adm_Dr;
+                joHisInfo.billID = MPat.billID;
+                joHisInfo.recordID = MPat.recordID;
+                joTmp.hisInfo = joHisInfo;
+                joTmp.psn_type = MPat.psn_type;
+                joTmp.mobilePayFlag = "Y";
+                joTmp.sumFeeObj = joSumFee;
+                joTmp.mdtrtinfo = MPat.mdtrtID;
+                JObject joRtn = invoker.invokeHISService(JsonHelper.setIrisInpar("05110018", joTmp).ToString(), "返回移动支付结算结果给HIS");
+                if (JsonHelper.parseIrisRtnValue(joRtn, out errMsg) != 0)
+                {
+                    outParam = "返回移动支付结算结果给HIS失败,请联系管理员!" + errMsg;
+                    return -1;
+                }
+                else
+                {
+                    joSumFee.Add("payAuthNo", MPat.payAuthNo);
+                    joSumFee.Add("payOrdId", MPat.payOrdId);
+                    joSumFee.Add("setlLatlnt", MPat.uldLatlnt);
+                    joSumFee.Add("org_no", Global.inf.hospitalNO);
+                    joSumFee.Add("medOrgOrd", MPat.recordID);
+                    joSumFee.Add("mdtrtId", MPat.mdtrtID);
+                    joSumFee.Add("gmt_out_create", MSettl.settlTime.ToString("yyyy-MM-dd HH:mm:ss"));
+                    joRtn["result"] = joSumFee;
+                    outParam = joRtn.ToString();
+                    return 0;
+                }
+            }
+            catch (Exception ex)
+            {
+                outParam = "返回移动支付结算结果给HIS出现异常:!" + ex.Message;
+                return -1;
+            }
+
+        }
+
+        //查询结算信息
+        public int QuerySettleInfo(out string errMsg)
+        {
+            errMsg = "";
+            try
+            {
+                string sqlStr = "SELECT * FROM BS_MedInsuSettlement WHERE Hospital_Dr=  " + Global.inf.hospitalDr;
+                sqlStr = sqlStr + " and AdmType = 3 and Adm_Dr= " + MPat.adm_Dr + " and SettlementID= '" + MPat.payOrdId + "'";
+                JObject joSqlstr = new JObject();
+                joSqlstr.Add("sqlStr", sqlStr);
+                JObject joRtn = mIS.DynamicQuerySettlInfo(joSqlstr);
+                if (JsonHelper.parseIrisRtnValue(joRtn, out errMsg) != 0)
+                {
+                    return -1;
+                }
+                else
+                {
+                    errMsg = joRtn.ToString();
+                    return 0;
+                }
+            }
+            catch (Exception ex)
+            {
+                errMsg = ex.Message;
+                return -1;
+            }
+        }
+        #endregion
+
+        #region 存入MI
+        /// <summary>
+        /// 插入患者该次就诊参保信息
+        /// </summary>
+        /// <param name="joBaseInfo"></param>
+        /// <param name="joInsuInfo"></param>
+        /// <param name="joIdetInfo"></param>
+        /// <param name="outParam"></param>
+        /// <returns></returns>
+        private int insertPatCurInsuInfo(out string outParam)
+        {
+            JObject joTmp = new JObject();
+            string errMsg = "";
+            try
+            {
+                joTmp.Add("HospitalDr", Global.inf.hospitalDr);
+                joTmp.Add("InterfaceDr", Global.inf.interfaceDr);
+                joTmp.Add("AdmID", MPat.adm_Dr);
+                joTmp.Add("PatientName", MPat.name);
+                joTmp.Add("PersonalNO", MPat.psn_no);
+                joTmp.Add("MdtrtID", MPat.mdtrtID);
+                joTmp.Add("PsnCertType", "");
+                joTmp.Add("PsnCertNO", MPat.certNO);
+                joTmp.Add("Gend", MPat.gend);
+                joTmp.Add("Naty", "");
+                joTmp.Add("Brdy", MPat.brdy);
+                joTmp.Add("Age", MPat.age);
+                joTmp.Add("Balc", MPat.balc);
+                joTmp.Add("Insutype", MPat.insuType);
+                joTmp.Add("PsnType", MPat.psn_type);
+                joTmp.Add("PsnInsuStas", "");
+                joTmp.Add("PsnInsuDate", "");
+                joTmp.Add("PausInsuDate", "");
+                joTmp.Add("Cvlservflag", "");
+                joTmp.Add("insuplcAdmdvs", MPat.insuplc_admdvs);
+                joTmp.Add("EmpName", MPat.emp_name);
+                joTmp.Add("PsnIdettype", "");
+                joTmp.Add("PsnTypeLv", "");
+                joTmp.Add("IdetBegntime", "");
+                joTmp.Add("IdetEndtime", "");
+                if (string.IsNullOrEmpty(Global.user.ID)) Global.user.ID = "0";
+                joTmp.Add("updateUserID", Global.user.ID);
+
+                string serviceCode = "09010070";
+                string inpar = JsonHelper.setIrisInpar(serviceCode, joTmp).ToString();
+                JObject joRtn = invoker.invokeInsuService(inpar, "插入患者该次就诊参保信息");
+
+                if (JsonHelper.parseIrisRtnValue(joRtn, out errMsg) != 0)
+                {
+                    outParam = errMsg;
+                    return -1;
+                }
+                else
+                {
+                    outParam = joRtn.ToString();
+                    return 0;
+                }
+            }
+            catch (Exception ex)
+            {
+                outParam = "医保平台插入患者该次就诊参保信息:" + ex.Message;
+                return -1;
+            }
+
+        }
+
+        /// <summary>
+        /// 插入登记信息
+        /// </summary>
+        /// <param name="joInpar"></param> 48交易入参
+        /// <param name="joOutpar"></param>48交易出参
+        /// <param name="outParam"></param>
+        /// <returns></returns>
+        private int saveRegisterInfo(out string outParam)
+        {
+            //插入云医保平台
+            JObject joTmp = new JObject();
+            string errMsg = "";
+            try
+            {
+                joTmp.Add("HospitalDr", Global.inf.hospitalDr);
+                joTmp.Add("InterfaceDr", Global.inf.interfaceDr);
+                joTmp.Add("AdmDr", MPat.adm_Dr);
+                joTmp.Add("PatientName", MPat.name);
+                joTmp.Add("PersonalNO", MPat.psn_no);
+                joTmp.Add("InsuRegID", MPat.mdtrtID);
+                joTmp.Add("RegDate", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
+                joTmp.Add("InsuType", MPat.insuType);
+                joTmp.Add("CertificateType", MPat.certType);
+                joTmp.Add("CertificateNO", MPat.certNO);
+                joTmp.Add("MedicalType", MPat.medType);
+                joTmp.Add("AttendDoctorNO", MPat.admAttendDoctorNO);
+                joTmp.Add("ChiefPhyDocName", "");
+                joTmp.Add("AdmInDiagDesc", "");
+                joTmp.Add("AdmInDepCode", MPat.AdmInDepCode);
+                joTmp.Add("AdmInDepName", "");
+                joTmp.Add("AdmBed", "");
+                joTmp.Add("MainDiagCode", MPat.admDiagCode);
+                joTmp.Add("MainDiagName", MPat.admDiagName);
+                joTmp.Add("MainConditionDesc", "");
+                joTmp.Add("DiseasecCode", "");
+                joTmp.Add("DiseasecName", "");
+                joTmp.Add("OperationCode", "");
+                joTmp.Add("OperationName", "");
+                joTmp.Add("DiseasecTypeCode", "");
+                joTmp.Add("InsuranceAreaCode", MPat.insuplc_admdvs);
+                joTmp.Add("TreatmentAreaCode", Global.inf.areaCode);
+                joTmp.Add("payOrdId", MPat.payOrdId);
+                joTmp.Add("payToken", MPat.payToken);
+                joTmp.Add("RegState", "1");
+                joTmp.Add("ValidFlag", "1");
+                joTmp.Add("Type", "4");//线上支付门诊
+                joTmp.Add("updateUserID", Global.user.ID);
+                joTmp.Add("msgid", Global.curEvt.msgid);
+                joTmp.Add("OccurTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
+
+                string serviceCode = "09010044";
+                string inpar = JsonHelper.setIrisInpar(serviceCode, joTmp).ToString();
+                JObject joRtn = invoker.invokeInsuService(inpar, "新增门诊登记信息");
+
+                if (JsonHelper.parseIrisRtnValue(joRtn, out errMsg) != 0)
+                {
+                    outParam = joRtn.ToString();
+                    return -1;
+                }
+                else
+                {
+                    outParam = joRtn.ToString();
+                    return 0;
+                }
+            }
+            catch (Exception ex)
+            {
+                outParam = "保存门诊登记信息异常:" + ex.Message;
+                return -1;
+            }
+
+        }
+
+        /// <summary>
+        /// 插入结算信息
+        /// </summary>
+        /// <param name="joSettlement"></param>
+        /// <param name="outParam"></param>
+        /// <returns></returns>
+        public int saveSettlement(out string outParam)
+        {
+            JObject joTmp = new JObject();
+            string errMsg = "";
+            try
+            {
+                JObject joSetlinfo = new JObject();
+                joSetlinfo.Add("HospitalDr", Global.inf.hospitalDr);
+                joSetlinfo.Add("admID", MPat.adm_Dr);
+                joSetlinfo.Add("mdtrt_id", MPat.mdtrtID);
+                joSetlinfo.Add("setl_id", MSettl.settlID);//
+                joSetlinfo.Add("psn_no", MPat.psn_no);
+                joSetlinfo.Add("psn_name", MPat.name);
+                //joSetlinfo.Add("mdtrt_cert_type", JsonHelper.getDestValue(joRtnSetlinfo, "mdtrt_cert_type"));
+                joSetlinfo.Add("certno", MPat.certNO);
+                joSetlinfo.Add("gend", MPat.gend);
+                joSetlinfo.Add("naty", MPat.naty);
+                joSetlinfo.Add("brdy", MPat.brdy);
+                joSetlinfo.Add("age", MPat.age);
+                joSetlinfo.Add("insutype", MPat.insuType);
+                joSetlinfo.Add("psn_type", MPat.psn_type);
+                joSetlinfo.Add("cvlserv_flag", "");
+                joSetlinfo.Add("setl_time", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
+                joSetlinfo.Add("mdtrt_cert_type", MPat.mdtrtcertType);
+                joSetlinfo.Add("med_type", MPat.medType);
+                joSetlinfo.Add("medfee_sumamt", MSettl.sumamt);//总费用
+                joSetlinfo.Add("fulamt_ownpay_amt", MSettl.fundPaySumamt);//全自费金额
+                joSetlinfo.Add("overlmt_selfpay", MSettl.overLimitAmountmt);//超限价自费费用
+                joSetlinfo.Add("preselfpay_amt", MSettl.preSelfPayAmount);//先行自付金额
+                joSetlinfo.Add("inscp_scp_amt", MSettl.inPolicyRangeAmount);//符合政策范围金额
+                joSetlinfo.Add("act_pay_dedc", MSettl.actualPayDeductible);//实际支付起付线
+                joSetlinfo.Add("hifp_pay", MSettl.healthInsurancePay);//基本医疗保险统筹基金支出
+                joSetlinfo.Add("pool_prop_selfpay", MSettl.healthInsuranceRatio);//基本医疗保险统筹基金支付比例
+                joSetlinfo.Add("cvlserv_pay", MSettl.civilserviceAllowancePay);//公务员医疗补助资金支出
+                joSetlinfo.Add("hifes_pay", MSettl.enterpriseSupplementPay);//企业支付  占用 大病报销金额
+                joSetlinfo.Add("hifmi_pay", MSettl.seriousIllnessPay);// 居民大病保险资金支出
+                joSetlinfo.Add("hifob_pay", MSettl.largeExpensesSupplementPay);//职工大额医疗费用补助基金支出
+                joSetlinfo.Add("maf_pay", MSettl.medicalAssistPay);//医疗救助基金支出
+                joSetlinfo.Add("hosp_part_amt", MSettl.hospitalPartAmount);//医院负担金额
+                joSetlinfo.Add("oth_pay", MSettl.otherPay);//其他支出
+                joSetlinfo.Add("fund_pay_sumamt", MSettl.fundPaySumamt);//基金支付总额
+                joSetlinfo.Add("psn_part_amt", MSettl.personPaySumamt);//个人负担总金额
+                joSetlinfo.Add("acct_pay", MSettl.accountMutualAidAmount);//个人账户支出
+                joSetlinfo.Add("psn_cash_pay", MSettl.personCashPay);//个人现金支出
+                joSetlinfo.Add("balc", MSettl.balance);// 余额
+                joSetlinfo.Add("acct_mulaid_pay", "");//个人账户共济支付金额
+                joSetlinfo.Add("medins_setl_id", "");//医药机构结算ID
+                joSetlinfo.Add("clr_optins", MSettl.clearingOrgan);//清算经办机构
+                joSetlinfo.Add("clr_way", MSettl.clearingWay);//清算方式
+                joSetlinfo.Add("clr_type", MSettl.clearingType);//清算类别
+                joSetlinfo.Add("ValidFlag", 1);
+                joSetlinfo.Add("BillType", 1);
+                joSetlinfo.Add("ConfirmFlag", MSettl.confirmFlag);
+                joSetlinfo.Add("msgid", Global.curEvt.msgid);
+                joSetlinfo.Add("admType", "3");
+                joSetlinfo.Add("billID", MPat.billID);
+                joSetlinfo.Add("recordID", MPat.recordID);
+                joSetlinfo.Add("interfaceDr", Global.inf.interfaceDr);
+                joSetlinfo.Add("insuplc_admdvs", MPat.insuplc_admdvs);
+                joSetlinfo.Add("OccurTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
+                joSetlinfo.Add("HospitalizationsDays", MSettl.hospitalizationsDays);
+                joSetlinfo.Add("HospitalizationsTimes", MSettl.hospitalizationsTimes);
+                joSetlinfo.Add("HISAdmTime", MSettl.hisAdmTime);
+                joSetlinfo.Add("HISDischargeTime", MSettl.hisDischargeTime);
+                joSetlinfo.Add("updateUserID", Global.user.ID);
+
+                JObject joRtn = invoker.invokeInsuService(JsonHelper.setIrisInpar("09010051", joSetlinfo).ToString(), "插入结算信息");
+                if (JsonHelper.parseIrisRtnValue(joRtn, out errMsg) != 0)
+                {
+                    outParam = errMsg;
+                    return -1;
+                }
+                else
+                {
+                    outParam = joSetlinfo.ToString();
+                    return 0;
+                }
+            }
+            catch (Exception ex)
+            {
+                outParam = "插入结算信息:" + ex.Message;
+                return -1;
+            }
+        }
+        public int updateSettlement(out string outParam)
+        {
+            JObject joTmp = new JObject();
+            string errMsg = "";
+            try
+            {
+                JObject joSetlinfo = new JObject();
+                joSetlinfo.Add("HospitalDr", Global.inf.hospitalDr);
+                joSetlinfo.Add("AdmDr", MPat.adm_Dr);
+                joSetlinfo.Add("MdtrtID", MPat.mdtrtID);
+                joSetlinfo.Add("SettlementID", MSettl.settlID);//
+                joSetlinfo.Add("PersonnelNO", MPat.psn_no);
+                joSetlinfo.Add("PatientName", MPat.name);
+                //joSetlinfo.Add("CertificateType", JsonHelper.getDestValue(joRtnSetlinfo, "mdtrt_cert_type"));
+                joSetlinfo.Add("CertificateNO", MPat.certNO);
+                joSetlinfo.Add("Gender", MPat.gend);
+                joSetlinfo.Add("Nation", MPat.naty);
+                joSetlinfo.Add("BirthDay", MPat.brdy);
+                joSetlinfo.Add("Age", MPat.age);
+                joSetlinfo.Add("InsuranceType", MPat.insuType);
+                joSetlinfo.Add("PersonType", MPat.psn_type);
+                joSetlinfo.Add("CivilserviceFlag", "");
+                joSetlinfo.Add("SettlementDateTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
+                joSetlinfo.Add("MdtrtCertType", MPat.mdtrtcertType);
+                joSetlinfo.Add("MedicalType", MPat.medType);
+                joSetlinfo.Add("Sumamt", MSettl.sumamt);//总费用
+                joSetlinfo.Add("OwnPayAmount", MSettl.fundPaySumamt);//全自费金额
+                joSetlinfo.Add("OverLimitAmount", MSettl.overLimitAmountmt);//超限价自费费用
+                joSetlinfo.Add("PreSelfPayAmount", MSettl.preSelfPayAmount);//先行自付金额
+                joSetlinfo.Add("InPolicyRangeAmount", MSettl.inPolicyRangeAmount);//符合政策范围金额
+                joSetlinfo.Add("ActualPayDeductible", MSettl.actualPayDeductible);//实际支付起付线
+                joSetlinfo.Add("HealthInsurancePay", MSettl.healthInsurancePay);//基本医疗保险统筹基金支出
+                joSetlinfo.Add("HealthInsuranceRatio", MSettl.healthInsuranceRatio);//基本医疗保险统筹基金支付比例
+                joSetlinfo.Add("CivilserviceAllowancePay", MSettl.civilserviceAllowancePay);//公务员医疗补助资金支出
+                joSetlinfo.Add("EnterpriseSupplementPay", MSettl.enterpriseSupplementPay);//企业支付  
+                joSetlinfo.Add("SeriousIllnessPay", MSettl.seriousIllnessPay);// 居民大病保险资金支出
+                joSetlinfo.Add("LargeExpensesSupplementPay", MSettl.largeExpensesSupplementPay);//职工大额医疗费用补助基金支出
+                joSetlinfo.Add("MedicalAssistPay", MSettl.medicalAssistPay);//医疗救助基金支出
+                joSetlinfo.Add("HospitalPartAmount", MSettl.hospitalPartAmount);//医院负担金额
+                joSetlinfo.Add("OtherPay", MSettl.otherPay);//其他支出
+                joSetlinfo.Add("FundPaySumamt", MSettl.fundPaySumamt);//基金支付总额
+                joSetlinfo.Add("PersonPaySumamt", MSettl.personPaySumamt);//个人负担总金额
+                joSetlinfo.Add("AccountPaySumamt", MSettl.accountMutualAidAmount);//个人账户支出
+                joSetlinfo.Add("PersonCashPay", MSettl.personCashPay);//个人现金支出
+                joSetlinfo.Add("Balance", MSettl.balance);// 余额
+                joSetlinfo.Add("AccountMutualAidAmount", "");//个人账户共济支付金额
+                joSetlinfo.Add("OrganSettlementID", "");//医药机构结算ID
+                joSetlinfo.Add("ClearingOrgan", MSettl.clearingOrgan);//清算经办机构
+                joSetlinfo.Add("ClearingWay", MSettl.clearingWay);//清算方式
+                joSetlinfo.Add("ClearingType", MSettl.clearingType);//清算类别
+                joSetlinfo.Add("ValidFlag", 1);
+                joSetlinfo.Add("BillType", 1);
+                joSetlinfo.Add("ConfirmFlag", MSettl.confirmFlag);
+                joSetlinfo.Add("MSGID", Global.curEvt.msgid);
+                joSetlinfo.Add("AdmType", "3");
+                joSetlinfo.Add("BillID", MPat.billID);
+                joSetlinfo.Add("RecordID", MPat.recordID);
+                joSetlinfo.Add("InterfaceDr", Global.inf.interfaceDr);
+                joSetlinfo.Add("InsuranceAreaCode", MPat.insuplc_admdvs);
+                joSetlinfo.Add("OccurTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
+                joSetlinfo.Add("HospitalizationsDays", MSettl.hospitalizationsDays);
+                joSetlinfo.Add("HospitalizationsTimes", MSettl.hospitalizationsTimes);
+                joSetlinfo.Add("HISAdmTime", MSettl.hisAdmTime);
+                joSetlinfo.Add("HISDischargeTime", MSettl.hisDischargeTime);
+                joSetlinfo.Add("updateUserID", Global.user.ID);
+
+                JObject joRtn = invoker.invokeInsuService(JsonHelper.setIrisInpar("09010080", joSetlinfo).ToString(), "更新结算信息");
+                if (JsonHelper.parseIrisRtnValue(joRtn, out errMsg) != 0)
+                {
+                    outParam = errMsg;
+                    return -1;
+                }
+                else
+                {
+                    outParam = joSetlinfo.ToString();
+                    return 0;
+                }
+            }
+            catch (Exception ex)
+            {
+                outParam = "插入结算信息:" + ex.Message;
+                return -1;
+            }
+        }
+        /// <summary>
+        /// 取消结算
+        /// </summary>
+        /// <param name="outParam"></param>
+        /// <returns></returns>
+        public int cancleSettlement(string newSettlID, out string outParam)
+        {
+            JObject joTmp = new JObject();
+            string errMsg = "";
+            try
+            {
+                joTmp.Add("HospitalDr", Global.inf.hospitalDr);
+                joTmp.Add("InterfaceDr", Global.inf.interfaceDr);
+                joTmp.Add("admID", MPat.adm_Dr);
+                joTmp.Add("mdtrt_id", MPat.mdtrtID);
+                joTmp.Add("setl_id", MPat.settlID);
+                joTmp.Add("new_setl_id", newSettlID);
+                joTmp.Add("updateUserID", Global.user.ID);
+                joTmp.Add("msgid", Global.curEvt.msgid);
+                joTmp.Add("OccurTime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
+                JObject joRtn = invoker.invokeInsuService(JsonHelper.setIrisInpar("09010052", joTmp).ToString(), "取消结算信息");
+
+                if (JsonHelper.parseIrisRtnValue(joRtn, out errMsg) != 0)
+                {
+                    outParam = errMsg;
+                    return -1;
+                }
+                else
+                {
+                    outParam = JsonHelper.setExceptionJson(0, "云医保平台", "取消结算成功").ToString();
+                    return 0;
+                }
+            }
+            catch (Exception ex)
+            {
+                outParam = "取消结算信息:" + ex.Message;
+                return -1;
+            }
+        }
+
+        /// <summary>
+        /// 插入医保费用
+        /// </summary>
+        /// <param name="jaTmp"></param>
+        /// <param name="outParam"></param>
+        /// <returns></returns>
+        public int insertFee(JArray jaTmp, out string outParam)
+        {
+            try
+            {
+                outParam = "";
+                string errMsg;
+                dynamic joTmp = new JObject();
+                joTmp = new JObject();
+                joTmp.code = "09010046";
+                joTmp.HospitalDr = Global.inf.hospitalDr;
+                joTmp.admID = MPat.adm_Dr;
+                joTmp.mdtrt_id = MPat.mdtrtID;
+                joTmp.updateUserID = Global.user.ID;
+                joTmp.Add("params", jaTmp);
+                ;
+                JObject joRtn = invoker.invokeInsuService(joTmp.ToString(), "插入2301明细");
+                if (JsonHelper.parseIrisRtnValue(joRtn, out errMsg) != 0)
+                {
+                    outParam = errMsg;
+                    return -1;
+                }
+                else
+                {
+                    outParam = joRtn.ToString();
+                    return 0;
+                }
+            }
+            catch (Exception ex)
+            {
+                outParam = "insertFee 异常:" + ex.Message;
+                return -1;
+            }
+        }
+        private int saveToMi(out string errMsg)
+        {
+            errMsg = "";
+            try
+            {
+                //存储参保信息
+
+                if (insertPatCurInsuInfo(out errMsg) != 0)
+                {
+                    return -1;
+                }
+                //存储登记信息
+                if (saveRegisterInfo(out errMsg) != 0)
+                {
+                    return -1;
+                }
+                //处理jaFee
+                foreach (var jo in jaFee)
+                {
+                    jo["mdtrt_id"] = MPat.mdtrtID;
+                    jo["psn_no"] = MPat.psn_no;
+                }
+                //存储费用信息
+                if (insertFee(jaFee, out errMsg) != 0)
+                {
+                    return -1;
+                }
+                return 0;
+            }
+            catch (Exception ex)
+            {
+                errMsg = "saveToMi:" + ex.Message;
+                return -1;
+            }
+        }
+        #endregion
+
+        #region  解析中心返回
+        /// <summary>
+        /// 解析银海移动支付返参
+        /// </summary>
+        /// <param name="joRtn"></param>
+        /// <param name="errorMsg"></param>
+        /// <returns></returns>
+        public int ParseCenterRtnValue(JObject joRtn, out string errorMsg)
+        {
+            try
+            {
+                errorMsg = JsonHelper.getDestValue(joRtn, "message");
+                return int.Parse(JsonHelper.getDestValue(joRtn, "code")); //0 成功-1 失败
+            }
+            catch (Exception ex)
+            {
+                errorMsg = "解析银海移动支付返参发生异常:" + ex.Message;
+                return -1;
+            }
+        }
+        #endregion
+    }
+}

+ 529 - 0
Common/GmUtil.cs

@@ -0,0 +1,529 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text;
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.GM;
+using Org.BouncyCastle.Asn1.X9;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Digests;
+using Org.BouncyCastle.Crypto.Engines;
+using Org.BouncyCastle.Crypto.Generators;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Math.EC;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.X509;
+
+namespace PTMedicalInsurance.Common
+{
+	public class GmUtil
+	{
+		public static byte[] SignSm3WithSm2(byte[] msg, byte[] userId, AsymmetricKeyParameter privateKey)
+		{
+			return GmUtil.RsAsn1ToPlainByteArray(GmUtil.SignSm3WithSm2Asn1Rs(msg, userId, privateKey));
+		}
+
+		public static byte[] SignSm3WithSm2Asn1Rs(byte[] msg, byte[] userId, AsymmetricKeyParameter privateKey)
+		{
+			byte[] result;
+			try
+			{
+				ISigner signer = SignerUtilities.GetSigner("SM3withSM2");
+				//signer.Init(true, new ParametersWithRandom(privateKey));
+				signer.Init(true, new ParametersWithID(privateKey, userId));
+				signer.BlockUpdate(msg, 0, msg.Length);
+				result = signer.GenerateSignature();
+			}
+			catch (Exception)
+			{
+				result = null;
+			}
+			return result;
+		}
+
+		public static bool VerifySm3WithSm2(byte[] msg, byte[] userId, byte[] rs, AsymmetricKeyParameter publicKey)
+		{
+			return rs != null && msg != null && userId != null && rs.Length == 64 && GmUtil.VerifySm3WithSm2Asn1Rs(msg, userId, GmUtil.RsPlainByteArrayToAsn1(rs), publicKey);
+		}
+
+		public static bool VerifySm3WithSm2Asn1Rs(byte[] msg, byte[] userId, byte[] sign, AsymmetricKeyParameter publicKey)
+		{
+			bool result;
+			try
+			{
+				ISigner signer = SignerUtilities.GetSigner("SM3withSM2");
+				signer.Init(false, publicKey);
+				signer.BlockUpdate(msg, 0, msg.Length);
+				result = signer.VerifySignature(sign);
+			}
+			catch (Exception)
+			{
+				result = false;
+			}
+			return result;
+		}
+
+		private static byte[] ChangeC1C2C3ToC1C3C2(byte[] c1c2c3)
+		{
+			int num = (GmUtil.x9ECParameters.Curve.FieldSize + 7) / 8 * 2 + 1;
+			byte[] array = new byte[c1c2c3.Length];
+			Buffer.BlockCopy(c1c2c3, 0, array, 0, num);
+			Buffer.BlockCopy(c1c2c3, c1c2c3.Length - 32, array, num, 32);
+			Buffer.BlockCopy(c1c2c3, num, array, num + 32, c1c2c3.Length - num - 32);
+			return array;
+		}
+
+		private static byte[] ChangeC1C3C2ToC1C2C3(byte[] c1c3c2)
+		{
+			int num = (GmUtil.x9ECParameters.Curve.FieldSize + 7) / 8 * 2 + 1;
+			byte[] array = new byte[c1c3c2.Length];
+			Buffer.BlockCopy(c1c3c2, 0, array, 0, num);
+			Buffer.BlockCopy(c1c3c2, num + 32, array, num, c1c3c2.Length - num - 32);
+			Buffer.BlockCopy(c1c3c2, num, array, c1c3c2.Length - 32, 32);
+			return array;
+		}
+
+		public static byte[] Sm2Decrypt(byte[] data, AsymmetricKeyParameter key)
+		{
+			return GmUtil.Sm2DecryptOld(GmUtil.ChangeC1C3C2ToC1C2C3(data), key);
+		}
+
+		public static byte[] Sm2Encrypt(byte[] data, AsymmetricKeyParameter key)
+		{
+			return GmUtil.ChangeC1C2C3ToC1C3C2(GmUtil.Sm2EncryptOld(data, key));
+		}
+
+		public static byte[] Sm2EncryptOld(byte[] data, AsymmetricKeyParameter pubkey)
+		{
+			byte[] result;
+			try
+			{
+				SM2Engine sm2Engine = new SM2Engine();
+				sm2Engine.Init(true, new ParametersWithRandom(pubkey, new SecureRandom()));
+				result = sm2Engine.ProcessBlock(data, 0, data.Length);
+			}
+			catch (Exception)
+			{
+				result = null;
+			}
+			return result;
+		}
+
+		public static byte[] Sm2DecryptOld(byte[] data, AsymmetricKeyParameter key)
+		{
+			byte[] result;
+			try
+			{
+				SM2Engine sm2Engine = new SM2Engine();
+				sm2Engine.Init(false, key);
+				result = sm2Engine.ProcessBlock(data, 0, data.Length);
+			}
+			catch (Exception)
+			{
+				result = null;
+			}
+			return result;
+		}
+
+		public static byte[] Sm3(byte[] bytes)
+		{
+			byte[] result;
+			try
+			{
+				SM3Digest sm3Digest = new SM3Digest();
+				sm3Digest.BlockUpdate(bytes, 0, bytes.Length);
+				result = DigestUtilities.DoFinal(sm3Digest);
+			}
+			catch (Exception)
+			{
+				result = null;
+			}
+			return result;
+		}
+
+		private static byte[] BigIntToFixexLengthBytes(BigInteger rOrS)
+		{
+			byte[] array = rOrS.ToByteArray();
+			if (array.Length == 32)
+			{
+				return array;
+			}
+			if (array.Length == 33 && array[0] == 0)
+			{
+				return Arrays.CopyOfRange(array, 1, 33);
+			}
+			if (array.Length < 32)
+			{
+				byte[] array2 = new byte[32];
+				Arrays.Fill(array2, 0);
+				Buffer.BlockCopy(array, 0, array2, 32 - array.Length, array.Length);
+				return array2;
+			}
+			throw new ArgumentException("err rs: " + Hex.ToHexString(array));
+		}
+
+		private static byte[] RsAsn1ToPlainByteArray(byte[] rsDer)
+		{
+			Asn1Sequence instance = Asn1Sequence.GetInstance(rsDer);
+			byte[] array = GmUtil.BigIntToFixexLengthBytes(DerInteger.GetInstance(instance[0]).Value);
+			byte[] array2 = GmUtil.BigIntToFixexLengthBytes(DerInteger.GetInstance(instance[1]).Value);
+			byte[] array3 = new byte[64];
+			Buffer.BlockCopy(array, 0, array3, 0, array.Length);
+			Buffer.BlockCopy(array2, 0, array3, 32, array2.Length);
+			return array3;
+		}
+
+		private static byte[] RsPlainByteArrayToAsn1(byte[] sign)
+		{
+			if (sign.Length != 64)
+			{
+				throw new ArgumentException("err rs. ");
+			}
+			BigInteger value = new BigInteger(1, Arrays.CopyOfRange(sign, 0, 32));
+			BigInteger value2 = new BigInteger(1, Arrays.CopyOfRange(sign, 32, 64));
+			Asn1EncodableVector asn1EncodableVector = new Asn1EncodableVector();
+			asn1EncodableVector.Add(new DerInteger(value));
+			asn1EncodableVector.Add(new DerInteger(value2));
+			byte[] result;
+			try
+			{
+				result = new DerSequence(asn1EncodableVector).GetEncoded("DER");
+			}
+			catch (IOException)
+			{
+				result = null;
+			}
+			return result;
+		}
+
+		public static AsymmetricCipherKeyPair GenerateKeyPair()
+		{
+			AsymmetricCipherKeyPair result;
+			try
+			{
+				ECKeyPairGenerator eckeyPairGenerator = new ECKeyPairGenerator();
+				eckeyPairGenerator.Init(new ECKeyGenerationParameters(GmUtil.ecDomainParameters, new SecureRandom()));
+				result = eckeyPairGenerator.GenerateKeyPair();
+			}
+			catch (Exception)
+			{
+				result = null;
+			}
+			return result;
+		}
+
+		public static ECPrivateKeyParameters GetPrivatekeyFromD(BigInteger d)
+		{
+			return new ECPrivateKeyParameters(d, GmUtil.ecDomainParameters);
+		}
+
+		public static ECPublicKeyParameters GetPublickeyFromXY(byte[] pubkey)
+		{
+			ECPoint q = GMNamedCurves.GetByName("SM2P256V1").Curve.DecodePoint(pubkey);
+			ECDomainParameters parameters = new ECDomainParameters(GmUtil.x9ECParameters.Curve, GmUtil.x9ECParameters.G, GmUtil.x9ECParameters.N);
+			return new ECPublicKeyParameters(q, parameters);
+		}
+
+		public static ECPublicKeyParameters GetPublickeyFromXY(BigInteger x, BigInteger y)
+		{
+			return new ECPublicKeyParameters(GmUtil.x9ECParameters.Curve.CreatePoint(x, y), GmUtil.ecDomainParameters);
+		}
+
+		public static AsymmetricKeyParameter GetPublickeyFromX509File(FileInfo file)
+		{
+			FileStream fileStream = null;
+			try
+			{
+				fileStream = new FileStream(file.FullName, FileMode.Open, FileAccess.Read);
+				return new X509CertificateParser().ReadCertificate(fileStream).GetPublicKey();
+			}
+			catch (Exception)
+			{
+			}
+			finally
+			{
+				if (fileStream != null)
+				{
+					fileStream.Close();
+				}
+			}
+			return null;
+		}
+
+		private static byte[] ToByteArray(int i)
+		{
+			return new byte[]
+			{
+				(byte)(i >> 24),
+				(byte)((i & 16777215) >> 16),
+				(byte)((i & 65535) >> 8),
+				(byte)(i & 255)
+			};
+		}
+
+		private static byte[] Join(params byte[][] byteArrays)
+		{
+			List<byte> list = new List<byte>();
+			for (int i = 0; i < byteArrays.Length; i++)
+			{
+				list.AddRange(byteArrays[i]);
+			}
+			return list.ToArray();
+		}
+
+		private static byte[] KDF(byte[] Z, int klen)
+		{
+			int num = 1;
+			int num2 = (int)Math.Ceiling((double)klen * 1.0 / 32.0);
+			List<byte> list = new List<byte>();
+			try
+			{
+				for (int i = 1; i < num2; i++)
+				{
+					list.AddRange(GmUtil.Sm3(GmUtil.Join(new byte[][]
+					{
+						Z,
+						GmUtil.ToByteArray(num)
+					})));
+					num++;
+				}
+				byte[] array = GmUtil.Sm3(GmUtil.Join(new byte[][]
+				{
+					Z,
+					GmUtil.ToByteArray(num)
+				}));
+				if (klen % 32 == 0)
+				{
+					list.AddRange(array);
+				}
+				else
+				{
+					list.AddRange(Arrays.CopyOfRange(array, 0, klen % 32));
+				}
+				return list.ToArray();
+			}
+			catch (Exception)
+			{
+			}
+			return null;
+		}
+
+		public static byte[] Sm4DecryptCBC(byte[] keyBytes, byte[] cipher, byte[] iv, string algo)
+		{
+			if (keyBytes.Length != 16)
+			{
+				throw new ArgumentException("err key length");
+			}
+			if (cipher.Length % 16 != 0)
+			{
+				throw new ArgumentException("err data length");
+			}
+			byte[] result;
+			try
+			{
+				KeyParameter parameters = ParameterUtilities.CreateKeyParameter("SM4", keyBytes);
+				IBufferedCipher cipher2 = CipherUtilities.GetCipher(algo);
+				if (iv == null)
+				{
+					iv = GmUtil.ZeroIv(algo);
+				}
+				cipher2.Init(false, new ParametersWithIV(parameters, iv));
+				result = cipher2.DoFinal(cipher);
+			}
+			catch (Exception)
+			{
+				result = null;
+			}
+			return result;
+		}
+
+		public static byte[] Sm4EncryptCBC(byte[] keyBytes, byte[] plain, byte[] iv, string algo)
+		{
+			if (keyBytes.Length != 16)
+			{
+				throw new ArgumentException("err key length");
+			}
+			if (plain.Length % 16 != 0)
+			{
+				throw new ArgumentException("err data length");
+			}
+			byte[] result;
+			try
+			{
+				KeyParameter parameters = ParameterUtilities.CreateKeyParameter("SM4", keyBytes);
+				IBufferedCipher cipher = CipherUtilities.GetCipher(algo);
+				if (iv == null)
+				{
+					iv = GmUtil.ZeroIv(algo);
+				}
+				cipher.Init(true, new ParametersWithIV(parameters, iv));
+				result = cipher.DoFinal(plain);
+			}
+			catch (Exception)
+			{
+				result = null;
+			}
+			return result;
+		}
+
+		public static byte[] Sm4EncryptECB(byte[] keyBytes, byte[] plain, string algo)
+		{
+			if (keyBytes.Length != 16)
+			{
+				throw new ArgumentException("err key length");
+			}
+			byte[] result;
+			try
+			{
+				KeyParameter parameters = ParameterUtilities.CreateKeyParameter("SM4", keyBytes);
+				IBufferedCipher cipher = CipherUtilities.GetCipher(algo);
+				cipher.Init(true, parameters);
+				result = cipher.DoFinal(plain);
+			}
+			catch (Exception)
+			{
+				result = null;
+			}
+			return result;
+		}
+
+		public static byte[] Sm4DecryptECB(byte[] keyBytes, byte[] cipher, string algo)
+		{
+			if (cipher.Length % 16 != 0)
+			{
+				throw new ArgumentException("err data length");
+			}
+			byte[] result;
+			try
+			{
+				KeyParameter parameters = ParameterUtilities.CreateKeyParameter("SM4", keyBytes);
+				IBufferedCipher cipher2 = CipherUtilities.GetCipher(algo);
+				cipher2.Init(false, parameters);
+				result = cipher2.DoFinal(cipher);
+			}
+			catch (Exception)
+			{
+				result = null;
+			}
+			return result;
+		}
+
+		public static GmUtil.Sm2Cert readSm2File(byte[] pem, string pwd)
+		{
+			GmUtil.Sm2Cert sm2Cert = new GmUtil.Sm2Cert();
+			GmUtil.Sm2Cert result;
+			try
+			{
+				Asn1Sequence asn1Sequence = (Asn1Sequence)Asn1Object.FromByteArray(pem);
+				Asn1Sequence asn1Sequence2 = (Asn1Sequence)asn1Sequence[1];
+				Asn1Sequence asn1Sequence3 = (Asn1Sequence)asn1Sequence[2];
+				Asn1OctetString asn1OctetString = (Asn1OctetString)asn1Sequence2[2];
+				byte[] data = GmUtil.KDF(Encoding.UTF8.GetBytes(pwd), 32);
+				byte[] bytes = GmUtil.Sm4DecryptCBC(Arrays.CopyOfRange(data, 16, 32), asn1OctetString.GetOctets(), Arrays.CopyOfRange(data, 0, 16), "SM4/CBC/PKCS7Padding");
+				sm2Cert.privateKey = GmUtil.GetPrivatekeyFromD(new BigInteger(1, bytes));
+				Asn1OctetString asn1OctetString2 = (Asn1OctetString)asn1Sequence3[1];
+				X509Certificate x509Certificate = new X509CertificateParser().ReadCertificate(asn1OctetString2.GetOctets());
+				sm2Cert.publicKey = x509Certificate.GetPublicKey();
+				sm2Cert.certId = x509Certificate.SerialNumber.ToString(10);
+				result = sm2Cert;
+			}
+			catch (Exception)
+			{
+				result = null;
+			}
+			return result;
+		}
+
+		public static GmUtil.Sm2Cert ReadSm2X509Cert(byte[] cert)
+		{
+			GmUtil.Sm2Cert sm2Cert = new GmUtil.Sm2Cert();
+			GmUtil.Sm2Cert result;
+			try
+			{
+				X509Certificate x509Certificate = new X509CertificateParser().ReadCertificate(cert);
+				sm2Cert.publicKey = x509Certificate.GetPublicKey();
+				sm2Cert.certId = x509Certificate.SerialNumber.ToString(10);
+				result = sm2Cert;
+			}
+			catch (Exception)
+			{
+				result = null;
+			}
+			return result;
+		}
+
+		public static byte[] ZeroIv(string algo)
+		{
+			byte[] result;
+			try
+			{
+				byte[] array = new byte[CipherUtilities.GetCipher(algo).GetBlockSize()];
+				Arrays.Fill(array, 0);
+				result = array;
+			}
+			catch (Exception)
+			{
+				result = null;
+			}
+			return result;
+		}
+
+		public static void Main2(string[] s)
+		{
+			foreach (object obj in GMNamedCurves.Names)
+			{
+				string text = (string)obj;
+			}
+			AsymmetricCipherKeyPair asymmetricCipherKeyPair = GmUtil.GenerateKeyPair();
+			byte[] bytes = Encoding.UTF8.GetBytes("message digest");
+			byte[] bytes2 = Encoding.UTF8.GetBytes("userId");
+			GmUtil.SignSm3WithSm2(bytes, bytes2, asymmetricCipherKeyPair.Private);
+			GmUtil.GetPrivatekeyFromD(new BigInteger("097b5230ef27c7df0fa768289d13ad4e8a96266f0fcb8de40d5942af4293a54a", 16));
+			GmUtil.GetPublickeyFromX509File(new FileInfo("d:/certs/69629141652.cer"));
+			GmUtil.GetPublickeyFromXY(new BigInteger("59cf9940ea0809a97b1cbffbb3e9d96d0fe842c1335418280bfc51dd4e08a5d4", 16), new BigInteger("9a7f77c578644050e09a9adc4245d1e6eba97554bc8ffd4fe15a78f37f891ff8", 16));
+			AsymmetricCipherKeyPair asymmetricCipherKeyPair2 = GmUtil.GenerateKeyPair();
+			AsymmetricKeyParameter @public = asymmetricCipherKeyPair2.Public;
+			AsymmetricKeyParameter @private = asymmetricCipherKeyPair2.Private;
+			byte[] array = GmUtil.Sm2Encrypt(Encoding.UTF8.GetBytes("s"), @public);
+			array = GmUtil.Sm2Decrypt(array, @private);
+			byte[] plain = Hex.Decode("0123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba9876543210");
+			byte[] keyBytes = Hex.Decode("0123456789abcdeffedcba9876543210");
+			Hex.Decode("595298c7c6fd271f0402f804c33d3f66");
+			array = GmUtil.Sm4EncryptECB(keyBytes, plain, "SM4/ECB/NoPadding");
+			array = GmUtil.Sm4DecryptECB(keyBytes, array, "SM4/ECB/NoPadding");
+			array = Convert.FromBase64String("MIIDHQIBATBHBgoqgRzPVQYBBAIBBgcqgRzPVQFoBDDW5/I9kZhObxXE9Vh1CzHdZhIhxn+3byBU\nUrzmGRKbDRMgI3hJKdvpqWkM5G4LNcIwggLNBgoqgRzPVQYBBAIBBIICvTCCArkwggJdoAMCAQIC\nBRA2QSlgMAwGCCqBHM9VAYN1BQAwXDELMAkGA1UEBhMCQ04xMDAuBgNVBAoMJ0NoaW5hIEZpbmFu\nY2lhbCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEbMBkGA1UEAwwSQ0ZDQSBURVNUIFNNMiBPQ0Ex\nMB4XDTE4MTEyNjEwMTQxNVoXDTIwMTEyNjEwMTQxNVowcjELMAkGA1UEBhMCY24xEjAQBgNVBAoM\nCUNGQ0EgT0NBMTEOMAwGA1UECwwFQ1VQUkExFDASBgNVBAsMC0VudGVycHJpc2VzMSkwJwYDVQQD\nDCAwNDFAWnRlc3RAMDAwMTAwMDA6U0lHTkAwMDAwMDAwMTBZMBMGByqGSM49AgEGCCqBHM9VAYIt\nA0IABDRNKhvnjaMUShsM4MJ330WhyOwpZEHoAGfqxFGX+rcL9x069dyrmiF3+2ezwSNh1/6YqfFZ\nX9koM9zE5RG4USmjgfMwgfAwHwYDVR0jBBgwFoAUa/4Y2o9COqa4bbMuiIM6NKLBMOEwSAYDVR0g\nBEEwPzA9BghggRyG7yoBATAxMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmNmY2EuY29tLmNuL3Vz\nL3VzLTE0Lmh0bTA4BgNVHR8EMTAvMC2gK6AphidodHRwOi8vdWNybC5jZmNhLmNvbS5jbi9TTTIv\nY3JsNDI4NS5jcmwwCwYDVR0PBAQDAgPoMB0GA1UdDgQWBBREhx9VlDdMIdIbhAxKnGhPx8FcHDAd\nBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwDAYIKoEcz1UBg3UFAANIADBFAiEAgWvQi3h6\niW4jgF4huuXfhWInJmTTYr2EIAdG8V4M8fYCIBixygdmfPL9szcK2pzCYmIb6CBzo5SMv50Odycc\nVfY6");
+			string pwd = "cfca1234";
+			GmUtil.Sm2Cert sm2Cert = GmUtil.readSm2File(array, pwd);
+			array = GmUtil.Sm2Encrypt(Encoding.UTF8.GetBytes("s"), (ECPublicKeyParameters)sm2Cert.publicKey);
+			array = GmUtil.Sm2Decrypt(array, (ECPrivateKeyParameters)sm2Cert.privateKey);
+			byte[] bytes3 = Encoding.UTF8.GetBytes("message digest");
+			bytes2 = Encoding.UTF8.GetBytes("userId");
+			GmUtil.SignSm3WithSm2(bytes3, bytes2, (ECPrivateKeyParameters)sm2Cert.privateKey);
+		}
+
+		private static X9ECParameters x9ECParameters = GMNamedCurves.GetByName("sm2p256v1");
+
+		private static ECDomainParameters ecDomainParameters = new ECDomainParameters(GmUtil.x9ECParameters.Curve, GmUtil.x9ECParameters.G, GmUtil.x9ECParameters.N);
+
+
+		public const string SM4_ECB_NOPADDING = "SM4/ECB/NoPadding";
+
+		public const string SM4_ECB_PKCS7PADDING = "SM4/ECB/PKCS7Padding";
+
+		public const string SM4_CBC_NOPADDING = "SM4/CBC/NoPadding";
+
+		public const string SM4_CBC_PKCS7PADDING = "SM4/CBC/PKCS7Padding";
+
+		public class Sm2Cert
+		{
+			public AsymmetricKeyParameter privateKey;
+
+			public AsymmetricKeyParameter publicKey;
+
+			public string certId;
+		}
+	}
+}

+ 465 - 0
Common/SMLib/EasyGmUtils.cs

@@ -0,0 +1,465 @@
+/*
+* @Description: 
+* @Author: ylz-lichong
+* @Date: 2022-06-16 17:46:23
+*/
+using System;
+using Org.BouncyCastle.Utilities.Encoders;
+using Org.BouncyCastle.Asn1;
+using Org.BouncyCastle.Asn1.GM;
+using Org.BouncyCastle.Asn1.X9;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Digests;
+using Org.BouncyCastle.Crypto.Engines;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities;
+using System.IO;
+
+namespace GMCrypto.Lib
+{
+    class EasyGmUtils
+    {
+        private static X9ECParameters x9ECParameters = GMNamedCurves.GetByName("sm2p256v1");
+        private static ECDomainParameters ecDomainParameters = new ECDomainParameters(x9ECParameters.Curve, x9ECParameters.G, x9ECParameters.N);
+
+
+        /**
+          *
+          * @param msg
+          * @param userId
+          * @param privateKey
+          * @return r||s,直接拼接byte数组的rs
+          */
+        public static byte[] signSm3WithSm2(byte[] msg, byte[] userId, byte[] privateKeyBytes)
+        {
+            ECPrivateKeyParameters privateKeyParameters=getPrivatekeyFromD(new BigInteger(1, privateKeyBytes));
+            return rsAsn1ToPlainByteArray(signSm3WithSm2Asn1Rs(msg, userId, privateKeyParameters));
+        }
+
+
+        /**
+          * @param msg
+          * @param userId
+          * @param privateKey
+          * @return rs in <b>asn1 format</b>
+          */
+        public static byte[] signSm3WithSm2Asn1Rs(byte[] msg, byte[] userId, AsymmetricKeyParameter privateKey)
+        {
+            try
+            {
+                ISigner signer = SignerUtilities.InitSigner("SM3withSM2", true, privateKey, new SecureRandom());
+                signer.BlockUpdate(msg, 0, msg.Length);
+                byte[] sig = signer.GenerateSignature();
+                return sig;
+            }
+            catch (Exception e)
+            {
+                //log.Error("SignSm3WithSm2Asn1Rs error: " + e.Message, e);
+                return null;
+            }
+        }
+
+
+        /**
+      *
+      * @param msg
+      * @param userId
+      * @param rs r||s,直接拼接byte数组的rs
+      * @param publicKey
+      * @return
+      */
+        public static bool verifySm3WithSm2(byte[] msg, byte[] userId, byte[] rs, byte[] publicKeyBytes)
+        {
+            if (rs == null || msg == null || userId == null) return false;
+            if (rs.Length != RS_LEN * 2) return false;
+
+            if (publicKeyBytes.Length != 64 && publicKeyBytes.Length != 65) throw new ArgumentException("err key length");
+            BigInteger x, y;
+            if (publicKeyBytes.Length > 64)
+            {
+                x = fromUnsignedByteArray(publicKeyBytes, 1, 32);
+                y = fromUnsignedByteArray(publicKeyBytes, 33, 32);
+            }
+            else
+            {
+                x = fromUnsignedByteArray(publicKeyBytes, 0, 32);
+                y = fromUnsignedByteArray(publicKeyBytes, 32, 32);
+            }
+            ECPublicKeyParameters publicKey = getPublickeyFromXY(x, y);
+            return verifySm3WithSm2Asn1Rs(msg, userId, rsPlainByteArrayToAsn1(rs), publicKey);
+        }
+
+        public static BigInteger fromUnsignedByteArray(byte[] var0, int var1, int var2)
+        {
+            byte[] var3 = var0;
+            if (var1 != 0 || var2 != var0.Length)
+            {
+                var3 = new byte[var2];
+                Array.Copy(var0, var1, var3, 0, var2);
+            }
+
+            return new BigInteger(1, var3);
+        }
+
+        /**
+         *
+         * @param msg
+         * @param userId
+         * @param rs in <b>asn1 format</b>
+         * @param publicKey
+         * @return
+         */
+
+        public static bool verifySm3WithSm2Asn1Rs(byte[] msg, byte[] userId, byte[] sign, AsymmetricKeyParameter publicKey)
+        {
+            try
+            {
+                ISigner signer = SignerUtilities.GetSigner("SM3withSM2");
+                signer.Init(false, publicKey);
+                signer.BlockUpdate(msg, 0, msg.Length);
+                return signer.VerifySignature(sign);
+            }
+            catch (Exception e)
+            {
+                //log.Error("VerifySm3WithSm2Asn1Rs error: " + e.Message, e);
+                return false;
+            }
+        }
+
+
+        /**
+        * bc加解密使用旧标c1||c2||c3,此方法在加密后调用,将结果转化为c1||c3||c2
+        * @param c1c2c3
+        * @return
+        */
+        private static byte[] changeC1C2C3ToC1C3C2(byte[] c1c2c3)
+        {
+            int c1Len = (x9ECParameters.Curve.FieldSize + 7) / 8 * 2 + 1; //sm2p256v1的这个固定65。可看GMNamedCurves、ECCurve代码。
+            const int c3Len = 32; //new SM3Digest().getDigestSize();
+            byte[] result = new byte[c1c2c3.Length];
+            Buffer.BlockCopy(c1c2c3, 0, result, 0, c1Len); //c1
+            Buffer.BlockCopy(c1c2c3, c1c2c3.Length - c3Len, result, c1Len, c3Len); //c3
+            Buffer.BlockCopy(c1c2c3, c1Len, result, c1Len + c3Len, c1c2c3.Length - c1Len - c3Len); //c2
+            return result;
+        }
+
+
+        /**
+         * bc加解密使用旧标c1||c3||c2,此方法在解密前调用,将密文转化为c1||c2||c3再去解密
+         * @param c1c3c2
+         * @return
+         */
+        private static byte[] changeC1C3C2ToC1C2C3(byte[] c1c3c2)
+        {
+            int c1Len = (x9ECParameters.Curve.FieldSize + 7) / 8 * 2 + 1; //sm2p256v1的这个固定65。可看GMNamedCurves、ECCurve代码。
+            const int c3Len = 32; //new SM3Digest().GetDigestSize();
+            byte[] result = new byte[c1c3c2.Length];
+            Buffer.BlockCopy(c1c3c2, 0, result, 0, c1Len); //c1: 0->65
+            Buffer.BlockCopy(c1c3c2, c1Len + c3Len, result, c1Len, c1c3c2.Length - c1Len - c3Len); //c2
+            Buffer.BlockCopy(c1c3c2, c1Len, result, c1c3c2.Length - c3Len, c3Len); //c3
+            return result;
+        }
+
+        /**
+         * c1||c3||c2
+         * @param data
+         * @param key
+         * @return
+         */
+        public static byte[] sm2Decrypt(byte[] data, AsymmetricKeyParameter key)
+        {
+            return sm2DecryptOld(changeC1C3C2ToC1C2C3(data), key);
+        }
+
+        /**
+         * c1||c3||c2
+         * @param data
+         * @param key
+         * @return
+         */
+
+        public static byte[] sm2Encrypt(byte[] data, AsymmetricKeyParameter key)
+        {
+            return changeC1C2C3ToC1C3C2(sm2EncryptOld(data, key));
+        }
+
+        /**
+         * c1||c2||c3
+         * @param data
+         * @param key
+         * @return
+         */
+        public static byte[] sm2EncryptOld(byte[] data, AsymmetricKeyParameter pubkey)
+        {
+            try
+            {
+                SM2Engine sm2Engine = new SM2Engine();
+                sm2Engine.Init(true, new ParametersWithRandom(pubkey, new SecureRandom()));
+                return sm2Engine.ProcessBlock(data, 0, data.Length);
+            }
+            catch (Exception e)
+            {
+                //log.Error("Sm2EncryptOld error: " + e.Message, e);
+                return null;
+            }
+        }
+
+        /**
+         * c1||c2||c3
+         * @param data
+         * @param key
+         * @return
+         */
+        public static byte[] sm2DecryptOld(byte[] data, AsymmetricKeyParameter key)
+        {
+            try
+            {
+                SM2Engine sm2Engine = new SM2Engine();
+                sm2Engine.Init(false, key);
+                return sm2Engine.ProcessBlock(data, 0, data.Length);
+            }
+            catch (Exception e)
+            {
+                //log.Error("Sm2DecryptOld error: " + e.Message, e);
+                return null;
+            }
+        }
+
+        /**
+        * @param bytes
+        * @return
+        */
+        public static byte[] sm3(byte[] bytes)
+        {
+            try
+            {
+                SM3Digest digest = new SM3Digest();
+                digest.BlockUpdate(bytes, 0, bytes.Length);
+                byte[] result = DigestUtilities.DoFinal(digest);
+                return result;
+            }
+            catch (Exception e)
+            {
+                //log.Error("Sm3 error: " + e.Message, e);
+                return null;
+            }
+        }
+
+        private const int RS_LEN = 32;
+
+        private static byte[] bigIntToFixexLengthBytes(BigInteger rOrS)
+        {
+            // for sm2p256v1, n is 00fffffffeffffffffffffffffffffffff7203df6b21c6052b53bbf40939d54123,
+            // r and s are the result of mod n, so they should be less than n and have length<=32
+            byte[] rs = rOrS.ToByteArray();
+            if (rs.Length == RS_LEN) return rs;
+            else if (rs.Length == RS_LEN + 1 && rs[0] == 0) return Arrays.CopyOfRange(rs, 1, RS_LEN + 1);
+            else if (rs.Length < RS_LEN)
+            {
+                byte[] result = new byte[RS_LEN];
+                Arrays.Fill(result, (byte)0);
+                Buffer.BlockCopy(rs, 0, result, RS_LEN - rs.Length, rs.Length);
+                return result;
+            }
+            else
+            {
+                throw new ArgumentException("err rs: " + Hex.ToHexString(rs));
+            }
+        }
+
+        /**
+         * BC的SM3withSM2签名得到的结果的rs是asn1格式的,这个方法转化成直接拼接r||s
+         * @param rsDer rs in asn1 format
+         * @return sign result in plain byte array
+         */
+        private static byte[] rsAsn1ToPlainByteArray(byte[] rsDer)
+        {
+            Asn1Sequence seq = Asn1Sequence.GetInstance(rsDer);
+            byte[] r = bigIntToFixexLengthBytes(DerInteger.GetInstance(seq[0]).Value);
+            byte[] s = bigIntToFixexLengthBytes(DerInteger.GetInstance(seq[1]).Value);
+            byte[] result = new byte[RS_LEN * 2];
+            Buffer.BlockCopy(r, 0, result, 0, r.Length);
+            Buffer.BlockCopy(s, 0, result, RS_LEN, s.Length);
+            return result;
+        }
+
+        /**
+         * BC的SM3withSM2验签需要的rs是asn1格式的,这个方法将直接拼接r||s的字节数组转化成asn1格式
+         * @param sign in plain byte array
+         * @return rs result in asn1 format
+         */
+        private static byte[] rsPlainByteArrayToAsn1(byte[] sign)
+        {
+            if (sign.Length != RS_LEN * 2) throw new ArgumentException("err rs. ");
+            BigInteger r = new BigInteger(1, Arrays.CopyOfRange(sign, 0, RS_LEN));
+            BigInteger s = new BigInteger(1, Arrays.CopyOfRange(sign, RS_LEN, RS_LEN * 2));
+            Asn1EncodableVector v = new Asn1EncodableVector();
+            v.Add(new DerInteger(r));
+            v.Add(new DerInteger(s));
+            try
+            {
+                return new DerSequence(v).GetEncoded("DER");
+            }
+            catch (IOException e)
+            {
+                //log.Error("RsPlainByteArrayToAsn1 error: " + e.Message, e);
+                return null;
+            }
+        }
+
+        public static byte[] sm4DecryptCBC(byte[] keyBytes, byte[] cipher, byte[] iv, String algo)
+        {
+            if (keyBytes.Length != 16) throw new ArgumentException("err key length");
+            if (cipher.Length % 16 != 0) throw new ArgumentException("err data length");
+
+            try
+            {
+                KeyParameter key = ParameterUtilities.CreateKeyParameter("SM4", keyBytes);
+                IBufferedCipher c = CipherUtilities.GetCipher(algo);
+                if (iv == null) iv = zeroIv(algo);
+                c.Init(false, new ParametersWithIV(key, iv));
+                return c.DoFinal(cipher);
+            }
+            catch (Exception e)
+            {
+                //log.Error("Sm4DecryptCBC error: " + e.Message, e);
+                return null;
+            }
+        }
+
+
+        public static byte[] sm4EncryptCBC(byte[] keyBytes, byte[] plain, byte[] iv, String algo)
+        {
+            if (keyBytes.Length != 16) throw new ArgumentException("err key length");
+            if (plain.Length % 16 != 0) throw new ArgumentException("err data length");
+
+            try
+            {
+                KeyParameter key = ParameterUtilities.CreateKeyParameter("SM4", keyBytes);
+                IBufferedCipher c = CipherUtilities.GetCipher(algo);
+                if (iv == null) iv = zeroIv(algo);
+                c.Init(true, new ParametersWithIV(key, iv));
+                return c.DoFinal(plain);
+            }
+            catch (Exception e)
+            {
+                //log.Error("Sm4EncryptCBC error: " + e.Message, e);
+                return null;
+            }
+        }
+
+
+        public static byte[] sm4EncryptECB(byte[] keyBytes, byte[] plain, string algo)
+        {
+            if (keyBytes.Length != 16) throw new ArgumentException("err key length");
+            if (plain.Length % 16 != 0) throw new ArgumentException("err data length");
+
+            try
+            {
+                KeyParameter key = ParameterUtilities.CreateKeyParameter("SM4", keyBytes);
+                IBufferedCipher c = CipherUtilities.GetCipher(algo);
+                c.Init(true, key);
+                return c.DoFinal(plain);
+            }
+            catch (Exception e)
+            {
+                //log.Error("Sm4EncryptECB error: " + e.Message, e);
+                return null;
+            }
+        }
+
+        public static byte[] sm4DecryptECB(byte[] keyBytes, byte[] cipher, string algo)
+        {
+            if (keyBytes.Length != 16) throw new ArgumentException("err key length");
+            if (cipher.Length % 16 != 0) throw new ArgumentException("err data length");
+
+            try
+            {
+                KeyParameter key = ParameterUtilities.CreateKeyParameter("SM4", keyBytes);
+                IBufferedCipher c = CipherUtilities.GetCipher(algo);
+                c.Init(false, key);
+                return c.DoFinal(cipher);
+            }
+            catch (Exception e)
+            {
+                //log.Error("Sm4DecryptECB error: " + e.Message, e);
+                return null;
+            }
+        }
+
+
+        public static ECPrivateKeyParameters getPrivatekeyFromD(BigInteger d)
+        {
+            return new ECPrivateKeyParameters(d, ecDomainParameters);
+        }
+
+        public static ECPublicKeyParameters getPublickeyFromXY(BigInteger x, BigInteger y)
+        {
+            return new ECPublicKeyParameters(x9ECParameters.Curve.CreatePoint(x, y), ecDomainParameters);
+        }
+
+        public static byte[] sm4Encrypt(byte[] keyBytes, byte[] plain)
+        {
+            if (keyBytes.Length != 16) throw new ArgumentException("err key length");
+            //        if (plain.length % 16 != 0) throw new RuntimeException("err data length");
+
+            try
+            {
+                KeyParameter key = ParameterUtilities.CreateKeyParameter("SM4", keyBytes);
+                IBufferedCipher c = CipherUtilities.GetCipher("SM4/ECB/PKCS7Padding");
+                c.Init(true, key);
+
+                return c.DoFinal(plain);
+            }
+            catch (Exception e)
+            {
+                return null;
+            }
+        }
+
+        public static byte[] sm4Decrypt(byte[] keyBytes, byte[] cipher)
+        {
+            //        if (keyBytes.length != 16) throw new RuntimeException("err key length");
+            if (cipher.Length % 16 != 0) throw new ArgumentException("err data length");
+
+            try
+            {
+                KeyParameter key = ParameterUtilities.CreateKeyParameter("SM4", keyBytes);
+                IBufferedCipher c = CipherUtilities.GetCipher("SM4/ECB/PKCS7Padding");
+                c.Init(false, key);
+                return c.DoFinal(cipher);
+
+            }
+            catch (Exception e)
+            {
+                return null;
+            }
+        }
+
+        public const String SM4_ECB_NOPADDING = "SM4/ECB/NoPadding";
+        public const String SM4_CBC_NOPADDING = "SM4/CBC/NoPadding";
+        public const String SM4_CBC_PKCS7PADDING = "SM4/CBC/PKCS7Padding";
+
+        public static byte[] zeroIv(String algo)
+        {
+
+            try
+            {
+                IBufferedCipher cipher = CipherUtilities.GetCipher(algo);
+                int blockSize = cipher.GetBlockSize();
+                byte[] iv = new byte[blockSize];
+                Arrays.Fill(iv, (byte)0);
+                return iv;
+            }
+            catch (Exception e)
+            {
+                //log.Error("ZeroIv error: " + e.Message, e);
+                return null;
+            }
+        }
+
+
+    }
+}

+ 131 - 0
Common/SMLib/SMUtil.cs

@@ -0,0 +1,131 @@
+/*
+* @Description: 
+* @Author: ylz-lichong
+* @Date: 2022-06-16 17:46:23
+*/
+using Org.BouncyCastle.Utilities.Encoders;
+using System;
+using System.Text;
+using Newtonsoft.Json.Linq;
+using Newtonsoft.Json;
+
+namespace GMCrypto.Lib
+{
+    class SMUtil
+    {
+        /**
+        * 加密
+        *
+        * @param data
+        * @param appId
+        * @param appSecret
+        * @return
+        */
+        public static String encrypt(String data, String appId, String appSecret)
+        {
+            //加密流程
+            //用appId加密appSecret获取新秘钥
+            byte[] appSecretEncData = EasyGmUtils.sm4Encrypt(Encoding.UTF8.GetBytes(appId.Substring(0, 16)), Encoding.UTF8.GetBytes(appSecret));
+            //新秘钥串
+            byte[] secKey = Encoding.UTF8.GetBytes(Hex.ToHexString(appSecretEncData).ToUpper().Substring(0, 16));
+            //加密0数据
+            String encryptDataStr = Hex.ToHexString(EasyGmUtils.sm4Encrypt(secKey, Encoding.UTF8.GetBytes(data))).ToUpper();
+            return encryptDataStr;
+        }
+
+        /**
+         * 解密
+         *
+         * @param data
+         * @param appId
+         * @param appSecret
+         * @return
+        */
+        public static String decrypt(String data, String appId, String appSecret)
+        {
+            byte[] appSecretEncDataDecode = EasyGmUtils.sm4Encrypt(Encoding.UTF8.GetBytes(appId.Substring(0, 16)), Encoding.UTF8.GetBytes(appSecret));
+            byte[] secKeyDecode = Encoding.UTF8.GetBytes(Hex.ToHexString(appSecretEncDataDecode).ToUpper().Substring(0, 16));
+            String decryptDataStr = Encoding.UTF8.GetString(EasyGmUtils.sm4Decrypt(secKeyDecode, Hex.Decode(data)));
+            return decryptDataStr;
+        }
+
+        /**
+        * 签名
+        *
+        * @param jsonObject
+        * @param appSecret
+        * @param privateKey
+        * @return
+        */
+        public static String sign(JObject jsonObject, String appSecret, String privateKey)
+        {
+            // 获取签名串
+            byte[] signText = Encoding.UTF8.GetBytes(SignUtil.getSignText(jsonObject, appSecret));
+            byte[] userId = Encoding.UTF8.GetBytes(appSecret);
+            byte[] prvkey = Base64.Decode(privateKey);
+            String responseSign = Base64.ToBase64String(EasyGmUtils.signSm3WithSm2(signText, userId, prvkey));
+            return responseSign;
+        }
+
+
+        /**
+         * 验签
+         *
+         * @param jsonObject
+         * @param appSecret
+         * @param publicKey
+         * @param responseSign
+         * @return
+         */
+        public static Boolean verify(JObject jsonObject, String appSecret, String publicKey, String responseSign)
+        {
+            //验签
+            byte[] msg = Encoding.UTF8.GetBytes(SignUtil.getSignText(jsonObject, appSecret));
+            byte[] userIdDecode = Encoding.UTF8.GetBytes(appSecret);
+            byte[] pubkey = Base64.Decode(publicKey);
+            byte[] signData = Base64.Decode(responseSign);
+            return EasyGmUtils.verifySm3WithSm2(msg, userIdDecode, signData, pubkey);
+        }
+
+
+
+        /**
+        * 签名
+        *
+        * @param jsonObject
+        * @param appSecret
+        * @param privateKey
+        * @return
+        */
+        public static String sign(String jsonString, String appSecret, String privateKey)
+        {
+            JObject jsonObject = (JObject)JObject.Parse(jsonString);
+            // 获取签名串
+            byte[] signText = Encoding.UTF8.GetBytes(SignUtil.getSignText(jsonObject, appSecret));
+            byte[] userId = Encoding.UTF8.GetBytes(appSecret);
+            byte[] prvkey = Base64.Decode(privateKey);
+            String responseSign = Base64.ToBase64String(EasyGmUtils.signSm3WithSm2(signText, userId, prvkey));
+            return responseSign;
+        }
+
+        /**
+         * 验签
+         *
+         * @param jsonObject
+         * @param appSecret
+         * @param publicKey
+         * @param responseSign
+         * @return
+         */
+        public static Boolean verify(String jsonString, String appSecret, String publicKey, String responseSign)
+        {
+            JObject jsonObject = (JObject)JObject.Parse(jsonString);
+            //验签
+            byte[] msg = Encoding.UTF8.GetBytes(SignUtil.getSignText(jsonObject, appSecret));
+            byte[] userIdDecode = Encoding.UTF8.GetBytes(appSecret);
+            byte[] pubkey = Base64.Decode(publicKey);
+            byte[] signData = Base64.Decode(responseSign);
+            return EasyGmUtils.verifySm3WithSm2(msg, userIdDecode, signData, pubkey);
+        }
+    }
+}

+ 308 - 0
Common/SMLib/SignUtil.cs

@@ -0,0 +1,308 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System.Collections;
+
+namespace GMCrypto.Lib
+{
+    class SignUtil
+    {
+        private static List<String> ignoreSign = new List<String>() { "signData", "encData", "extra" };
+
+
+        public static string SortInput(JObject jsonObject)
+        {
+            SortedDictionary<String, String> signMap = new SortedDictionary<String, String>(StringComparer.Ordinal);
+
+            foreach (var entry in jsonObject)
+            {
+                if (!String.IsNullOrEmpty(entry.Value.ToString()) && !ignoreSign.Contains(entry.Key))
+                {
+                    signMap.Add(entry.Key, getValue(entry.Value));
+                }
+            }
+            return JsonConvert.SerializeObject(signMap);
+        }
+
+        public static String getSignText(JObject jsonObject, String appSecret)
+        {
+            SortedDictionary<String, String> signMap = new SortedDictionary<String, String>(StringComparer.Ordinal);
+
+            foreach (var entry in jsonObject)
+            {
+                if (!String.IsNullOrEmpty(entry.Value.ToString()) && !ignoreSign.Contains(entry.Key))
+                {
+                    signMap.Add(entry.Key, getValue(entry.Value));
+                }
+            }
+
+            List<String> list = new List<String>();
+
+            foreach (var entry in signMap)
+            {
+                if (!String.IsNullOrEmpty(getObjString(entry.Value)))
+                {
+                    list.Add((String)entry.Key + "=" + (String)entry.Value + "&");
+                }
+            }
+
+            int size = list.Count();
+            String[] arrayToSort = (String[])list.ToArray();
+            Array.Sort(arrayToSort, new CaseInsensitiveComparer());
+            StringBuilder sb = new StringBuilder();
+
+            for (int i = 0; i < size; ++i)
+            {
+                sb.Append(arrayToSort[i]);
+            }
+
+            String signText = sb.Append("key=").Append(appSecret).ToString();
+            return signText;
+        }
+
+        public static String getObjString(Object obj)
+        {
+            return obj == null ? "" : (String)obj;
+        }
+
+        private static String getValue(Object value)
+        {
+            return value is String ? getObjString(value) : treeJsonParam(value);
+        }
+
+        private static String treeJsonParam(Object value)
+        {
+            String jsonParam = null;
+            if (value is Dictionary<Object, Object>)
+            {
+                SortedDictionary<String, Object> treeNestedMap = new SortedDictionary<String, Object>(StringComparer.Ordinal);
+                Dictionary<Object, Object> nestedMap = (Dictionary<Object, Object>)value;
+
+                foreach (var entry in nestedMap)
+                {
+                    treeNestedMap.Add(entry.Key.ToString(), entry.Value);
+                }
+                jsonParam = JsonConvert.SerializeObject(treeParams(treeNestedMap), Formatting.None);
+            }
+            else if (value is List<Object>)
+            {
+                List<Object> ar = (List<Object>)value;
+                if (ar != null && ar.Count() != 0)
+                    jsonParam = JsonConvert.SerializeObject(treeList(ar), Formatting.None);
+            }
+            else if (value is JObject)
+            {
+                SortedDictionary<String, Object> treeNestedMap = new SortedDictionary<String, Object>(StringComparer.Ordinal);
+                JObject nestedMap = (JObject)value;
+                foreach (var entry in nestedMap)
+                {
+                    treeNestedMap.Add(entry.Key.ToString(), entry.Value);
+                }
+                jsonParam = JsonConvert.SerializeObject(treeParams(treeNestedMap), Formatting.None);
+            }
+            else if (value is JArray)
+            {
+                JArray ar = (JArray)value;
+                if (ar != null && ar.Count() != 0)
+                    jsonParam = JsonConvert.SerializeObject(treeJsonArray(ar), Formatting.None);
+            }
+            else if (value is JValue)
+            {
+                JValue jval = (JValue)value;
+                if (jval != null && !String.IsNullOrEmpty(jval.ToString()))
+                {
+                    if (jval.ToString().ToLower().Trim().Equals("true") || jval.ToString().ToLower().Trim().Equals("false"))
+                        jsonParam = jval.ToString().ToLower().Trim();
+                    else
+                        jsonParam = jval.Value.ToString();
+                }
+
+
+            }
+            else if (value is JProperty)
+            {
+                SortedDictionary<String, Object> treeNestedMap = new SortedDictionary<String, Object>(StringComparer.Ordinal);
+                JProperty nestedMap = (JProperty)value;
+                treeNestedMap.Add(nestedMap.Name, nestedMap.Value);
+                jsonParam = JsonConvert.SerializeObject(treeParams(treeNestedMap), Formatting.None);
+            }
+            else
+            {
+                jsonParam = value.ToString();
+            }
+
+            return jsonParam;
+        }
+
+        private static SortedDictionary<String, Object> treeParams(SortedDictionary<String, Object> param)
+        {
+            if (param == null)
+            {
+                return new SortedDictionary<String, Object>(StringComparer.Ordinal);
+            }
+            else
+            {
+                SortedDictionary<String, Object> treeParam = new SortedDictionary<String, Object>(StringComparer.Ordinal);
+
+                while (true)
+                {
+                    foreach (var entry in param)
+                    {
+
+                        String key = (String)entry.Key;
+                        Object value = entry.Value;
+                        if (value is Dictionary<Object, Object>)
+                        {
+                            SortedDictionary<String, Object> treeNestedMap = new SortedDictionary<String, Object>(StringComparer.Ordinal);
+                            Dictionary<Object, Object> nestedMap = (Dictionary<Object, Object>)value;
+
+                            foreach (var nestedEntry in nestedMap)
+                            {
+                                treeNestedMap.Add(nestedEntry.Key.ToString(), nestedEntry.Value);
+                            }
+
+                            treeParam.Add(key, treeParams(treeNestedMap));
+                        }
+                        else if (value is List<Object>)
+                        {
+                            List<Object> ar = (List<Object>)value;
+                            if (ar != null && ar.Count() != 0)
+                                treeParam.Add(key, treeList(ar));
+                        }
+                        else if (value is JArray)
+                        {
+                            JArray ar = (JArray)value;
+                            if (ar != null && ar.Count() != 0)
+                                treeParam.Add(key, treeJsonArray(ar));
+                        }
+                        else if (value is JObject)
+                        {
+                            SortedDictionary<String, Object> treeNestedMap = new SortedDictionary<String, Object>(StringComparer.Ordinal);
+                            JObject nestedMap = (JObject)value;
+                            foreach (var nestedEntry in nestedMap)
+                            {
+                                treeNestedMap.Add(nestedEntry.Key.ToString(), nestedEntry.Value);
+                            }
+                            treeParam.Add(key, treeParams(treeNestedMap));
+                        }
+                        else if (value is JValue)
+                        {
+                            JValue jval = (JValue)value;
+                            if (jval != null && !String.IsNullOrEmpty(jval.ToString()))
+                            {
+                                if (jval.ToString().ToLower().Trim().Equals("true") || jval.ToString().ToLower().Trim().Equals("false"))
+                                    treeParam.Add(key, jval.ToString().ToLower().Trim());
+                                else
+                                    treeParam.Add(key, jval.ToString());
+                            }
+                        }
+                        else if (value is JProperty)
+                        {
+                            SortedDictionary<String, Object> treeNestedMap = new SortedDictionary<String, Object>(StringComparer.Ordinal);
+                            JProperty nestedMap = (JProperty)value;
+                            treeNestedMap.Add(nestedMap.Name, nestedMap.Value);
+                            treeParam.Add(key, treeParams(treeNestedMap));
+                        }
+                        else if (!"".Equals(value) && value != null)
+                        {
+                            treeParam.Add(key, value.ToString());
+                        }
+                    }
+                    return treeParam;
+                }
+            }
+        }
+
+        private static List<Object> treeList(List<Object> list)
+        {
+            if (list != null && list.Count() != 0)
+            {
+                JArray jsonArray = new JArray();
+                int size = list.Count();
+
+                for (int i = 0; i < size; ++i)
+                {
+                    jsonArray.Add(list[i]);
+                }
+
+                return treeJsonArray(jsonArray);
+            }
+            else
+            {
+                return null;
+            }
+        }
+
+        private static List<Object> treeJsonArray(JArray jarr)
+        {
+            if (jarr != null && jarr.Count() != 0)
+            {
+                List<Object> jsonArray = new List<Object>();
+                int size = jarr.Count();
+
+                for (int i = 0; i < size; ++i)
+                {
+                    Object value = jarr[i];
+                    if (value is List<Object>)
+                    {
+                        List<Object> ar = (List<Object>)value;
+                        if (ar != null && ar.Count() != 0)
+                            jsonArray.Add(treeList(ar));
+                    }
+                    else if (value is JArray)
+                    {
+                        JArray ar = (JArray)value;
+                        if (ar != null && ar.Count() != 0)
+                            jsonArray.Add(treeJsonArray(ar));
+                    }
+                    else if (value is JObject)
+                    {
+                        SortedDictionary<String, Object> treeNestedMap = new SortedDictionary<String, Object>(StringComparer.Ordinal);
+                        JObject nestedMap = (JObject)value;
+                        foreach (var nestedEntry in nestedMap)
+                        {
+                            treeNestedMap.Add(nestedEntry.Key.ToString(), nestedEntry.Value);
+                        }
+                        jsonArray.Add(treeParams(treeNestedMap));
+
+                    }
+                    else if (value is JValue)
+                    {
+                        JValue jval = (JValue)value;
+                        if (jval != null && !String.IsNullOrEmpty(jval.ToString()))
+                        {
+                            if (jval.ToString().ToLower().Trim().Equals("true") || jval.ToString().ToLower().Trim().Equals("false"))
+                                jsonArray.Add(jval.ToString().ToLower().Trim());
+                            else
+                                jsonArray.Add(jval.ToString());
+                        }
+                    }
+                    else if (value is JProperty)
+                    {
+                        SortedDictionary<String, Object> treeNestedMap = new SortedDictionary<String, Object>(StringComparer.Ordinal);
+                        JProperty nestedMap = (JProperty)value;
+                        treeNestedMap.Add(nestedMap.Name, nestedMap.Value);
+                        jsonArray.Add(treeParams(treeNestedMap));
+                    }
+                    else if (!"".Equals(value))
+                    {
+                        jsonArray.Add(value.ToString());
+                    }
+
+                }
+
+                return jsonArray;
+            }
+            else
+            {
+                return null;
+            }
+        }
+
+
+
+    }
+}

+ 83 - 0
Common/SignUtils.cs

@@ -0,0 +1,83 @@
+using System;
+using System.Text;
+using GMCrypto.Lib;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Utilities.Encoders;
+using PTMedicalInsurance.Variables;
+
+namespace PTMedicalInsurance.Common
+{
+    class SignUtils
+    {
+		public static string signSm3WithSm2(string sm4key, string prvkey, string data)
+		{
+			ECPrivateKeyParameters privatekeyFromD = GmUtil.GetPrivatekeyFromD(new BigInteger(Convert.FromBase64String(prvkey)));
+			return Convert.ToBase64String(GmUtil.SignSm3WithSm2(Encoding.UTF8.GetBytes(data), Encoding.UTF8.GetBytes(sm4key), privatekeyFromD));
+		}
+
+		public static bool verifySm3WithSm2(string msg, string sm4key, string signData, string pubKey)
+		{
+			byte[] array = Convert.FromBase64String(pubKey);
+			BitConverter.ToString(array);
+			AsymmetricKeyParameter publickeyFromXY = GmUtil.GetPublickeyFromXY(array);
+			byte[] rs = Convert.FromBase64String(signData);
+			return GmUtil.VerifySm3WithSm2(Encoding.UTF8.GetBytes(msg), Encoding.UTF8.GetBytes(sm4key), rs, publickeyFromXY);
+		}
+
+
+		public static long CurrentTimeStamp(bool isMinseconds = false)
+		{
+			TimeSpan timeSpan = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
+			return Convert.ToInt64(isMinseconds ? timeSpan.TotalMilliseconds : timeSpan.TotalSeconds);
+		}
+
+		public static string encryptMsg(string appId, string appSecret, string prvkey, string data, ref string rtSignPlain)
+		{
+			string ts = Convert.ToString(CurrentTimeStamp());
+
+			JObject jobject = new JObject();
+			jobject.Add("appId", appId);
+			jobject.Add("data", JObject.Parse(data));
+			jobject.Add("encType", "SM4");
+			jobject.Add("signType", "SM2");
+			jobject.Add("timestamp", ts); ;
+			//jobject.Add("version", "2.0.1");
+
+			string signData = SMUtil.sign(jobject, appSecret, prvkey);
+			string encData = SMUtil.encrypt(data, appId, appSecret);
+
+			jobject.Add("encData", encData);
+			jobject.Add("signData", signData);
+			// 删除明文
+			jobject.Remove("data");
+
+			rtSignPlain = signData;
+
+			return jobject.ToString(Formatting.None, null);
+		}
+
+
+		public static string sm4Encrypt(string chnlId, string sm4key, string message)
+		{
+			byte[] bytes = Encoding.UTF8.GetBytes(chnlId.Substring(0, 16));
+			byte[] bytes2 = Encoding.UTF8.GetBytes(sm4key);
+			byte[] bytes3 = Encoding.UTF8.GetBytes(message);
+			string text = Hex.ToHexString(GmUtil.Sm4EncryptECB(bytes, bytes2, "SM4/ECB/PKCS7Padding")).ToUpper();
+			return Hex.ToHexString(GmUtil.Sm4EncryptECB(Encoding.UTF8.GetBytes(text.Substring(0, 16)), bytes3, "SM4/ECB/PKCS7Padding"));
+		}
+
+		public static string sm4Decrypt(string chnlId, string sm4key, string message)
+		{
+			byte[] bytes = Encoding.UTF8.GetBytes(chnlId.Substring(0, 16));
+			byte[] bytes2 = Encoding.UTF8.GetBytes(sm4key);
+			byte[] cipher = Hex.Decode(message);
+			string text = BitConverter.ToString(GmUtil.Sm4EncryptECB(bytes, bytes2, "SM4/ECB/PKCS7Padding"), 0).Replace("-", string.Empty).ToUpper();
+			byte[] bytes3 = GmUtil.Sm4DecryptECB(Encoding.UTF8.GetBytes(text.Substring(0, 16)), cipher, "SM4/ECB/PKCS7Padding");
+			return Encoding.UTF8.GetString(bytes3);
+		}
+	}
+}

+ 48 - 62
Helper/EncryptHelper.cs

@@ -7,25 +7,55 @@ using PTMedicalInsurance.Common;
 using Newtonsoft.Json.Linq;
 //using GMUtilLib;
 using PTMedicalInsurance.Variables;
+using GMCrypto.Lib;
+using Newtonsoft.Json;
 
 namespace PTMedicalInsurance.Helper
 {
     class EncryptHelper
     {
-        //private string ak = "1G94963I20403F60C80A00005FF7A699";
-        //private string sk = "APyE9G1D+C8g3qV3Z6VshXztOa55YJBgwN+P4WqU5n0x";
-        //private string appid = "1G94963HS03V3F60C80A00000DB330D8";
+        //private string appSecret = "1G566663V0033F60C80A0000B26913B4";
+        //private string privateKey = "DsexH970Mz9RAuu9SZtqdz/JwwZtppfS1lzOZvtO/Q==";
+        //private static string appId = "1G566663I0023F60C80A00000A8F1C36";
 
+        //测试
+        private string appSecret = "1H1INA1L90OH3F60C80A00008119D616";   //appSecret 数字密钥sm4
+        private string privateKey = "APCIAgJqh3+AcK/IXL1WJD130i2q+6UblRxQzus3+sVw";     //渠道私密
+        private string appId = "1H1INA1L30OG3F60C80A0000DEE43558";    //渠道ID
+        private string publicKey = "BDMsMM2HPRkaKSl2ynBbCRtJodP8Nh4G5IkEnV+7YHaCplkAZbPMsUlvJpWqQ+Q4sT7611xGSZ1/mPsqgqJ49zs=";            //平台公钥
 
-        private string ak = "1H1INA1L90OH3F60C80A00008119D616";
-        private string sk = "APCIAgJqh3+AcK/IXL1WJD130i2q+6UblRxQzus3+sVw";
-        private string appid = "1H1INA1L30OG3F60C80A0000DEE43558";
-        public string encrypt(string data)
+        //正式
+        //private string ak = "1H62Q1KH205K76430B0A0000BF149773";
+        //private string sk = "YbNObZNMdUgwgLUEyK4ixNSkaCF9OPtCdDth9APWYKU=";
+        //private string appid = "1H62Q1KGP05J76430B0A00007144E257";
+
+        public EncryptHelper()
+        {
+
+        }
+
+        public EncryptHelper(string appId, string appSecret, string publicKey, string privateKey)
+        {
+            this.appId = appId;
+            this.appSecret = appSecret;
+            this.publicKey = publicKey;
+            this.privateKey = privateKey;
+        }
+
+        public string getSignText(string data)
+        {
+            return "";
+            //string ts = DateTime.Now.ToString("yyyyMMddHHmmss");
+            //return SignUtils.getSignText(appid, ak, data,StringUtils.CurrentTimeStamp());
+        }
+        public string encrypt(string data, ref string signText)
         {
             string encryptData = "";
             try
             {
-                //encryptData = GMUtilLib.SignUtil.encryptMsg(appid, ak, sk, data);
+                string strData = JsonConvert.SerializeObject(JObject.Parse(data), Newtonsoft.Json.Formatting.None);
+                encryptData = SignUtils.encryptMsg(appId, appSecret, privateKey, strData, ref signText);
+
                 return encryptData;
             }
             catch (Exception ex)
@@ -35,7 +65,7 @@ namespace PTMedicalInsurance.Helper
             }
             finally
             {
-                Global.writeLog("ak:" + ak +";sk:" + sk + ";appid:" + appid,data,encryptData);
+                //Global.writeLog("ak:" + appSecret + ";sk:" + privateKey + ";appid:" + appId, data, encryptData);
             }
         }
 
@@ -44,7 +74,7 @@ namespace PTMedicalInsurance.Helper
             string encryptData = "";
             try
             {
-                //encryptData = GMUtilLib.SignUtil.signSm3WithSm2(appid, ak, sk, data);
+                encryptData = SignUtils.signSm3WithSm2(appSecret, privateKey, data);
                 return encryptData;
             }
             catch (Exception ex)
@@ -54,69 +84,25 @@ namespace PTMedicalInsurance.Helper
             }
             finally
             {
-                Global.writeLog("ak:" + ak + ";sk:" + sk + ";appid:" + appid, data, encryptData);
+                Global.writeLog("ak:" + appSecret + ";sk:" + privateKey + ";appid:" + appId, data, encryptData);
             }
         }
 
-        public string signWithSM2(JObject obj)
-        {
-            string data = sortKeys(obj);
-            Sm2Crypto crypto = new Sm2Crypto();
-            string publicKey = "", privateKey = "";
-            Sm2Crypto.GetKey(out privateKey, out publicKey);
-
-            crypto.PublicKey = publicKey;
-            crypto.PrivateKey = privateKey;
-
-            crypto.Str = data;
-            return crypto.Encrypt();
-        }
-
-        public string sortKeys(JObject obj) {
-
-            StringBuilder sb = new StringBuilder();
-            Dictionary<string, string> dict = new Dictionary<string, string>();
-            foreach (var p in obj.Properties())
-            {
-                dict.Add(p.Name, p.Value.ToString());
-            }
-            string[] keys = dict.Keys.ToArray();
-            Array.Sort(keys, string.CompareOrdinal);
-            foreach (var k in keys)
-            {
-                if (sb.Length > 1)
-                {
-                    sb.Append("&");
-                }
-                sb.Append(k);
-                sb.Append("=");
-                sb.Append(dict[k]);
-            }
-            return sb.ToString();
-        }
-        public int verify(string data,string encryptData)
+        public bool verify(JObject signDto, string signData)
         {
-            string error ="";
+            string error = "";
             try
             {
-                //if (GMUtilLib.SignUtil.verifySm3WithSm2(data, ak, encryptData, sk))
-                //{
-                //    return 0;
-                //}
-                //else
-                //{
-                //    return -1;
-                //}
-                return 0;
+                return SMUtil.verify(signDto, appSecret, publicKey, signData);
             }
             catch (Exception ex)
             {
                 error = ex.Message;
-                return -1;
+                return false;
             }
             finally
             {
-                Global.writeLog("ak:" + ak + ";sk:" + sk + ";appid:" + appid, data + ";" + encryptData, error);
+                Global.writeLog("ak:" + appSecret + ";sk:" + privateKey + ";appid:" + appId, signDto.ToString() + ";" + signData, error);
             }
         }
 
@@ -125,7 +111,7 @@ namespace PTMedicalInsurance.Helper
             string data = "";
             try
             {
-                //data = GMUtilLib.SignUtil.decryptMsg(ak, sk, encryptData);
+                data = SMUtil.decrypt(encryptData, appId, appSecret);
                 return data;
             }
             catch (Exception ex)
@@ -135,7 +121,7 @@ namespace PTMedicalInsurance.Helper
             }
             finally
             {
-                Global.writeLog("ak:" + ak + ";sk:" + sk + ";appid:" + appid, encryptData, data);
+                Global.writeLog("ak:" + appSecret + ";sk:" + privateKey + ";appid:" + appId, encryptData, data);
             }
         }
     }

+ 102 - 8
Helper/InvokeHelper.cs

@@ -44,6 +44,18 @@ namespace PTMedicalInsurance.Helper
                 Global.inf.uploadURL = ini.ReadValue("CENTER", "upload");
                 Global.inf.downURL = ini.ReadValue("CENTER", "download");
                 Global.inf.ecURL = ini.ReadValue("CENTER", "ecToken");
+                Global.inf.mobilePayURL = ini.ReadValue("CENTER", "mobilePay");
+                Global.inf.ecPrescURL = ini.ReadValue("CENTER", "prescription");
+                // 移动支付及电子处方
+                if (string.IsNullOrEmpty(Global.inf.mobilePayURL))
+                {
+                    Global.inf.mobilePayURL = "http://10.123.185.12:8080";
+                }
+
+                if (string.IsNullOrEmpty(Global.inf.ecPrescURL))
+                {
+                    Global.inf.ecPrescURL = "http://10.123.185.12:8080/epc/api";
+                }
             }
         }
 
@@ -341,17 +353,100 @@ namespace PTMedicalInsurance.Helper
         /// <param name="data"></param>
         /// <returns></returns>
         public JObject invokeMPService(string funNO, string data)
+        {
+            return invokeMPService(funNO, JObject.Parse(data));
+        }
+        public JObject invokeMPService(string funNO, JObject joInput)
         {
             JObject joRtn = new JObject();
             String outPar = "";
             try
             {
-                Global.curEvt.URL = Global.inf.centerURL + funNO;
-                joRtn = invokeCenterService(data);
-                outPar = JsonHelper.Compress(joRtn);
-                return joRtn;
+                string url = "";
+                switch (funNO)
+                {
+                    case "6201":
+                        url = "/org/local/api/hos/uldFeeInfo";
+                        break;
+                    case "6202":
+                        url = "/org/local/api/hos/pay_order";
+                        break;
+                    case "6203":
+                        url = "/org/local/api/hos/refund_Order";
+                        break;
+                    case "6301":
+                        url = "/org/local/api/hos/query_order_info";
+                        break;
+                    case "6401":
+                        url = "/org/local/api/hos/revoke_order";
+                        break;
+                    default:
+                        break;
+                }
+                EncryptHelper encrypt = new EncryptHelper();
+                string data = JsonHelper.setMPCenterInpar(funNO, joInput);
+                // 移动支付地址
+                Global.curEvt.URL = Global.inf.mobilePayURL + url;
+
+                string outputData = "", errMsg = "";
+
+                // 动态调试模式
+                if (Global.curEvt.enabledDebug)
+                {
+                    CenterResult center = new CenterResult();
+                    center.setTradeNo(funNO,data);
+                    if (center.ShowDialog() == DialogResult.OK)
+                    {
+                        outPar = center.returnData;
+                        return JObject.Parse(outPar);
+                    }
+                }
+
+                try
+                {
+                    InvokeRestCenter mobileCenter = new InvokeRestCenter();
+                    int iInt = mobileCenter.Business(data, ref outputData, ref errMsg);
+                    joRtn = JObject.Parse(outputData);
+
+                    Global.writeLog(funNO + "【密文出参】:\r\n" + joRtn.ToString());
+
+                    string encData = JsonHelper.getDestValue(joRtn, "encData");
+                    string signData = JsonHelper.getDestValue(joRtn, "signData");
+                    if (!string.IsNullOrEmpty(encData) && !string.IsNullOrEmpty(signData))
+                    {
+                        joRtn.Remove("encData");
+                        joRtn.Remove("signData");
+                        joRtn.Remove("data");
+                        //解密
+                        string decData = encrypt.decrypt(encData);
+                        // 验签
+                        JsonConvert.DefaultSettings = () => new JsonSerializerSettings
+                        {
+                            FloatParseHandling = FloatParseHandling.Decimal
+                        };
+                        joRtn.Add("data", JToken.FromObject(JsonConvert.DeserializeObject(decData)));
+
+                        bool rtn = encrypt.verify(joRtn, signData);
+                        if (rtn)
+                        {
+                            Global.writeLog(funNO + "【明文出参】:\r\n" + decData);
+
+                            joRtn = JObject.Parse(decData);
+                            joRtn.Add("success", "True");
+                        }
+                        else
+                        {
+                            Global.writeLog("验签失败,请核查!");
+                        }
+                    }
 
-                
+                    return joRtn;
+
+                }
+                finally
+                {
+                    this.saveCenterLog(JsonHelper.Compress(data), joRtn.ToString(), JsonHelper.Compress(data), joRtn.ToString());
+                }
 
             }
             catch (Exception ex)
@@ -365,11 +460,10 @@ namespace PTMedicalInsurance.Helper
             }
             finally
             {
-                Global.writeLog(funNO + "(" + Global.curEvt.URL + ")", JsonHelper.Compress(data), joRtn.ToString());
-                this.saveCenterLog(JsonHelper.Compress(data), joRtn.ToString(), JsonHelper.Compress(data), joRtn.ToString());
+                Global.writeLog(funNO + "(" + Global.curEvt.URL + ")", joInput.ToString(), joRtn.ToString());
+                this.saveCenterLog(joInput.ToString(), joRtn.ToString(), joInput.ToString(), joRtn.ToString());
             }
         }
-
         /// <summary>
         /// 保存中心交易日志到数据库
         /// </summary>

+ 22 - 37
Helper/JsonHelper.cs

@@ -20,6 +20,7 @@ using PTMedicalInsurance.Common;
 using System.IO;
 using PTMedicalInsurance.Variables;
 using Newtonsoft.Json;
+using GMCrypto.Lib;
 
 namespace PTMedicalInsurance.Helper
 {
@@ -252,49 +253,33 @@ namespace PTMedicalInsurance.Helper
         /// <param name="infno"></param>
         /// <param name="input"></param>
         /// <returns></returns>
-        public static string setMPCenterInpar(string infno, string input)
+        public static string setMPCenterInpar(string infno, JObject joInput)
         {
-            dynamic Jo = new JObject();
-            Jo.infno = infno;
-            Global.curEvt.msgid = Global.inf.hospitalNO + DateTime.Now.ToString("yyyyMMddHHmmssffff");
-            Jo.msgid = Global.curEvt.msgid;
+            return setMPCenterInpar(infno, joInput.ToString());
+        }
 
-            if (Global.pat.insuplc_admdvs == "")
-            {
-                Global.pat.insuplc_admdvs = Global.inf.areaCode;
-            }
-            Jo.insuplc_admdvs = Global.pat.insuplc_admdvs;
-
-            Jo.mdtrtarea_admvs = "530100";
-            Global.pat.mdtrtarea_admvs = Jo.mdtrtarea_admvs;
-            Jo.recer_sys_code = "ShenYang";
-            Jo.dev_safe_info = Global.inf.dev_safe_info; //设备编号
-            Jo.cainfo = Global.inf.cainfo;//
-            Jo.signtype = "asn1"; ;
-            Jo.infver = "v1.0";
-            Jo.opter_type = Global.user.type; ;
-            Jo.opter = Global.user.ID; ;
-            Jo.opter_name = Global.user.name; ;
-            Jo.inf_time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
-            Jo.fixmedins_code = Global.inf.hospitalNO;
-            Jo.fixmedins_name = Global.inf.hospitalName;
-            Jo.sign_no = Global.curEvt.signno;
+        /// <summary>
+        /// 移动支付组织中心入参
+        /// </summary>
+        /// <param name="infno"></param>
+        /// <param name="input"></param>
+        /// <returns></returns>
+        public static string setMPCenterInpar(string infno, string txtData)
+        {
+            EncryptHelper encrypt = new EncryptHelper();
 
-            if (input != "")
-            {
-                JObject joInput = (JObject)Newtonsoft.Json.JsonConvert.DeserializeObject(input);
+            string plainText = SignUtil.SortInput(JObject.Parse(txtData));
 
-                Jo.cainfo = "";
-                Jo.Add("input", JObject.FromObject(joInput));
+            Global.writeLog(infno + "【明文入参】:\r\n" + plainText);
 
-            }
-            else
-            {
-                Jo.cainfo = "";
-                Jo.Add("input", "");
-            }
+            string signData = "";
+
+
+            string output = encrypt.encrypt(txtData, ref signData);
+
+            Global.writeLog(infno + "【密文入参】:\r\n" + output);
 
-            return Jo.ToString();
+            return output;
         }
 
         public static string setCenterInpar(string infno, JObject joInput)

+ 33 - 36
InsuBusiness.cs

@@ -430,53 +430,50 @@ namespace PTMedicalInsurance
                     case "M6"://门诊移动支付结算
                         {
                             #region 移动支付
-                            //MobilePay mp = new MobilePay(InParam, out errMsg);
-                            //if (errMsg != "")
-                            //{
-                            //    rtnResult = JsonHelper.setExceptionJson(-1, "Settlement 交易", errMsg).ToString();
-                            //    return rtnResult;
-                            //}
-                            //if (mp.MobilePaySettlement(out outParam) != 0)
-                            //    rtnResult = JsonHelper.setExceptionJson(-1, "Settlement 交易", outParam).ToString();
-                            //else
-                            //    rtnResult = outParam;
-                            //return rtnResult;
+                            MobilePay mp = new MobilePay(InParam, out errMsg);
+                            if (errMsg != "")
+                            {
+                                rtnResult = JsonHelper.setExceptionJson(-1, "Settlement 交易", errMsg).ToString();
+                                return rtnResult;
+                            }
+                            if (mp.MobilePaySettlement(out outParam) != 0)
+                                rtnResult = JsonHelper.setExceptionJson(-1, "Settlement 交易", outParam).ToString();
+                            else
+                                rtnResult = outParam;
+                            return rtnResult;
                             #endregion
-                            break;
                         }
                     case "M6C"://门诊移动支付结算撤销
                         {
                             #region 移动支付取消
-                            //MobilePay mp = new MobilePay(InParam, out errMsg);
-                            //if (errMsg != "")
-                            //{
-                            //    rtnResult = JsonHelper.setExceptionJson(-1, "Settlement 交易", errMsg).ToString();
-                            //    return rtnResult;
-                            //}
-                            //if (mp.MobilePayCancelSettlement(out outParam) != 0)
-                            //    rtnResult = JsonHelper.setExceptionJson(-1, "Settlement 交易", outParam).ToString();
-                            //else
-                            //    rtnResult = outParam;
-                            //return rtnResult;
+                            MobilePay mp = new MobilePay(InParam, out errMsg);
+                            if (errMsg != "")
+                            {
+                                rtnResult = JsonHelper.setExceptionJson(-1, "Settlement 交易", errMsg).ToString();
+                                return rtnResult;
+                            }
+                            if (mp.MobilePayCancelSettlement(out outParam) != 0)
+                                rtnResult = JsonHelper.setExceptionJson(-1, "Settlement 交易", outParam).ToString();
+                            else
+                                rtnResult = outParam;
+                            return rtnResult;
                             #endregion
-                            break;
                         }
                     case "M6Confirm"://门诊移动支付确认
                         {
                             #region 移动支付确认
-                            //MobilePay mp = new MobilePay(InParam, out errMsg);
-                            //if (errMsg != "")
-                            //{
-                            //    rtnResult = JsonHelper.setExceptionJson(-1, "Settlement 交易", errMsg).ToString();
-                            //    return rtnResult;
-                            //}
-                            //if (mp.MobilePayConfirmSettlement(out outParam) != 0)
-                            //    rtnResult = JsonHelper.setExceptionJson(-1, "Settlement 交易", outParam).ToString();
-                            //else
-                            //    rtnResult = outParam;
-                            //return rtnResult;
+                            MobilePay mp = new MobilePay(InParam, out errMsg);
+                            if (errMsg != "")
+                            {
+                                rtnResult = JsonHelper.setExceptionJson(-1, "Settlement 交易", errMsg).ToString();
+                                return rtnResult;
+                            }
+                            if (mp.MobilePayConfirmSettlement(out outParam) != 0)
+                                rtnResult = JsonHelper.setExceptionJson(-1, "Settlement 交易", outParam).ToString();
+                            else
+                                rtnResult = outParam;
+                            return rtnResult;
                             #endregion
-                            break;
                         }
                     case "Z4"://住院预结算
                         {

+ 7 - 0
NanChangMI.csproj

@@ -95,6 +95,7 @@
     <Compile Include="Business\CenterBusiness.cs" />
     <Compile Include="Business\DataImoport.cs" />
     <Compile Include="Business\HisMainBusiness.cs" />
+    <Compile Include="Business\IMobilePay.cs" />
     <Compile Include="Business\Inpatient\IPExitCancelProcess.cs" />
     <Compile Include="Business\Inpatient\IPExitProcess.cs" />
     <Compile Include="Business\Inpatient\IPFeeUploadCancelProcess.cs" />
@@ -111,6 +112,7 @@
     <Compile Include="Business\Local\OtherQueryProcess.cs" />
     <Compile Include="Business\Local\ReadCardProcess.cs" />
     <Compile Include="Business\Local\TestProcess.cs" />
+    <Compile Include="Business\MobilePay.cs" />
     <Compile Include="Business\Other\MedDirDownloadProcess.cs" />
     <Compile Include="Business\Other\SettleBillPrintProcess.cs" />
     <Compile Include="Business\Other\SignInProcess.cs" />
@@ -140,7 +142,12 @@
     <Compile Include="Common\ExPortToExcel.cs" />
     <Compile Include="Common\ExpressionEvaluator.cs" />
     <Compile Include="Common\FastReportScript.cs" />
+    <Compile Include="Common\GmUtil.cs" />
+    <Compile Include="Common\SignUtils.cs" />
     <Compile Include="Common\SMCipher.cs" />
+    <Compile Include="Common\SMLib\EasyGmUtils.cs" />
+    <Compile Include="Common\SMLib\SignUtil.cs" />
+    <Compile Include="Common\SMLib\SMUtil.cs" />
     <Compile Include="Common\WinApi.cs" />
     <Compile Include="Common\WindowWrapper.cs" />
     <Compile Include="Entity\Base\Other\DirectoryDownload.cs" />

+ 6 - 0
Variables/Struct.cs

@@ -41,12 +41,18 @@ namespace PTMedicalInsurance.Variables
         public string uploadURL;
         public string downURL;
         public string cardURL;
+        public string mobilePayURL;
         public string ecURL;
+        public string ecPrescURL;
         public string areaCode;
         public string dllName;
         public string version;
         public string signatureType;
         public string recivedSystem;
+        public string appId;
+        public string privateKey;
+        public string secretKey;
+        public string publicKey;
         public string AK;
         public string SK;
         public string dev_no;