Exemplo n.º 1
0
        /// <summary>
        /// Clone the current object and return the copy
        /// </summary>
        /// <returns></returns>
        public object Clone()
        {
            var obj = (DataObject)MemberwiseClone();

            obj.ObjectId = IDGenerator.GenerateID();
            return(obj);
        }
Exemplo n.º 2
0
        public static void CreateNewPart(Chapter chapter, string name, string quote = "", string authorOfTheQuote = "", string description = "", string FileName = "")
        {
            try
            {
                Validator.ValidateName(name);

                if (!String.IsNullOrWhiteSpace(quote) && String.IsNullOrWhiteSpace(authorOfTheQuote))
                {
                    throw new ApplicationException("Не указан автор цитаты");
                }
                if (String.IsNullOrWhiteSpace(quote) && !String.IsNullOrWhiteSpace(authorOfTheQuote))
                {
                    throw new ApplicationException("Указан автор цитаты, но не указана цитата");
                }

                int  ID          = IDGenerator.GenerateID();
                int  orderNumber = chapter.Parts.Count + 1;
                Part newPart     = new Part(id: ID, name: name, chapterid: chapter.ID, orderNumber: orderNumber, description: description, quote: quote, authorOfTheQuote: authorOfTheQuote, fileName: FileName);
                if (!String.IsNullOrWhiteSpace(FileName))
                {
                    SaveFile(ref newPart);
                }
                AddPartInXML(newPart);
            }
            catch (ApplicationException ex)
            {
                throw new ApplicationException($"Ошибка при создании новой части: {ex.Message}");
            }
            catch (Exception ex)
            {
                throw new ApplicationException($"Непредвиденная ошибка при создании новой части: {ex.Message}");
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Checks whether we should send our packaged player actions to the server yet (we do
        /// so at regular intervals).
        /// </summary>
        void SendInput()
        {
            if (OurChampion != null)
            {
                TimeSinceLastInputSent += GameTime.ElapsedGameTime.TotalSeconds;

                if (TimeSinceLastInputSent >= SEND_INPUTS_TO_SERVER_INTERVAL.TotalSeconds)
                {
                    var package = OurChampion.GetActionPackage();

                    if (package.Count == 0)                       // no actions? send a heartbeat to say that we're connected
                    {
                        package.Enqueue(new PlayerAction(IDGenerator.GenerateID(),
                                                         PlayerActionType.Idle,
                                                         (float)Client.Instance.GetTime().TotalSeconds,
                                                         OurChampion.Champion.Position));
                    }

                    // Send packaged input
                    Client.SendPlayerActionPackage(package);
                    package.Clear();

                    TimeSinceLastInputSent = 0f;
                }
            }
        }
Exemplo n.º 4
0
 /// <summary>
 /// Default-Construktor that generates a new Object-ID and set
 /// Dirty and Persisted to <c>false</c>
 /// </summary>
 protected DataObject()
 {
     ObjectId    = IDGenerator.GenerateID();
     IsPersisted = false;
     AllowAdd    = true;
     AllowDelete = true;
     IsDeleted   = false;
 }
Exemplo n.º 5
0
        /// <summary>
        /// Creates a champion.
        /// </summary>
        ServerChampion CreateChampion(ChampionTypes champ)
        {
            var team = GetSmallestTeam();

            return(new ServerChampion(IDGenerator.GenerateID(),
                                      GetSpawnPosition(team),
                                      champ,
                                      team));
        }
Exemplo n.º 6
0
        /// <summary>
        /// Packages a client-side action to be sent to the server. This also simulates the action locally
        /// for client-side prediction.
        /// </summary>
        public void PackageAction(PlayerActionType action, Vec2 target)
        {
            PlayerAction toPackage = new PlayerAction(
                IDGenerator.GenerateID(),
                action,
                (float)Client.Instance.GetTime().TotalSeconds,
                Champion.Position,
                target);

            Champion.PackageAction(toPackage);
        }
Exemplo n.º 7
0
        public string Save(DBSpell spell)
        {
            if (!spell.IsPersisted)
            {
                spell.ObjectId = IDGenerator.GenerateID();
                DatabaseManager.Database.AddObject(spell);
                return(spell.ObjectId);
            }

            DatabaseManager.Database.SaveObject(spell);
            return(spell.ObjectId);
        }
Exemplo n.º 8
0
        public string Save(DBDataQuest quest)
        {
            if (!quest.IsPersisted)
            {
                quest.ObjectId = IDGenerator.GenerateID();
                DatabaseManager.Database.AddObject(quest);
                return(quest.ObjectId);
            }

            DatabaseManager.Database.SaveObject(quest);
            return(quest.ObjectId);
        }
        public string Save(DBNpcTemplate template)
        {
            if (!template.IsPersisted)
            {
                template.ObjectId = IDGenerator.GenerateID();
                DatabaseManager.Database.AddObject(template);
                return(template.ObjectId);
            }

            DatabaseManager.Database.SaveObject(template);
            return(template.ObjectId);
        }
Exemplo n.º 10
0
        void CastTowerSpell(Teams team, Vec2 origin, Vec2 target)
        {
            LinearSpell spell = new LinearSpell(
                IDGenerator.GenerateID(),
                team,
                origin,
                target,
                SpellTypes.Tower_Shot,
                null);

            CastSpell(spell, target);
        }
Exemplo n.º 11
0
        public async Task <string> Save(List <MerchantItem> models, string itemListId)
        {
            return(await Task.Run(() =>
            {
                var existingId = models.FirstOrDefault(x => !string.IsNullOrWhiteSpace(x.ItemListID))?.ItemListID;

                List <MerchantItem> current = new List <MerchantItem>();
                if (!string.IsNullOrWhiteSpace(existingId))
                {
                    current = Get(existingId);
                }

                if (string.IsNullOrWhiteSpace(itemListId))
                {
                    itemListId = IDGenerator.GenerateID();
                }

                // update all items to the set ID
                models
                .Where(x => !string.IsNullOrWhiteSpace(x.ItemListID))
                .ForEach(x => x.ItemListID = itemListId);

                // remove deleted
                current
                .Where(x => !models.Select(s => s.ObjectId).Contains(x.ObjectId))
                .ForEach(x => DatabaseManager.Database.DeleteObject(x));

                // add new
                models
                .Where(x => string.IsNullOrWhiteSpace(x.ItemListID))
                .ForEach(x =>
                {
                    x.ItemListID = itemListId;
                    DatabaseManager.Database.AddObject(x);
                });

                // update changed
                (from model in models
                 join existing in current on model.ObjectId equals existing.ObjectId
                 where model.ItemListID != existing.ItemListID ||
                 model.ItemTemplateID != existing.ItemTemplateID ||
                 model.PageNumber != existing.PageNumber ||
                 model.SlotPosition != existing.SlotPosition
                 select model)
                .ToList()
                .ForEach(x => DatabaseManager.Database.SaveObject(x));

                return itemListId;
            }));
        }
Exemplo n.º 12
0
        /// <summary>
        /// Adds a new object to the database.
        /// </summary>
        /// <param name="dataObject">the object to add to the database</param>
        /// <returns>true if the object was added successfully; false otherwise</returns>
        protected override bool AddObjectImpl(DataObject dataObject)
        {
            DataTable table = null;
            DataRow   row   = null;

            try
            {
                string tableName = dataObject.TableName;

                DataSet dataset = GetDataSet(tableName);
                table = dataset.Tables[tableName];

                lock (dataset)                 // lock dataset before making any changes to it
                {
                    row = table.NewRow();
                    FillRowWithObject(dataObject, row);
                    table.Rows.Add(row);
                }

                if (dataObject.ObjectId == null)
                {
                    dataObject.ObjectId = IDGenerator.GenerateID();
                }

                dataObject.ObjectId = row[tableName + "_ID"].ToString();

                dataObject.Dirty       = false;
                dataObject.IsPersisted = true;
                dataObject.IsDeleted   = false;

                return(true);
            }

            catch (Exception e)
            {
                if (Log.IsErrorEnabled)
                {
                    Log.Error("AddNewObject", e);
                }

                if (row != null && table != null)
                {
                    table.Rows.Remove(row);
                }

                throw new DatabaseException("Adding Databaseobject failed !", e);
            }
        }
Exemplo n.º 13
0
 public static void CreateNewChapter(int orderNumber, string name, string description)
 {
     try
     {
         Validator.ValidateName(name);
         Chapter newChapter = new Chapter(id: IDGenerator.GenerateID(), name: name, orderNumber: orderNumber, description: description);
         AddChapterInXML(newChapter);
     }
     catch (ApplicationException ex)
     {
         throw new ApplicationException($"Ошибка при создании новой главы: {ex.Message}");
     }
     catch (Exception ex)
     {
         throw new ApplicationException($"Непредвиденная ошибка при создании новой главы: {ex.Message}");
     }
 }
Exemplo n.º 14
0
 private void AddRecursive(int depth, Node <T> parent, Node <T> node)
 {
     // check if current data is less than root data
     if (IsNodeLeftSide(parent, node))
     {
         if (parent.Left == null)
         {
             node.ID     = IDGenerator.GenerateID(nodes.Count, depth, true);
             node.Parent = parent;
             parent.Left = node;
             KeyValuePair <int, string> pair = new KeyValuePair <int, string>(depth, "Left");
             nodes.Add(node, pair);
             lefts.Add(node, pair);
         }
         else
         {
             if (!IsNodeDuplicated(parent, node))
             {
                 AddRecursive(depth + 1, parent.Left, node);
             }
         }
     }
     else
     {
         if (parent.Data.Equals(node.Data))
         {
             return;
         }
         if (parent.Right == null)
         {
             node.ID      = IDGenerator.GenerateID(nodes.Count, depth, false);
             node.Parent  = parent;
             parent.Right = node;
             KeyValuePair <int, string> pair = new KeyValuePair <int, string>(depth, "Right");
             nodes.Add(node, pair);
             rights.Add(node, pair);
         }
         else
         {
             if (!IsNodeDuplicated(parent, node))
             {
                 AddRecursive(depth + 1, parent.Right, node);
             }
         }
     }
 }
Exemplo n.º 15
0
        const double RADIANS_BETWEEN_PROJECTILES = Math.PI / 36.0;         // ~5 degrees
        void CastChampionSpell(ICharacter champ, PlayerAction action)
        {
            Debug.Assert(action.Target != null);

            // aim in the direction of the spell
            champ.FacingLeft = action.Target.X < champ.Position.X + champ.CollisionWidth / 2f;

            SpellTypes type        = ChampionTypesHelper.GetSpellFromAction(champ.Type, action.Type);
            int        projectiles = SpellsHelper.Info(type).Projectiles;
            Vec2       spawn       = champ.GetHandsPosition();

            double angle = 0.0;

            if (action.Target != null)
            {
                Vec2 dir = action.Target - spawn;
                angle = Math.Atan2(dir.Y, dir.X);                                     // current angle
                double completeArc = RADIANS_BETWEEN_PROJECTILES * (projectiles - 1); // complete arc that we'll cover
                angle -= completeArc / 2f;                                            // start from the lowest angle
            }

            for (int i = 0; i < projectiles; ++i)
            {
                Vec2 dir = Vec2.Zero;
                if (action.Target != null)
                {
                    double current = angle + i * RADIANS_BETWEEN_PROJECTILES;
                    dir = new Vec2((float)Math.Cos(current), (float)Math.Sin(current));
                }

                LinearSpell spell = new LinearSpell(
                    IDGenerator.GenerateID(),
                    champ.Team,
                    spawn,
                    spawn + dir,
                    type,
                    champ);

                CastSpell(spell, action.Target);
            }
        }
        public string Save(NPCEquipment template)
        {
            if (string.IsNullOrWhiteSpace(template.TemplateID))
            {
                template.TemplateID = IDGenerator.GenerateID();
            }

            if (string.IsNullOrWhiteSpace(template.ObjectId))
            {
                if (string.IsNullOrWhiteSpace(template.TemplateID))
                {
                    template.ObjectId = IDGenerator.GenerateID();
                }

                DatabaseManager.Database.AddObject(template);
                return(template.TemplateID);
            }

            DatabaseManager.Database.SaveObject(template);
            return(template.TemplateID);
        }
Exemplo n.º 17
0
        public void TestStateClone()
        {
            MatchState state = new MatchState(new PhysicsEngine(new GameWorld(null)));

            IEntity e = new IEntity(IDGenerator.GenerateID(), new Vec2(100f, -99f), 1f, 1f, 1f);

            state.AddEntity(e);

            Assert.True(state.ContainsEntity(e.ID), "entity1 added to match");

            IEntity e2 = new IEntity(IDGenerator.GenerateID(), new Vec2(42f, 24f), 1f, 1f, 1f);

            state.AddEntity(e2);

            Assert.True(state.ContainsEntity(e2.ID), "entity2 added to match");


            MatchState clone = state.Clone() as MatchState;

            Assert.True(clone.ContainsEntity(e.ID), "clone contains entity1");
            Assert.True(clone.ContainsEntity(e2.ID), "clone contains entity2");

            IEntity clonedE = clone.GetEntity(e.ID);

            TestClonedEntityValues(e, clonedE, true, "after clone (e1)");

            ChangeClonedEntity(clonedE, new Vec2(11f, 111f), new Vec2(22f, 222f), 1000f, 2000f, 333f);
            TestClonedEntityValues(e, clonedE, false, "after clone modif (e1)");

            IEntity clonedE2 = clone.GetEntity(e2.ID);

            TestClonedEntityValues(e2, clonedE2, true, "after clone (e2)");

            ChangeClonedEntity(clonedE2, new Vec2(87f, 78f), new Vec2(52f, 25f), 76f, 88f, 2121f);
            TestClonedEntityValues(e2, clonedE2, false, "after clone modif (e2)");
        }
Exemplo n.º 18
0
        public XResult <SingleSettlementPaymentApplyResponse> Pay(SingleSettlementPaymentApplyRequest request)
        {
            if (request == null)
            {
                return(new XResult <SingleSettlementPaymentApplyResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentNullException($"{nameof(request)}为null")));
            }

            if (!request.IsValid)
            {
                return(new XResult <SingleSettlementPaymentApplyResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException(request.ErrorMessage)));
            }

            String service = $"{this.GetType().FullName}.{nameof(Pay)}(...)";

            var requestHash = $"{nameof(Pay)}:{request.OrderNo}".GetHashCode();

            if (_lockProvider.Exists(requestHash))
            {
                return(new XResult <SingleSettlementPaymentApplyResponse>(null, ErrorCode.SUBMIT_REPEAT));
            }

            try
            {
                if (!_lockProvider.Lock(requestHash))
                {
                    return(new XResult <SingleSettlementPaymentApplyResponse>(null, ErrorCode.SUBMIT_REPEAT));
                }

                Boolean existOrder = true;
                try
                {
                    existOrder = (from t0 in _fundOutOrderRepository.QueryProvider
                                  where t0.OutTradeNo == request.OrderNo
                                  select t0.Id).Count() > 0;
                }
                catch (Exception ex)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, "existOrder", "查询订单失败", ex, request);
                    return(new XResult <SingleSettlementPaymentApplyResponse>(null, ErrorCode.DB_QUERY_FAILED, new DbQueryException($"查询订单号失败,订单号:{request.OrderNo}")));
                }

                if (existOrder)
                {
                    return(new XResult <SingleSettlementPaymentApplyResponse>(null, ErrorCode.OUT_TRADE_NO_EXISTED));
                }

                Int64  newId   = IDGenerator.GenerateID();
                String tradeNo = newId.ToString();

                var fundoutOrder = new FundOutOrder()
                {
                    Id         = newId,
                    AppId      = request.AppId,
                    TradeNo    = tradeNo,
                    OutTradeNo = request.OrderNo,
                    Amount     = request.Amount,
                    RealName   = request.CreditName,
                    PayStatus  = PayStatus.PROCESSING.ToString(),
                    FeeAction  = request.FeeAction,
                    BankCardNo = request.BankCardNo,
                    BankName   = request.BankName,
                    Mobile     = request.Mobile,
                    CreateTime = DateTime.Now,
                    Remark     = request.Remark
                };

                //入库
                _fundOutOrderRepository.Add(fundoutOrder);
                var saveResult = _fundOutOrderRepository.SaveChanges();
                if (!saveResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), nameof(CallResultStatus.ERROR), service, $"{nameof(_fundOutOrderRepository)}.SaveChanges()", "保存订单失败", saveResult.FirstException, fundoutOrder);
                    return(new XResult <SingleSettlementPaymentApplyResponse>(null, ErrorCode.DB_UPDATE_FAILED, new DbUpdateException($"保存订单失败,订单编号:{fundoutOrder.OutTradeNo}")));
                }

                //开始执行代付
                var requestBuilder = new RequestBuilder(_serializer, _logger)
                {
                    EncryptKey      = CryptoHelper.GenerateRandomKey(),
                    RequestType     = "pay2BankRequest",
                    RequestHead     = "pay2bankHead",
                    RequestBodyType = "requestBody",
                    RequestBody     = request
                };

                var postXml = requestBuilder.Build(doc =>
                {
                    var amountEl = doc.Root.Element("amount");
                    if (amountEl != null)
                    {
                        var amountText = amountEl.Value;
                        if (Decimal.TryParse(amountText, out Decimal amount))
                        {
                            amountEl.Value = Convert.ToInt32(amount * 100m).ToString();
                        }
                    }
                });

                //更新申请时间
                fundoutOrder.ApplyTime = DateTime.Now;

                String callMethod = $"{nameof(_client)}.PostXml(...)";

                _logger.Trace(TraceType.BLL.ToString(), nameof(CallResultStatus.OK), service, callMethod, LogPhase.BEGIN, $"开始调用{callMethod}", new Object[] { ApiConfig.Bill99FOSinglePayApplyRequestUrl, postXml });

                var postResult = _client.PostXml(ApiConfig.Bill99FOSinglePayApplyRequestUrl, postXml);

                _logger.Trace(TraceType.BLL.ToString(), (postResult.Success ? CallResultStatus.OK : CallResultStatus.ERROR).ToString(), service, callMethod, LogPhase.ACTION, $"完成调用{callMethod}");

                if (!postResult.Success)
                {
                    return(new XResult <SingleSettlementPaymentApplyResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, postResult.FirstException));
                }

                String resp = null;
                try
                {
                    resp = postResult.Value.Content.ReadAsStringAsync().GetAwaiter().GetResult();
                    _logger.Trace(TraceType.BLL.ToString(), nameof(CallResultStatus.OK), service, callMethod, LogPhase.END, $"调用{callMethod}结果", resp);
                }
                catch (Exception ex)
                {
                    _logger.Error(TraceType.BLL.ToString(), nameof(CallResultStatus.ERROR), service, callMethod, "读取第三方返回的消息内容失败", ex, postXml);
                    return(new XResult <SingleSettlementPaymentApplyResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, ex));
                }

                if (String.IsNullOrWhiteSpace(resp))
                {
                    return(new XResult <SingleSettlementPaymentApplyResponse>(null, ErrorCode.REMOTE_RETURN_NOTHING));
                }

                //更新结束时间
                fundoutOrder.EndTime = DateTime.Now;

                var parseResult = ParseXml(resp);
                if (!parseResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), nameof(CallResultStatus.ERROR), service, "ParseXml(...)", "解析返回数据失败", parseResult.FirstException, resp);
                    return(new XResult <SingleSettlementPaymentApplyResponse>(null, ErrorCode.XML_PARSE_FAILED, new SystemException("解析返回数据失败")));
                }

                var root = parseResult.Value.Root;

                var memberCodeEl = root.Descendants("memberCode").FirstOrDefault();
                if (memberCodeEl == null)
                {
                    _logger.Error(TraceType.BLL.ToString(), nameof(CallResultStatus.ERROR), service, "memberCodeEl", "返回数据中未包含<memberCode></memberCode>元素");
                    return(new XResult <SingleSettlementPaymentApplyResponse>(null, ErrorCode.XML_ELEMENT_NOT_EXIST, new RemoteException("<memberCode> not found")));
                }

                var decodeResult = Decode(root, "responseBody");
                if (!decodeResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), nameof(CallResultStatus.ERROR), service, $"Decode(...)", "解码失败");
                    return(new XResult <SingleSettlementPaymentApplyResponse>(null, ErrorCode.DECODE_FAILED, decodeResult.FirstException));
                }

                var deserializeResult = Deserialize <SingleSettlementPaymentApplyResponse>(decodeResult.Value);
                if (deserializeResult.Success && deserializeResult.Value != null)
                {
                    var result = deserializeResult.Value;
                    result.MemberCode = memberCodeEl.Value;

                    var errorCodeEl = root.Descendants("errorCode").FirstOrDefault();
                    if (errorCodeEl != null)
                    {
                        result.ErrorCode = errorCodeEl.Value;
                    }

                    var errorMsgEl = root.Descendants("errorMsg").FirstOrDefault();
                    if (errorMsgEl != null)
                    {
                        result.ErrorMessage = errorMsgEl.Value;
                    }

                    //将以分为单位的金额转成以元为单位
                    result.Amount *= 0.01m;

                    //更新时间
                    fundoutOrder.UpdateTime = DateTime.Now;
                    //将申请时间、结束时间和更新时间更新到数据库
                    _fundOutOrderRepository.Update(fundoutOrder);
                    var updateResult = _fundOutOrderRepository.SaveChanges();
                    if (!updateResult.Success)
                    {
                        _logger.Error(TraceType.BLL.ToString(), nameof(CallResultStatus.ERROR), service, $"{nameof(_fundOutOrderRepository)}.SaveChanges()", "更新代付订单申请时间|结束时间|更新时间失败", updateResult.FirstException, fundoutOrder);
                    }

                    return(new XResult <SingleSettlementPaymentApplyResponse>(result));
                }

                return(new XResult <SingleSettlementPaymentApplyResponse>(null, ErrorCode.DESERIALIZE_FAILED, deserializeResult.FirstException));
            }
            finally
            {
                _lockProvider.UnLock(requestHash);
            }
        }
Exemplo n.º 19
0
        public XResult <YeePayAgreePayBindCardResponse> BindCard(YeePayAgreePayBindCardRequest request)
        {
            if (request == null)
            {
                return(new XResult <YeePayAgreePayBindCardResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentNullException(nameof(request))));
            }

            if (!request.IsValid)
            {
                return(new XResult <YeePayAgreePayBindCardResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException(request.ErrorMessage)));
            }

            String service = $"{this.GetType().FullName}.{nameof(BindCard)}(...)";

            var requestHash = $"{nameof(BindCard)}:{request.PayerId}.{request.BankCardNo}".GetHashCode();

            if (_lockProvider.Exists(requestHash))
            {
                return(new XResult <YeePayAgreePayBindCardResponse>(null, ErrorCode.SUBMIT_REPEAT));
            }

            try
            {
                if (!_lockProvider.Lock(requestHash))
                {
                    return(new XResult <YeePayAgreePayBindCardResponse>(null, ErrorCode.SUBMIT_REPEAT));
                }

                // 根据付款人Id、银行卡号和通道判断绑卡数据是否已存在
                var existsBindInfo = _bankCardBindInfoRepository.Exists(x => x.PayerId == request.PayerId && x.BankCardNo == request.BankCardNo && x.PayChannelCode == GlobalConfig.X99BILL_PAYCHANNEL_CODE);
                if (existsBindInfo)
                {
                    return(new XResult <YeePayAgreePayBindCardResponse>(null, ErrorCode.INFO_EXISTED, new ArgumentException("绑卡信息已存在")));
                }

                // 从已保存的绑卡数据中查出缺失的字段数据
                var existedBankCardInfo = _bankCardInfoRepository.QueryProvider.FirstOrDefault(x => x.BankCardNo == request.BankCardNo);
                if (existedBankCardInfo == null)
                {
                    return(new XResult <YeePayAgreePayBindCardResponse>(null, ErrorCode.INFO_NOT_EXIST, new ArgumentException("该付款人的申请绑卡记录不存在")));
                }
                else
                {
                    request.Mobile = existedBankCardInfo.Mobile;
                }

                var tradeTime = DateTime.Now;

                var result = YeePayAgreePayUtil.Execute <RawYeePayBindCardRequest, RawYeePayBindCardResponse>("/rest/v1.0/paperorder/auth/confirm", new RawYeePayBindCardRequest()
                {
                    merchantno   = GlobalConfig.YeePay_AgreePay_MerchantNo,
                    requestno    = request.OutTradeNo,
                    validatecode = request.SmsValidCode
                });

                String callMethod = $"{nameof(YeePayAgreePayUtil)}.{nameof(YeePayAgreePayUtil.Execute)}(...)";

                if (!result.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, callMethod, "绑卡失败", result.FirstException, new Object[] { request, result.Value });
                    return(new XResult <YeePayAgreePayBindCardResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, result.FirstException));
                }

                if (result.Value == null)
                {
                    return(new XResult <YeePayAgreePayBindCardResponse>(null, ErrorCode.REMOTE_RETURN_NOTHING));
                }

                var respResult = result.Value;
                if (respResult.status != "BIND_SUCCESS")
                {
                    //如果绑卡失败要删除之前的申请绑卡时保存的银行卡信息
                    _bankCardInfoRepository.Remove(existedBankCardInfo);
                    var removeExistedBankCardInfoResult = _bankCardInfoRepository.SaveChanges();
                    if (!removeExistedBankCardInfoResult.Success)
                    {
                        _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(_bankCardInfoRepository)}.SaveChanges()", "删除绑卡失败的银行卡信息失败", removeExistedBankCardInfoResult.FirstException, existedBankCardInfo);
                    }

                    return(new XResult <YeePayAgreePayBindCardResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, new RemoteException(respResult.errormsg)));
                }

                // 绑卡成功后数据入库
                var bindInfo = new AgreePayBankCardBindInfo()
                {
                    Id             = IDGenerator.GenerateID(),
                    AppId          = request.AppId,
                    PayerId        = request.PayerId,
                    BankCardId     = existedBankCardInfo.Id,
                    OutTradeNo     = request.OutTradeNo,
                    BankCardNo     = request.BankCardNo,
                    PayChannelCode = GlobalConfig.YEEPAY_PAYCHANNEL_CODE,
                    BindStatus     = nameof(BankCardBindStatus.BOUND),
                    ApplyTime      = tradeTime
                };

                _bankCardBindInfoRepository.Add(bindInfo);
                var saveResult = _bankCardBindInfoRepository.SaveChanges();
                if (!saveResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(_bankCardBindInfoRepository)}.SaveChanges()", "保存绑卡信息失败", saveResult.FirstException, bindInfo);
                    return(new XResult <YeePayAgreePayBindCardResponse>(null, ErrorCode.DB_UPDATE_FAILED, saveResult.FirstException));
                }

                var resp = new YeePayAgreePayBindCardResponse()
                {
                    PayerId    = request.PayerId,
                    OutTradeNo = respResult.requestno,
                    BindTime   = tradeTime.ToString("yyyy-MM-dd HH:mm:ss"),
                    Status     = CommonStatus.SUCCESS.ToString(),
                    Msg        = $"绑卡{CommonStatus.SUCCESS.GetDescription()}"
                };

                return(new XResult <YeePayAgreePayBindCardResponse>(resp));
            }
            finally
            {
                _lockProvider.UnLock(requestHash);
            }
        }
Exemplo n.º 20
0
        public XResult <PersonalRegisterResponse> Register(PersonalRegisterRequest request)
        {
            if (request == null)
            {
                return(new XResult <PersonalRegisterResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentNullException(nameof(request))));
            }

            String service = $"{this.GetType().FullName}.Register(...)";

            if (!request.IsValid)
            {
                _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(request)}.IsValid", LogPhase.ACTION, $"请求参数验证失败:{request.ErrorMessage}", request);
                return(new XResult <PersonalRegisterResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException(request.ErrorMessage)));
            }

            var requestHash = $"register:{request.PayeeId}".GetHashCode();

            if (_lockProvider.Exists(requestHash))
            {
                return(new XResult <PersonalRegisterResponse>(null, ErrorCode.SUBMIT_REPEAT));
            }

            try
            {
                if (!_lockProvider.Lock(requestHash))
                {
                    return(new XResult <PersonalRegisterResponse>(null, ErrorCode.SUBMIT_REPEAT));
                }

                var existedRegisterInfo = _personalSubAccountRepository.QueryProvider.Where(x => x.AppId == request.AppId && x.UID == request.PayeeId).Count() > 0;
                if (existedRegisterInfo)
                {
                    return(new XResult <PersonalRegisterResponse>(null, ErrorCode.INFO_EXISTED, new RequestException("开户信息已存在")));
                }

                var newId      = IDGenerator.GenerateID();
                var newAccount = new PersonalSubAccount()
                {
                    Id         = newId,
                    AppId      = request.AppId,
                    UID        = request.PayeeId,
                    IDCardNo   = request.IDCardNo,
                    IDCardType = request.IDCardType,
                    RealName   = request.RealName,
                    Mobile     = request.Mobile,
                    Email      = request.Email,
                    Status     = PersonalInfoRegisterStatus.WAITFORAUDIT.ToString(),
                    UpdateTime = DateTime.Now
                };
                _personalSubAccountRepository.Add(newAccount);

                var saveResult = _personalSubAccountRepository.SaveChanges();
                if (!saveResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(_personalSubAccountRepository)}.SaveChanges()", "保存个人开户信息失败", saveResult.FirstException, request);
                    return(new XResult <PersonalRegisterResponse>(null, ErrorCode.DB_UPDATE_FAILED, saveResult.FirstException));
                }

                String traceMethod = "Bill99Util.Execute(/person/register)";

                _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.OK.ToString(), service, traceMethod, LogPhase.BEGIN, "开始调用快钱个人开户接口", request);

                var execResult = Bill99UtilYZT.Execute <RawPersonalRegisterRequest, RawPersonalRegisterResponse>("/person/register", new RawPersonalRegisterRequest()
                {
                    uId          = request.PayeeId,
                    email        = request.Email,
                    idCardNumber = request.IDCardNo,
                    idCardType   = request.IDCardType,
                    mobile       = request.Mobile,
                    name         = request.RealName
                });

                _logger.Trace(TraceType.BLL.ToString(), (execResult.Success ? CallResultStatus.OK : CallResultStatus.ERROR).ToString(), service, traceMethod, LogPhase.END, $"结束调用快钱开户接口", request);

                if (!execResult.Success || execResult.Value == null)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, traceMethod, "个人开户失败", execResult.FirstException, execResult.Value);

                    _personalSubAccountRepository.Remove(newAccount);
                    saveResult = _personalSubAccountRepository.SaveChanges();
                    if (!saveResult.Success)
                    {
                        _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, traceMethod, "删除个人开户记录失败", saveResult.FirstException, newAccount);
                    }

                    _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.OK.ToString(), service, traceMethod, LogPhase.ACTION, "已删除开户失败的记录");
                    return(new XResult <PersonalRegisterResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, execResult.FirstException));
                }

                //开户成功之后要更新openid
                if (execResult.Value.ResponseCode == "0000")
                {
                    Boolean statusHasChanged = false;
                    switch (execResult.Value.AuditStatus)
                    {
                    case "03":
                        newAccount.Status = PersonalInfoRegisterStatus.SUCCESS.ToString();
                        newAccount.OpenId = execResult.Value.OpenId;
                        statusHasChanged  = true;
                        break;

                    case "02":
                        newAccount.Status = PersonalInfoRegisterStatus.WAITFORREVIEW.ToString();
                        statusHasChanged  = true;
                        break;
                    }

                    if (statusHasChanged)
                    {
                        _personalSubAccountRepository.Update(newAccount);
                        var updateResult = _personalSubAccountRepository.SaveChanges();
                        if (!updateResult.Success)
                        {
                            _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, traceMethod, "更新开户信息的OpenId失败", updateResult.FirstException, newAccount);
                            return(new XResult <PersonalRegisterResponse>(null, ErrorCode.DB_UPDATE_FAILED, new DbUpdateException("更新开户信息失败")));
                        }
                    }
                }

                var resp = new PersonalRegisterResponse()
                {
                    Status = newAccount.Status,
                    OpenId = newAccount.OpenId,
                    Msg    = GetRegisterAuditStatusMsg(newAccount.Status)
                };

                return(new XResult <PersonalRegisterResponse>(resp));
            }
            finally
            {
                _lockProvider.UnLock(requestHash);
            }
        }
Exemplo n.º 21
0
        public XResult <PersonalWithdrawBindCardResponse> WithdrawBindCard(PersonalWithdrawBindCardRequest request)
        {
            if (request == null)
            {
                return(new XResult <PersonalWithdrawBindCardResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentNullException(nameof(request))));
            }

            String service = $"{this.GetType().FullName}.WithdrawBindCard(...)";

            if (!request.IsValid)
            {
                _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(request)}.IsValid", LogPhase.ACTION, $"请求参数验证失败:{request.ErrorMessage}", request);
                return(new XResult <PersonalWithdrawBindCardResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentNullException(request.ErrorMessage)));
            }

            var requestHash = $"bindcard:{request.PayeeId}".GetHashCode();

            if (_lockProvider.Exists(requestHash))
            {
                return(new XResult <PersonalWithdrawBindCardResponse>(null, ErrorCode.SUBMIT_REPEAT));
            }

            try
            {
                if (!_lockProvider.Lock(requestHash))
                {
                    return(new XResult <PersonalWithdrawBindCardResponse>(null, ErrorCode.SUBMIT_REPEAT));
                }

                var existedBindInfo = _withdrawBankCardBindInfoRepository.Exists(x => x.PayeeId == request.PayeeId && x.BankCardNo == request.BankCardNo);
                if (existedBindInfo)
                {
                    return(new XResult <PersonalWithdrawBindCardResponse>(null, ErrorCode.INFO_EXISTED, new ArgumentException("绑卡信息已存在")));
                }

                var newBindInfo = new WithdrawBankCardBindInfo()
                {
                    Id           = IDGenerator.GenerateID(),
                    AppId        = request.AppId,
                    PayeeId      = request.PayeeId,
                    BankCardNo   = request.BankCardNo,
                    Mobile       = request.Mobile,
                    ApplyTime    = DateTime.Now,
                    BankCardFlag = request.SecondAccountFlag.ToInt32(),
                    BindStatus   = WithdrawBindCardStatus.PROCESSING.ToString()
                };

                using (var tx = new TransactionScope())
                {
                    _withdrawBankCardBindInfoRepository.Add(newBindInfo);
                    var saveResult = _withdrawBankCardBindInfoRepository.SaveChanges();
                    if (!saveResult.Success)
                    {
                        _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(_withdrawBankCardBindInfoRepository)}.SaveChanges()", "保存提现绑卡信息失败", saveResult.FirstException, request);
                        return(new XResult <PersonalWithdrawBindCardResponse>(null, ErrorCode.DB_UPDATE_FAILED, saveResult.FirstException));
                    }

                    String traceMethod = "Bill99Util.Execute(/person/bankcard/bind)";

                    _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.OK.ToString(), service, traceMethod, LogPhase.BEGIN);

                    var execResult = Bill99UtilYZT.Execute <RawPersonalWithdrawBindCardRequest, RawPersonalWithdrawBindCardResponse>("/person/bankcard/bind", new RawPersonalWithdrawBindCardRequest()
                    {
                        uId        = request.PayeeId,
                        bankAcctId = request.BankCardNo,
                        mobile     = request.Mobile,
                        secondAcct = request.SecondAccountFlag
                    });

                    _logger.Trace(TraceType.BLL.ToString(), (execResult.Success ? CallResultStatus.OK : CallResultStatus.ERROR).ToString(), service, traceMethod, LogPhase.END);

                    if (!execResult.Success || execResult.Value == null)
                    {
                        _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, traceMethod, "提现绑卡失败", execResult.FirstException, request);
                        return(new XResult <PersonalWithdrawBindCardResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, execResult.FirstException));
                    }

                    if (execResult.Value.ResponseCode != "0000")
                    {
                        _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, traceMethod, "提现绑卡失败", null, execResult.Value);
                        return(new XResult <PersonalWithdrawBindCardResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, new RemoteException(execResult.Value.ResponseMessage)));
                    }

                    newBindInfo.MemberBankAccountId = execResult.Value.memberBankAcctId;
                    var updateResult = _withdrawBankCardBindInfoRepository.SaveChanges();
                    if (!updateResult.Success)
                    {
                        _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, traceMethod, "更新绑卡信息失败", updateResult.FirstException, newBindInfo);
                        return(new XResult <PersonalWithdrawBindCardResponse>(null, ErrorCode.DB_UPDATE_FAILED, new RequestException("更新绑卡信息失败")));
                    }

                    tx.Complete();
                }

                var resp = new PersonalWithdrawBindCardResponse()
                {
                    MemberBankAccountId = newBindInfo.MemberBankAccountId,
                    Status = CommonStatus.SUCCESS.ToString(),
                    Msg    = $"绑卡{CommonStatus.SUCCESS.GetDescription()}"
                };

                return(new XResult <PersonalWithdrawBindCardResponse>(resp));
            }
            finally
            {
                _lockProvider.UnLock(requestHash);
            }
        }
Exemplo n.º 22
0
        public XResult <YeePaySinglePayResponse> Pay(YeePaySinglePayRequest request)
        {
            if (request == null)
            {
                return(new XResult <YeePaySinglePayResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentNullException(nameof(request))));
            }

            if (!request.IsValid)
            {
                return(new XResult <YeePaySinglePayResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException(request.ErrorMessage)));
            }

            String service     = $"{this.GetType().FullName}.Pay(...)";
            var    requestHash = $"pay:{request.AppId}.{request.OutTradeNo}".GetHashCode();

            if (_lockProvider.Exists(requestHash))
            {
                return(new XResult <YeePaySinglePayResponse>(null, ErrorCode.SUBMIT_REPEAT));
            }

            try
            {
                if (!_lockProvider.Lock(requestHash))
                {
                    return(new XResult <YeePaySinglePayResponse>(null, ErrorCode.SUBMIT_REPEAT));
                }

                var existsOutTradeNo = _fundOutOrderRepository.Exists(x => x.OutTradeNo == request.OutTradeNo);
                if (existsOutTradeNo)
                {
                    return(new XResult <YeePaySinglePayResponse>(null, ErrorCode.OUT_TRADE_NO_EXISTED));
                }

                var now   = DateTime.Now;
                var newId = IDGenerator.GenerateID();

                var fundoutOrder = new FundOutOrder()
                {
                    Id         = newId,
                    TradeNo    = newId.ToString(),
                    AppId      = request.AppId,
                    OutTradeNo = request.OutTradeNo,
                    Amount     = request.Amount.ToDecimal(),
                    RealName   = request.AccountName,
                    BankCardNo = request.BankCardNo,
                    Remark     = request.Remark,
                    PayStatus  = PayStatus.APPLY.ToString(),
                    CreateTime = DateTime.Now
                };

                _fundOutOrderRepository.Add(fundoutOrder);
                var saveResult = _fundOutOrderRepository.SaveChanges();
                if (!saveResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(_fundOutOrderRepository)}.SaveChanges()", "保存代付订单数据失败", saveResult.FirstException, fundoutOrder);
                    return(new XResult <YeePaySinglePayResponse>(null, ErrorCode.DB_UPDATE_FAILED, new DbUpdateException("保存代付订单数据失败")));
                }

                String traceMethod = $"{nameof(YeePayFundOutUtil)}.Execute(...)";

                _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.OK.ToString(), service, traceMethod, LogPhase.BEGIN, "开始调用易宝代付支付接口", request);

                //记录请求开始时间
                fundoutOrder.ApplyTime = DateTime.Now;

                var execResult = YeePayFundOutUtil.Execute <RawYeePaySinglePayRequest, RawYeePaySinglePayResult>("/rest/v1.0/balance/transfer_send", new RawYeePaySinglePayRequest()
                {
                    orderId        = request.OutTradeNo,
                    accountName    = request.AccountName,
                    accountNumber  = request.BankCardNo,
                    amount         = request.Amount,
                    bankCode       = request.BankCode,
                    batchNo        = fundoutOrder.TradeNo,
                    customerNumber = GlobalConfig.YeePay_FundOut_MerchantNo,
                    groupNumber    = GlobalConfig.YeePay_FundOut_MerchantNo,
                    feeType        = request.FeeType
                });

                //记录请求结束时间
                fundoutOrder.EndTime = DateTime.Now;

                _logger.Trace(TraceType.BLL.ToString(), (execResult.Success ? CallResultStatus.OK : CallResultStatus.ERROR).ToString(), service, traceMethod, LogPhase.ACTION, "结束调用易宝代付支付接口");

                if (!execResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, traceMethod, "代付失败", execResult.FirstException, execResult);
                    return(new XResult <YeePaySinglePayResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, new RequestException(execResult.ErrorMessage)));
                }

                var respResult = execResult.Value;
                if (respResult.errorCode != "BAC001")
                {
                    fundoutOrder.PayStatus = PayStatus.FAILURE.ToString();
                    UpdateFundOutOrder(fundoutOrder);
                    return(new XResult <YeePaySinglePayResponse>(null, ErrorCode.FAILURE, new RemoteException(respResult.errorMsg.HasValue() ? respResult.errorMsg : "发送请求失败")));
                }

                fundoutOrder.PayStatus = PayStatus.PROCESSING.ToString();
                switch (respResult.transferStatusCode)
                {
                case "0028":
                    fundoutOrder.PayStatus = PayStatus.FAILURE.ToString();
                    break;
                }

                UpdateFundOutOrder(fundoutOrder);

                var payResp = new YeePaySinglePayResponse()
                {
                    BatchNo    = respResult.batchNo,
                    OutTradeNo = request.OutTradeNo,
                    Status     = fundoutOrder.PayStatus,
                    Msg        = GetPayStatusDescription(fundoutOrder.PayStatus)
                };

                return(new XResult <YeePaySinglePayResponse>(payResp));
            }
            finally
            {
                _lockProvider.UnLock(requestHash);
            }
        }
Exemplo n.º 23
0
        public XResult <YeePayAgreePayRefundResponse> Refund(YeePayAgreePayRefundRequest request)
        {
            if (request == null)
            {
                return(new XResult <YeePayAgreePayRefundResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentNullException(nameof(request))));
            }

            if (!request.IsValid)
            {
                return(new XResult <YeePayAgreePayRefundResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException(request.ErrorMessage)));
            }

            String service = $"{this.GetType().FullName}.{nameof(Refund)}(...)";

            var requestHash = $"{nameof(Refund)}:{request.OutTradeNo}".GetHashCode();

            if (_lockProvider.Exists(requestHash))
            {
                return(new XResult <YeePayAgreePayRefundResponse>(null, ErrorCode.SUBMIT_REPEAT));
            }

            try
            {
                if (!_lockProvider.Lock(requestHash))
                {
                    return(new XResult <YeePayAgreePayRefundResponse>(null, ErrorCode.SUBMIT_REPEAT));
                }

                // 保证外部交易号不重复
                var existsOutTradeNo = _payOrderRepository.Exists(x => x.AppId == request.AppId && x.OutTradeNo == request.OutTradeNo);
                if (existsOutTradeNo)
                {
                    return(new XResult <YeePayAgreePayRefundResponse>(null, ErrorCode.OUT_TRADE_NO_EXISTED));
                }

                //保证原始单号是存在的
                var originalPayOrder = _payOrderRepository.QueryProvider.FirstOrDefault(x => x.OutTradeNo == request.OriginalOutTradeNo);
                if (originalPayOrder == null)
                {
                    return(new XResult <YeePayAgreePayRefundResponse>(null, ErrorCode.INFO_NOT_EXIST, new ArgumentException("原支付单不存在")));
                }

                if (request.Amount < 0.01m || request.Amount > originalPayOrder.PayAmount)
                {
                    return(new XResult <YeePayAgreePayRefundResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException("退款金额必须大于0.01元且小于或等于支付金额")));
                }

                //生成全局唯一的ID号
                Int64 newId     = IDGenerator.GenerateID();
                var   tradeTime = DateTime.Now;

                // 添加退款记录
                var refundOrder = new PayOrder()
                {
                    Id             = newId,
                    AppId          = request.AppId,
                    PayerId        = originalPayOrder.PayerId,
                    OutTradeNo     = request.OutTradeNo,
                    TradeNo        = originalPayOrder.TradeNo,
                    PayAmount      = request.Amount,
                    BankCardNo     = originalPayOrder.BankCardNo,
                    PayChannelCode = GlobalConfig.YEEPAY_PAYCHANNEL_CODE,
                    PayStatus      = PayStatus.APPLY.ToString(),
                    PayType        = PayType.REFUND.ToString(),
                    CreateTime     = tradeTime,
                    Remark         = request.Remark
                };

                _payOrderRepository.Add(refundOrder);
                var saveResult = _payOrderRepository.SaveChanges();
                if (!saveResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(_payOrderRepository)}.SaveChanges()", "支付单保存失败", saveResult.FirstException, refundOrder);
                    return(new XResult <YeePayAgreePayRefundResponse>(null, ErrorCode.DB_UPDATE_FAILED, saveResult.FirstException));
                }

                var execResult = YeePayAgreePayUtil.Execute <RawYeePayRefundRequest, RawYeePayRefundResponse>("/rest/v1.0/paperorder/api/refund/request", new RawYeePayRefundRequest()
                {
                    merchantno       = GlobalConfig.YeePay_AgreePay_MerchantNo,
                    requestno        = request.OutTradeNo,
                    paymentyborderid = refundOrder.TradeNo,
                    amount           = request.Amount.ToString("0.00"),
                    requesttime      = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                    remark           = request.Remark
                });

                String callMethod = $"{nameof(YeePayAgreePayUtil)}.{nameof(YeePayAgreePayUtil.Execute)}(...)";

                if (!execResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, callMethod, "支付失败", execResult.FirstException, execResult);
                    return(new XResult <YeePayAgreePayRefundResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, execResult.FirstException));
                }

                if (execResult.Value == null)
                {
                    return(new XResult <YeePayAgreePayRefundResponse>(null, ErrorCode.REMOTE_RETURN_NOTHING));
                }

                var respResult = execResult.Value;

                //如果易宝返回的不是PROCESSING则表示处理失败
                if (respResult.status != nameof(PayStatus.PROCESSING))
                {
                    refundOrder.PayStatus  = PayStatus.FAILURE.ToString();
                    refundOrder.UpdateTime = DateTime.Now;
                    UpdatePayOrder(service, refundOrder);
                    return(new XResult <YeePayAgreePayRefundResponse>(null, ErrorCode.FAILURE, new RemoteException($"{respResult.errorcode}:{respResult.errormsg}")));
                }

                //如果易宝返回PROCESSING表示已处理
                //并且要将易宝返回的易宝内部交易号更新到数据库
                //这个TradeNo以后可以作为退款接口的原交易号
                refundOrder.PayStatus  = nameof(PayStatus.PROCESSING);
                refundOrder.TradeNo    = respResult.yborderid;
                refundOrder.UpdateTime = DateTime.Now;
                UpdatePayOrder(service, refundOrder);

                var resp = new YeePayAgreePayRefundResponse()
                {
                    OutTradeNo    = respResult.requestno,
                    YeePayTradeNo = respResult.yborderid,
                    ApplyTime     = tradeTime.ToString("yyyy-MM-dd HH:mm:ss"),
                    Status        = PayStatus.PROCESSING.ToString(),
                    Msg           = PayStatus.PROCESSING.GetDescription()
                };

                return(new XResult <YeePayAgreePayRefundResponse>(resp));
            }
            finally
            {
                _lockProvider.UnLock(requestHash);
            }
        }
Exemplo n.º 24
0
        public XResult <CPIEntrustPayPaymentResponse> Pay(CPIEntrustPayPaymentRequest request)
        {
            if (request == null)
            {
                return(new XResult <CPIEntrustPayPaymentResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentNullException(nameof(request))));
            }

            if (!request.IsValid)
            {
                return(new XResult <CPIEntrustPayPaymentResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException(request.ErrorMessage)));
            }

            if (request.Amount < GlobalConfig.X99bill_EntrustPay_PayMinAmount)
            {
                return(new XResult <CPIEntrustPayPaymentResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException($"支付金额至少为{GlobalConfig.X99bill_EntrustPay_PayMinAmount.ToString()}元")));
            }

            var parseSharingInfoResult = JsonUtil.DeserializeObject <SharingInfo>(request.SharingInfo);

            if (!parseSharingInfoResult.Success)
            {
                return(new XResult <CPIEntrustPayPaymentResponse>(null, ErrorCode.DESERIALIZE_FAILED, new ArgumentException("解析SharingInfo参数失败")));
            }

            var sharingInfo = parseSharingInfoResult.Value;

            String service = $"{this.GetType().FullName}.{nameof(Pay)}(...)";

            var requestHash = $"{request.OutTradeNo}".GetHashCode();

            if (_lockProvider.Exists(requestHash))
            {
                return(new XResult <CPIEntrustPayPaymentResponse>(null, ErrorCode.SUBMIT_REPEAT));
            }

            try
            {
                if (!_lockProvider.Lock(requestHash))
                {
                    return(new XResult <CPIEntrustPayPaymentResponse>(null, ErrorCode.SUBMIT_REPEAT));
                }

                var existsOutTradeNo = _payOrderRepository.Exists(x => x.OutTradeNo == request.OutTradeNo);
                if (existsOutTradeNo)
                {
                    return(new XResult <CPIEntrustPayPaymentResponse>(null, ErrorCode.OUT_TRADE_NO_EXISTED));
                }

                //生成全局唯一的ID号
                String tradeNo = IDGenerator.GenerateID().ToString();

                // 1. 添加交易记录
                var newOrder = new PayOrder()
                {
                    Id             = IDGenerator.GenerateID(),
                    AppId          = request.AppId,
                    OutTradeNo     = request.OutTradeNo,
                    TradeNo        = tradeNo,
                    PayAmount      = request.Amount,
                    BankCardNo     = request.BankCardNo,
                    PayerId        = request.PayerId,
                    PayChannelCode = GlobalConfig.X99BILL_PAYCHANNEL_CODE,
                    PayStatus      = PayStatus.APPLY.ToString(),
                    PayType        = PayType.ENTRUSTPAY.ToString(),
                    CreateTime     = DateTime.Now
                };

                _payOrderRepository.Add(newOrder);
                var saveResult = _payOrderRepository.SaveChanges();
                if (!saveResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), nameof(CallResultStatus.ERROR), service, $"{nameof(_payOrderRepository)}.SaveChanges()", "支付单保存失败", saveResult.FirstException, newOrder);
                    return(new XResult <CPIEntrustPayPaymentResponse>(null, ErrorCode.DB_UPDATE_FAILED, saveResult.FirstException));
                }

                //添加分账记录
                var allotAmountOrder = new AllotAmountOrder()
                {
                    Id          = IDGenerator.GenerateID(),
                    AppId       = request.AppId,
                    PayeeId     = request.PayerId,
                    TradeNo     = tradeNo,
                    OutTradeNo  = request.OutTradeNo,
                    TotalAmount = request.Amount,
                    FeePayerId  = sharingInfo.FeePayerId,
                    SharingType = sharingInfo.SharingType == "0" ? AllotAmountType.Pay.ToString() : AllotAmountType.Refund.ToString(),
                    SharingInfo = sharingInfo.SharingData,
                    ApplyTime   = DateTime.Now,
                    Status      = AllotAmountOrderStatus.APPLY.ToString()
                };

                _allotAmountOrderRepository.Add(allotAmountOrder);
                saveResult = _allotAmountOrderRepository.SaveChanges();

                if (!saveResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), nameof(CallResultStatus.ERROR), service, $"{nameof(_allotAmountOrderRepository)}.SaveChanges()", "分账数据保存失败", saveResult.FirstException, allotAmountOrder);
                    return(new XResult <CPIEntrustPayPaymentResponse>(null, ErrorCode.DB_UPDATE_FAILED, saveResult.FirstException));
                }

                //构造分账参数
                ExtDate sharingExtDate = null;
                if (sharingInfo.SharingType == "0")
                {
                    //构造消费分账数据
                    var sharingDic = new Dictionary <String, String>(5);
                    sharingDic["sharingFlag"] = "1";
                    sharingDic["feeMode"]     = sharingInfo.FeeMode;
                    sharingDic["feePayer"]    = sharingInfo.FeePayerId;
                    sharingDic["sharingData"] = sharingInfo.SharingData;

                    sharingExtDate = new ExtDate()
                    {
                        Key   = "sharingInfo",
                        Value = JsonUtil.SerializeObject(sharingDic).Value
                    };
                }
                else if (sharingInfo.SharingType == "1")
                {
                    //构造退款分账数据
                    var sharingDic = new Dictionary <String, String>(5);
                    sharingDic["sharingFlag"] = "1";
                    sharingDic["feeMode"]     = sharingInfo.FeeMode;
                    sharingDic["feePayer"]    = sharingInfo.FeePayerId;
                    sharingDic["sharingData"] = sharingInfo.SharingData;

                    sharingExtDate = new ExtDate()
                    {
                        Key   = "refundSharingInfo",
                        Value = JsonUtil.SerializeObject(sharingDic).Value
                    };
                }

                var tradeTime = DateTime.Now;

                var payRequest = new EntrustPayRequest()
                {
                    Version = "1.0",
                    EntrustPayRequestContent = new EntrustPayRequestContent()
                    {
                        Amount            = request.Amount.ToString(),
                        CardHolderId      = request.IDCardNo,
                        CardHolderName    = request.RealName,
                        CardNo            = request.BankCardNo,
                        EntryTime         = tradeTime.ToString("yyyyMMddHHmmss"),
                        ExternalRefNumber = request.OutTradeNo,
                        IdType            = "0",
                        InteractiveStatus = "TR1",
                        TxnType           = "PUR",
                        ExtMap            = new ExtMap()
                        {
                            ExtDates = new ExtDate[] {
                                new ExtDate()
                                {
                                    Key = "phone", Value = request.Mobile
                                },
                                sharingExtDate
                            }
                        }
                    }
                };

                String callMethod = $"{_api.GetType().FullName}.{nameof(_api.EntrustPay)}(...)";

                _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.OK.ToString(), service, callMethod, LogPhase.BEGIN, $"开始调用{callMethod}", new Object[] { ApiConfig.Bill99_EntrustPay_Pay_RequestUrl, payRequest });

                var result = _api.EntrustPay(ApiConfig.Bill99_EntrustPay_Pay_RequestUrl, payRequest);

                _logger.Trace(TraceType.BLL.ToString(), (result.Success ? CallResultStatus.OK : CallResultStatus.ERROR).ToString(), service, callMethod, LogPhase.END, $"完成调用{callMethod}", result.Value);

                if (!result.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, callMethod, "支付失败", result.FirstException, payRequest);
                    UpdateAllotAmountOrder(service, allotAmountOrder, AllotAmountOrderStatus.FAILURE);
                    return(new XResult <CPIEntrustPayPaymentResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, result.FirstException));
                }

                if (result.Value == null || result.Value.EntrustPayResponseContent == null)
                {
                    _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, callMethod, LogPhase.ACTION, "快钱未返回任何数据");
                    UpdateAllotAmountOrder(service, allotAmountOrder, AllotAmountOrderStatus.FAILURE);
                    return(new XResult <CPIEntrustPayPaymentResponse>(null, ErrorCode.REMOTE_RETURN_NOTHING));
                }

                var respContent = result.Value.EntrustPayResponseContent;
                if (respContent.ResponseCode != "00")
                {
                    UpdateAllotAmountOrder(service, allotAmountOrder, AllotAmountOrderStatus.FAILURE);
                    return(new XResult <CPIEntrustPayPaymentResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, new RemoteException(respContent.ResponseTextMessage)));
                }

                UpdateAllotAmountOrder(service, allotAmountOrder, AllotAmountOrderStatus.SUCCESS);

                //判断是否有该付款人的绑卡信息,如果没有则创建
                var existesBankCardInfo = (from t0 in _agreePayBankCardInfoRepository.QueryProvider
                                           where t0.IDCardNo == request.IDCardNo && t0.BankCardNo == request.BankCardNo
                                           select t0).Count() > 0;
                if (!existesBankCardInfo)
                {
                    var bankcardInfo = new AgreePayBankCardInfo()
                    {
                        Id         = IDGenerator.GenerateID(),
                        AppId      = request.AppId,
                        RealName   = request.RealName,
                        BankCardNo = request.BankCardNo,
                        IDCardNo   = request.IDCardNo,
                        Mobile     = request.Mobile,
                        BankCode   = "-",
                        UpdateTime = DateTime.Now
                    };

                    _agreePayBankCardInfoRepository.Add(bankcardInfo);

                    saveResult = _agreePayBankCardInfoRepository.SaveChanges();
                    if (!saveResult.Success)
                    {
                        _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(_agreePayBankCardInfoRepository)}.SaveChanges()", "保存付款人信息失败", saveResult.FirstException, bankcardInfo);
                    }
                }

                var resp = new CPIEntrustPayPaymentResponse()
                {
                    OutTradeNo = respContent.ExternalRefNumber,
                    TradeNo    = tradeNo,
                    PayTime    = tradeTime.ToString("yyyy-MM-dd HH:mm:ss"),
                    Status     = PayStatus.SUCCESS.ToString(),
                    Msg        = PayStatus.SUCCESS.GetDescription()
                };

                //根据返回码计算对应的支付状态,并更新到数据库
                var payStatus = Bill99Util.GetAgreepayPayStatus(respContent.ResponseCode);
                var payOrder  = (from t0 in _payOrderRepository.QueryProvider
                                 where t0.TradeNo == tradeNo
                                 select t0).FirstOrDefault();

                //如果支付单存在,并且状态不是最终状态,才更新状态
                if (newOrder != null &&
                    newOrder.PayStatus != PayStatus.SUCCESS.ToString() &&
                    newOrder.PayStatus != PayStatus.FAILURE.ToString())
                {
                    newOrder.PayStatus  = payStatus.ToString();
                    newOrder.UpdateTime = DateTime.Now;
                    _payOrderRepository.Update(newOrder);
                    saveResult = _payOrderRepository.SaveChanges();
                    if (!saveResult.Success)
                    {
                        _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(_payOrderRepository)}.SaveChanges()", "更新支付结果失败", saveResult.FirstException, newOrder);
                    }
                }

                return(new XResult <CPIEntrustPayPaymentResponse>(resp));
            }
            finally
            {
                _lockProvider.UnLock(requestHash);
            }
        }
Exemplo n.º 25
0
        /// <summary>
        /// Adds new DataObjects to the database.
        /// </summary>
        /// <param name="dataObjects">DataObjects to add to the database</param>
        /// <param name="tableHandler">Table Handler for the DataObjects Collection</param>
        /// <returns>True if objects were added successfully; false otherwise</returns>
        protected override IEnumerable <bool> AddObjectImpl(DataTableHandler tableHandler, IEnumerable <DataObject> dataObjects)
        {
            var success = new List <bool>();

            if (!dataObjects.Any())
            {
                return(success);
            }

            try
            {
                // Check Primary Keys
                var usePrimaryAutoInc = tableHandler.FieldElementBindings.Any(bind => bind.PrimaryKey != null && bind.PrimaryKey.AutoIncrement);

                // Columns
                var columns = tableHandler.FieldElementBindings.Where(bind => bind.PrimaryKey == null || !bind.PrimaryKey.AutoIncrement)
                              .Select(bind => new { Binding = bind, ColumnName = string.Format("`{0}`", bind.ColumnName), ParamName = string.Format("@{0}", bind.ColumnName) }).ToArray();

                // Prepare SQL Query
                var command = string.Format("INSERT INTO `{0}` ({1}) VALUES({2})", tableHandler.TableName,
                                            string.Join(", ", columns.Select(col => col.ColumnName)),
                                            string.Join(", ", columns.Select(col => col.ParamName)));

                var objs = dataObjects.ToArray();

                // Init Object Id GUID
                foreach (var obj in objs.Where(obj => obj.ObjectId == null))
                {
                    obj.ObjectId = IDGenerator.GenerateID();
                }

                // Build Parameters
                var parameters = objs.Select(obj => columns.Select(col => new QueryParameter(col.ParamName, col.Binding.GetValue(obj))));

                // Primary Key Auto Inc Handler
                if (usePrimaryAutoInc)
                {
                    var lastId = ExecuteScalarImpl(command, parameters, true);

                    var binding         = tableHandler.FieldElementBindings.First(bind => bind.PrimaryKey != null && bind.PrimaryKey.AutoIncrement);
                    var resultByObjects = lastId.Select((result, index) => new { Result = Convert.ToInt64(result), DataObject = objs[index] });

                    foreach (var result in resultByObjects)
                    {
                        if (result.Result > 0)
                        {
                            DatabaseSetValue(result.DataObject, binding, result.Result);
                            result.DataObject.ObjectId    = result.Result.ToString();
                            result.DataObject.Dirty       = false;
                            result.DataObject.IsPersisted = true;
                            result.DataObject.IsDeleted   = false;
                            success.Add(true);
                        }
                        else
                        {
                            if (Log.IsErrorEnabled)
                            {
                                Log.ErrorFormat("Error adding data object into {0} Object = {1}, UsePrimaryAutoInc, Query = {2}", tableHandler.TableName, result.DataObject, command);
                            }

                            success.Add(false);
                        }
                    }
                }
                else
                {
                    var affected        = ExecuteNonQueryImpl(command, parameters);
                    var resultByObjects = affected.Select((result, index) => new { Result = result, DataObject = objs[index] });

                    foreach (var result in resultByObjects)
                    {
                        if (result.Result > 0)
                        {
                            result.DataObject.Dirty       = false;
                            result.DataObject.IsPersisted = true;
                            result.DataObject.IsDeleted   = false;
                            success.Add(true);
                        }
                        else
                        {
                            if (Log.IsErrorEnabled)
                            {
                                Log.ErrorFormat("Error adding data object into {0} Object = {1} Query = {2}", tableHandler.TableName, result.DataObject, command);
                            }

                            success.Add(false);
                        }
                    }
                }
            }
            catch (Exception e)
            {
                if (Log.IsErrorEnabled)
                {
                    Log.ErrorFormat("Error while adding data objects in table: {0}\n{1}", tableHandler.TableName, e);
                }
            }

            return(success);
        }
Exemplo n.º 26
0
        /// <summary>
        /// Adds a new object to the database.
        /// </summary>
        /// <param name="dataObject">the object to add to the database</param>
        /// <returns>true if the object was added successfully; false otherwise</returns>
        protected override bool AddObjectImpl(DataObject dataObject)
        {
            try
            {
                string tableName = dataObject.TableName;

                var columns = new StringBuilder();
                var values  = new StringBuilder();

                MemberInfo[] objMembers        = dataObject.GetType().GetMembers();
                bool         hasRelations      = false;
                bool         usePrimary        = false;
                object       primaryKey        = null;
                string       primaryColumnName = "";
                bool         firstColumn       = true;
                string       dateFormat        = Connection.GetDBDateFormat();

                for (int i = 0; i < objMembers.Length; i++)
                {
                    bool isPrimary = false;

                    if (!hasRelations)
                    {
                        object[] relAttrib = GetRelationAttributes(objMembers[i]);
                        hasRelations = relAttrib.Length > 0;
                    }
                    object[] keyAttrib = objMembers[i].GetCustomAttributes(typeof(PrimaryKey), true);
                    object[] attrib    = objMembers[i].GetCustomAttributes(typeof(DataElement), true);

                    // if a primary key field is using auto increment then use it as the key instead of the tablename_id column
                    if (keyAttrib.Length > 0 && (keyAttrib[0] as PrimaryKey).AutoIncrement)
                    {
                        usePrimary        = true;
                        primaryColumnName = objMembers[i].Name;
                        isPrimary         = true;
                    }

                    if (attrib.Length > 0 || keyAttrib.Length > 0)
                    {
                        object val = null;
                        if (objMembers[i] is PropertyInfo)
                        {
                            val = ((PropertyInfo)objMembers[i]).GetValue(dataObject, null);
                        }
                        else if (objMembers[i] is FieldInfo)
                        {
                            val = ((FieldInfo)objMembers[i]).GetValue(dataObject);
                        }

                        if (firstColumn == false)
                        {
                            columns.Append(", ");
                            values.Append(", ");
                        }

                        columns.Append("`" + objMembers[i].Name + "`");

                        firstColumn = false;

                        if (val is bool)
                        {
                            val = ((bool)val) ? (byte)1 : (byte)0;
                        }
                        else if (val is DateTime)
                        {
                            val = ((DateTime)val).ToString(dateFormat);
                        }
                        else if (val is float)
                        {
                            val = ((float)val).ToString(Nfi);
                        }
                        else if (val is double)
                        {
                            val = ((double)val).ToString(Nfi);
                        }
                        else if (val is string)
                        {
                            val = Escape(val.ToString());
                        }

                        values.Append('\'');
                        values.Append(val);
                        values.Append('\'');

                        if (isPrimary)
                        {
                            if (val is int)
                            {
                                primaryKey = Convert.ToInt32(val);
                            }
                            else if (val is long)
                            {
                                primaryKey = Convert.ToInt64(val);
                            }
                            else
                            {
                                if (Log.IsErrorEnabled)
                                {
                                    Log.Error("Error adding object into " + dataObject.TableName + ".  PrimaryKey with AutoIncrement must be of type int or long.");
                                }

                                return(false);
                            }
                        }
                    }
                }

                if (usePrimary == false)
                {
                    if (dataObject.ObjectId == null)
                    {
                        dataObject.ObjectId = IDGenerator.GenerateID();
                    }

                    // Add the silly Tablename_ID column
                    columns.Insert(0, "`" + tableName + "_ID`, ");
                    values.Insert(0, "'" + Escape(dataObject.ObjectId) + "', ");
                }

                string sql = "INSERT INTO `" + tableName + "` (" + columns + ") VALUES (" + values + ")";

                if (Log.IsDebugEnabled)
                {
                    Log.Debug(sql);
                }

                if (usePrimary)
                {
                    object objID = Connection.ExecuteScalar(sql + "; SELECT LAST_INSERT_ID();");

                    object newID;
                    bool   newIDzero = false;
                    bool   error     = false;

                    if (primaryKey is int)
                    {
                        newID     = Convert.ToInt32(objID);
                        newIDzero = (int)newID == 0;
                        error     = newIDzero && (int)primaryKey == 0;
                    }
                    else
                    {
                        newID     = Convert.ToInt64(objID);
                        newIDzero = (long)newID == 0;
                        error     = newIDzero && (long)primaryKey == 0;
                    }

                    if (primaryKey == null || error)
                    {
                        if (Log.IsErrorEnabled)
                        {
                            Log.Error("Error adding object into " + dataObject.TableName + " ID=" + objID + ", UsePrimary, Query = " + sql);
                        }
                        return(false);
                    }
                    else
                    {
                        if (newIDzero)
                        {
                            newID = Convert.ToInt64(primaryKey);
                        }

                        for (int i = 0; i < objMembers.Length; i++)
                        {
                            if (objMembers[i].Name == primaryColumnName)
                            {
                                if (objMembers[i] is PropertyInfo)
                                {
                                    if (primaryKey is long)
                                    {
                                        ((PropertyInfo)objMembers[i]).SetValue(dataObject, (long)newID, null);
                                    }
                                    else
                                    {
                                        ((PropertyInfo)objMembers[i]).SetValue(dataObject, (int)newID, null);
                                    }
                                }
                                else if (objMembers[i] is FieldInfo)
                                {
                                    if (primaryKey is long)
                                    {
                                        ((FieldInfo)objMembers[i]).SetValue(dataObject, (long)newID);
                                    }
                                    else
                                    {
                                        ((FieldInfo)objMembers[i]).SetValue(dataObject, (int)newID);
                                    }
                                }

                                break;
                            }
                        }
                    }
                }
                else
                {
                    int res = Connection.ExecuteNonQuery(sql);
                    if (res == 0)
                    {
                        if (Log.IsErrorEnabled)
                        {
                            Log.Error("Error adding object into " + dataObject.TableName + " ID=" + dataObject.ObjectId + "Query = " + sql);
                        }
                        return(false);
                    }
                }


                if (hasRelations)
                {
                    SaveObjectRelations(dataObject);
                }

                dataObject.Dirty       = false;
                dataObject.IsPersisted = true;
                dataObject.IsDeleted   = false;

                return(true);
            }
            catch (Exception e)
            {
                if (Log.IsErrorEnabled)
                {
                    Log.Error("Error while adding data object: " + dataObject.ToString(), e);
                }
            }

            return(false);
        }
Exemplo n.º 27
0
        public XResult <YeePayAgreePayPaymentResponse> Pay(YeePayAgreePayPaymentRequest request)
        {
            if (request == null)
            {
                return(new XResult <YeePayAgreePayPaymentResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentNullException(nameof(request))));
            }

            if (!request.IsValid)
            {
                return(new XResult <YeePayAgreePayPaymentResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException(request.ErrorMessage)));
            }

            String terminalPattern = $"^({Resources.YeePayAgreePayTerminalNo})|({Resources.YeePayEntrustPayTerminalNo})$";

            if (!Regex.IsMatch(request.TerminalNo, terminalPattern))
            {
                return(new XResult <YeePayAgreePayPaymentResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException("TerminalNo字段传值错误")));
            }

            if (request.Amount < GlobalConfig.YeePay_AgreePay_PayMinAmount)
            {
                return(new XResult <YeePayAgreePayPaymentResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException($"支付总金额必须大于{GlobalConfig.YeePay_AgreePay_PayMinAmount.ToString()}")));
            }

            String service = $"{this.GetType().FullName}.{nameof(Pay)}(...)";

            var requestHash = $"{nameof(Pay)}:{request.OutTradeNo}".GetHashCode();

            if (_lockProvider.Exists(requestHash))
            {
                return(new XResult <YeePayAgreePayPaymentResponse>(null, ErrorCode.SUBMIT_REPEAT));
            }

            try
            {
                if (!_lockProvider.Lock(requestHash))
                {
                    return(new XResult <YeePayAgreePayPaymentResponse>(null, ErrorCode.SUBMIT_REPEAT));
                }

                // 保证外部交易号不重复
                var existsOutTradeNo = _payOrderRepository.Exists(x => x.AppId == request.AppId && x.OutTradeNo == request.OutTradeNo);
                if (existsOutTradeNo)
                {
                    return(new XResult <YeePayAgreePayPaymentResponse>(null, ErrorCode.OUT_TRADE_NO_EXISTED));
                }

                //生成全局唯一的ID号
                Int64  newId     = IDGenerator.GenerateID();
                String tradeNo   = newId.ToString();
                var    tradeTime = DateTime.Now;

                // 添加支付单记录
                var newOrder = new PayOrder()
                {
                    Id             = newId,
                    AppId          = request.AppId,
                    PayerId        = request.PayerId,
                    OutTradeNo     = request.OutTradeNo,
                    TradeNo        = tradeNo,
                    PayAmount      = request.Amount,
                    BankCardNo     = request.BankCardNo,
                    PayChannelCode = GlobalConfig.YEEPAY_PAYCHANNEL_CODE,
                    PayStatus      = PayStatus.APPLY.ToString(),
                    PayType        = request.TerminalNo == Resources.YeePayAgreePayTerminalNo ? PayType.AGREEMENTPAY.ToString() : PayType.ENTRUSTPAY.ToString(),
                    CreateTime     = tradeTime
                };

                _payOrderRepository.Add(newOrder);
                var saveResult = _payOrderRepository.SaveChanges();
                if (!saveResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(_payOrderRepository)}.SaveChanges()", "支付单保存失败", saveResult.FirstException, newOrder);
                    return(new XResult <YeePayAgreePayPaymentResponse>(null, ErrorCode.DB_UPDATE_FAILED, saveResult.FirstException));
                }

                var result = YeePayAgreePayUtil.Execute <RawYeePayAgreePayPaymentRequest, RawYeePayAgreePayPaymentResponse>("/rest/v1.0/paperorder/unified/pay", new RawYeePayAgreePayPaymentRequest()
                {
                    merchantno   = GlobalConfig.YeePay_AgreePay_MerchantNo,
                    requestno    = request.OutTradeNo,
                    issms        = "false",
                    identityid   = request.PayerId,
                    identitytype = "USER_ID",
                    cardtop      = request.BankCardNo.Substring(0, 6),
                    cardlast     = request.BankCardNo.Substring(request.BankCardNo.Length - 4, 4),
                    amount       = request.Amount.ToString(),
                    productname  = "消费支付",
                    requesttime  = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                    terminalno   = request.TerminalNo
                });

                String callMethod = $"{nameof(YeePayAgreePayUtil)}.{nameof(YeePayAgreePayUtil.Execute)}(...)";

                if (!result.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, callMethod, "支付失败", result.FirstException, result);
                    return(new XResult <YeePayAgreePayPaymentResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, result.FirstException));
                }

                if (result.Value == null)
                {
                    return(new XResult <YeePayAgreePayPaymentResponse>(null, ErrorCode.REMOTE_RETURN_NOTHING));
                }

                var respResult = result.Value;

                //如果易宝返回的不是PROCESSING则表示处理失败
                if (respResult.status != nameof(PayStatus.PROCESSING))
                {
                    newOrder.PayStatus  = PayStatus.FAILURE.ToString();
                    newOrder.UpdateTime = DateTime.Now;
                    UpdatePayOrder(service, newOrder);
                    return(new XResult <YeePayAgreePayPaymentResponse>(null, ErrorCode.FAILURE, new RemoteException($"{respResult.errorcode}:{respResult.errormsg}")));
                }

                //如果易宝返回PROCESSING表示已处理
                //并且要将易宝返回的易宝内部交易号更新到数据库
                //这个TradeNo以后可以作为退款接口的原交易号
                newOrder.PayStatus  = PayStatus.PROCESSING.ToString();
                newOrder.TradeNo    = respResult.yborderid;
                newOrder.UpdateTime = DateTime.Now;
                UpdatePayOrder(service, newOrder);

                var resp = new YeePayAgreePayPaymentResponse()
                {
                    OutTradeNo    = respResult.requestno,
                    YeePayTradeNo = respResult.yborderid,
                    ApplyTime     = tradeTime.ToString("yyyy-MM-dd HH:mm:ss"),
                    Status        = PayStatus.PROCESSING.ToString(),
                    Msg           = PayStatus.PROCESSING.GetDescription()
                };

                return(new XResult <YeePayAgreePayPaymentResponse>(resp));
            }
            finally
            {
                _lockProvider.UnLock(requestHash);
            }
        }
Exemplo n.º 28
0
        public XResult <YeePayAgreePayApplyResponse> Apply(YeePayAgreePayApplyRequest request)
        {
            if (request == null)
            {
                return(new XResult <YeePayAgreePayApplyResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentNullException(nameof(request))));
            }

            if (!request.IsValid)
            {
                return(new XResult <YeePayAgreePayApplyResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException(request.ErrorMessage)));
            }

            String service = $"{this.GetType().FullName}.{nameof(Apply)}(...)";

            var requestHash = $"{nameof(Apply)}:{request.PayerId}.{request.BankCardNo}".GetHashCode();

            if (_lockProvider.Exists(requestHash))
            {
                return(new XResult <YeePayAgreePayApplyResponse>(null, ErrorCode.SUBMIT_REPEAT));
            }

            try
            {
                if (!_lockProvider.Lock(requestHash))
                {
                    return(new XResult <YeePayAgreePayApplyResponse>(null, ErrorCode.SUBMIT_REPEAT));
                }

                DateTime applyTime = DateTime.Now;

                // 如果未保存绑卡信息则添加到数据库
                var existedBankCard = _bankCardInfoRepository.QueryProvider.FirstOrDefault(x => x.IDCardNo == request.IDCardNo && x.BankCardNo == request.BankCardNo);
                if (existedBankCard == null)
                {
                    // 先将绑卡的银行卡数据入库
                    var bankCardInfo = new AgreePayBankCardInfo()
                    {
                        Id         = IDGenerator.GenerateID(),
                        AppId      = request.AppId,
                        RealName   = request.RealName,
                        IDCardNo   = request.IDCardNo,
                        BankCardNo = request.BankCardNo,
                        Mobile     = request.Mobile,
                        BankCode   = request.BankCode,
                        UpdateTime = applyTime
                    };

                    _bankCardInfoRepository.Add(bankCardInfo);
                    var saveResult = _bankCardInfoRepository.SaveChanges();
                    if (!saveResult.Success)
                    {
                        _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(_bankCardInfoRepository)}.SaveChanges()", "快钱协议支付:保存绑卡信息失败", saveResult.FirstException, bankCardInfo);
                        return(new XResult <YeePayAgreePayApplyResponse>(null, ErrorCode.DB_UPDATE_FAILED, saveResult.FirstException));
                    }
                }

                var execResult = YeePayAgreePayUtil.Execute <RawYeePayApplyBindCardRequest, RawYeePayApplyBindCardResponse>("/rest/v1.0/paperorder/unified/auth/request", new RawYeePayApplyBindCardRequest()
                {
                    merchantno   = GlobalConfig.YeePay_AgreePay_MerchantNo,
                    requestno    = request.OutTradeNo,
                    identityid   = request.PayerId,
                    identitytype = "USER_ID",
                    idcardno     = request.IDCardNo,
                    cardno       = request.BankCardNo,
                    idcardtype   = "ID",
                    username     = request.RealName,
                    phone        = request.Mobile,
                    issms        = "true",
                    requesttime  = applyTime.ToString("yyyy/MM/dd HH:mm:ss"),
                    authtype     = "COMMON_FOUR"
                });

                String traceMethod = $"{nameof(YeePayAgreePayUtil)}.{nameof(YeePayAgreePayUtil.Execute)}(...)";

                if (!execResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, traceMethod, "协议支付失败", execResult.FirstException, execResult);
                    return(new XResult <YeePayAgreePayApplyResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, new RequestException(execResult.ErrorMessage)));
                }

                var respResult = execResult.Value;
                if (respResult.status != "TO_VALIDATE")
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, "respResult", $"{respResult.errorcode}:{respResult.errormsg}", null, respResult);

                    _bankCardInfoRepository.Remove(existedBankCard);
                    var removeResult = _bankCardInfoRepository.SaveChanges();
                    if (!removeResult.Success)
                    {
                        _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, "removeResult", "无法删除申请绑卡失败的记录", removeResult.FirstException, existedBankCard);
                    }
                    else
                    {
                        _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.OK.ToString(), service, "removeResult", LogPhase.ACTION, "成功删除申请绑卡失败的记录", existedBankCard);
                    }

                    return(new XResult <YeePayAgreePayApplyResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, new RemoteException(respResult.errormsg)));
                }

                var resp = new YeePayAgreePayApplyResponse()
                {
                    OutTradeNo = respResult.requestno,
                    ApplyTime  = applyTime.ToString("yyyy-MM-dd HH:mm:ss"),
                    PayerId    = request.PayerId,
                    Status     = CommonStatus.SUCCESS.ToString(),
                    Msg        = $"申请{CommonStatus.SUCCESS.GetDescription()}"
                };

                return(new XResult <YeePayAgreePayApplyResponse>(resp));
            }
            finally
            {
                _lockProvider.UnLock(requestHash);
            }
        }
Exemplo n.º 29
0
        public XResult <PayResponse> Pay(PayRequest request)
        {
            if (request == null)
            {
                return(new XResult <PayResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentNullException(nameof(request))));
            }

            String service = $"{this.GetType().FullName}.Pay(...)";

            if (!request.IsValid)
            {
                return(new XResult <PayResponse>(null, ErrorCode.INVALID_ARGUMENT, new ArgumentException(request.ErrorMessage)));
            }

            var requestHash = $"pay:{request.AppId}.{request.OutTradeNo}".GetHashCode();

            if (_lockProvider.Exists(requestHash))
            {
                return(new XResult <PayResponse>(null, ErrorCode.SUBMIT_REPEAT));
            }

            try
            {
                if (!_lockProvider.Lock(requestHash))
                {
                    return(new XResult <PayResponse>(null, ErrorCode.SUBMIT_REPEAT));
                }

                var existsOutTradeNo = _fundOutOrderRepository.Exists(x => x.OutTradeNo == request.OutTradeNo);
                if (existsOutTradeNo)
                {
                    return(new XResult <PayResponse>(null, ErrorCode.OUT_TRADE_NO_EXISTED));
                }

                //申请冻结商户放款余额
                var applyFreezeLoanParas = new Dictionary <String, String>(4);
                applyFreezeLoanParas["MerchantNo"]        = request.MerchantNo;
                applyFreezeLoanParas["OrderNo"]           = request.OutTradeNo;
                applyFreezeLoanParas["FrozenLoanBalance"] = request.Amount;
                applyFreezeLoanParas["Sign"] = MerchantUtil.MD5Sign(applyFreezeLoanParas);

                var client = GetClient();

                String traceMethod = $"{nameof(client)}.PostForm(...)";

                _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.OK.ToString(), service, traceMethod, LogPhase.BEGIN, "开始请求商户系统冻结放款余额", new Object[] { ApiConfig.SystemMerchantAccountBalanceFreezeRequestUrl, applyFreezeLoanParas });

                var freezeResult = client.PostForm <ApiResult>(ApiConfig.SystemMerchantAccountBalanceFreezeRequestUrl, applyFreezeLoanParas);

                _logger.Trace(TraceType.BLL.ToString(), (freezeResult.Success ? CallResultStatus.OK : CallResultStatus.ERROR).ToString(), service, traceMethod, LogPhase.END, "结束请求商户系统冻结放款余额", freezeResult.Value);

                if (!freezeResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, traceMethod, "商户系统冻结放款余额失败", freezeResult.FirstException, applyFreezeLoanParas);
                    return(new XResult <PayResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, new RemoteException("商户系统冻结放款余额失败")));
                }

                if (freezeResult.Value == null)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, traceMethod, "商户系统冻结放款余额返回的业务数据为空", null, applyFreezeLoanParas);
                    return(new XResult <PayResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, new RemoteException("商户系统冻结放款余额返回的业务数据为空")));
                }

                if (freezeResult.Value.Status != "SUCCESS")
                {
                    _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, traceMethod, LogPhase.ACTION, "商户系统冻结放款余额失败", freezeResult.Value);
                    return(new XResult <PayResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, new RemoteException("商户系统冻结放款余额失败")));
                }

                var now   = DateTime.Now;
                var newId = IDGenerator.GenerateID();

                var fundoutOrder = new FundOutOrder()
                {
                    Id         = newId,
                    TradeNo    = newId.ToString(),
                    AppId      = request.AppId,
                    OutTradeNo = request.OutTradeNo,
                    Amount     = request.Amount.ToDecimal(),
                    RealName   = request.RealName,
                    BankCardNo = request.BankCardNo,
                    Mobile     = request.Mobile,
                    Remark     = request.Remark,
                    PayStatus  = PayStatus.APPLY.ToString(),
                    CreateTime = DateTime.Now
                };

                _fundOutOrderRepository.Add(fundoutOrder);
                var saveResult = _fundOutOrderRepository.SaveChanges();
                if (!saveResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(_fundOutOrderRepository)}.SaveChanges()", "保存代付订单数据失败", saveResult.FirstException, fundoutOrder);
                    return(new XResult <PayResponse>(null, ErrorCode.DB_UPDATE_FAILED, new DbUpdateException("保存订单数据失败")));
                }

                var dic = new Dictionary <String, String>(6);
                dic["LoanJsonList"] = JsonUtil.SerializeObject(new FundOutLoanInfo()
                {
                    Amount           = request.Amount,
                    CardNumber       = CryptoHelper.RSAEncrypt(request.BankCardNo, KeyConfig.EPay95_FundOut_PublicKey).Value,
                    IdentificationNo = request.IDCardNo,
                    Mobile           = request.Mobile,
                    OrderNo          = request.OutTradeNo,
                    RealName         = request.RealName,
                    Type             = "0"
                }).Value;
                dic["PlatformMoneymoremore"] = GlobalConfig.X95epay_FundOut_Hehua_PlatformMoneymoremore;
                dic["BatchNo"]   = request.OutTradeNo;
                dic["Remark"]    = request.Remark;
                dic["NotifyURL"] = ApiConfig.EPay95_FundOut_Pay_NotifyUrl;

                var signResult = EPay95Util.MakeSign(dic);
                if (signResult.IsNullOrWhiteSpace())
                {
                    return(new XResult <PayResponse>(null, ErrorCode.SIGN_FAILED));
                }

                dic["LoanJsonList"] = HttpUtility.UrlEncode(dic["LoanJsonList"]);
                dic["SignInfo"]     = signResult;

                _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.OK.ToString(), service, traceMethod, LogPhase.BEGIN, $"开始调用{ApiConfig.EPay95_FundOut_Pay_RequestUrl}", new Object[] { ApiConfig.EPay95_FundOut_Pay_RequestUrl, dic });

                //记录请求开始时间
                fundoutOrder.ApplyTime = DateTime.Now;
                var respMsgResult = client.PostForm(ApiConfig.EPay95_FundOut_Pay_RequestUrl, dic);

                _logger.Trace(TraceType.BLL.ToString(), (respMsgResult.Success ? CallResultStatus.OK : CallResultStatus.ERROR).ToString(), service, traceMethod, LogPhase.ACTION, $"结束调用{ApiConfig.EPay95_FundOut_Pay_RequestUrl}");

                if (!respMsgResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, traceMethod, "代付失败", respMsgResult.FirstException, dic);
                    return(new XResult <PayResponse>(null, ErrorCode.DEPENDENT_API_CALL_FAILED, new RequestException(respMsgResult.ErrorMessage)));
                }

                String respContent = null;
                try
                {
                    respContent = respMsgResult.Value.Content.ReadAsStringAsync().GetAwaiter().GetResult();
                    _logger.Trace(TraceType.BLL.ToString(), CallResultStatus.OK.ToString(), service, traceMethod, LogPhase.END, $"调用{ApiConfig.EPay95_FundOut_Pay_RequestUrl}返回结果", respContent);
                }
                catch (Exception ex)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, traceMethod, "读取代付返回的消息内容出现异常", ex, dic);
                    return(new XResult <PayResponse>(null, ErrorCode.RESPONSE_READ_FAILED, ex));
                }

                if (respContent.IsNullOrWhiteSpace())
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, traceMethod, "双乾未返回任何数据", null, dic);
                    return(new XResult <PayResponse>(null, ErrorCode.REMOTE_RETURN_NOTHING));
                }

                EPay95PayReturnResult respResult = JsonUtil.DeserializeObject <EPay95PayReturnResult>(respContent).Value;
                if (respResult == null)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, "respResult", "无法将代付结果反序列化为EPay95PayReturnResult对象", null, respContent);
                    return(new XResult <PayResponse>(null, ErrorCode.DESERIALIZE_FAILED));
                }

                //记录请求结束时间
                fundoutOrder.EndTime = DateTime.Now;

                switch (respResult.ResultCode)
                {
                case "88":
                case "90":
                case "15":
                    //修改支付状态为正在处理中
                    fundoutOrder.PayStatus = PayStatus.PROCESSING.ToString();
                    break;

                default:
                    //修改支付状态为正在处理中
                    fundoutOrder.PayStatus = PayStatus.FAILURE.ToString();
                    break;
                }

                fundoutOrder.UpdateTime = DateTime.Now;
                _fundOutOrderRepository.Update(fundoutOrder);
                var updateResult = _fundOutOrderRepository.SaveChanges();
                if (!updateResult.Success)
                {
                    _logger.Error(TraceType.BLL.ToString(), CallResultStatus.ERROR.ToString(), service, $"{nameof(_fundOutOrderRepository)}.SaveChanges()", "更新支付状态失败", updateResult.FirstException, fundoutOrder);
                }

                var payResp = new PayResponse()
                {
                    Status = fundoutOrder.PayStatus,
                    Msg    = respResult.Message.HasValue() ? respResult.Message : PayStatus.PROCESSING.GetDescription()
                };

                if (respResult.LoanJsonList != null)
                {
                    payResp.Amount     = respResult.LoanJsonList.Amount;
                    payResp.BankCardNo = respResult.LoanJsonList.CardNumber;
                    payResp.OutTradeNo = respResult.LoanJsonList.OrderNo;
                }

                return(new XResult <PayResponse>(payResp));
            }
            finally
            {
                _lockProvider.UnLock(requestHash);
            }
        }
Exemplo n.º 30
0
        public void DragFinished(bool cancelled)
        {
            if (_isDragging)
            {
                if (cancelled)
                {
                    _isDown     = false;
                    _isDragging = false;
                    SlideBack();
                }
                else
                {
                    Mouse.Capture(null);

                    FrameworkElement directlyOver = Mouse.DirectlyOver as FrameworkElement;

                    while (!(directlyOver is TreeViewItem) && !(directlyOver is TreeView))
                    {
                        if (directlyOver == null)
                        {
                            _isDragging = false;
                            _isDown     = false;
                            _dragCopy   = false;
                            SlideBack();
                            return;
                        }

                        directlyOver = directlyOver.TemplatedParent as FrameworkElement;
                    }

                    TreeViewItem newParent;
                    TreeViewItem oldParent = _originalElement.Parent as TreeViewItem;
                    int          oldIndex  = oldParent.Items.IndexOf(_originalElement);

                    if (directlyOver is TreeViewItem)
                    {
                        newParent = directlyOver as TreeViewItem;
                        int index;

                        if (newParent.Parent is TreeViewItem)
                        {
                            newParent = newParent.Parent as TreeViewItem;
                            index     = newParent.Items.IndexOf(directlyOver);
                        }
                        else
                        {
                            index = 0;
                        }

                        //
                        // Prevent items from being dragged between tree views.
                        //
                        if (newParent.Parent != oldParent.Parent)
                        {
                            DragFinished(true);
                            return;
                        }

                        if (!_dragCopy)
                        {
                            oldParent.Items.Remove(_originalElement);
                            newParent.Items.Insert(index, _originalElement);
                            _originalElement.IsSelected = true;
                            UpdateLayout();
                        }
                        else
                        {
                            //
                            // Hard-coded functionality only for Task objects.
                            //
                            UserTask copy = new UserTask(_originalElement.Header as UserTask);
                            copy.ID = IDGenerator.GenerateID();

                            //
                            // Copy the details file if it exists
                            //
                            if (File.Exists(TaskDatabase.TasksAppData + "\\" + (_originalElement.Header as UserTask).ID))
                            {
                                File.Copy(TaskDatabase.TasksAppData + "\\" + (_originalElement.Header as UserTask).ID,
                                          TaskDatabase.TasksAppData + "\\" + copy.ID);
                            }

                            _originalElement        = new TreeViewItem();
                            _originalElement.Header = copy;

                            newParent.Items.Insert(index, _originalElement);
                            _originalElement.IsSelected = true;

                            // Force a layout update, to ensure that all elements are
                            // in their correct locations.
                            UpdateLayout();

                            AdornerLayer layer = AdornerLayer.GetAdornerLayer(this);
                            layer.Remove(_overlayElement);
                            _overlayElement = new DragDropImage(_originalElement);
                            layer.Add(_overlayElement);
                        }
                    }
                    else
                    {
                        newParent = Items[Items.Count - 1] as TreeViewItem;

                        //
                        // Prevent items from being dragged between tree views.
                        //
                        if (newParent.Parent != oldParent.Parent)
                        {
                            DragFinished(true);
                            return;
                        }

                        if (!_dragCopy)
                        {
                            oldParent.Items.Remove(_originalElement);
                            newParent.Items.Add(_originalElement);
                            _originalElement.IsSelected = true;
                            UpdateLayout();
                        }
                        else
                        {
                            //
                            // Hard-coded functionality only for Task objects.
                            //
                            UserTask copy = new UserTask(_originalElement.Header as UserTask);
                            copy.ID = IDGenerator.GenerateID();

                            //
                            // Copy the details file if it exists
                            //
                            if (File.Exists(TaskDatabase.TasksAppData + "\\" + (_originalElement.Header as UserTask).ID))
                            {
                                File.Copy(TaskDatabase.TasksAppData + "\\" + (_originalElement.Header as UserTask).ID,
                                          TaskDatabase.TasksAppData + "\\" + copy.ID);
                            }

                            _originalElement         = new TreeViewItem();
                            _originalElement.Opacity = 1;
                            _originalElement.Header  = copy;

                            newParent.Items.Add(_originalElement);
                            _originalElement.IsSelected = true;

                            // Force a layout update, to ensure that all elements are
                            // in their correct locations.
                            UpdateLayout();

                            AdornerLayer layer = AdornerLayer.GetAdornerLayer(this);
                            layer.Remove(_overlayElement);
                            _overlayElement = new DragDropImage(_originalElement);
                            layer.Add(_overlayElement);
                        }
                    }

                    newParent.IsExpanded = true;

                    Point mse = Mouse.GetPosition(_originalElement);
                    _overlayElement.LeftOffset = mse.X - _dragOffset.X;
                    _overlayElement.TopOffset  = mse.Y - _dragOffset.Y;

                    DragDirection direction;

                    if (newParent == oldParent)
                    {
                        direction = newParent.Items.IndexOf(_originalElement) < oldIndex ? DragDirection.Up : DragDirection.Down;
                    }
                    else
                    {
                        direction = Items.IndexOf(newParent) < Items.IndexOf(oldParent) ? DragDirection.Up : DragDirection.Down;
                    }

                    if (!(newParent == oldParent && newParent.Items.IndexOf(_originalElement) == oldIndex))
                    {
                        OnItemReorder(new ItemReorderEventArgs(_originalElement, oldParent, newParent, _dragCopy, direction));
                    }

                    SlideBack();
                }
            }
            else
            {
                _dragCopy = false;
                Mouse.Capture(null);
            }

            _isDragging = false;
            _isDown     = false;
        }