SMSHandle.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. #include "stdafx.h"
  2. #include "SMSHandle.h"
  3. #include <WinNls.h>
  4. #include <Windows.h>
  5. #include "DataManager.h"
  6. #ifdef _DEBUG
  7. #define new DEBUG_NEW
  8. #endif
  9. #define SENDCOUNT _T("SendCount")
  10. #define BALANCE _T("Balance")
  11. #define ERPHONE _T("ErrorPhone")
  12. #define SENDSID _T("Sid")
  13. #define QUERYCOUNT _T("SMSCharacterCount")
  14. #define QUERYSIGLE _T("Signatures")
  15. #define QUERYOWNER _T("OwnedOperators")
  16. #define ACCOUNT _T("account")
  17. #define SIGNATURES _T("Signatures")
  18. #define OPERATORS _T("OwnedOperators")
  19. #define RETH _T("<ReturnInfo><![CDATA[")
  20. #define RETE _T("]]></ReturnInfo>")
  21. //#define USE_DOMAIN 0
  22. #define SENDSMS _T("http://%s:%d/webService/SendSmsMessage?account=%s&password=%s&phone=%s&content=%s&time=%s&t=%s")
  23. #define QUERYACCOUNT _T("http://%s:%d/webService/getuserinfo?account=%s&password=%s&t=%s")
  24. #define QUERYSEND _T("http://%s:%d/webService/QuerySendRecordInfo?account=%s&password=%s&sid=%s&t=%s")
  25. #define INSERTSENDREG _T("insert into sendreg([msgtype],[phones],[content],[timestamp],[msgcount],[status],[issended],[isautosend],[ren]) values('%s','%s','%s','%s','%d','%s','%s','%s','%s')")
  26. //#define INSERTSENDREG_old _T("insert into sendreg([phones],[content],[timestamp],[msgcount],[status],[issended],[isautosend],[ren]) values('%s','%s','%s','%d','%s','%s','%s','%s')")
  27. #define UPDATESENDREG _T("update sendreg set msgcount='%s',log='%s',status='%s',issended='%s' where autoid='%s'")
  28. //#define UPDATE_VERSION _T(" update [version] set [msgbalance] = convert(int,msgbalance,10) - %s, [msgused] = convert(int,msgused,10) + %s ");
  29. #define UPDATE_VERSION _T(" update [version] set [msgbalance] = '%s', [msgused] = convert(int,msgused) + %s ")
  30. CSMSHandle::CSMSHandle()
  31. {
  32. m_url.Initialize();
  33. }
  34. CSMSHandle::~CSMSHandle()
  35. {
  36. }
  37. void CSMSHandle::UrlUTF8Decode(LPBYTE lpRespone, CString &strRespone)
  38. {
  39. // 从uft-8转到gb2312,再转到unicode;
  40. std::string str = strCoding::UrlUTF8Decode((LPSTR)lpRespone);
  41. INT wLen = 0;
  42. wLen = MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0);
  43. WCHAR *ptRespone = new WCHAR[wLen];
  44. memset(ptRespone, 0, wLen*sizeof(WCHAR));
  45. MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, ptRespone, wLen);
  46. strRespone.Format(_T("%s"), ptRespone);
  47. if (ptRespone)
  48. {
  49. delete ptRespone;
  50. ptRespone = NULL;
  51. }
  52. }
  53. //************************************//
  54. // [函数]:GetSMSBlance
  55. // [描述]:获取帐户信息
  56. // [参数]:
  57. // pSMSServer 短信服务端主机名称;
  58. // dwPort 短信服务端主机通信端口
  59. // strAccount 登录帐号
  60. // strPwd 密码
  61. // tAccountInfo 返回帐户的信息
  62. // [返回]:0成功, -1失败
  63. //************************************//
  64. int CSMSHandle::GetSMSBlance(const TCHAR* pSMSServer, const DWORD& dwPort, CString& strAccount, CString& strPwd, QuerAccountInfo& tAccountInfo)
  65. {
  66. AutoThreadSection aSection(&s_critSection);
  67. CString str = _T("");
  68. CString strRespone;
  69. str.Format(QUERYACCOUNT,pSMSServer, dwPort,
  70. utilitySdk::CharEncoding::EnCode_UTF8URL(strAccount).c_str(),
  71. utilitySdk::CharEncoding::EnCode_UTF8URL(strPwd).c_str(), utilitySdk::CharEncoding::EnCode_UTF8URL(CTime::GetCurrentTime().Format(_T("%Y%m%d%H%M%S"))).c_str());
  72. if (0 == m_url.Get(str, strRespone))
  73. {
  74. INT nPos = strRespone.Find(RETH);
  75. strRespone.Delete(0, nPos + _tcslen(RETH));
  76. nPos = strRespone.Find(RETE);
  77. strRespone = strRespone.Mid(0, nPos);
  78. // 解析参数值;
  79. nPos = strRespone.Find(ACCOUNT);
  80. tAccountInfo.strSendStatus = strRespone.Left(nPos - 1);
  81. strRespone.Delete(0, nPos + _tcslen(ACCOUNT) + 1);
  82. nPos = strRespone.Find(BALANCE);
  83. tAccountInfo.strAccount = strRespone.Left(nPos - 1);
  84. strRespone.Delete(0, nPos + _tcslen(BALANCE) + 1);
  85. nPos = strRespone.Find(QUERYCOUNT);
  86. tAccountInfo.strBalance = strRespone.Left(nPos - 1);
  87. strRespone.Delete(0, nPos + _tcslen(QUERYCOUNT) + 1);
  88. nPos = strRespone.Find(SIGNATURES);
  89. tAccountInfo.strSMSCharacterCount = strRespone.Left(nPos - 1);
  90. strRespone.Delete(0, nPos + _tcslen(SIGNATURES) + 1);
  91. nPos = strRespone.Find(OPERATORS);
  92. tAccountInfo.strSignatures = strRespone.Left(nPos - 1);
  93. strRespone.Delete(0, nPos + _tcslen(OPERATORS) + 1);
  94. tAccountInfo.strOwnedOperators = strRespone;
  95. return TRUE;
  96. }
  97. return FALSE;
  98. }
  99. void CSMSHandle::UTF8ToWideChar(LPBYTE lpRespone, CString &strRespone)
  100. {
  101. // 从uft-8转到gb2312,再转到unicode;
  102. std::string str;
  103. strCoding::UTF_8ToGB2312(str, (char*)lpRespone, strlen((char*)lpRespone));
  104. INT wLen = 0;
  105. wLen = MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0);
  106. WCHAR *ptRespone = new WCHAR[wLen];
  107. memset(ptRespone, 0, wLen*sizeof(WCHAR));
  108. MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, ptRespone, wLen);
  109. strRespone.Format(_T("%s"), ptRespone);
  110. if (ptRespone)
  111. {
  112. delete ptRespone;
  113. ptRespone = NULL;
  114. }
  115. }
  116. INT CSMSHandle::AnalyzeSendStatus(LPBYTE lpRespone, ResponebySend &lRespone)
  117. {
  118. CString strRespone = (TCHAR*)lpRespone;
  119. WriteTextLog("服务端返回内容:%s",strRespone);
  120. INT nIndex = strRespone.Find(RETH);
  121. if ( nIndex == -1 )
  122. {
  123. WriteTextLog("没有找到:\"<ReturnInfo><![CDATA[\" 元素");
  124. return -13;
  125. }
  126. strRespone.Delete(0, nIndex + _tcslen(RETH));
  127. nIndex = strRespone.Find(RETE);
  128. if ( nIndex == -1 )
  129. {
  130. WriteTextLog("没有找到:\"]]></ReturnInfo>\" 元素");
  131. return -13;
  132. }
  133. strRespone = strRespone.Mid(0, nIndex);
  134. // 解析参数值;
  135. nIndex = strRespone.Find(SENDCOUNT);
  136. if ( nIndex == -1 )
  137. {
  138. WriteTextLog("没有找到:\"SendCount\" 元素");
  139. return -13;
  140. }
  141. lRespone.strSendStatus = strRespone.Left(nIndex - 1);
  142. strRespone.Delete(0, nIndex + _tcslen(SENDCOUNT) + 1);
  143. nIndex = strRespone.Find(BALANCE);
  144. if ( nIndex == -1 )
  145. {
  146. WriteTextLog("没有找到:\"Balance\" 元素");
  147. return -13;
  148. }
  149. lRespone.strSendCount = strRespone.Left(nIndex - 1);
  150. strRespone.Delete(0, nIndex + _tcslen(BALANCE) + 1);
  151. nIndex = strRespone.Find(ERPHONE);
  152. if ( nIndex == -1 )
  153. {
  154. WriteTextLog("没有找到:\"ErrorPhone\" 元素");
  155. return -13;
  156. }
  157. lRespone.strBalance = strRespone.Left(nIndex - 1);
  158. strRespone.Delete(0, nIndex + _tcslen(ERPHONE) + 1);
  159. nIndex = strRespone.Find(SENDSID);
  160. if ( nIndex == -1 )
  161. {
  162. WriteTextLog("没有找到:\"Sid\" 元素");
  163. return -13;
  164. }
  165. lRespone.strErPhone = strRespone.Left(nIndex - 1);
  166. strRespone.Delete(0, nIndex + _tcslen(SENDSID) + 1);
  167. lRespone.strSid = strRespone;
  168. return _ttoi(lRespone.strSendStatus);
  169. }
  170. //************************************//
  171. // [函数]:SendSMToSever
  172. // [描述]:获取帐户信息
  173. // [参数]:
  174. // pSMSServer 短信服务端主机名称;
  175. // dwPort 短信服务端主机通信端口
  176. // strAccount 登录帐号
  177. // strPwd 密码
  178. // strPhones 所有要发送的号码
  179. // strContent 发送的内容
  180. // strStampTime 时间
  181. // strAutoID 短信记录ID
  182. // [返回]:0成功, -1失败
  183. //************************************//
  184. int CSMSHandle::SendSMToSever(const TCHAR* pSMSServer, const DWORD& dwPort, const CString& strAccount, const CString& strPwd, const CString& strPhones, const CString& strContent, const CString& strStampTime, const CString& strAutoID)
  185. {
  186. if(strAutoID == _T(""))
  187. return -1;
  188. CString str = _T("");
  189. str.Format(SENDSMS, pSMSServer, dwPort,
  190. utilitySdk::CharEncoding::EnCode_UTF8URL(strAccount).c_str(),
  191. utilitySdk::CharEncoding::EnCode_UTF8URL(strPwd).c_str(),
  192. utilitySdk::CharEncoding::EnCode_UTF8URL(strPhones).c_str(),
  193. //strPhones,
  194. utilitySdk::CharEncoding::EnCode_UTF8URL(strContent).c_str(),
  195. utilitySdk::CharEncoding::EnCode_UTF8URL(strStampTime).c_str(),
  196. utilitySdk::CharEncoding::EnCode_UTF8URL(CTime::GetCurrentTime().Format(_T("%Y%m%d%H%M%S"))).c_str());
  197. CString strResponse;
  198. if (0 != m_url.Gets(str, strResponse))
  199. {
  200. return -1;
  201. }
  202. //update sendreg set msgcount='%s',log='%s',status='%s',issended='%s' where autoid='%s'"
  203. //解析
  204. ResponebySend lRespone;
  205. INT nRet = AnalyzeSendStatus((LPBYTE)strResponse.GetString(), lRespone);
  206. //更新记录
  207. if(UpdateSMLog(nRet, &lRespone, strAutoID) == -1)
  208. return -1;
  209. return 0;
  210. }
  211. //************************************//
  212. // [函数]:GetSMState
  213. // [描述]:获取短信状态
  214. // [参数]:
  215. // pSMSServer 短信服务端主机名称;
  216. // dwPort 短信服务端主机通信端口
  217. // strAccount 登录帐号
  218. // strPwd 密码
  219. // sr 短信记录信息
  220. // [返回]:0成功, -1失败
  221. //************************************//
  222. int CSMSHandle::GetSMState(const TCHAR* pSMSServer, const DWORD& dwPort, const CString& strAccount, const CString& strPwd, const SSendReg* pSR)
  223. {
  224. AutoThreadSection aSection(&s_critSection);
  225. static CString strQuerySMS;
  226. strQuerySMS = _T("");
  227. strQuerySMS.Format(QUERYSEND, pSMSServer, dwPort,
  228. utilitySdk::CharEncoding::EnCode_UTF8URL(strAccount).c_str(),
  229. utilitySdk::CharEncoding::EnCode_UTF8URL(strPwd).c_str(),
  230. utilitySdk::CharEncoding::EnCode_UTF8URL(pSR->Sid).c_str(),
  231. utilitySdk::CharEncoding::EnCode_UTF8URL(CTime::GetCurrentTime().Format(_T("%Y%m%d%H%M%S"))).c_str());
  232. static CString strRespone = _T("");
  233. if (TRUE == m_url.Get(strQuerySMS, strRespone))
  234. {
  235. WriteTextLog("查询时返回:%s",strRespone);
  236. static ResponebySend lRespone;
  237. lRespone.strSendStatus = _T("");
  238. lRespone.strSendCount = _T("");
  239. lRespone.strErPhone = _T("");
  240. lRespone.strSid = _T("");
  241. static INT nPos = 0;
  242. nPos = strRespone.Find(RETH);
  243. strRespone.Delete(0, nPos + _tcslen(RETH));
  244. nPos = strRespone.Find(RETE);
  245. strRespone = strRespone.Mid(0, nPos);
  246. // 解析参数值;
  247. nPos = strRespone.Find(SENDCOUNT);
  248. lRespone.strSendStatus = strRespone.Left(nPos - 1);
  249. strRespone.Delete(0, nPos + _tcslen(SENDCOUNT) + 1);
  250. nPos = strRespone.Find(SENDSID);
  251. lRespone.strSendCount = strRespone.Left(nPos - 1);
  252. strRespone.Delete(0, nPos + _tcslen(SENDSID) + 1);
  253. lRespone.strSid = strRespone;
  254. nPos = 0;
  255. strRespone = _T("");
  256. //更新记录
  257. if(UpdateSMLog(_ttoi(lRespone.strSendStatus), &lRespone, pSR->autoid) == -1)
  258. return -1;
  259. }
  260. return 0;
  261. }
  262. //************************************//
  263. // [函数]:UpdateSMLog
  264. // [描述]:更新短信记录
  265. // [参数]:
  266. // lRespone 服务器响应信息
  267. // strAutoID 记录ID
  268. // [返回]:0成功, -1失败
  269. //************************************//
  270. int CSMSHandle::UpdateSMLog(const int nRet, const ResponebySend* pRespone, const CString& strAutoID)
  271. {
  272. if(pRespone == NULL || strAutoID == _T(""))
  273. return -1;
  274. CString strValues = _T("");
  275. CString strfilter = _T("");
  276. switch(nRet)
  277. {
  278. case 0: // 成功;
  279. strValues = _T("msgcount='") + pRespone->strSendCount + _T("',log='1/1',status='OK',") + _T("Sid='0'");
  280. break;
  281. case -1: // 当前账号余额不足;
  282. strValues = _T("msgcount='") + pRespone->strSendCount + _T("',log='当前账号余额不足',status='") + pRespone->strSendStatus + _T("',Sid='0'");
  283. break;
  284. case -2: // 当前账号错误;
  285. strValues = _T("msgcount='") + pRespone->strSendCount + _T("',log='当前账号错误',status='") + pRespone->strSendStatus + _T("',Sid='0'");
  286. break;
  287. case -3: // 当前密码错误;
  288. strValues = _T("msgcount='") + pRespone->strSendCount + _T("',log='当前密码错误',status='") + pRespone->strSendStatus + _T("',Sid='0'");
  289. break;
  290. case -4: // 参数不够或参数内容的类型错误;
  291. strValues = _T("msgcount='") + pRespone->strSendCount + _T("',log='参数不够或参数内容的类型错误',status='") + pRespone->strSendStatus + _T("',Sid='0'");
  292. break;
  293. case -5: // 手机号码格式不对;
  294. strValues = _T("msgcount='") + pRespone->strSendCount + _T("',log='手机号码格式不对',status='") + pRespone->strSendStatus + _T("',Sid='0'");
  295. break;
  296. case -6: // 短信内容编码不对;
  297. strValues = _T("msgcount='") + pRespone->strSendCount + _T("',log='短信内容编码不对',status='") + pRespone->strSendStatus + _T("',Sid='0'");
  298. break;
  299. case -7: // 短信内容含有敏感字符;
  300. strValues = _T("msgcount='") + pRespone->strSendCount + _T("',log='短信内容含有敏感字符',status='") + pRespone->strSendStatus + _T("',Sid='0'");
  301. break;
  302. case -8: // 无接收数据;
  303. strValues = _T("msgcount='") + pRespone->strSendCount + _T("',log='无接收数据',status='") + pRespone->strSendStatus + _T("',Sid='0'");
  304. break;
  305. case -9: // 系统维护中;
  306. strValues = _T("msgcount='") + pRespone->strSendCount + _T("',log='无接收数据',status='") + pRespone->strSendStatus + _T("',Sid='0'");
  307. break;
  308. case -10: // 手机号码数量超长_每次最多100个;
  309. strValues = _T("msgcount='") + pRespone->strSendCount + _T("',log='手机号码数量超长_每次最多100个',status='") + pRespone->strSendStatus + _T("',Sid='0'");
  310. break;
  311. case -11: // 短信内容超长_每条390个字符;
  312. strValues = _T("msgcount='") + pRespone->strSendCount + _T("',log='短信内容超长_每条390个字符',status='") + pRespone->strSendStatus + _T("',Sid='0'");
  313. break;
  314. case -12: // 其它错误;
  315. strValues = _T("msgcount='") + pRespone->strSendCount + _T("',log='其它错误',status='") + pRespone->strSendStatus + _T("',Sid='0'");
  316. break;
  317. case -13: // 服务器错误;
  318. strValues = _T("msgcount='") + pRespone->strSendCount + _T("',log='服务器错误',status='") + pRespone->strSendStatus + _T("',Sid='0'");
  319. break;
  320. case -14: // 域名不正确;//短信接口不会有该错误返回;
  321. strValues = _T("msgcount='") + pRespone->strSendCount + _T("',log='域名不正确',status='") + pRespone->strSendStatus + _T("',Sid='0'");
  322. break;
  323. case -15: // 域名所在服务器未提交过IP;//短信接口不会有该错误返回;
  324. strValues = _T("msgcount='") + pRespone->strSendCount + _T("',log='域名所在服务器未提交过IP',status='") + pRespone->strSendStatus + _T("',Sid='0'");
  325. break;
  326. case -16: // 硬件码不能小于5个字符;//短信接口不会有该错误返回;
  327. strValues = _T("msgcount='") + pRespone->strSendCount + _T("',log='硬件码不能小于5个字符',status='") + pRespone->strSendStatus + _T("',Sid='0'");
  328. break;
  329. case -17: // 服务器连接失败;
  330. strValues = _T("msgcount='") + pRespone->strSendCount + _T("',log='服务器连接失败',status='") + pRespone->strSendStatus + _T("',Sid='0'");
  331. break;
  332. case -18: // 硬件码不能为空;//短信接口不会有该错误返回;
  333. strValues = _T("msgcount='") + pRespone->strSendCount + _T("',log='硬件码不能为空',status='") + pRespone->strSendStatus + _T("',Sid='0'");
  334. break;
  335. case -19: // 查询的短信记录不存在或已被删除;
  336. strValues = _T("msgcount='") + pRespone->strSendCount + _T("',log='查询的短信记录不存在或已被删除',status='") + pRespone->strSendStatus + _T("',Sid='0'");
  337. break;
  338. case -20: // 短信超时过期忽略发送;
  339. strValues = _T("msgcount='") + pRespone->strSendCount + _T("',log='短信超时过期忽略发送',status='") + pRespone->strSendStatus + _T("',Sid='0'");
  340. break;
  341. case 100: // 服务器授理并等待发送中;并将返回的Sid更新到status中保存;
  342. strValues = _T("msgcount='") + pRespone->strSendCount + _T("',log='服务器授理并等待发送中',status='") + pRespone->strSendStatus + _T("',") + _T("Sid='") + pRespone->strSid + _T("'");
  343. break;
  344. default:
  345. strValues = _T("");
  346. break;
  347. }
  348. // update数据库;
  349. CString strTableName = _T("sendreg");
  350. strfilter = _T("autoid=") + strAutoID;
  351. if (CDataManager::GetInstance()->Update(strTableName, strValues, strfilter) == -1)
  352. {
  353. // 记录失败,需要相应的补救处理,将更新内容写入SQLite数据库中或其他文本中记录;
  354. // 但同时会加大处理难度,暂时不处理这种情况。
  355. // 可能会多发一至多条短信;
  356. WriteTextLog(_T("更新记录数据表%s失败, autoid = %s"), strTableName, strAutoID);
  357. return -1;
  358. }
  359. return 0;
  360. }