Jelajahi Sumber

使用兑换码接口

Jason 6 hari lalu
induk
melakukan
4d6854b27f
3 mengubah file dengan 246 tambahan dan 13 penghapusan
  1. 201 11
      webapi/webapi/HttpSocket.cpp
  2. 10 0
      webapi/webapi/HttpSocket.h
  3. 35 2
      webapi/webapi/data.h

+ 201 - 11
webapi/webapi/HttpSocket.cpp

@@ -40,6 +40,8 @@ HttpSocket::HttpSocket()
 	m_pdb = boost::make_shared<mongocxx::database>();
 	m_gamelog = boost::make_shared<mongocxx::database>();
 	m_pvipuserdb = boost::make_shared<mongocxx::database>();
+	m_webdata = boost::make_shared<mongocxx::database>();
+
 	m_pallindex = boost::make_shared<mongocxx::collection>();
 	m_pcoll = boost::make_shared<mongocxx::collection>();
 	m_plosewincoll = boost::make_shared<mongocxx::collection>();
@@ -60,10 +62,13 @@ HttpSocket::HttpSocket()
 	m_pthirdtranslog = boost::make_shared<mongocxx::collection>();
 	m_pthirddeveloper = boost::make_shared<mongocxx::collection>();
 	m_predeemcode = boost::make_shared<mongocxx::collection>();
+	m_predeemcodelog = boost::make_shared<mongocxx::collection>();
+	m_pactivityini = boost::make_shared<mongocxx::collection>();
 
 	*m_pdb = (*m_pclient)["accounts"];
 	*m_gamelog = (*m_pclient)["gamelog"];
 	*m_platform = (*m_pclient)["platform"];
+	*m_webdata = (*m_pclient)["webdata"];
 
 	*m_pvipuserdb = (*m_pclient)["vipuser"];
 	*m_pallindex = (*m_pdb)["allindex"];
@@ -86,6 +91,8 @@ HttpSocket::HttpSocket()
 	*m_pthirdtranslog = (*m_gamelog)["thirdtranslog"];
 	*m_pthirddeveloper = (*m_platform)["thirddeveloper"];
 	*m_predeemcode = (*m_pvipuserdb)["redeemcode"];
+	*m_predeemcodelog = (*m_gamelog)["redeemcodelog"];
+	*m_pactivityini = (*m_webdata)["activeini"];
 
 	m_strshahead = "X-REQUEST-SIGN";
 	m_strshaheadcontent = "6e4c91001979851a97c2b5360f044ff67b48e186d6ecd4394532851bffdeeae9";
@@ -209,6 +216,10 @@ bool HttpSocket::postmsg(std::function<void(std::string&, int)> funhttpmsg, std:
 			{
 				strtojson = generateredeemcodes(getdata);
 			}
+			else if (itype == HTTPUSEDEEMCODE)
+			{
+				strtojson = useredeemcodes(getdata);
+			}
 			else
 			{
 				return false;
@@ -1051,8 +1062,8 @@ std::string HttpSocket::updateuserscore(std::map<std::string, std::string> getda
 	// type=1商家送分给玩家;type=2商家给玩家收分
 	__int32 itype = 0;
 	__int64 vipscore = vipuser->view()["score"].get_int64();
-	if (tuserscore.iwallet == 2)
-		vipscore = vipuser->view()["freescore"] ? vipuser->view()["freescore"].get_int64() : 0;
+	/*if (tuserscore.iwallet == 2)
+		vipscore = vipuser->view()["freescore"] ? vipuser->view()["freescore"].get_int64() : 0;*/
 	std::string strusername;
 	std::string struseraccount;
 	std::string struserip;
@@ -1060,13 +1071,15 @@ std::string HttpSocket::updateuserscore(std::map<std::string, std::string> getda
 	std::string strspreaderaccount;
 	std::string strspreaderip;
 	std::string strwebonlyuser{};
-	std::string strwallet = tuserscore.iwallet == 2 ? "freescore" : "score";
+	std::string strwallet = "score"; // tuserscore.iwallet == 2 ? "freescore" : "score";
+	bool btruescore = tuserscore.iwallet != 2;
 
+	std::int64_t llagentscore = btruescore ? tuserscore.score : 0;
 	//商家送分
 	if (tuserscore.score < 0)
 	{
 		//可以赠送
-		if (vipscore + tuserscore.score >= 0)
+		if (!btruescore || vipscore + tuserscore.score >= 0)
 		{
 			//用户不存在不减商家的分数
 			if (!firstuser->view()["score"] || !firstuser->view()["name"] || !firstuser->view()["account"] || !firstuser->view()["lastlogonip"] || !firstuser->view()["userid"])
@@ -1082,9 +1095,9 @@ std::string HttpSocket::updateuserscore(std::map<std::string, std::string> getda
 			strwebonlyuser = firstuser->view()["webuser"].get_utf8().value.data();
 			iuserid = firstuser->view()["userid"].get_int64();
 
-			//减商家分数
+			//减商家分数			
 			auto criteria = make_document(kvp("userid", adminuserid));
-			auto update = make_document(kvp("$inc", make_document(kvp(strwallet, tuserscore.score))));
+			auto update = make_document(kvp("$inc", make_document(kvp(strwallet, llagentscore))));
 			auto retscore = m_pvipuser->find_one_and_update(criteria.view(), update.view());
 			if (!retscore)
 			{
@@ -1097,7 +1110,7 @@ std::string HttpSocket::updateuserscore(std::map<std::string, std::string> getda
 				strret = funclib::rettojson(Err_AgentUpdateScoreFailed, "modify score erro1");
 				return strret;
 			}
-
+			
 			beforespreaderscore = retscore->view()[strwallet] ? retscore->view()[strwallet].get_int64() : 0;
 			strspreadername = retscore->view()["name"].get_utf8().value.data();
 			strspreaderaccount = retscore->view()["account"].get_utf8().value.data();
@@ -1124,7 +1137,7 @@ std::string HttpSocket::updateuserscore(std::map<std::string, std::string> getda
 
 			__int64 iOne32 = 1;
 			auto vipscorecriteria = make_document(kvp("business", iOne32));
-			auto vipscoreupdate = make_document(kvp("$inc", make_document(kvp("sellscore", tradescore))));
+			auto vipscoreupdate = make_document(kvp("wallet", tuserscore.iwallet), kvp("$inc", make_document(kvp("sellscore", tradescore))));
 			mongocxx::options::find_one_and_update options;
 			options.upsert(true);
 			auto vipscore = m_pvipscore->find_one_and_update(vipscorecriteria.view(), vipscoreupdate.view(), options);
@@ -1340,7 +1353,7 @@ std::string HttpSocket::updateuserscore(std::map<std::string, std::string> getda
 		//减用户分数
 		tuserscore.score = -1 * tuserscore.score;
 		auto usercriteria = make_document(kvp("account", tuserscore.account.c_str()));
-		auto userupdate = make_document(kvp("$inc", make_document(kvp("score", tuserscore.score))));
+		auto userupdate = make_document(kvp("$inc", make_document(kvp(strwallet, tuserscore.score))));
 		auto tempscore = m_pcoll->find_one_and_update(usercriteria.view(), userupdate.view());
 		if (!tempscore)
 		{
@@ -1360,7 +1373,7 @@ std::string HttpSocket::updateuserscore(std::map<std::string, std::string> getda
 		m_plosewincoll->find_one_and_update(usercriteria.view(), xiafenupdate.view());
 		
 		auto admincriteria = make_document(kvp("userid", adminuserid));
-		auto adminupdate = make_document(kvp("$inc", make_document(kvp(strwallet, tradescore))));
+		auto adminupdate = make_document(kvp("$inc", make_document(kvp(strwallet, llagentscore))));
 		auto adminretscore = m_pvipuser->find_one_and_update(admincriteria.view(), adminupdate.view());
 		if (!adminretscore)
 		{
@@ -1370,7 +1383,7 @@ std::string HttpSocket::updateuserscore(std::map<std::string, std::string> getda
 
 		__int64 iOne32 = 1;
 		auto vipscorecriteria = make_document(kvp("business", iOne32));
-		auto vipscoreupdate = make_document(kvp("$inc", make_document(kvp("buyscore", tradescore))));
+		auto vipscoreupdate = make_document(kvp("wallet", tuserscore.iwallet), kvp("$inc", make_document(kvp("buyscore", tradescore))));
 		mongocxx::options::find_one_and_update options;
 		options.upsert(true);
 		auto vipscore = m_pvipscore->find_one_and_update(vipscorecriteria.view(), vipscoreupdate.view(), options);
@@ -3720,4 +3733,181 @@ std::string HttpSocket::generateredeemcodes(std::map<std::string, std::string> g
 }
 
 
+//使用兑换码
+std::string HttpSocket::useredeemcodes(std::map<std::string, std::string> getdata)
+{
+	sUserRedeemCode reqparam;
+	getvaluedata(getdata, reqparam);
+	std::string strret;
+
+	bool bret = reqparam.datavalue();
+	if (!bret)
+	{
+		strret = funclib::rettojson(Err_ParamError, "param erro");
+		return strret;
+	}
+	
+	auto filteruser = make_document(kvp("account", reqparam.struseracc.c_str()), kvp("dynamicpass", reqparam.strcert.c_str()));
+	auto finduser = m_pcoll->find_one(filteruser.view());
+	if (!finduser || !finduser->view()["userid"])
+	{
+		strret = funclib::rettojson(Err_No_Player, "param erro");
+		return strret;
+	}
+
+	if (!finduser || !finduser->view()["usertype"] || !finduser->view()["score"] || !finduser->view()["areaid"] || !finduser->view()["spreaderid"])
+	{
+		strret = funclib::rettojson(Err_GAMECURRENCY_NOTMATCH, "account not support");
+		return strret;
+	}
+
+	__int64 iuserid = finduser->view()["userid"].get_int64();
+	__int64 iuserscore = finduser->view()["score"].get_int64();
+	__int32 iusertype = finduser->view()["usertype"].get_int32();
+	__int64 ispreaderid = finduser->view()["spreaderid"].get_int64();
+	__int32 iuserarea = finduser->view()["areaid"].get_int32();
+	std::string strredeemcode = reqparam.strredeemcode;
+
+
+	//如果玩家在线
+	auto useroline = m_pplayuseronline->find_one(bsoncxx::builder::stream::document{} << "userid" << iuserid << bsoncxx::builder::stream::finalize);
+	{
+		strret = funclib::rettojson(Err_Player_InGame, "player in games");
+		return strret;
+	}
+
+
+	// 检查货币类型
+	bool bnewfree = (iuserscore == 0);
+	if (iuserscore > 0 && iusertype != 2)
+	{
+		strret = funclib::rettojson(Err_GAMECURRENCY_NOTMATCH, "account not support");
+		return strret;
+	}
+
+	auto filterredeemcode = make_document(kvp("code", reqparam.strredeemcode.c_str()));
+	auto findredeemcode = m_predeemcode->find_one(filterredeemcode.view());
+	//检测状态
+	if (!findredeemcode || !findredeemcode->view()["codetype"] || !findredeemcode->view()["areaid"] || !findredeemcode->view()["spreaderid"] || !findredeemcode->view()["open"] || findredeemcode->view()["open"].get_int32() < 1)
+	{
+		strret = funclib::rettojson(Err_RedeemCodeInvalid, "redeemcode is invalid");
+		return strret;
+	}
+	__int64 icreator = findredeemcode->view()["spreaderid"].get_int64();
+	__int64 icodearea = findredeemcode->view()["areaid"].get_int32();
+	if (icreator > 1 && ispreaderid != icreator)
+	{
+		strret = funclib::rettojson(Err_RedeemCodeInvalid, "redeemcode is invalid");
+		return strret;
+	}
+
+	if (icodearea != iuserarea)
+	{
+		strret = funclib::rettojson(Err_RedeemCodeInvalid, "redeemcode is invalid");
+		return strret;
+	}
+
+	//检测有效期
+	__int64 checktime = funclib::gettimestamp();
+	__int64 istarttime = findredeemcode->view()["st"].get_int64();
+	__int64 iendtime = findredeemcode->view()["et"].get_int64();
+	__int32 icodetype = findredeemcode->view()["codetype"].get_int32();
+	if (checktime < istarttime || checktime > iendtime)
+	{
+		strret = funclib::rettojson(Err_Not_ValidityPeriod, "not validity period");
+		return strret;
+	}
+
+	// 检测使用次数
+	if (!findredeemcode->view()["score"] || !findredeemcode->view()["st"] || !findredeemcode->view()["et"] ||
+		!findredeemcode->view()["st"] || !findredeemcode->view()["exchangelimit"] || !findredeemcode->view()["accountlimit"])
+	{
+		strret = funclib::rettojson(Err_InnerError, "inner error");
+		return strret;
+	}
+	__int32 iexchangelimit = findredeemcode->view()["exchangelimit"].get_int32();
+	__int32 icodeusedcount = findredeemcode->view()["usedcount"].get_int32();
+	if (icodeusedcount >= iexchangelimit)
+	{
+		strret = funclib::rettojson(Err_NoValidity_Times, "redeemcode used up");
+		return strret;
+	}
+
+	//账号兑换限制( 单码)
+	__int32 iaccountlimit = findredeemcode->view()["accountlimit"].get_int32();
+	document filterlog;
+	filterlog.append(kvp("userid", iuserid), kvp("redeemcode", strredeemcode.c_str()));
+	filterlog.append(kvp("$and",
+		make_array(
+			make_document(kvp("inserttime",
+				make_document(kvp("$gte", istarttime)))),
+			make_document(kvp("inserttime",
+				make_document(kvp("$lt", iendtime)))))));
+	auto iaccusedcnt = m_predeemcodelog->count_documents(filterlog.view());
+	if (iaccusedcnt >= iaccountlimit)
+	{
+		strret = funclib::rettojson(Err_Account_NoValidityTimes, "account exchange limit");
+		return strret;
+	}
+
+	//账号兑换限制(全局)
+	__int32 igloballimit = 0;
+	if (finduser->view()["redeemcodelimit"])
+		igloballimit = finduser->view()["redeemcodelimit"].get_int32();
+	if (igloballimit == 0)
+	{
+		auto findactivity = m_pactivityini->find_one(make_document(kvp("name", 20)));
+		if (findactivity && findactivity->view()["userlimit"])
+			igloballimit = findactivity->view()["userlimit"].get_int32();
+	}
+	if (igloballimit > 0)
+	{
+		auto iaccusedcnt = m_predeemcodelog->count_documents(make_document(kvp("userid", iuserid)));
+		if (iaccusedcnt >= igloballimit)
+		{
+			strret = funclib::rettojson(Err_Account_NoValidityTimes, "account exchange global limit");
+			return strret;
+		}
+	}
+
+
+	//扣除兑换码使用次数
+	auto filteruse = make_document(kvp("code", strredeemcode.c_str()),
+		kvp("$expr", make_document(kvp("$lt", make_array("$usedcount", "$exchangelimit")))));
+	auto updateuse = make_document(kvp("$inc", make_document(kvp("usedcount", 1))));
+	auto result = m_predeemcode->find_one_and_update(filteruse.view(), updateuse.view());
+	if (!result)
+	{
+		if (iaccusedcnt >= igloballimit)
+		{
+			strret = funclib::rettojson(Err_NoValidity_Times, "redeemcode used up");
+			return strret;
+		}
+	}
+
+	// 给玩家加分
+	__int64 iscore = findredeemcode->view()["score"].get_int64();
+	document updatescore;
+	updatescore.append(kvp("$inc", make_document(kvp("score", iscore))));
+	if (bnewfree)
+		updatescore.append(kvp("$set", make_document(kvp("usertype", 2))));
+	auto cursor = m_pcoll->find_one_and_update(filteruser.view(), updatescore.view());
+	if (!cursor)
+	{		
+		strret = funclib::rettojson(Err_No_Player, "player not found");
+		return strret;
+	}
+
+	//记录玩家兑换日志
+	auto updatelogdoc = make_document(kvp("userid", iuserid), kvp("redeemcode", strredeemcode.c_str()),
+		kvp("inserttime", checktime), kvp("score", iscore), kvp("codetype", icodetype), kvp("spreaderid", ispreaderid));
+	m_predeemcodelog->insert_one(updatelogdoc.view());
+
+
+
+	strret = funclib::rettojson(-1, "ok");
+	return strret;
+}
+
+
 

+ 10 - 0
webapi/webapi/HttpSocket.h

@@ -48,6 +48,9 @@ protected:
 	boost::shared_ptr<mongocxx::collection> m_pallindex;
 	// 用户数据库
 	boost::shared_ptr<mongocxx::database> m_pdb;
+	// webdata数据库
+	boost::shared_ptr<mongocxx::database> m_webdata;
+
 	// 日志库
 	boost::shared_ptr<mongocxx::database> m_gamelog;
 	// 推广数据库
@@ -92,6 +95,10 @@ protected:
 	boost::shared_ptr<mongocxx::collection> m_pthirddeveloper;
 	// 兑换码
 	boost::shared_ptr<mongocxx::collection> m_predeemcode;
+	// 兑换码日志
+	boost::shared_ptr<mongocxx::collection> m_predeemcodelog;
+	// activityini
+	boost::shared_ptr<mongocxx::collection> m_pactivityini;
 public:
 	HttpSocket();
 	~HttpSocket();
@@ -145,6 +152,9 @@ protected:
 	void getreelgameurl(std::string struseracc, __int32 ikindid, __int64 iuserid, std::function<void(std::string&, int)> dofun);
 
 	//-------------------------------兑换码---------------------------------------
+	//生成兑换码
 	std::string generateredeemcodes(std::map<std::string, std::string> getdata);
+	//玩家使用兑换码
+	std::string useredeemcodes(std::map<std::string, std::string> getdata);
 };
 #endif

+ 35 - 2
webapi/webapi/data.h

@@ -65,7 +65,7 @@
 #define HTTPLOOKUPALLUSERPLAYSCORE	28				//查询所有玩家总下注和总赢回
 #define HTTPLOGINREEL				29				//登录真人视讯
 #define HTTPGENERATEREDEEMCODE		30				//兑换码
-
+#define HTTPUSEDEEMCODE				31				//玩家使用兑换码
 
 #define HTTPMAX						31				//http最大id
 
@@ -186,7 +186,10 @@ enum EErrorCode
 	Err_RedeemLableDuplicate = 1060, //  兑换码标签重复
 	Err_TRANS_FAILED = 1061, //  转账失败
 	Err_GAMECURRENCY_NOTMATCH = 1062,	// 游戏货币类型不对
-
+	Err_RedeemCodeInvalid = 1063,	// 兑换码无效
+	Err_Not_ValidityPeriod = 1064,	// 不在有效期
+	Err_NoValidity_Times = 1065,	// 使用次数用光
+	Err_Account_NoValidityTimes = 1066,	// 账号使用次数用过
 };
 
 
@@ -761,4 +764,34 @@ public:
 
 	}
 };
+
+
+
+struct sUserRedeemCode
+{
+	std::string			struseracc{};				//玩家
+	std::string			strcert{};			//玩家密钥
+	std::string			strredeemcode{};			//兑换码
+
+public:
+	std::string getfieldvalue(std::int32_t index)
+	{
+		const char* value[] = { "useracc",  "cert", "redeemcode" };
+		return value[index];
+	}
+
+	void getdata()
+	{
+	}
+
+	bool datavalue()
+	{
+		if (struseracc.empty() || strcert.empty() || strredeemcode.empty() )
+		{
+			return false;
+		}
+		return true;
+	}
+};
+
 #pragma pack()