UploadManager.cpp 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964
  1. #include "stdafx.h"
  2. #include "UploadManager.h"
  3. #include "basic_struct.h"
  4. #include "BatchService.h"
  5. #include "ResultUploader.h"
  6. #include "rapidjson/document.h"
  7. #include "rapidjson/writer.h"
  8. #include "rapidjson/stringbuffer.h"
  9. //type 0 INT 1 DOUBLE
  10. void AddNumberMember(rapidjson::Value&root, rapidjson::Document::AllocatorType& allocator, const char*key, int value, int type);
  11. void AddStringMember(rapidjson::Value&root, rapidjson::Document::AllocatorType& allocator, const char*key, const char*value);
  12. UploadManager* g_upload_manager;
  13. extern int g_my_scan_type;
  14. UploadManager::UploadManager()
  15. :m_pNotify(nullptr)
  16. {
  17. m_zxhxCreateUploadDBSuccess = false;
  18. m_bScanStartFlag = false;
  19. m_pBatchService = nullptr;
  20. m_bEnable = false;
  21. ::InitializeCriticalSection(&upload_db_lock);
  22. }
  23. bool UploadManager::Init(bool bEanble, bool bCountiue, bool bErrorHanle, bool bOnlineCard,int nSubjectID, IUploudNotify*pNotify, CppSQLite3DB*rst_db, RTL_CRITICAL_SECTION*rst_db_lock)
  24. {
  25. if (!pNotify)
  26. {
  27. m_pNotify = NULL;
  28. return true;
  29. }
  30. m_nSubjectID = nSubjectID;
  31. m_bSendUploadRstToZHXH = false;
  32. m_bOnlineCard = bOnlineCard;
  33. g_upload_manager = this;
  34. m_bEnable = bEanble;
  35. m_bCoutinue = bCountiue;
  36. result_db = rst_db;
  37. result_db_lock = rst_db_lock;
  38. if (!bEanble)return false;
  39. m_pNotify = pNotify;
  40. return OpenDB(bCountiue);
  41. }
  42. namespace OnLineCard{
  43. std::string UnicodeToAnsi(const CString& str);
  44. }
  45. bool UploadManager::OpenDB(bool bCountiue)
  46. {
  47. LOGFMTI("OpenDB: 是否继续:%d", bCountiue ? 1 : 0);
  48. TCHAR FilePath[MAX_PATH];
  49. GetModuleFileName(NULL, FilePath, MAX_PATH);
  50. CString ret;
  51. (_tcsrchr(FilePath, '\\'))[1] = 0;
  52. lstrcat(FilePath, _T("upload_manager.db"));
  53. char db_file_name[520] = { 0 };
  54. WideCharToMultiByte(CP_UTF8, 0, FilePath, -1, db_file_name, 520, NULL, NULL);
  55. ::EnterCriticalSection(&upload_db_lock);
  56. if (!upload_db.is_open())
  57. upload_db.open(db_file_name);
  58. if (!upload_db.tableExists("upload_db")){
  59. std::string strSql = "CREATE TABLE upload_db ( student_paper_id INT, ori_upload_state INT,paper_state INT, rst_upload_state INT, ori_info VARCHAR, rst_info VARCHAR)";
  60. upload_db.execDML(strSql.c_str());
  61. }
  62. if (!bCountiue){
  63. LOGI("清空上传缓存");
  64. std::string sql = "delete from upload_db";
  65. upload_db.execDML(sql.c_str());
  66. }
  67. ::LeaveCriticalSection(&upload_db_lock);
  68. return true;
  69. }
  70. #include <future>
  71. #include <mutex>
  72. UploadManager::~UploadManager(){
  73. m_pNotify = nullptr;
  74. if (m_thread.joinable()){
  75. m_bExit.store(true);
  76. m_thread.join();
  77. }
  78. ::DeleteCriticalSection(&upload_db_lock);
  79. }
  80. void UploadManager::ScanListFilter(bool bSuccess,int nUploadState)
  81. {
  82. if ( m_bEnable){
  83. if (m_thread.joinable()){
  84. m_bExit.store(true);
  85. m_thread.join();
  86. }
  87. m_bExit.store(false);
  88. m_thread = std::thread(&UploadManager::ScanListFilterThread, this, bSuccess, nUploadState);
  89. }
  90. }
  91. int UploadManager::GetPaperUploadState(int paper_id, char*szErrorInfo, int nLen)
  92. {
  93. std::string sql = "select * from upload_db where student_paper_id=";
  94. sql += std::to_string(paper_id);
  95. EnterCriticalSection(&upload_db_lock);
  96. if (upload_db.is_open()){
  97. CppSQLite3Query q = upload_db.execQuery(sql.c_str());
  98. if (!q.eof()){
  99. int state = q.getIntField("rst_upload_state");
  100. if (state == 3){
  101. std::string str_info = q.getStringField("rst_info");
  102. strncpy(szErrorInfo, str_info.c_str(), nLen - 1);
  103. LeaveCriticalSection(&upload_db_lock);
  104. return 2;
  105. }
  106. else if (state == 2){
  107. LeaveCriticalSection(&upload_db_lock);
  108. return 1;
  109. }
  110. else if (state == 1){
  111. LeaveCriticalSection(&upload_db_lock);
  112. return 3;
  113. }
  114. else if (state == 0){
  115. LeaveCriticalSection(&upload_db_lock);
  116. return 4;
  117. }
  118. }
  119. }
  120. LeaveCriticalSection(&upload_db_lock);
  121. return 0;
  122. }
  123. void UploadManager::ScanListFilterThread(bool bSuccess, int nUploadState)
  124. {
  125. if (!m_bExit.load()){
  126. std::string tmp;
  127. {
  128. std::lock_guard<std::mutex> _lk(m_tx_pre_paperid);
  129. if (!m_vctPrePaperid.empty()){
  130. tmp = " and student_paper_id not in(";
  131. for (std::size_t i = 0; i < m_vctPrePaperid.size(); ++i){
  132. tmp += std::to_string(m_vctPrePaperid[i]);
  133. if (i != m_vctPrePaperid.size() - 1)
  134. tmp += ",";
  135. else
  136. tmp += ")";
  137. }
  138. }
  139. }
  140. std::string sql = "select * from upload_db where ";
  141. sql += (bSuccess ?"paper_state=0 ":"paper_state!=0 ");
  142. if (nUploadState == 1){// 上传完成
  143. sql += "and rst_upload_state=2";
  144. }
  145. else if (nUploadState == 2){ //上传失败
  146. sql += "and rst_upload_state=3";
  147. }
  148. else if (nUploadState == 3){// 上传中
  149. sql += "and rst_upload_state=1 ";
  150. }
  151. else if (nUploadState == 4 || nUploadState == 0){//待上传//全部
  152. if (!bSuccess){
  153. std::string rst_sql = "select student_paper_id from student_paper where paper_state!=0";
  154. EnterCriticalSection(result_db_lock);
  155. if (result_db&&result_db->is_open()){
  156. rst_sql += tmp;
  157. CppSQLite3Query q_rst = result_db->execQuery(rst_sql.c_str());
  158. if (!q_rst.eof()){
  159. while (!q_rst.eof()){
  160. int student_paper_id = q_rst.getIntField("student_paper_id");
  161. q_rst.nextRow();
  162. if (nUploadState == 4){
  163. std::string sql_tmp = "select count(*) from upload_db where student_paper_id=";
  164. sql_tmp += std::to_string(student_paper_id);
  165. if (upload_db.execScalar(sql_tmp.c_str()) <= 0){
  166. if (m_pNotify){
  167. m_pNotify->OnScanListFilter(student_paper_id);
  168. }
  169. }
  170. else{
  171. sql += q_rst.eof() ? ")" : ",";
  172. }
  173. }
  174. else{
  175. if (m_pNotify){
  176. m_pNotify->OnScanListFilter(student_paper_id);
  177. }
  178. }
  179. }
  180. if (nUploadState != 4){
  181. LeaveCriticalSection(result_db_lock);
  182. return;
  183. }
  184. }
  185. else{
  186. LeaveCriticalSection(result_db_lock);
  187. return;
  188. }
  189. }
  190. LeaveCriticalSection(result_db_lock);
  191. }
  192. }
  193. EnterCriticalSection(&upload_db_lock);
  194. try{
  195. if (upload_db.is_open()){
  196. sql += tmp;
  197. CppSQLite3Query q = upload_db.execQuery(sql.c_str());
  198. while (!q.eof()){
  199. if (m_bExit.load())break;
  200. if (m_pNotify){
  201. m_pNotify->OnScanListFilter(q.getIntField("student_paper_id"));
  202. }
  203. q.nextRow();
  204. }
  205. }
  206. }
  207. catch (...){
  208. LeaveCriticalSection(&upload_db_lock);
  209. return;
  210. }
  211. LeaveCriticalSection(&upload_db_lock);
  212. }
  213. }
  214. void UploadManager::NotifyScanProcess(UploadProcess*pRt/* = nullptr*/)
  215. {
  216. std::string tmp = "";
  217. UploadProcess obj;
  218. EnterCriticalSection(&upload_db_lock);
  219. try{
  220. if (upload_db.is_open()){
  221. {
  222. std::lock_guard<std::mutex> _lk(m_tx_pre_paperid);
  223. if (!m_vctPrePaperid.empty()){
  224. tmp = " and student_paper_id not in(";
  225. for (std::size_t i = 0; i < m_vctPrePaperid.size(); ++i){
  226. tmp += std::to_string(m_vctPrePaperid[i]);
  227. if (i != m_vctPrePaperid.size() - 1)
  228. tmp += ",";
  229. else
  230. tmp += ")";
  231. }
  232. }
  233. }
  234. // 答卷上传成功数量
  235. std::string sql = "select count(*) from upload_db where paper_state=0 and rst_upload_state=2"; sql += tmp;
  236. obj.m_nRstUploadSuccess = upload_db.execScalar(sql.c_str());
  237. // 答卷上传失败数量
  238. sql = "select count(*) from upload_db where paper_state=0 and rst_upload_state=3"; sql += tmp;
  239. obj.m_nRstUploadBad = upload_db.execScalar(sql.c_str());
  240. // 原卷上传成功数量
  241. sql = "select count(*) from upload_db where paper_state=0 and ori_upload_state=2"; sql += tmp;
  242. obj.m_nOriUploadSuccess = upload_db.execScalar(sql.c_str());
  243. // 原卷上传失败数量
  244. sql = "select count(*) from upload_db where paper_state=0 and ori_upload_state=3"; sql += tmp;
  245. obj.m_nOriUploadBad = upload_db.execScalar(sql.c_str());
  246. // 异常卷上传成功数量
  247. sql = "select count(*) from upload_db where paper_state!=0 and rst_upload_state=2"; sql += tmp;
  248. obj.m_nErrorUploadSuccess = upload_db.execScalar(sql.c_str());
  249. // 异常卷上传成功数量
  250. sql = "select count(*) from upload_db where paper_state!=0 and rst_upload_state=3"; sql += tmp;
  251. obj.m_nErrorUploadBad = upload_db.execScalar(sql.c_str());
  252. }
  253. }
  254. catch (...){
  255. LeaveCriticalSection(&upload_db_lock);
  256. return;
  257. }
  258. LeaveCriticalSection(&upload_db_lock);
  259. EnterCriticalSection(result_db_lock);
  260. try{
  261. if (result_db && result_db->is_open()){
  262. // 异常卷上传总量
  263. std::string sql = "select count(*) from student_paper where paper_state!=0 and Is_Covered!=1"; sql += tmp;
  264. obj.m_nErrorUploadTotal = result_db->execScalar(sql.c_str());
  265. // 答/原卷卷上传总量
  266. sql = "select count(*) from student_paper where paper_state=0 and Is_Covered!=1"; sql += tmp;
  267. obj.m_nOriUploadTotal = result_db->execScalar(sql.c_str());
  268. obj.m_nRstUploadTotal = obj.m_nOriUploadTotal;
  269. }
  270. }
  271. catch (...){
  272. LeaveCriticalSection(result_db_lock);
  273. return;
  274. }
  275. LeaveCriticalSection(result_db_lock);
  276. if (!pRt){
  277. if (m_pNotify){
  278. m_pNotify->OnUploadNotify(UPLOAD_SHIJUAN_TYPE::UPLOAD_PROCESS_RST, &obj);
  279. }
  280. }
  281. else{
  282. *pRt = obj;
  283. }
  284. }
  285. void UploadManager::OnTcpError()
  286. {
  287. m_zxhxCreateUploadDBSuccess = false;
  288. }
  289. void UploadManager::OnReConnect(bool bSuccess)
  290. {
  291. if (bSuccess){
  292. LOGFMTI("通知知心慧学开启边扫边传任务:%s", m_strStartParam.c_str());
  293. // 通知知心慧学开启边扫边传任务
  294. if (m_strStartParam.length())
  295. NetOperator::ClientSendData(m_strStartParam.c_str());
  296. }
  297. }
  298. void UploadManager::OnNetNotify(const char*param)
  299. {
  300. if (!param) return;
  301. rapidjson::Document root;
  302. root.Parse(param);
  303. if (!root.HasParseError()){
  304. auto it_task_type = root.FindMember("net_task_type");
  305. auto it_cmd = root.FindMember("net_task_cmd");
  306. if (it_cmd != root.MemberEnd() && it_task_type != root.MemberEnd()){
  307. std::string cmd = it_cmd->value.GetString();
  308. auto it_data = root.FindMember("data");
  309. if (it_data == root.MemberEnd()){
  310. LOGE("没有找到从知心慧学返回的data节点");
  311. return;
  312. }
  313. // 检查batch_code 不是本批次的放弃处理
  314. auto it_bantch_code = it_data->value.FindMember("bantch_code");
  315. #ifdef _DEBUG
  316. auto it_code = it_bantch_code->value.GetString();
  317. #endif
  318. if (!(it_bantch_code != it_data->value.MemberEnd() &&
  319. it_bantch_code->value.IsString() &&
  320. std::string(it_bantch_code->value.GetString()) == m_bantch_code))
  321. {
  322. LOGFMTE("bantch_code 错误 或者 不是本批次的batch_code 放弃之: 当前bantch_code=%s 知心慧学端 bantch_code:%s",
  323. std::string(it_bantch_code->value.GetString()).c_str(),
  324. m_bantch_code.c_str());
  325. return;
  326. }
  327. // 服务端是否成功创建数据库
  328. if (cmd == "upload_on_scan_start"){ //
  329. auto it_rst = it_data->value.FindMember("success");
  330. if (it_rst != it_data->value.MemberEnd() && it_rst->value.IsInt()){
  331. auto rst = it_rst->value.GetInt();
  332. if (rst == 0){//失败
  333. m_zxhxCreateUploadDBSuccess = false;
  334. auto it_msg = it_data->value.FindMember("message");
  335. if (it_msg != it_data->value.MemberEnd() && it_msg->value.IsString())
  336. LOGFMTE("知心慧学端创建数据库失败:%s", it_msg->value.GetString());
  337. }
  338. else{
  339. m_zxhxCreateUploadDBSuccess = true;
  340. LOGI("知心慧学端创建数据库成功");
  341. SendUploadTaskWhenReConnected();
  342. }
  343. if (m_pBatchService){
  344. SetEvent(m_pBatchService->GetEventZXHXCreateDB());
  345. }
  346. }
  347. }
  348. if (!m_zxhxCreateUploadDBSuccess){
  349. return;
  350. }
  351. if (cmd == "upload_on_scan_add_upload_task"){
  352. auto it_success = it_data->value.FindMember("success");
  353. if (it_success != it_data->value.MemberEnd() && it_success->value.IsInt()){
  354. if (it_success->value.GetInt() != 1){
  355. std::string err_msg, exception_json;
  356. int student_paper_id = -1;
  357. auto it_msg = it_data->value.FindMember("message");
  358. if (it_msg != it_data->value.MemberEnd() && it_msg->value.IsString()){
  359. err_msg = it_msg->value.GetString();
  360. }
  361. else{
  362. LOGI("upload_on_scan_add_upload_task 协议错误:message缺失 或者 message不是string类型 ");
  363. return;
  364. }
  365. auto it_exception_json = it_data->value.FindMember("exception_json");
  366. if (it_exception_json != it_data->value.MemberEnd() && it_exception_json->value.IsString()){
  367. exception_json = it_exception_json->value.GetString();
  368. }
  369. else{
  370. LOGI("upload_on_scan_add_upload_task 协议错误:exception_json缺失 或者 exception_json不是string类型 ");
  371. return;
  372. }
  373. auto it_student_paper_id = it_data->value.FindMember("student_paper_id");
  374. if (it_student_paper_id != it_data->value.MemberEnd() && it_student_paper_id->value.IsInt()){
  375. student_paper_id = it_student_paper_id->value.GetInt();
  376. }
  377. else{
  378. LOGI("upload_on_scan_add_upload_task 协议错误:student_paper_id缺失 或者 student_paper_id不是int类型 ");
  379. return;
  380. }
  381. char sz_sql[512] = { 0 };
  382. std::string update_sql_fmt = "update upload_db set ori_upload_state=%d, rst_upload_state=3, rst_info='%s' where student_paper_id=%d";
  383. sprintf_s(sz_sql, update_sql_fmt.c_str(), exception_json == "normal" ? 3 : 2,
  384. (std::string("write_to_db_error-") + err_msg).c_str(), student_paper_id);
  385. ::EnterCriticalSection(&upload_db_lock);
  386. if (upload_db.is_open()){
  387. upload_db.execDML((sz_sql));
  388. }
  389. ::LeaveCriticalSection(&upload_db_lock);
  390. memset(sz_sql, 0, sizeof(sz_sql) / sizeof(char));
  391. // 通知界面更新状态
  392. MY_UPLOAD_REV_INFO _param;
  393. _param.paperid = student_paper_id;
  394. _param.status = UPLOAD_STATUS::UPLOAD_ERROR;
  395. if (exception_json == "normal"){
  396. update_sql_fmt = "update student_paper set ret_upload=3,img_upload=3 where student_paper_id=%d";
  397. sprintf_s(sz_sql, update_sql_fmt.c_str(), student_paper_id);
  398. ::EnterCriticalSection(result_db_lock);
  399. if (result_db && result_db->is_open()){
  400. result_db->execDML(sz_sql);
  401. }
  402. ::LeaveCriticalSection(result_db_lock);
  403. OnUploadNotify(UPLOAD_SHIJUAN_TYPE::TYPE_RST, &_param);
  404. OnUploadNotify(UPLOAD_SHIJUAN_TYPE::TYPE_ORI, &_param);
  405. }
  406. else{
  407. update_sql_fmt = "update student_paper set ret_upload=3,img_upload=2 where student_paper_id=%d";
  408. sprintf_s(sz_sql, update_sql_fmt.c_str(), student_paper_id);
  409. ::EnterCriticalSection(result_db_lock);
  410. if (result_db && result_db->is_open()){
  411. result_db->execDML(sz_sql);
  412. }
  413. ::LeaveCriticalSection(result_db_lock);
  414. OnUploadNotify(UPLOAD_SHIJUAN_TYPE::TYPE_ERROR, &_param);
  415. }
  416. }
  417. }
  418. else{
  419. LOGI("upload_on_scan_add_upload_task 协议错误:success缺失 或者 success不是int类型 ");
  420. }
  421. }
  422. //////////////////////////////////////////////////////////////////////////
  423. // student_paper_id int 类型 //
  424. // bantch_code 批次号 字符串 //
  425. // upload_state 1 成功 0 失败 int 类型 //
  426. // message 失败原因 字符串 //
  427. //////////////////////////////////////////////////////////////////////////
  428. else if (cmd == "upload_on_scan_rst_state_notify" || // 答卷上传状态
  429. cmd == "upload_on_scan_ori_state_notify" || // 原卷上传状态
  430. cmd == "upload_on_scan_error_state_notify") { // 异常卷上传状态
  431. int student_paper_id = 0, upload_state = 0;
  432. std::string message;
  433. // 解析 student_paper_id
  434. auto it_student_paper_id = it_data->value.FindMember("student_paper_id");
  435. if (it_student_paper_id != it_data->value.MemberEnd() &&
  436. it_student_paper_id->value.IsInt()){
  437. student_paper_id = it_student_paper_id->value.GetInt();
  438. }
  439. // 解析 upload_state 1 成功 0失败
  440. auto it_upload_state = it_data->value.FindMember("upload_state");
  441. if (it_upload_state != it_data->value.MemberEnd() &&
  442. it_upload_state->value.IsInt()){
  443. upload_state = it_upload_state->value.GetInt();
  444. }
  445. // 解析失败原因
  446. auto it_message = it_data->value.FindMember("err_msg");
  447. if (it_message != it_data->value.MemberEnd() && it_message->value.IsString()){
  448. message = it_message->value.GetString();
  449. }
  450. UPLOAD_SHIJUAN_TYPE _upload_shijuan_type = UPLOAD_SHIJUAN_TYPE::TYPE_ORI;
  451. if (cmd == "upload_on_scan_rst_state_notify"){
  452. _upload_shijuan_type = UPLOAD_SHIJUAN_TYPE::TYPE_RST;
  453. }
  454. else if (cmd == "upload_on_scan_error_state_notify"){
  455. _upload_shijuan_type = UPLOAD_SHIJUAN_TYPE::TYPE_ERROR;
  456. }
  457. char sz_sql_result_db[512] = { 0 };
  458. char sz_sql_upload_db[512] = { 0 };
  459. switch (_upload_shijuan_type)
  460. {
  461. // 原卷状态更新到数据库
  462. case UPLOAD_SHIJUAN_TYPE::TYPE_ORI:
  463. {
  464. std::string sz_sql_result_db_fmt = "update student_paper set img_upload = %d where student_paper_id = %d and paper_state=0";
  465. sprintf_s(sz_sql_result_db, sz_sql_result_db_fmt.c_str(),
  466. upload_state,
  467. student_paper_id);
  468. std::string sql_upload_db_fmt = "update upload_db set ori_upload_state = %d ,ori_info='%s' where student_paper_id=%d and paper_state=0";
  469. sprintf_s(sz_sql_upload_db, sql_upload_db_fmt.c_str(),
  470. upload_state,
  471. message.c_str(), student_paper_id);
  472. }
  473. break;
  474. // 原卷状态更新到数据库
  475. case UPLOAD_SHIJUAN_TYPE::TYPE_RST:
  476. {
  477. std::string sz_sql_result_db_fmt = "update student_paper set ret_upload = %d where student_paper_id = %d and paper_state=0";
  478. sprintf_s(sz_sql_result_db, sz_sql_result_db_fmt.c_str(),
  479. upload_state,
  480. student_paper_id);
  481. std::string sql_upload_db_fmt = "update upload_db set rst_upload_state = %d ,rst_info='%s' where student_paper_id=%d and paper_state=0";
  482. sprintf_s(sz_sql_upload_db, sql_upload_db_fmt.c_str(),
  483. upload_state,
  484. message.c_str(), student_paper_id);
  485. }
  486. break;
  487. // 异常卷状态更新到数据
  488. case UPLOAD_SHIJUAN_TYPE::TYPE_ERROR:{
  489. std::string sz_sql_result_db_fmt = "update student_paper set ret_upload = %d where student_paper_id = %d and paper_state!=0";
  490. sprintf_s(sz_sql_result_db, sz_sql_result_db_fmt.c_str(),
  491. upload_state,
  492. student_paper_id);
  493. std::string sql_upload_db_fmt = "update upload_db set rst_upload_state = %d , ori_upload_state = 2 ,rst_info='%s' where student_paper_id=%d and paper_state!=0";
  494. sprintf_s(sz_sql_upload_db, sql_upload_db_fmt.c_str(),
  495. upload_state,
  496. message.c_str(), student_paper_id);
  497. }
  498. break;
  499. }
  500. EnterCriticalSection(result_db_lock);
  501. if (result_db && result_db->is_open()){
  502. result_db->execDML(sz_sql_result_db);
  503. LOGFMTI("更新batch_db:%s", sz_sql_result_db);
  504. }
  505. LeaveCriticalSection(result_db_lock);
  506. EnterCriticalSection(&upload_db_lock);
  507. if (upload_db.is_open()){
  508. upload_db.execDML(sz_sql_upload_db);
  509. LOGFMTI("更新upload_db:%s", sz_sql_upload_db);
  510. }
  511. LeaveCriticalSection(&upload_db_lock);
  512. // 通知界面更新状态
  513. MY_UPLOAD_REV_INFO _param;
  514. _param.paperid = student_paper_id;
  515. _param.status = ((upload_state == 2)? UPLOAD_STATUS::UPLOAD_SUCCESS : UPLOAD_STATUS::UPLOAD_ERROR);
  516. OnUploadNotify(_upload_shijuan_type, &_param);
  517. }
  518. }
  519. }
  520. }
  521. void UploadManager::OnUploadNotify(int type, void*data)
  522. {
  523. if (m_pNotify){
  524. m_pNotify->OnUploadNotify(type, data);
  525. if (type == UPLOAD_SHIJUAN_TYPE::TYPE_RST ||
  526. type == UPLOAD_SHIJUAN_TYPE::TYPE_ERROR ||
  527. type == UPLOAD_SHIJUAN_TYPE::TYPE_ORI)
  528. {
  529. NotifyScanProcess();
  530. if (m_bScanStopFlag){
  531. NotifyUploadOnScanStop();
  532. }
  533. }
  534. }
  535. }
  536. void UploadManager::OnScanListFilter(int paper_id)
  537. {
  538. //
  539. }
  540. namespace OnLineCard{
  541. std::string UnicodeToAnsi(const CString& str);
  542. }
  543. std::string readFileIntoString(const std::string& filename);
  544. std::wstring strUTF8toW(const std::string& src);
  545. extern std::string g_strUpLoadDbPathName;;
  546. #include "rapidjson/document.h"
  547. void UploadManager::NotifyUploadOnScanStop()
  548. {
  549. bool bNotify = true;
  550. EnterCriticalSection(&upload_db_lock);
  551. if (bNotify){
  552. std::string sql = "select count(*) from upload_db where rst_upload_state=0 OR rst_upload_state=1";
  553. if (upload_db.execScalar(sql.c_str()) > 0) bNotify = false;
  554. }
  555. LeaveCriticalSection(&upload_db_lock);
  556. if (bNotify && m_pNotify){
  557. LOGI("上传结束通告");
  558. NotifyEnd();
  559. }
  560. }
  561. void UploadManager::NotifyEnd()
  562. {
  563. if (m_bSendUploadRstToZHXH)return;
  564. m_bSendUploadRstToZHXH = true;
  565. if (!m_bEnable)return;
  566. if (m_pNotify)
  567. m_pNotify->OnUploadNotify(UPLOAD_SHIJUAN_TYPE::TYPE_END, NULL);
  568. }
  569. int UploadManager::UploadOnScanCmd(int nCmd, const char*param, int nOnlineScanType, void*ret)
  570. {
  571. if (!m_bEnable){
  572. return -1;
  573. }
  574. switch (nCmd)
  575. {
  576. case CMD_IS_HAS_UPLOADERROR: // 是否
  577. {
  578. int nRet = -1;
  579. EnterCriticalSection(&upload_db_lock);
  580. if (upload_db.is_open()){
  581. std::string sql = "select count(*) from upload_db where rst_upload_state=3 ";
  582. if (strcmp(param, "success") == 0) sql += " and paper_state=0";
  583. else if (strcmp(param, "error") == 0)sql += " and paper_state!=0";
  584. nRet = upload_db.execScalar(sql.c_str());
  585. }
  586. LeaveCriticalSection(&upload_db_lock);
  587. return nRet;
  588. }
  589. break;
  590. case UPLOAD_ON_SCAN_CMD::CMD_DEL_UPLOAD_REPORT:
  591. {
  592. if (param != NULL){
  593. std::vector<std::string> split_param;
  594. split(param, (std::string)",", &split_param);
  595. if (!m_vctPrePaperid.empty()){
  596. for (auto it_student_papaer_id : split_param)
  597. {
  598. int student_paper_id = std::stoi(it_student_papaer_id);
  599. std::lock_guard<std::mutex> _lk(m_tx_pre_paperid);
  600. auto it_find = std::find(m_vctPrePaperid.begin(), m_vctPrePaperid.end(), student_paper_id);
  601. if (it_find != m_vctPrePaperid.end()){
  602. m_vctPrePaperid.erase(it_find);
  603. }
  604. }
  605. }
  606. EnterCriticalSection(&upload_db_lock);
  607. if (upload_db.is_open()){
  608. std::string sql = "delete from upload_db where student_paper_id in(";
  609. sql += std::string(param) + ")";
  610. upload_db.execDML(sql.c_str());
  611. }
  612. LeaveCriticalSection(&upload_db_lock);
  613. if (m_zxhxCreateUploadDBSuccess){
  614. for (auto it_student_papaer_id : split_param)
  615. {
  616. int student_paper_id = std::stoi(it_student_papaer_id);
  617. rapidjson::Document doc;
  618. doc.SetObject();
  619. rapidjson::Document::AllocatorType& allocator = doc.GetAllocator();
  620. AddStringMember(doc, allocator, "net_task_type", "upload_on_scan_upload");
  621. AddStringMember(doc, allocator, "net_task_cmd", "upload_on_scan_del_paper");
  622. rapidjson::Value root; root.SetObject();
  623. AddStringMember(root, allocator, "bantch_code", m_bantch_code.c_str());
  624. AddNumberMember(root, allocator, "student_paper_id", student_paper_id, 0);
  625. doc.AddMember("data", root, allocator);
  626. rapidjson::StringBuffer buffer;
  627. rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
  628. doc.Accept(writer);
  629. std::string reststring = buffer.GetString();
  630. LOGFMTI("通知知心慧学删除试卷: param=%s", reststring.c_str());
  631. // 通知知心慧学删除试卷
  632. NetOperator::ClientSendData(reststring.c_str());
  633. }
  634. }
  635. }
  636. }
  637. break;
  638. case UPLOAD_ON_SCAN_CMD::CMD_START_SCAN:
  639. {
  640. {
  641. std::lock_guard<std::mutex> _lk(m_tx_pre_paperid);
  642. m_vctPrePaperid.clear();
  643. }
  644. NotifyScanProcess();
  645. if (!m_bCoutinue){
  646. EnterCriticalSection(result_db_lock);
  647. if (result_db && result_db->is_open()){
  648. std::string sql = "select student_paper_id,paper_state,ret_upload,img_upload from student_paper where Is_Covered!=1";
  649. auto qry = result_db->execQuery(sql.c_str());
  650. while (!qry.eof()){
  651. int paper_id = qry.getIntField("student_paper_id");
  652. std::lock_guard<std::mutex> _lk(m_tx_pre_paperid);
  653. m_vctPrePaperid.push_back(paper_id);
  654. qry.nextRow();
  655. }
  656. }
  657. LeaveCriticalSection(result_db_lock);
  658. }
  659. rapidjson::Document doc;
  660. doc.SetObject();
  661. rapidjson::Document::AllocatorType& allocator = doc.GetAllocator();
  662. AddStringMember(doc, allocator, "net_task_type", "upload_on_scan_upload");
  663. AddStringMember(doc, allocator, "net_task_cmd", "upload_on_scan_start");
  664. rapidjson::Value root; root.SetObject();
  665. ScanParamInfo*pParamInfo = (ScanParamInfo*)(param);
  666. if (pParamInfo){
  667. m_bantch_code = pParamInfo->bantch_code;
  668. AddStringMember(root, allocator, "bantch_code", m_bantch_code.c_str());
  669. AddStringMember(root, allocator, "exam_id", pParamInfo->exam_id.c_str());
  670. AddStringMember(root, allocator, "subject_name", pParamInfo->course_name.c_str());
  671. AddStringMember(root, allocator, "subject_id", pParamInfo->subject_id.c_str());
  672. }
  673. if (m_pBatchService && m_pBatchService->GetRstUploaderPtr()){
  674. char sUrl[1024] = { 0 };
  675. int nLen = sizeof(sUrl) / sizeof(char);
  676. m_pBatchService->GetRstUploaderPtr()->readNewUploadUrl();
  677. m_pBatchService->GetRstUploaderPtr()->getupLoadUrl(sUrl, nLen);
  678. AddStringMember(root, allocator, "url", sUrl);
  679. AddStringMember(root, allocator, "session", "");
  680. //AddStringMember(root, allocator, "session",OnLineCard::UnicodeToAnsi( m_pBatchService->GetRstUploaderPtr()->MarkHttpHeaderData()).c_str());
  681. }
  682. // 业务类型
  683. TCHAR FilePath[MAX_PATH];
  684. GetModuleFileName(NULL, FilePath, MAX_PATH);
  685. (_tcsrchr(FilePath, '\\'))[1] = 0;
  686. lstrcat(FilePath, _T("paperinfo.ini"));
  687. int service_type = GetPrivateProfileInt(_T("paperinfo"), _T("servicetype"), 0, FilePath);
  688. AddNumberMember(root, allocator, "service_type", service_type, 0);
  689. if (nOnlineScanType == 0)//魔法词汇宝
  690. {
  691. AddNumberMember(root, allocator, "ntype", 6, 0);
  692. }
  693. else
  694. {
  695. AddNumberMember(root, allocator, "ntype", g_my_scan_type + 1, 0);
  696. }
  697. TCHAR exam_name[256] = { 0 };
  698. (_tcsrchr(FilePath, '\\'))[1] = 0;
  699. lstrcat(FilePath, _T("config.ini"));
  700. GetPrivateProfileString(_T("THIRD"), _T("exam_name"), _T(""), exam_name, sizeof(exam_name)/sizeof(TCHAR), FilePath);
  701. AddStringMember(root, allocator, "exam_name", OnLineCard::UnicodeToAnsi(exam_name).c_str());
  702. doc.AddMember("data",root,allocator);
  703. rapidjson::StringBuffer buffer;
  704. rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
  705. doc.Accept(writer);
  706. m_strStartParam = buffer.GetString();
  707. LOGFMTI("通知知心慧学开启边扫边传任务:%s", m_strStartParam.c_str());
  708. // 通知知心慧学开启边扫边传任务
  709. NetOperator::ClientSendData(m_strStartParam.c_str());
  710. m_bScanStartFlag = true;
  711. }
  712. break;
  713. case UPLOAD_ON_SCAN_CMD::CMD_SET_SCAN_STOP_FLAG:
  714. LOGI("扫描结束");
  715. m_bScanStopFlag = (_stricmp(param, "true") == 0);
  716. if (m_bScanStopFlag)
  717. NotifyUploadOnScanStop();
  718. break;
  719. case CMD_SEND_UPLAOD_RST_TO_ZXHX:
  720. if (m_bScanStopFlag)
  721. NotifyUploadOnScanStop();
  722. break;
  723. case UPLOAD_ON_SCAN_CMD::CMD_GET_UPLOAD_PROCESS:
  724. NotifyScanProcess();
  725. break;
  726. case UPLOAD_ON_SCAN_CMD::CMD_UPLOAD_YICHANGEJUAN:
  727. UploadYichangjuan();
  728. break;
  729. case UPLOAD_ON_SCAN_CMD::CMD_UPLOAD_SUCCESSSJUAN:{
  730. if (param){
  731. std::string tmp = param;
  732. if(!tmp.empty())
  733. UploadSuccessjuan(std::stoi(tmp));
  734. }
  735. }
  736. break;
  737. case UPLOAD_ON_SCAN_CMD::CMD_UPLOAD_STOP:{
  738. if (m_thread.joinable()){
  739. m_bExit.store(true);
  740. m_thread.join();
  741. }
  742. NotifyEnd();
  743. }
  744. break;
  745. case UPLOAD_ON_SCAN_CMD::CMD_RE_UPLOADERROR:
  746. {
  747. ReUploadUploadError(param);
  748. }
  749. break;
  750. }
  751. return 0;
  752. }
  753. void UploadManager::SendUploadTaskWhenReConnected()
  754. {
  755. LOGI("重连后发送待上传的试卷到知心慧学");
  756. std::string sql = "select student_paper_id, paper_state from upload_db where (rst_upload_state=0 OR ori_upload_state=0)";
  757. if (!m_bScanStopFlag){
  758. sql += " AND paper_state=0";
  759. }
  760. ::EnterCriticalSection(&upload_db_lock);
  761. try{
  762. if (upload_db.is_open()){
  763. auto qry = upload_db.execQuery(sql.c_str());
  764. while (!qry.eof()){
  765. int student_paper_id = qry.getIntField("student_paper_id");
  766. int paper_state = qry.getIntField("paper_state");
  767. LOGFMTI("将试卷插入到边上传数据库: id = %d paper_state", student_paper_id, paper_state);
  768. if (m_pBatchService && m_zxhxCreateUploadDBSuccess){
  769. m_pBatchService->StartUploadPaper(NULL, student_paper_id, paper_state!=0);
  770. }
  771. else{
  772. LOGE("将试卷插入到边上传数据库失败");
  773. }
  774. qry.nextRow();
  775. }
  776. }
  777. }
  778. catch (...){
  779. LOGE("将试卷插入到边上传数据库失败-SQL异常");
  780. ::LeaveCriticalSection(&upload_db_lock);
  781. }
  782. ::LeaveCriticalSection(&upload_db_lock);
  783. LOGI("重连后发送待上传的试卷到知心慧学-END");
  784. }
  785. #define reset_batchdb_sql_rst_fmt "update student_paper set ret_upload=0 where student_paper_id in (%s)"
  786. #define reset_batchdb_sql_ori_fmt "update student_paper set ret_upload=0 where student_paper_id in (%s)"
  787. #define reset_uploaddb_sql_rst_fmt "update upload_db set rst_upload_state=0 where student_paper_id in (%s)"
  788. #define reset_uploaddb_sql_ori_fmt "update upload_db set ori_upload_state=0 where student_paper_id in (%s)"
  789. void UploadManager::ReUploadUploadError(const char*param)
  790. {
  791. if (!param){
  792. return;
  793. }
  794. bool re_upload_yichang = false;
  795. LOGI("开始重新上传[上传失败的试卷]");
  796. std::string sql_qry = "select paper_state,student_paper_id,ret_upload,img_upload from student_paper where ";
  797. if (strcmp(param, "success") == 0){
  798. sql_qry += " paper_state=0 and ret_upload=3";
  799. }
  800. else if (strcmp(param, "error") == 0){
  801. sql_qry += " paper_state!=0 and ret_upload=3";
  802. re_upload_yichang = true;
  803. }
  804. else{
  805. sql_qry += std::string("student_paper_id=") + param;
  806. }
  807. LOGFMTI("重新上传 sql = %s", sql_qry.c_str());
  808. std::vector<int> vct_ori_paperid;//原卷
  809. std::vector<int> vct_rst_paperid;//答卷
  810. std::string str_ori_paper_id;
  811. std::string str_rst_paper_id;
  812. // 重传扫描成功的试卷
  813. ::EnterCriticalSection(result_db_lock);
  814. if (result_db && result_db->is_open()){
  815. LOGFMTD("SQL:%s", sql_qry.c_str());
  816. CppSQLite3Query qry = result_db->execQuery(sql_qry.c_str());
  817. if (qry.eof())
  818. LOGI("没有找到要上传的数据");
  819. while (!qry.eof()){
  820. int paper_state = qry.getIntField("paper_state");
  821. int student_paper_id = qry.getIntField("student_paper_id");
  822. // 答卷上传状态
  823. int ret_upload = qry.getIntField("ret_upload");
  824. if (ret_upload == 3){
  825. str_rst_paper_id += std::to_string(student_paper_id) + ",";
  826. vct_rst_paperid.push_back(student_paper_id);
  827. }
  828. if (paper_state == 0){
  829. // 原卷上传状态
  830. int img_upload = qry.getIntField("img_upload");
  831. if (img_upload == 3){
  832. str_ori_paper_id += std::to_string(student_paper_id) + ",";
  833. vct_ori_paperid.push_back(student_paper_id);
  834. }
  835. }
  836. else{
  837. re_upload_yichang = true;
  838. }
  839. qry.nextRow();
  840. }
  841. if (!str_rst_paper_id.empty()){
  842. str_rst_paper_id = std::string(str_rst_paper_id, 0, str_rst_paper_id.size() - 1);
  843. char sz_sql[1024] = { 0 };
  844. sprintf_s(sz_sql, reset_batchdb_sql_rst_fmt, str_rst_paper_id.c_str());
  845. result_db->execDML(sz_sql);
  846. }
  847. if (!str_ori_paper_id.empty()){
  848. str_ori_paper_id = std::string(str_ori_paper_id, 0, str_ori_paper_id.size() - 1);
  849. char sz_sql[1024] = { 0 };
  850. sprintf_s(sz_sql, reset_batchdb_sql_ori_fmt, str_ori_paper_id.c_str());
  851. result_db->execDML(sz_sql);
  852. }
  853. if (upload_db.is_open()){
  854. ::EnterCriticalSection(&upload_db_lock);
  855. if (!str_rst_paper_id.empty()){
  856. char sz_sql[1024] = { 0 };
  857. sprintf_s(sz_sql, reset_uploaddb_sql_rst_fmt, str_rst_paper_id.c_str());
  858. upload_db.execDML(sz_sql);
  859. }
  860. if (!str_ori_paper_id.empty()){
  861. char sz_sql[1024] = { 0 };
  862. sprintf_s(sz_sql, reset_uploaddb_sql_ori_fmt, str_ori_paper_id.c_str());
  863. upload_db.execDML(sz_sql);
  864. }
  865. ::LeaveCriticalSection(&upload_db_lock);
  866. }
  867. }
  868. ::LeaveCriticalSection(result_db_lock);
  869. auto p_send_data_func = [](int student_paper_id, int type, const std::string&batch_code){
  870. rapidjson::Document doc;doc.SetObject();
  871. rapidjson::Document::AllocatorType& allocator = doc.GetAllocator();
  872. rapidjson::Value _data; _data.SetObject();
  873. // 数据头
  874. AddStringMember(doc, allocator, "net_task_type", "upload_on_scan_upload");
  875. AddStringMember(doc, allocator, "net_task_cmd", "upload_on_scan_updata_upload_task");
  876. // 数据体
  877. AddStringMember(_data, allocator, "bantch_code", batch_code.c_str());
  878. AddNumberMember(_data, allocator, "student_paper_id", student_paper_id, 0);
  879. //type 0答卷、1原卷、2异常卷
  880. AddNumberMember(_data, allocator, "type", type, 0);
  881. doc.AddMember("data", _data, allocator);
  882. rapidjson::StringBuffer buffer;
  883. rapidjson::Writer<rapidjson::StringBuffer> writer(buffer);
  884. doc.Accept(writer);
  885. std::string reststring = buffer.GetString();
  886. LOGFMTD("向知心慧学端发送重传命令: %s", reststring.c_str());
  887. NetOperator::ClientSendData(reststring.c_str());
  888. };
  889. for (auto it : vct_rst_paperid){
  890. p_send_data_func(it, re_upload_yichang ? 2 : 0,m_bantch_code);
  891. }
  892. for (auto it : vct_ori_paperid){
  893. p_send_data_func(it, 1, m_bantch_code);
  894. }
  895. LOGI("重传状态设置完成");
  896. }
  897. void UploadManager::UploadSuccessjuan(int student_paper_id)
  898. {
  899. std::string insert_sql_fmt = "INSERT INTO upload_db (student_paper_id, paper_state,ori_upload_state,rst_upload_state,ori_info,rst_info) VALUES (%d,0,0,0,'','')";
  900. if (upload_db.is_open()){
  901. EnterCriticalSection(&upload_db_lock);
  902. char szSQL[256] = { 0 };
  903. sprintf(szSQL, insert_sql_fmt.c_str(), student_paper_id);
  904. upload_db.execDML(szSQL);
  905. LeaveCriticalSection(&upload_db_lock);
  906. LOGFMTI("将成功卷插入到边上传数据库: id = %d", student_paper_id);
  907. if (m_pBatchService && m_zxhxCreateUploadDBSuccess){
  908. LOGFMTI("开启上传 m_pBatchService id=%d",student_paper_id);
  909. m_pBatchService->StartUploadPaper(NULL, student_paper_id,false);
  910. }
  911. }
  912. }
  913. void UploadManager::UploadYichangjuan()
  914. {
  915. LOGI("开始上传异常卷");
  916. std::string sql = "select student_paper_id,paper_state from student_paper where paper_state!=0";
  917. std::string insert_sql_fmt = "INSERT INTO upload_db (student_paper_id, paper_state,ori_upload_state,rst_upload_state,ori_info,rst_info) VALUES (%d,%d,0,0,'','')";
  918. EnterCriticalSection(result_db_lock);
  919. if (result_db &&result_db->is_open()){
  920. CppSQLite3Query rs_qry = result_db->execQuery(sql.c_str());
  921. while (!rs_qry.eof()){
  922. if (upload_db.is_open()){
  923. EnterCriticalSection(&upload_db_lock);
  924. int student_paper_id = rs_qry.getIntField("student_paper_id");
  925. std::string sql_tmp = std::string("select count(*) from upload_db where student_paper_id=")+ std::to_string(student_paper_id);
  926. if (upload_db.execScalar(sql_tmp.c_str()) <= 0){
  927. int paper_state = rs_qry.getIntField("paper_state");
  928. char szSQL[256] = { 0 };
  929. sprintf(szSQL, insert_sql_fmt.c_str(), student_paper_id, paper_state);
  930. LOGFMTI("将异常卷插入到边上传数据库: id = %d, state = %d sql=%s", student_paper_id, paper_state, szSQL);
  931. upload_db.execDML(szSQL);
  932. if (m_pBatchService&&m_zxhxCreateUploadDBSuccess){
  933. LOGFMTI("开启上传 m_pBatchService id=%d", student_paper_id);
  934. m_pBatchService->StartUploadPaper(NULL, student_paper_id,true);
  935. }
  936. }
  937. LeaveCriticalSection(&upload_db_lock);
  938. }
  939. rs_qry.nextRow();
  940. }
  941. }
  942. LeaveCriticalSection(result_db_lock);
  943. LOGI("上传异常卷结束");
  944. }