Ejemplo n.º 1
0
        /// <summary>
        /// 投保接口,本接口对 XML 节点名称大小写敏感
        /// </summary>
        /// <param name="requestXML"></param>
        /// <returns></returns>
        public static string Issue(string requestXML)
        {
            /* 请求参数
             * <?xml version="1.0" encoding="utf-16"?>
             * <PurchaseRequestEntity>
             * <InsuranceCode>pd001</InsuranceCode>
             * <username>user001</username>
             * <password>pass001</password>
             * <flightDate>2012-03-15T00:00:00</flightDate>
             * <flightNo>HU3213</flightNo>
             * <customerGender>Male</customerGender>
             * <customerBirth>1982-01-11T00:00:00</customerBirth>
             * <customerIDType>身份证</customerIDType>
             * <customerID>352224198201110013</customerID>
             * <customerName>张山</customerName>
             * <customerPhone>13888888888</customerPhone>
             * </PurchaseRequestEntity>
             * 返回参数
             * <?xml version="1.0" encoding="utf-16"?>
             * <PurchaseResponseEntity>
             * <PolicyNo>PC00013234234</PolicyNo>
             * <SerialNo />
             * <CaseNo />
             * <AgentName>测试代理商</AgentName>
             * <ValidationPhoneNumber />
             * <Trace>
             * <ErrorMsg />
             * <Detail />
             * </Trace>
             * </PurchaseResponseEntity>
             */
            PurchaseRequestEntity  request;
            PurchaseResponseEntity resp;
            string ret;

            try
            {
                request = Common.XmlDeserialize <PurchaseRequestEntity>(requestXML);
            }
            catch (Exception e)
            {
                Common.LogIt(requestXML + Environment.NewLine + e.ToString());
                resp = new PurchaseResponseEntity();
                resp.Trace.ErrorMsg = "服务器异常,请稍后重试!";
                ret = Common.XmlSerialize <PurchaseResponseEntity>(resp);
                return(ret);
            }

            resp = WebServiceClass.Purchase(request, true, true);
            if (string.IsNullOrEmpty(resp.PolicyNo))
            {
                resp.PolicyNo = resp.CaseNo;
            }
            ret = Common.XmlSerialize <PurchaseResponseEntity>(resp);
            return(ret);
        }
Ejemplo n.º 2
0
    public static bool CheckIfSystemFailed(PurchaseResponseEntity response)
    {
        string systemFailInfo = ConfigurationManager.AppSettings["SystemFailInfo"];

        if (!string.IsNullOrEmpty(systemFailInfo))
        {
            //response.Trace.ErrorMsg = "接监管部门通知,系统暂停使用。";
            response.Trace.ErrorMsg = systemFailInfo.ToLower().Replace("[br]", "\n");
            return(true);
        }
        else
        {
            return(false);
        }
    }
Ejemplo n.º 3
0
        public IssuingResultEntity Issue(IssueEntity entity)
        {
            IssuingResultEntity   result = new IssuingResultEntity();
            PurchaseRequestEntity req    = new PurchaseRequestEntity();

            req.customerBirth  = entity.Birthday;
            req.customerGender = (Gender)entity.Gender;
            req.customerID     = entity.ID;
            req.customerIDType = (IdentityType)entity.IDType;
            req.customerName   = entity.Name;
            req.customerPhone  = entity.PhoneNumber;
            req.flightDate     = entity.EffectiveDate;
            req.flightNo       = entity.FlightNo;

            string[] config = entity.IOC_Class_Parameters.Split(',');
            req.InsuranceCode = config[2];
            req.password      = config[1];
            req.username      = config[0];

            string xml = Common.XmlSerialize <PurchaseRequestEntity>(req);
            string ret = ws.Issue(xml);
            PurchaseResponseEntity resp = Common.XmlDeserialize <PurchaseResponseEntity>(ret);

            if (string.IsNullOrEmpty(resp.Trace.ErrorMsg))
            {
                result.PolicyNo        = result.Trace.Detail = resp.PolicyNo;
                result.Insurer         = resp.Insurer;
                result.AmountInsured   = resp.AmountInsured;
                result.Website         = resp.ValidationWebsite;
                result.CustomerService = resp.ValidationPhoneNumber;
            }
            else
            {
                result.Trace.Detail   = resp.Trace.Detail;
                result.Trace.ErrorMsg = resp.Trace.ErrorMsg;
            }

            return(result);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// 出单
        /// </summary>
        /// <param name="request"></param>
        /// <param name="isExternal">是否外部(第三方机构)调用</param>
        /// <returns></returns>
        public static PurchaseResponseEntity Purchase(PurchaseRequestEntity request, bool isExternal, bool isSync)
        {
            PurchaseResponseEntity response = new PurchaseResponseEntity();

            if (Common.CheckIfSystemFailed(response))
            {
                return(response);
            }

            try
            {
                DateTime dtNow = Common.GetDatetime();//DateTime.Now;

                if (!isSync)
                {
                    #region  效性验证
                    if (request.flightDate < dtNow.AddMinutes(Common.IssuingDeadline)) //如果填写的起飞时间已过
                    {
                        if (request.flightDate.Date == dtNow.Date)                     //当日起飞,则进行时间部分的验证
                        {
                            if (request.flightDate.TimeOfDay.Ticks > 0)
                            {
                                response.Trace.ErrorMsg = "请输入准确的起飞时间!";
                            }
                            else//时间部分为零(PNR未能导入)
                            {
                                response.Trace.ErrorMsg = "请输入起飞时间!";
                            }
                            return(response);
                        }
                        else//日期是昨天、昨天以前
                        {
                            response.Trace.ErrorMsg = "请输入正确的乘机日期!";
                            return(response);
                        }
                    }
                    else if ((request.flightDate - dtNow) > new TimeSpan(180, 0, 0, 0, 0))
                    {
                        response.Trace.ErrorMsg = "乘机时间太过遥远(已超过180天)!";
                        return(response);
                    }

                    if (string.IsNullOrEmpty(request.flightNo))
                    {
                        response.Trace.ErrorMsg = "航班号不能为空!";
                        return(response);
                    }

                    if (string.IsNullOrEmpty(request.customerID))
                    {
                        response.Trace.ErrorMsg = "乘客证件号码不能为空!";
                        return(response);
                    }
                    else
                    {
                        request.customerID = request.customerID.ToUpper();
                        request.customerID = StringHelper.MiscelHelper.Full2Half(request.customerID);

                        if (request.customerIDType == IdentityType.身份证 && !Common.CheckIDCard(request.customerID))
                        {
                            response.Trace.ErrorMsg = "身份证号码填写有误,请核对!";
                            return(response);
                        }
                    }

                    if (string.IsNullOrEmpty(request.customerName))
                    {
                        response.Trace.ErrorMsg = "乘客姓名不能为空!";
                        return(response);
                    }
                    else
                    {
                        if (request.customerName.Contains("  "))
                        {
                            response.Trace.ErrorMsg = "客户名称不合法: 姓名不能有连续空格!";
                            return(response);
                        }
                    }

                    if (!string.IsNullOrEmpty(request.customerPhone))
                    {
                        if (!Regex.IsMatch(request.customerPhone, "^1[3458][0-9]{9}$"))
                        {
                            response.Trace.ErrorMsg = "手机号码格式不正确!";
                            return(response);
                        }
                    }
                    #endregion
                }

                UserLoginResponse userLogin = UserClass.AccessCheck(request.username, request.password);

                if (string.IsNullOrEmpty(userLogin.Trace.ErrorMsg))
                {
                    if (UserClass.IsParentDisabled(request.username))
                    {
                        response.Trace.ErrorMsg = "由于您的上级账号已被冻结,所以您无法出单,请联系您的上级用户!";
                        return(response);
                    }

                    if (Common.PaymOnline)
                    {
                        if (userLogin.Balance <= 0)
                        {
                            response.Trace.ErrorMsg = "账户余额不足,请充值或联系您的上级用户!";
                            return(response);
                        }
                    }

                    //if (Case.IsIssued(request.flightDate, request.customerName, request.customerID))
                    //{
                    //    response.Trace.ErrorMsg = "该旅客信息已经入库,请勿重复打印!";
                    //    return response;
                    //}

                    DataSet dsProduct = Product.GetProduct(request.InsuranceCode);

                    if (dsProduct.Tables[0].Rows.Count == 0)
                    {
                        response.Trace.ErrorMsg = "找不到您所指定的产品,或者该产品已停用,请重新选择!";
                        return(response);
                    }

                    DataRow drProduct            = dsProduct.Tables[0].Rows[0];
                    bool    isIssuingRequired    = Convert.ToBoolean(drProduct["IsIssuingRequired"]);
                    bool    isIssuingLazyEnabled = Convert.ToBoolean(drProduct["IsIssuingLazyEnabled"]);
                    bool    isMobileNoRequired   = Convert.ToBoolean(drProduct["IsMobileNoRequired"]);
                    if (isMobileNoRequired)
                    {
                        if (Regex.IsMatch(request.customerPhone, "^1[3458][0-9]{9}$"))
                        {
                            //处理销售点仅用一个手机号给所有乘客出保险的偷懒行为
                            if (Case.CountMobile(request.customerPhone, request.username) > 5)
                            {
                                response.Trace.ErrorMsg = "该手机号已重复使用多次,请如实填写以提供短信服务!";
                                return(response);
                            }
                        }
                        else
                        {
                            response.Trace.ErrorMsg = "该款产品必须提供手机号,请检查是否正确!";
                            return(response);
                        }
                    }
                    else if (!string.IsNullOrEmpty(request.customerPhone))
                    {
                        if (Regex.IsMatch(request.customerPhone, "^1[3458][0-9]{9}$"))
                        {
                            //处理销售点仅用一个手机号给所有乘客出保险的偷懒行为
                            if (Case.CountMobile(request.customerPhone, request.username) > 5)
                            {
                                response.Trace.ErrorMsg = "该手机号已重复使用多次,请如实填写,或者不填!";
                                return(response);
                            }
                        }
                        else
                        {
                            response.Trace.ErrorMsg = "请正确填写手机号,或者不填!";
                            return(response);
                        }
                    }

                    int    interface_Id = isIssuingRequired ? Convert.ToInt32(drProduct["interface_Id"]) : 0;//若非对接产品,接口ID置为0,以免影响接口出单统计
                    object caseSupplier = drProduct["productSupplier"];
                    int    caseDuration = Convert.ToInt32(drProduct["productDuration"]);
                    object productName  = drProduct["productName"];

                    //基于产品的 IP 过滤
                    string include           = drProduct["FilterInclude"].ToString().Trim();
                    string exclude           = drProduct["FilterExclude"].ToString().Trim();
                    string comment           = drProduct["FilterComment"].ToString();
                    string ip                = System.Web.HttpContext.Current.Request.UserHostAddress;
                    string ipLocation        = string.Empty;
                    bool   isValidIpLocation = true;
                    try
                    {
                        Ip2Location.Ip2Location ip2lo = new Ip2Location.Ip2Location();
                        ipLocation = ip2lo.GetLocation(ip);
                        if (!IsIpChecked(ipLocation, include, exclude))
                        {
                            string strLog = "ProductFilter User:{0} IP:{1} Location:{2} Include:{3} Exclude:{4}";
                            strLog = string.Format(strLog, request.username, ip, ipLocation, include, exclude);
                            Common.LogIt(strLog);
                            response.Trace.Detail   = comment;
                            response.Trace.ErrorMsg = "无法出单!(e001)";// "产品区域限制,禁止出单!";
                            return(response);
                        }
                    }
                    catch (Exception ee)
                    {
                        isValidIpLocation = false;
                        ipLocation        = ee.Message.Substring(0, 20);
                    }

                    response.AgentName = userLogin.DisplayName;
                    //response.ValidationPhoneNumber = UserClass.GetValidationPhoneNumber(request.username);

                    #region 数据库事务
                    //2008.4.19 改用全手工方式 因为 Nbear 的事务处理似乎不能及时释放掉connection,越来越的连接…满负荷…导致客户端访问webservice连接超时
                    using (SqlConnection cnn = new SqlConnection(Common.ConnectionString))
                    {
                        cnn.Open();
                        using (SqlTransaction tran = cnn.BeginTransaction())
                        {
                            string strSql = "";

                            try
                            {
                                //有限的行级排它锁with(rowlock,xlock,readpast),保证该行不会被其他进程读取,同时不会阻塞其他行的读取和主键更新
                                //2011.9.28 日志发现该语句依然可能导致死锁 原因:该语句除了对那一行上X锁之外,对top2、top3…(满足where条件的行)上IX锁
                                //而X和IX锁是互斥的,
                                //                                strSql = @"
                                //select top 1 * from t_serial with(rowlock,xlock,readpast)
                                //where caseOwner = '{0}' and caseSupplier = '{1}'
                                //order by caseNo asc";
                                strSql = @"
  delete top(1)
  from t_serial WITH (rowlock, READPAST)
  output deleted.caseNo, deleted.caseSupplier,
  deleted.locationInclude, deleted.locationExclude, deleted.locationComment
  where caseOwner = '{0}' and caseSupplier = '{1}'";
                                strSql = string.Format(strSql, request.username, caseSupplier);
                                DataSet    dsSerial = new DataSet();
                                SqlCommand cmm      = new SqlCommand("", cnn, tran);
                                cmm.CommandText = strSql;
                                SqlDataAdapter sda = new SqlDataAdapter(cmm);
                                sda.Fill(dsSerial);

                                if (dsSerial.Tables[0].Rows.Count == 0)
                                {
                                    tran.Rollback();
                                    response.Trace.ErrorMsg = "没有可用的单证号,请联系相关业务人员!";
                                    return(response);
                                }

                                DataRow drSerial = dsSerial.Tables[0].Rows[0];
                                string  caseNo   = drSerial["caseNo"].ToString();
                                response.CaseNo = caseNo;

                                if (isValidIpLocation)//上面验证若通过则此处继续审查
                                {
                                    //基于号段的 IP 过滤
                                    include = drSerial["locationInclude"].ToString();
                                    exclude = drSerial["locationExclude"].ToString();
                                    comment = drSerial["locationComment"].ToString();
                                    if (!IsIpChecked(ipLocation, include, exclude))
                                    {
                                        tran.Rollback();
                                        string strLog = "SerialFilter User:{0} IP:{1} Location:{2} Include:{3} Exclude:{4}";
                                        strLog = string.Format(strLog, request.username, ip, ipLocation, include, exclude);
                                        Common.LogIt(strLog);
                                        response.Trace.Detail   = comment;
                                        response.Trace.ErrorMsg = "无法出单!(e002)";//"号段区域限制,禁止出单!";
                                        return(response);
                                    }
                                }

                                //insert 语句本身不会阻塞,但是却引起其他线程的select阻塞
                                /*用MsSql2005的 output inserted.caseID 新语法代替原来的 SELECT CAST(scope_identity() AS int) 以返回自增列ID;*/
                                strSql = @"
insert into t_Case
(caseNo,caseOwner,caseSupplier,productID,customerFlightDate,customerFlightNo,customerID,customerName,customerPhone,
    parentPath,datetime,isPrinted,enabled,caseDuration, ip, IpLocation, reserved, customerGender, customerBirth, interface_Id)
output inserted.caseID
values ('{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}','{10}','{11}','{12}','{13}','{14}','{15}', '{16}', '{17}', '{18}', '{19}');";

                                string parentPath = userLogin.ParentPath + request.username + "/";//用于判定单证的层级归属
                                string gender     = request.customerGender == Gender.Female ? "女" : "男";
                                //if (interface_Id == null)//无需判断,空值、空格使用单引号括起插入到int型字段的时候,数据库会自动转成0值
                                //    interface_Id = 0;

                                strSql = string.Format(strSql, caseNo, request.username, drSerial["caseSupplier"], request.InsuranceCode.Trim(),
                                                       request.flightDate, request.flightNo.Trim(), request.customerID.Trim(), request.customerName.Trim(), request.customerPhone.Trim(), parentPath, dtNow.ToString(),
                                                       0, 1, caseDuration, ip, ipLocation, request.PNR, gender, request.customerBirth, interface_Id);
                                cmm.CommandText = strSql;
                                int caseId = Convert.ToInt32(cmm.ExecuteScalar()); //返回自增列id
                                //cmm.ExecuteNonQuery();
                                strSql = string.Empty;                             //清空SQL语句,以防干扰下面的语句合并

                                if (isIssuingRequired)
                                {
                                    #region 投保数据对接
                                    string      IOC_Class_Alias      = drProduct["IOC_Class_Alias"].ToString();
                                    string      IOC_Class_Parameters = drProduct["IOC_Class_Parameters"].ToString();
                                    IssueEntity entity = new IssueEntity();
                                    entity.Name     = request.customerName;
                                    entity.ID       = request.customerID;
                                    entity.IDType   = request.customerIDType;
                                    entity.Gender   = request.customerGender;
                                    entity.Birthday = request.customerBirth;
                                    //如果是今天之后的乘机日期,则时间部分置为0
                                    entity.EffectiveDate = request.flightDate.Date > DateTime.Today ? request.flightDate.Date : request.flightDate;
                                    entity.ExpiryDate    = request.flightDate.AddDays(caseDuration - 1);
                                    entity.PhoneNumber   = request.customerPhone;
                                    entity.FlightNo      = request.flightNo;

                                    entity.IsLazyIssue          = isIssuingLazyEnabled;
                                    entity.DbCommand            = cmm;
                                    entity.IOC_Class_Alias      = IOC_Class_Alias;
                                    entity.IOC_Class_Parameters = IOC_Class_Parameters;
                                    entity.CaseNo      = caseNo;
                                    entity.CaseId      = caseId.ToString();
                                    entity.InterfaceId = interface_Id;
                                    entity.Title       = productName.ToString();

                                    TraceEntity validate = Case.Validate(entity);
                                    if (string.IsNullOrEmpty(validate.ErrorMsg))
                                    {
                                        if (entity.IsLazyIssue && !isExternal)
                                        {
                                            //Thread th = new Thread(Case.IssueAsync);
                                            //th.Start(entity);
                                            entity.ConnectionString = Common.ConnectionString;
                                            //entity.MaxRedelivery = 3;
                                            Common.AQ_Issuing.EnqueueObject(entity);
                                        }
                                        else
                                        {
                                            IssuingResultEntity result = Case.Issue(entity);
                                            if (string.IsNullOrEmpty(result.Trace.ErrorMsg))
                                            {
                                                response.SerialNo              = result.PolicyNo;//暂借用该SerialNo字段
                                                response.PolicyNo              = result.PolicyNo;
                                                response.Insurer               = result.Insurer;
                                                response.AmountInsured         = result.AmountInsured;
                                                response.ValidationWebsite     = result.Website;
                                                response.ValidationPhoneNumber = result.CustomerService;
                                                //如果中途转投了别的接口
                                                if (entity.InterfaceId != interface_Id)
                                                {
                                                    strSql = "UPDATE [t_Case] SET [interface_Id] = {0} WHERE caseNo = '{1}'; ";
                                                    strSql = string.Format(strSql, entity.InterfaceId, caseNo);
                                                }
                                            }
                                            else
                                            {
                                                tran.Rollback();

                                                StringBuilder sbLog = new StringBuilder();
                                                sbLog.AppendLine(Common.XmlSerialize <IssueEntity>(entity));
                                                sbLog.Append(result.Trace.ErrorMsg);
                                                Common.LogIt(sbLog.ToString());

                                                response.Trace = result.Trace;
                                                return(response);
                                            }
                                        }
                                    }
                                    else
                                    {
                                        tran.Rollback();
                                        response.Trace = validate;
                                        return(response);
                                    }

                                    #endregion
                                    if (Common.Debug)
                                    {
                                        //Test.TestIt(entity);
                                    }
                                }

                                //修改出单量 主键更新 合并到下面的SQL语句一起执行
                                strSql += "update t_user set CountConsumed = CountConsumed + 1 where username = '******'; ";

                                #region 扣款
                                string[] parentArray = parentPath.Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries);//形如:/admin/tianzhi/bcaaa/bcaaa0150/
                                string   root        = parentArray[0];
                                string   distributor = "";
                                if (parentArray.Length > 1)
                                {
                                    distributor = parentArray[1];//第二级用户名既是一级分销商
                                    strSql     += "update t_User set balance = balance - price where username = '******'; update t_User set balance = balance - price where username = '******'";
                                    strSql      = string.Format(strSql, root, distributor);
                                }
                                else//管理员自己出单
                                {
                                    strSql += "update t_User set balance = balance - price where username = '******'";
                                    strSql  = string.Format(strSql, root);
                                }
                                cmm.CommandText = strSql;
                                cmm.ExecuteNonQuery();
                                #endregion

                                tran.Commit();//提交事务
                            }
                            catch
                            {
                                tran.Rollback();
                                Common.LogIt(strSql);
                                throw;
                            }
                        }
                    }
                    #endregion
                    return(response);
                }
                else
                {
                    response.Trace = userLogin.Trace;
                    return(response);
                }
            }
            catch (System.Exception ex)
            {
                StringBuilder sbLog = new StringBuilder();
                sbLog.AppendLine(Common.XmlSerialize <PurchaseRequestEntity>(request));
                sbLog.Append(ex.ToString());
                Common.LogIt(sbLog.ToString());

                response.Trace.ErrorMsg = "下单未成功,请稍后重试。";
                return(response);
            }
        }