add ordermgr
This commit is contained in:
parent
d49b207a37
commit
55112e40b7
@ -15,6 +15,7 @@
|
|||||||
#include "app.h"
|
#include "app.h"
|
||||||
#include "jsondatamgr.h"
|
#include "jsondatamgr.h"
|
||||||
#include "handlermgr.h"
|
#include "handlermgr.h"
|
||||||
|
#include "ApiListener.h"
|
||||||
|
|
||||||
struct MsgNode
|
struct MsgNode
|
||||||
{
|
{
|
||||||
@ -67,10 +68,10 @@ void App::Init(int argc, char* argv[])
|
|||||||
|
|
||||||
if (!ParseOpt()) {
|
if (!ParseOpt()) {
|
||||||
terminated = true;
|
terminated = true;
|
||||||
a8::XPrintf("masterserver启动失败,缺少-i参数\n", {});
|
a8::XPrintf("payserver启动失败,缺少-i参数\n", {});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
a8::XPrintf("masterserver starting instance_id:%d pid:%d\n", {instance_id, getpid()});
|
a8::XPrintf("payserver starting instance_id:%d pid:%d\n", {instance_id, getpid()});
|
||||||
|
|
||||||
loop_mutex_ = new std::mutex();
|
loop_mutex_ = new std::mutex();
|
||||||
loop_cond_ = new std::condition_variable();
|
loop_cond_ = new std::condition_variable();
|
||||||
@ -83,8 +84,9 @@ void App::Init(int argc, char* argv[])
|
|||||||
a8::Timer::Instance()->Init();
|
a8::Timer::Instance()->Init();
|
||||||
JsonDataMgr::Instance()->Init();
|
JsonDataMgr::Instance()->Init();
|
||||||
uuid.SetMachineId(instance_id);
|
uuid.SetMachineId(instance_id);
|
||||||
|
ApiListener::Instance()->Init();
|
||||||
|
|
||||||
a8::UdpLog::Instance()->Info("masterserver starting instance_id:%d pid:%d", {instance_id, getpid()});
|
a8::UdpLog::Instance()->Info("payserver starting instance_id:%d pid:%d", {instance_id, getpid()});
|
||||||
{
|
{
|
||||||
int perf_log_time = 1000 * 60 * 5;
|
int perf_log_time = 1000 * 60 * 5;
|
||||||
if (getenv("is_dev_env")) {
|
if (getenv("is_dev_env")) {
|
||||||
@ -104,6 +106,7 @@ void App::UnInit()
|
|||||||
if (terminated) {
|
if (terminated) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
ApiListener::Instance()->UnInit();
|
||||||
JsonDataMgr::Instance()->UnInit();
|
JsonDataMgr::Instance()->UnInit();
|
||||||
a8::Timer::Instance()->UnInit();
|
a8::Timer::Instance()->UnInit();
|
||||||
HandlerMgr::Instance()->UnInit();
|
HandlerMgr::Instance()->UnInit();
|
||||||
@ -125,7 +128,7 @@ int App::Run()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
a8::UdpLog::Instance()->Info("masterserver running", {});
|
a8::UdpLog::Instance()->Info("payserver running", {});
|
||||||
while (!terminated) {
|
while (!terminated) {
|
||||||
a8::tick_t begin_tick = a8::XGetTickCount();
|
a8::tick_t begin_tick = a8::XGetTickCount();
|
||||||
QuickExecute();
|
QuickExecute();
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <a8/mutable_xobject.h>
|
#include <a8/mutable_xobject.h>
|
||||||
|
|
||||||
#include "handlermgr.h"
|
#include "handlermgr.h"
|
||||||
|
#include "ApiListener.h"
|
||||||
|
|
||||||
static void _GMOpsSelfChecking(f8::JsonHttpRequest* request)
|
static void _GMOpsSelfChecking(f8::JsonHttpRequest* request)
|
||||||
{
|
{
|
||||||
@ -12,10 +13,24 @@ static void _GMOpsSelfChecking(f8::JsonHttpRequest* request)
|
|||||||
request->resp_xobj->SetVal("max_rundelay", 10);
|
request->resp_xobj->SetVal("max_rundelay", 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _GMPayGetOrderId(f8::JsonHttpRequest* request)
|
||||||
|
{
|
||||||
|
request->resp_xobj->SetVal("errcode", 0);
|
||||||
|
request->resp_xobj->SetVal("errmsg", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _GMPayNotify(f8::JsonHttpRequest* request)
|
||||||
|
{
|
||||||
|
request->resp_xobj->SetVal("errcode", 0);
|
||||||
|
request->resp_xobj->SetVal("errmsg", "");
|
||||||
|
}
|
||||||
|
|
||||||
void HandlerMgr::Init()
|
void HandlerMgr::Init()
|
||||||
{
|
{
|
||||||
RegisterNetMsgHandlers();
|
RegisterNetMsgHandlers();
|
||||||
RegisterGMMsgHandler("Ops$selfChecking", _GMOpsSelfChecking);
|
RegisterGMMsgHandler("Ops$selfChecking", _GMOpsSelfChecking);
|
||||||
|
RegisterGMMsgHandler("Pay$getOrderId", _GMPayGetOrderId);
|
||||||
|
RegisterGMMsgHandler("Pay$payNotify", _GMPayNotify);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HandlerMgr::UnInit()
|
void HandlerMgr::UnInit()
|
||||||
@ -30,9 +45,7 @@ void HandlerMgr::ProcGMMsg(unsigned long saddr, int sockhandle,
|
|||||||
const std::string& url, const std::string& querystr)
|
const std::string& url, const std::string& querystr)
|
||||||
{
|
{
|
||||||
if (url != "/webapp/index.php") {
|
if (url != "/webapp/index.php") {
|
||||||
#if 0
|
ApiListener::Instance()->SendText(sockhandle, a8::HttpResponse(404, ""));
|
||||||
GCListener::Instance()->SendText(sockhandle, a8::HttpResponse(404, ""));
|
|
||||||
#endif
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,16 +65,12 @@ void HandlerMgr::ProcGMMsg(unsigned long saddr, int sockhandle,
|
|||||||
if (!request->pending){
|
if (!request->pending){
|
||||||
std::string response;
|
std::string response;
|
||||||
request->resp_xobj->ToJsonStr(response);
|
request->resp_xobj->ToJsonStr(response);
|
||||||
#if 0
|
ApiListener::Instance()->SendText(sockhandle, a8::HttpResponse(response));
|
||||||
GCListener::Instance()->SendText(sockhandle, a8::HttpResponse(response));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
delete request;
|
delete request;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#if 0
|
ApiListener::Instance()->SendText(sockhandle, a8::HttpResponse("{}"));
|
||||||
GCListener::Instance()->SendText(sockhandle, a8::HttpResponse("{}"));
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
684
server/payserver/ordermgr.cc
Normal file
684
server/payserver/ordermgr.cc
Normal file
@ -0,0 +1,684 @@
|
|||||||
|
#include "precompile.h"
|
||||||
|
#include <mutex>
|
||||||
|
#include "ordermgr.h"
|
||||||
|
#if 0
|
||||||
|
#include "DBSListener.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct AddOrderNode
|
||||||
|
{
|
||||||
|
int seqid = 0;
|
||||||
|
int payresult = 0;
|
||||||
|
OrderInfo orderinfo;
|
||||||
|
AddOrderNode* next = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PayNotifyNode
|
||||||
|
{
|
||||||
|
int seqid;
|
||||||
|
int pay_type;//0:normal 1:ios 2:jinqi
|
||||||
|
std::string accountid;
|
||||||
|
std::string roleid;
|
||||||
|
std::string rolename;
|
||||||
|
int serverid;
|
||||||
|
int itemid;
|
||||||
|
std::string itemid_str;
|
||||||
|
std::string orderid;
|
||||||
|
std::string sp_orderid;
|
||||||
|
std::string sp_accountid;
|
||||||
|
double fee;
|
||||||
|
int payresult;
|
||||||
|
PayNotifyNode* next;
|
||||||
|
|
||||||
|
PayNotifyNode()
|
||||||
|
{
|
||||||
|
seqid = 0;
|
||||||
|
pay_type = 0;
|
||||||
|
serverid = 0;
|
||||||
|
itemid = 0;
|
||||||
|
payresult = 0;
|
||||||
|
next = NULL;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ReissueNode
|
||||||
|
{
|
||||||
|
int seqid = 0;
|
||||||
|
std::string orderid;
|
||||||
|
ReissueNode* next = NULL;
|
||||||
|
};
|
||||||
|
|
||||||
|
void OrderMgr::Init()
|
||||||
|
{
|
||||||
|
top_node_ = NULL;
|
||||||
|
bot_node_ = NULL;
|
||||||
|
work_node_ = NULL;
|
||||||
|
pay_notify_top_node_ = NULL;
|
||||||
|
pay_notify_bot_node_ = NULL;
|
||||||
|
pay_notify_work_node_ = NULL;
|
||||||
|
reissue_top_node_ = NULL;
|
||||||
|
reissue_bot_node_ = NULL;
|
||||||
|
reissue_work_node_ = NULL;
|
||||||
|
add_order_mutex_ = new std::mutex();
|
||||||
|
pay_notify_mutex_ = new std::mutex();
|
||||||
|
reissue_mutex_ = new std::mutex();
|
||||||
|
seq_mutex_ = new std::mutex();
|
||||||
|
add_order_result_mutex_ = new std::mutex();
|
||||||
|
pay_notify_result_mutex_ = new std::mutex();
|
||||||
|
|
||||||
|
current_seqid_ = 1000;
|
||||||
|
sub_orderid_ = 1;
|
||||||
|
#if 0
|
||||||
|
last_gen_order_time_ = g_nowtime;
|
||||||
|
#endif
|
||||||
|
last_ping_db_tick_ = a8::XGetTickCount();
|
||||||
|
#if 0
|
||||||
|
//assert(mysql_conn_.Connect("127.0.0.1", 3306, "root", "keji178", "paydb"));
|
||||||
|
assert(mysql_conn_.Connect(g_mysql_host, 3306, g_mysql_user, g_mysql_passwd, "paydb"));
|
||||||
|
query_.SetConnection(&mysql_conn_);
|
||||||
|
DumpMysqlInfo(query_);
|
||||||
|
RegisterNetMsgHandler<OrderMgr, SSMPing>(g_dbsmsghandler, &OrderMgr::_SSMPing);
|
||||||
|
RegisterNetMsgHandler<OrderMgr, D2PPayNotifyACK>(g_dbsmsghandler, &OrderMgr::_D2PPayNotifyACK);
|
||||||
|
#endif
|
||||||
|
LoadPedingOrders();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OrderMgr::UnInit()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void OrderMgr::Update()
|
||||||
|
{
|
||||||
|
if (a8::XGetTickCount() - last_ping_db_tick_ > 1000 * 60 * 5) {
|
||||||
|
last_ping_db_tick_ = a8::XGetTickCount();
|
||||||
|
#if 0
|
||||||
|
if (query_.ExecQuery("SELECT 1;", {}) <= 0) {
|
||||||
|
g_udplog->Warning("mysql disconnect", {});
|
||||||
|
if (mysql_conn_.Connect()) {
|
||||||
|
DumpMysqlInfo(query_);
|
||||||
|
g_udplog->Info("mysql reconnect successed", {});
|
||||||
|
} else {
|
||||||
|
g_udplog->Info("mysql reconnect failed", {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
ProcessOrderMsg();
|
||||||
|
ProcessNotifyMsg();
|
||||||
|
ProcessReissueMsg();
|
||||||
|
UpdatePedingOrders();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OrderMgr::HasTask()
|
||||||
|
{
|
||||||
|
{
|
||||||
|
if (!work_node_) {
|
||||||
|
add_order_mutex_->lock();
|
||||||
|
if (!work_node_ && top_node_) {
|
||||||
|
work_node_ = top_node_;
|
||||||
|
top_node_ = NULL;
|
||||||
|
bot_node_ = NULL;
|
||||||
|
}
|
||||||
|
add_order_mutex_->unlock();
|
||||||
|
}
|
||||||
|
if (work_node_) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
if (!pay_notify_work_node_) {
|
||||||
|
pay_notify_mutex_->lock();
|
||||||
|
if (!pay_notify_work_node_ && pay_notify_top_node_) {
|
||||||
|
pay_notify_work_node_ = pay_notify_top_node_;
|
||||||
|
pay_notify_top_node_ = NULL;
|
||||||
|
pay_notify_bot_node_ = NULL;
|
||||||
|
}
|
||||||
|
pay_notify_mutex_->unlock();
|
||||||
|
}
|
||||||
|
if (pay_notify_work_node_) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
if (!reissue_work_node_) {
|
||||||
|
reissue_mutex_->lock();
|
||||||
|
if (!reissue_work_node_ && reissue_top_node_) {
|
||||||
|
reissue_work_node_ = reissue_top_node_;
|
||||||
|
reissue_top_node_ = NULL;
|
||||||
|
reissue_bot_node_ = NULL;
|
||||||
|
}
|
||||||
|
reissue_mutex_->unlock();
|
||||||
|
}
|
||||||
|
if (reissue_work_node_) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int OrderMgr::AddOrder(const std::string& seqid, const std::string& accountid,
|
||||||
|
const std::string& roleid, const std::string& rolename,
|
||||||
|
const std::string& channel, const std::string& sp_accountid, int serverid,
|
||||||
|
int productid, int price,const std::string& sp_orderid)
|
||||||
|
{
|
||||||
|
int new_seqid = GenSeqId();
|
||||||
|
AddOrderNode *p = new AddOrderNode();
|
||||||
|
p->orderinfo.seqid = seqid;
|
||||||
|
p->orderinfo.accountid = accountid;
|
||||||
|
p->orderinfo.orderid = GenOrderId(productid);
|
||||||
|
p->orderinfo.roleid = roleid;
|
||||||
|
p->orderinfo.rolename = rolename;
|
||||||
|
p->orderinfo.sp_accountid = sp_accountid;
|
||||||
|
p->orderinfo.channel = channel;
|
||||||
|
p->orderinfo.itemid = productid;
|
||||||
|
p->orderinfo.price = price;
|
||||||
|
p->orderinfo.serverid = serverid;
|
||||||
|
p->orderinfo.sp_accountid = sp_orderid;
|
||||||
|
p->seqid = new_seqid;
|
||||||
|
add_order_mutex_->lock();
|
||||||
|
if (bot_node_) {
|
||||||
|
bot_node_->next = p;
|
||||||
|
bot_node_ = p;
|
||||||
|
} else {
|
||||||
|
top_node_ = p;
|
||||||
|
bot_node_ = p;
|
||||||
|
}
|
||||||
|
add_order_mutex_->unlock();
|
||||||
|
return new_seqid;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OrderMgr::WaitForAddOrderFinished(int seqid, AddOrderResult& addresult, int seconds)
|
||||||
|
{
|
||||||
|
a8::tick_t tick = a8::XGetTickCount();
|
||||||
|
while (true) {
|
||||||
|
if (a8::XGetTickCount() - tick > 1000 * seconds) { //timeout
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
add_order_result_mutex_->lock();
|
||||||
|
std::map<int, AddOrderResult>::iterator itr = add_order_results_.find(seqid);
|
||||||
|
if (itr != add_order_results_.end()) {
|
||||||
|
addresult = itr->second;
|
||||||
|
add_order_results_.erase(itr);
|
||||||
|
add_order_result_mutex_->unlock();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
add_order_result_mutex_->unlock();
|
||||||
|
#if 0
|
||||||
|
g_application->NotifyLoopCond();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int OrderMgr::AddPayNotify(int pay_type,
|
||||||
|
const std::string& accountid,
|
||||||
|
const std::string& roleid,
|
||||||
|
const std::string& rolename,
|
||||||
|
int serverid,
|
||||||
|
int itemid,
|
||||||
|
const std::string& itemid_str,
|
||||||
|
const std::string& orderid,
|
||||||
|
const std::string& sp_orderid,
|
||||||
|
double fee,
|
||||||
|
int payresult)
|
||||||
|
{
|
||||||
|
int new_seqid = GenSeqId();
|
||||||
|
PayNotifyNode *p = new PayNotifyNode();
|
||||||
|
p->seqid = new_seqid;
|
||||||
|
p->pay_type = pay_type;
|
||||||
|
p->accountid = accountid;
|
||||||
|
p->roleid = roleid;
|
||||||
|
p->rolename = rolename;
|
||||||
|
p->serverid = serverid;
|
||||||
|
p->itemid = itemid;
|
||||||
|
p->itemid_str = itemid_str;
|
||||||
|
p->orderid = orderid;
|
||||||
|
p->sp_orderid = sp_orderid;
|
||||||
|
p->fee = fee;
|
||||||
|
p->payresult = payresult;
|
||||||
|
pay_notify_mutex_->lock();
|
||||||
|
if (pay_notify_bot_node_) {
|
||||||
|
pay_notify_bot_node_->next = p;
|
||||||
|
pay_notify_bot_node_ = p;
|
||||||
|
} else {
|
||||||
|
pay_notify_top_node_ = p;
|
||||||
|
pay_notify_bot_node_ = p;
|
||||||
|
}
|
||||||
|
pay_notify_mutex_->unlock();
|
||||||
|
return new_seqid;
|
||||||
|
}
|
||||||
|
|
||||||
|
int OrderMgr::AddReissue(const std::string& orderid)
|
||||||
|
{
|
||||||
|
int new_seqid = GenSeqId();
|
||||||
|
ReissueNode *p = new ReissueNode();
|
||||||
|
p->seqid = new_seqid;
|
||||||
|
p->orderid = orderid;
|
||||||
|
reissue_mutex_->lock();
|
||||||
|
if (reissue_bot_node_) {
|
||||||
|
reissue_bot_node_->next = p;
|
||||||
|
reissue_bot_node_ = p;
|
||||||
|
} else {
|
||||||
|
reissue_top_node_ = p;
|
||||||
|
reissue_bot_node_ = p;
|
||||||
|
}
|
||||||
|
reissue_mutex_->unlock();
|
||||||
|
return new_seqid;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OrderMgr::WaitForReissueFinished(int seqid, int& result, int seconds)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OrderMgr::WaitForPayNotifyFinished(int seqid, int& result, int seconds)
|
||||||
|
{
|
||||||
|
a8::tick_t tick = a8::XGetTickCount();
|
||||||
|
while (true) {
|
||||||
|
if (a8::XGetTickCount() - tick > 1000 * seconds) { //timeout
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
pay_notify_result_mutex_->lock();
|
||||||
|
std::map<int, int>::iterator itr = pay_notify_results_.find(seqid);
|
||||||
|
if (itr != pay_notify_results_.end()) {
|
||||||
|
result = itr->second;
|
||||||
|
pay_notify_results_.erase(itr);
|
||||||
|
pay_notify_result_mutex_->unlock();
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
pay_notify_result_mutex_->unlock();
|
||||||
|
#if 0
|
||||||
|
g_application->NotifyLoopCond();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OrderMgr::ProcessOrderMsg()
|
||||||
|
{
|
||||||
|
if (!work_node_ && top_node_) {
|
||||||
|
add_order_mutex_->lock();
|
||||||
|
work_node_ = top_node_;
|
||||||
|
top_node_ = NULL;
|
||||||
|
bot_node_ = NULL;
|
||||||
|
add_order_mutex_->unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
while (work_node_) {
|
||||||
|
AddOrderNode *delnode = work_node_;
|
||||||
|
work_node_ = work_node_->next;
|
||||||
|
|
||||||
|
AddOrderResult result;
|
||||||
|
result.orderinfo = delnode->orderinfo;
|
||||||
|
result.isok = ProcAddOrder(result.orderinfo);
|
||||||
|
add_order_result_mutex_->lock();
|
||||||
|
add_order_results_[delnode->seqid] = result;
|
||||||
|
add_order_result_mutex_->unlock();
|
||||||
|
|
||||||
|
delete delnode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OrderMgr::ProcessReissueMsg()
|
||||||
|
{
|
||||||
|
if (!reissue_work_node_ && reissue_top_node_) {
|
||||||
|
reissue_mutex_->lock();
|
||||||
|
reissue_work_node_ = reissue_top_node_;
|
||||||
|
reissue_top_node_ = NULL;
|
||||||
|
reissue_bot_node_ = NULL;
|
||||||
|
reissue_mutex_->unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
while (reissue_work_node_) {
|
||||||
|
ReissueNode *delnode = reissue_work_node_;
|
||||||
|
reissue_work_node_ = reissue_work_node_->next;
|
||||||
|
|
||||||
|
ProcReissue(delnode->orderid);
|
||||||
|
|
||||||
|
delete delnode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OrderMgr::ProcessNotifyMsg()
|
||||||
|
{
|
||||||
|
if (!pay_notify_work_node_ && pay_notify_top_node_) {
|
||||||
|
pay_notify_mutex_->lock();
|
||||||
|
pay_notify_work_node_ = pay_notify_top_node_;
|
||||||
|
pay_notify_top_node_ = NULL;
|
||||||
|
pay_notify_bot_node_ = NULL;
|
||||||
|
pay_notify_mutex_->unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
while (pay_notify_work_node_) {
|
||||||
|
PayNotifyNode *delnode = pay_notify_work_node_;
|
||||||
|
pay_notify_work_node_ = pay_notify_work_node_->next;
|
||||||
|
|
||||||
|
int result = 0;
|
||||||
|
|
||||||
|
switch (delnode->pay_type) {
|
||||||
|
case 1:
|
||||||
|
result = ProcIosPayOrderNotify(delnode);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
result = ProcOrderNotify(delnode);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
result = ContinueSubscriptions(delnode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pay_notify_mutex_->lock();
|
||||||
|
pay_notify_results_[delnode->seqid] = result;
|
||||||
|
pay_notify_mutex_->unlock();
|
||||||
|
|
||||||
|
delete delnode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OrderMgr::ProcAddOrder(OrderInfo& orderinfo)
|
||||||
|
{
|
||||||
|
#if 1
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
return query_.ExecScript("INSERT INTO orderinfo(orderid, serverid, roleid, rolename, channel, itemid, price, status, createtime, accountid, sp_orderid)" \
|
||||||
|
"VALUES('%s', %d, '%s', '%s', '%s', '%s', %d, %d, %d, '%s','%s');",
|
||||||
|
{
|
||||||
|
orderinfo.orderid,
|
||||||
|
orderinfo.serverid,
|
||||||
|
orderinfo.roleid,
|
||||||
|
orderinfo.rolename,
|
||||||
|
orderinfo.channel,
|
||||||
|
orderinfo.itemid,
|
||||||
|
orderinfo.price,
|
||||||
|
0,
|
||||||
|
g_nowtime,
|
||||||
|
orderinfo.accountid,
|
||||||
|
orderinfo.sp_accountid
|
||||||
|
});
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int OrderMgr::ProcOrderNotify(PayNotifyNode* node)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (node->payresult != 0 && node->payresult != 1) {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
int ret = query_.ExecQuery("SELECT orderid, itemid, roleid, rolename, price, sp_pay_result, serverid "
|
||||||
|
"FROM orderinfo WHERE orderid='%s' and sp_confirm_time=0;",
|
||||||
|
{ node->orderid});
|
||||||
|
if (ret > 0) {
|
||||||
|
if (query_.GetValue(5).GetInt() == 0) {
|
||||||
|
OrderInfo info;
|
||||||
|
info.orderid = query_.GetValue(0).GetString();
|
||||||
|
info.itemid = query_.GetValue(1);
|
||||||
|
info.roleid = query_.GetValue(2).GetString();
|
||||||
|
info.rolename = query_.GetValue(3).GetString();
|
||||||
|
info.price = query_.GetValue(4);
|
||||||
|
info.lastchecktime = g_nowtime - 60 * 3;
|
||||||
|
info.serverid = query_.GetValue(6);
|
||||||
|
if (query_.ExecScript("UPDATE orderinfo SET sp_pay_result=%d, sp_confirm_time=%d, sp_orderid='%s' WHERE orderid='%s';",
|
||||||
|
{
|
||||||
|
node->payresult,
|
||||||
|
g_nowtime,
|
||||||
|
node->sp_orderid,
|
||||||
|
node->orderid
|
||||||
|
})) {
|
||||||
|
if (node->payresult == 1) {
|
||||||
|
peding_orders_[info.orderid] = info;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int OrderMgr::ContinueSubscriptions(PayNotifyNode* node)
|
||||||
|
{
|
||||||
|
#if 1
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
int ret = query_.ExecQuery("SELECT orderid, itemid, roleid, rolename, price, sp_pay_result, serverid "
|
||||||
|
"FROM orderinfo WHERE orderid='%s' ",
|
||||||
|
{ node->orderid });
|
||||||
|
|
||||||
|
if (ret <= 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
OrderInfo info;
|
||||||
|
info.orderid = query_.GetValue(0).GetString();
|
||||||
|
info.itemid = query_.GetValue(1);
|
||||||
|
info.roleid = query_.GetValue(2).GetString();
|
||||||
|
info.rolename = query_.GetValue(3).GetString();
|
||||||
|
info.price = query_.GetValue(4);
|
||||||
|
info.lastchecktime = g_nowtime - 60 * 3;
|
||||||
|
info.serverid = query_.GetValue(6);
|
||||||
|
peding_orders_[info.orderid] = info;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int OrderMgr::ProcIosPayOrderNotify(PayNotifyNode* node)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
Template::RechargeCard *cardtpl = g_configtable->GetRechargeCard(node->itemid);
|
||||||
|
if (!cardtpl) {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
int retcode = query_.ExecQuery("SELECT orderid FROM orderinfo WHERE channel='%s' and sp_orderid='%s';",
|
||||||
|
{
|
||||||
|
std::string(IOS_CHANNEL),
|
||||||
|
node->sp_orderid
|
||||||
|
});
|
||||||
|
if (retcode < 0) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
if (retcode > 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string orderid = GenOrderId(node->itemid);
|
||||||
|
bool ret = query_.ExecScript("INSERT INTO orderinfo(orderid, accountid, roleid, rolename, channel, serverid, itemid, price, status, createtime, sp_orderid, sp_accountid, sp_confirm_time, sp_pay_result)"
|
||||||
|
"VALUES('%s', '%s', '%s', '%s', '%s', %d, %d, %d, 0, %d, '%s', '%s', %d, 1);",
|
||||||
|
{
|
||||||
|
orderid,
|
||||||
|
node->accountid,
|
||||||
|
node->roleid,
|
||||||
|
node->rolename,
|
||||||
|
IOS_CHANNEL,
|
||||||
|
node->serverid,
|
||||||
|
node->itemid,
|
||||||
|
cardtpl->price * 10,
|
||||||
|
g_nowtime,
|
||||||
|
node->sp_orderid,
|
||||||
|
node->sp_accountid,
|
||||||
|
g_nowtime
|
||||||
|
});
|
||||||
|
if (!ret) {
|
||||||
|
printf("prociospaynotify %s\n", mysql_conn_.GetError().c_str());
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
OrderInfo info;
|
||||||
|
info.orderid = orderid;
|
||||||
|
info.accountid = node->accountid;
|
||||||
|
info.itemid = node->itemid;
|
||||||
|
info.price = cardtpl->price * 10;
|
||||||
|
info.customprice = info.price;
|
||||||
|
info.serverid = node->serverid;
|
||||||
|
info.roleid = node->roleid;
|
||||||
|
info.rolename = node->rolename;
|
||||||
|
info.sp_accountid = node->sp_accountid;
|
||||||
|
info.channel = IOS_CHANNEL;
|
||||||
|
peding_orders_[info.orderid] = info;
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void OrderMgr::ProcReissue(const std::string& orderid)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
//超过30天的不能补发
|
||||||
|
int ret = query_.ExecQuery("SELECT orderid, itemid, roleid, rolename, price, sp_pay_result, serverid "
|
||||||
|
"FROM orderinfo WHERE orderid='%s' AND status=1 AND confirmtime + 3600 * 24 * 30 > %d;",
|
||||||
|
{
|
||||||
|
orderid,
|
||||||
|
g_nowtime
|
||||||
|
});
|
||||||
|
if (ret > 0) {
|
||||||
|
OrderInfo info;
|
||||||
|
info.orderid = query_.GetValue(0).GetString();
|
||||||
|
info.itemid = query_.GetValue(1);
|
||||||
|
info.roleid = query_.GetValue(2).GetString();
|
||||||
|
info.rolename = query_.GetValue(3).GetString();
|
||||||
|
info.price = query_.GetValue(4);
|
||||||
|
info.lastchecktime = g_nowtime - 60 * 3;
|
||||||
|
info.serverid = query_.GetValue(6);
|
||||||
|
if (query_.ExecScript("UPDATE orderinfo SET status=0, confirmtime=0 WHERE orderid='%s';",
|
||||||
|
{orderid})) {
|
||||||
|
peding_orders_[info.orderid] = info;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void OrderMgr::UpdatePedingOrders()
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
g_udplog->Debug("UpdatePedingOrders peding_orders_ size:%d", { peding_orders_.size() });
|
||||||
|
for (std::map<std::string, OrderInfo>::iterator itr = peding_orders_.begin();
|
||||||
|
itr != peding_orders_.end(); ++itr){
|
||||||
|
if (g_nowtime - itr->second.lastchecktime > 15) {
|
||||||
|
itr->second.lastchecktime = g_nowtime;
|
||||||
|
P2DPayNotify msg;
|
||||||
|
msg.orderid = itr->second.orderid;
|
||||||
|
msg.roleid = itr->second.roleid;
|
||||||
|
msg.name = itr->second.rolename;
|
||||||
|
msg.itemid = itr->second.itemid;
|
||||||
|
msg.price = itr->second.price;
|
||||||
|
msg.serverid = itr->second.serverid;
|
||||||
|
g_dbslistener->SendToDBServer(msg);
|
||||||
|
g_udplog->Debug("UpdatePedingOrders send P2DPayNotify orderid:%s roleid:%d name:%s serverid:%d", { msg.orderid,msg.roleid,msg.name,msg.serverid });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void OrderMgr::_SSMPing(MsgHdr& hdr, const SSMPing& msg)
|
||||||
|
{
|
||||||
|
SSMPong respmsg;
|
||||||
|
g_dbslistener->SendToDBServer(respmsg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OrderMgr::_D2PPayNotifyACK(MsgHdr& hdr, const D2PPayNotifyACK& msg)
|
||||||
|
{
|
||||||
|
if (peding_orders_.find(msg.orderid) != peding_orders_.end()) {
|
||||||
|
if (query_.ExecScript("UPDATE orderinfo SET status=%d, confirmtime=%d WHERE orderid='%s';",
|
||||||
|
{
|
||||||
|
1,
|
||||||
|
g_nowtime,
|
||||||
|
msg.orderid
|
||||||
|
})) {
|
||||||
|
peding_orders_.erase(msg.orderid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//支付成功并且gameserver没有确认的订单
|
||||||
|
void OrderMgr::LoadPedingOrders()
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
int ret = query_.ExecQuery("SELECT orderid, itemid, roleid, rolename, price, serverid, accountid "
|
||||||
|
"FROM orderinfo WHERE sp_pay_result=1 AND status=0;", {});
|
||||||
|
if (ret < 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
while (!query_.Eof()) {
|
||||||
|
OrderInfo info;
|
||||||
|
info.orderid = query_.GetValue(0).GetString();
|
||||||
|
info.itemid = query_.GetValue(1);
|
||||||
|
info.roleid = query_.GetValue(2).GetString();
|
||||||
|
info.rolename = query_.GetValue(3).GetString();
|
||||||
|
info.price = query_.GetValue(4);
|
||||||
|
info.lastchecktime = g_nowtime - 60 * 1;
|
||||||
|
info.serverid = query_.GetValue(5);
|
||||||
|
info.accountid = query_.GetValue(6).GetString();
|
||||||
|
peding_orders_[info.orderid] = info;
|
||||||
|
query_.Next();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
long OrderMgr::GenSeqId()
|
||||||
|
{
|
||||||
|
long new_seqid = 0;
|
||||||
|
seq_mutex_->lock();
|
||||||
|
new_seqid = ++current_seqid_;
|
||||||
|
seq_mutex_->unlock();
|
||||||
|
return new_seqid;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string OrderMgr::GenOrderId(int itemid)
|
||||||
|
{
|
||||||
|
#if 1
|
||||||
|
return "";
|
||||||
|
#else
|
||||||
|
char orderid[80] = {0};
|
||||||
|
{
|
||||||
|
time_t nowtime = time(NULL);
|
||||||
|
if (nowtime == last_gen_order_time_) {
|
||||||
|
sub_orderid_++;
|
||||||
|
if (sub_orderid_ >= 10000) {
|
||||||
|
while (nowtime <= last_gen_order_time_) {
|
||||||
|
::usleep(100 * 10000);
|
||||||
|
nowtime = time(NULL);
|
||||||
|
}
|
||||||
|
sub_orderid_ = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sub_orderid_ = 1;
|
||||||
|
}
|
||||||
|
last_gen_order_time_ = nowtime;
|
||||||
|
|
||||||
|
struct tm tm_nowtime = {0};
|
||||||
|
struct tm *ptr = localtime_r(&nowtime, &tm_nowtime);
|
||||||
|
char strtime[80] = {0};
|
||||||
|
strftime(strtime, 80, "%y%m%d%H%M%S", ptr);
|
||||||
|
|
||||||
|
sprintf(orderid, "%s%5d", strtime, sub_orderid_);
|
||||||
|
for (int i = 0; i < a8::arraysize(orderid); i++) {
|
||||||
|
if (orderid[i] == ' ') {
|
||||||
|
orderid[i] = '0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int price = 0;
|
||||||
|
Template::RechargeCard *cardtpl = g_configtable->GetRechargeCard(itemid);
|
||||||
|
if (cardtpl) {
|
||||||
|
price = cardtpl->price * 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string strorderid;
|
||||||
|
strorderid = a8::format("%d_%d_%s",
|
||||||
|
{
|
||||||
|
itemid,
|
||||||
|
price,
|
||||||
|
std::string(orderid)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return strorderid;
|
||||||
|
#endif
|
||||||
|
}
|
135
server/payserver/ordermgr.h
Normal file
135
server/payserver/ordermgr.h
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
struct OrderInfo
|
||||||
|
{
|
||||||
|
std::string seqid;
|
||||||
|
std::string orderid;
|
||||||
|
std::string accountid;
|
||||||
|
int itemid;
|
||||||
|
int price;
|
||||||
|
int customprice;
|
||||||
|
int serverid;
|
||||||
|
std::string roleid;
|
||||||
|
std::string rolename;
|
||||||
|
std::string sp_accountid;
|
||||||
|
std::string channel;
|
||||||
|
std::string itemname;
|
||||||
|
std::string itemmemo;
|
||||||
|
std::string sp_orderid;
|
||||||
|
time_t lastchecktime;
|
||||||
|
|
||||||
|
OrderInfo()
|
||||||
|
{
|
||||||
|
serverid = 0;
|
||||||
|
itemid = 0;
|
||||||
|
price = 0;
|
||||||
|
lastchecktime = 0;
|
||||||
|
customprice = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AddOrderResult
|
||||||
|
{
|
||||||
|
bool isok;
|
||||||
|
OrderInfo orderinfo;
|
||||||
|
|
||||||
|
AddOrderResult()
|
||||||
|
{
|
||||||
|
isok = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AddOrderNode;
|
||||||
|
struct PayNotifyNode;
|
||||||
|
struct ReissueNode;
|
||||||
|
class OrderMgr : public a8::Singleton<OrderMgr>
|
||||||
|
{
|
||||||
|
|
||||||
|
private:
|
||||||
|
OrderMgr() {};
|
||||||
|
friend class a8::Singleton<OrderMgr>;
|
||||||
|
|
||||||
|
public:
|
||||||
|
void Init();
|
||||||
|
void UnInit();
|
||||||
|
|
||||||
|
void Update();
|
||||||
|
bool HasTask();
|
||||||
|
|
||||||
|
int AddOrder(const std::string& seqid,
|
||||||
|
const std::string& accountid,
|
||||||
|
const std::string& roleid,
|
||||||
|
const std::string& rolename,
|
||||||
|
const std::string& channel,
|
||||||
|
const std::string& sp_accountid, int serverid,
|
||||||
|
int productid, int price,
|
||||||
|
const std::string& sp_orderid);
|
||||||
|
bool WaitForAddOrderFinished(int seqid,
|
||||||
|
AddOrderResult& addresult,
|
||||||
|
int seconds);
|
||||||
|
|
||||||
|
int AddPayNotify(
|
||||||
|
int pay_type,
|
||||||
|
const std::string& accountid,
|
||||||
|
const std::string& roleid,
|
||||||
|
const std::string& rolename,
|
||||||
|
int serverid,
|
||||||
|
int itemid,
|
||||||
|
const std::string& itemid_str,
|
||||||
|
const std::string& orderid,
|
||||||
|
const std::string& sp_orderid,
|
||||||
|
double fee,
|
||||||
|
int payresult);
|
||||||
|
bool WaitForPayNotifyFinished(int seqid, int& result, int seconds);
|
||||||
|
|
||||||
|
int AddReissue(const std::string& orderid);
|
||||||
|
bool WaitForReissueFinished(int seqid, int& result, int seconds);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void ProcessOrderMsg();
|
||||||
|
void ProcessNotifyMsg();
|
||||||
|
void ProcessReissueMsg();
|
||||||
|
bool ProcAddOrder(OrderInfo& orderinfo);
|
||||||
|
int ProcOrderNotify(PayNotifyNode* node);
|
||||||
|
int ContinueSubscriptions(PayNotifyNode* node);
|
||||||
|
int ProcIosPayOrderNotify(PayNotifyNode* node);
|
||||||
|
void ProcReissue(const std::string& orderid);
|
||||||
|
void UpdatePedingOrders();
|
||||||
|
void LoadPedingOrders();
|
||||||
|
std::string GenOrderId(int itemid);
|
||||||
|
long GenSeqId();
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void _SSMPing(MsgHdr& hdr, const SSMPing& msg);
|
||||||
|
|
||||||
|
void _D2PPayNotifyACK(MsgHdr& hdr, const D2PPayNotifyACK& msg);
|
||||||
|
#endif
|
||||||
|
private:
|
||||||
|
#if 0
|
||||||
|
a8::mysql::Connection mysql_conn_;
|
||||||
|
a8::mysql::Query query_;
|
||||||
|
#endif
|
||||||
|
a8::tick_t last_ping_db_tick_ = 0;
|
||||||
|
|
||||||
|
std::mutex *add_order_mutex_ = nullptr;
|
||||||
|
AddOrderNode *top_node_, *bot_node_, *work_node_;
|
||||||
|
|
||||||
|
std::mutex *pay_notify_mutex_;
|
||||||
|
PayNotifyNode *pay_notify_top_node_, *pay_notify_bot_node_, *pay_notify_work_node_;
|
||||||
|
|
||||||
|
std::mutex *reissue_mutex_;
|
||||||
|
ReissueNode *reissue_top_node_, *reissue_bot_node_, *reissue_work_node_;
|
||||||
|
|
||||||
|
int last_gen_order_time_;
|
||||||
|
int sub_orderid_;
|
||||||
|
|
||||||
|
std::mutex *seq_mutex_;
|
||||||
|
volatile int current_seqid_;
|
||||||
|
std::mutex *add_order_result_mutex_;
|
||||||
|
std::map<int, AddOrderResult> add_order_results_;
|
||||||
|
|
||||||
|
std::mutex *pay_notify_result_mutex_;
|
||||||
|
std::map<int, int> pay_notify_results_;
|
||||||
|
|
||||||
|
std::map<std::string, OrderInfo> peding_orders_;
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user