#include "StdAfx.h" #include "BatchService.h" #include "scan_common.h" #include "..\EvaluationUtil\HttpClient.h" #include "..\Schema\schema_struct.h" #include "SchemaLoader.h" #include "basic_struct_result.h" #include "..\Identifier\schema_struct.h" #include "ServerConfig.h" //#include "Log4cplusInitalizer.h" #include "TemplateManager.h" #include "resource.h" #include "IdentifyService.h" #include "ResultUploader.h" #include #include #include "OnlineCardIdentifyService.h" #include #include "../Identifier/OnLineCardSchemaStruct.h" #include "..\ZLibWrapMemLib\UnZipFile.h" #include "..\ZLibWrapMemLib\MemZipFile.h" #include "..\ZLibWrapLib\ZLibWrapLib.h" #include "OnlineCardStudentMatcher.h" #include "ResultUploader.h" #include using namespace schema; using namespace OnLineCard; CString GetExePath() { HMODULE module = GetModuleHandle(0); TCHAR pFileName[MAX_PATH + 2] = { 0 }; GetModuleFileName(module, pFileName, MAX_PATH); CString csFullPath(pFileName); int nPos = csFullPath.ReverseFind(_T('\\')); if (nPos < 0) return CString(""); else return csFullPath.Left(nPos); } CString AnsiToUnicode(const std::string& str); std::string UnicodeToAnsi(const CString& str); int g_my_scan_type;//0答题卡 1督学卡 int g_my_continue_scan = 0; //督学卡学校id std::string g_strShoolId; std::string g_strUpLoadDbPathName; bool g_isAllSubject = false;//是否是全学科 int g_myindex = 1; extern int g_flagid; void ThreadLog2(char* ThreadName, char* fileName) { char buf[200]; _getcwd(buf, sizeof(buf)); strcat_s(buf, "\\ThirdParty\\"); strcat_s(buf, fileName); FILE *file = NULL; fopen_s(&file, buf, "at+"); if (file == NULL) { // printf("路径错误\n"); //system("pause"); return; } fseek(file, 0, SEEK_END); char bufThread[200]; strcpy_s(bufThread, sizeof(bufThread), ThreadName); fwrite(&bufThread, strlen(bufThread), 1, file); fclose(file); } CBatchService::CBatchService(bool bOnlineCard, int nSubjectID, int nOnlineScanType) :m_bantch_state(DATABASE_STATE_CREATE), m_result_uploader(new CResultUploader()), m_bOnlineCard(bOnlineCard), m_nSubjectID(nSubjectID), m_nOnlineScanType(nOnlineScanType) { m_eventZXHXCreateDB = CreateEvent(NULL, false, false, NULL); m_result_uploader->EnableOnLineCard(m_bOnlineCard, m_nSubjectID, nOnlineScanType); m_upload_manager.m_pBatchService = this; m_onlineCardTemplate = new OnLineCard::PaperTemplate; InitializeCriticalSection(&bantch_db_lock); m_bErrorHandle = false; NetOperator::SetClientNotifyPtr(this); if (getRunFlag() == _T("1")){ CString _ini_file = GetExePath() + _T("\\..\\config.ini"); TCHAR sz_b_code[100] = { 0 }; GetPrivateProfileString(_T("THRID"), _T("cur_bantch_code"), _T(""), sz_b_code, sizeof(sz_b_code) / sizeof(TCHAR), _ini_file); auto bantch_code = UnicodeToAnsi(sz_b_code); m_upload_manager.SetBatchCode(bantch_code); } LOGI("连接知心慧学"); int nRet = NetOperator::InitClient("127.0.0.1", 99995, this); if (nRet==-1){ LOGI("连接知心慧学已存在,无需再次连接"); } else if (nRet<0){ LOGE("连接知心慧学-ERROR"); } else{ LOGI("连接知心慧学-SUCCESS"); } } CBatchService::~CBatchService(void) { if (m_coverd_all_kaohaochongtu.valid()){ LOGI("等待覆盖所有考号冲突线程退出"); m_coverd_all_kaohaochongtu.wait(); LOGI("覆盖所有考号冲突线程退出"); } if (m_onlineCardTemplate) delete m_onlineCardTemplate; m_onlineCardTemplate = nullptr; DeleteCriticalSection(&bantch_db_lock); CloseHandle(m_eventZXHXCreateDB); NetOperator::SetClientNotifyPtr(NULL); } //开始扫描处理函数 ServiceState CBatchService::OnStarting(void) { char sql[512]; sprintf_s(sql, "update database set database_state =%d where database_id =%d", DATABASE_STATE_SCANNING, m_database_id); EnterCriticalSection(database_db_lock); database_db->execDML("begin transaction"); database_db->execDML(sql); database_db->execDML("commit transaction"); LeaveCriticalSection(database_db_lock); mainService->SetHandlerWnd(m_hwnd); mainService->Start(); while (mainService->GetServiceSate()== starting) { Sleep(10); } if (m_hwnd != NULL)::PostMessage(m_hwnd, WM_IDENTIFOR_STARTED, 0, 0); return running; } ServiceState CBatchService::OnRunning(void) { ServiceState nextState = IService::OnRunning(); if (nextState == pausing) return nextState; if (nextState == stoping) return nextState; if (mainService->GetServiceSate()==stoped){ return stoping; }else{ Sleep(10); } return running; } static void resetQueScore(std::vector &questions, std::string rule) { Json::Value qesScores; if (rule.empty()) return; Json::Features features; Json::Reader re(features); Json::Value root; re.parse(rule, root); qesScores = root["questions"]; if (qesScores.isNull()) return; int array_size = 0; array_size = qesScores.size(); for (int i = 0; i < array_size; i++) { Json::Value row = qesScores[i]; int qesid = row["questionNum"].asInt(); int qestype = row["questionTypeId"].asInt(); float score = atof(row["fullScore"].asString().c_str()); string answer = ""; if (!row["answer"].isNull()) { answer = row["answer"].asString(); } for (auto& it : questions) { char str[25]; itoa(qesid, str, 10); if (strcmp(it.question_code_new, str) == 0) { it.score = score; if (answer.length()) { it.answerA = answer; } break; } } } } string CBatchService::GetBatchCode() { string str = UnicodeToAnsi(m_bantch_code); return str; } int CBatchService::LoadSchema(long long examId, std::string examName, long examCourseId, std::string courseName, std::string schemaPath, std::string rule/*=""*/) { if (m_upload_manager.IsEanble()){ // 边扫描边上传模式 ScanParamInfo obj; obj.subject_id = std::to_string(m_examCourseId); obj.course_name = m_courseName; obj.exam_id = std::to_string(m_examId); CString _ini_file = GetExePath() + _T("\\..\\config.ini"); if (m_upload_manager.IsContinue()){ TCHAR sz_b_code[100] = { 0 }; GetPrivateProfileString(_T("THRID"), _T("cur_bantch_code"), _T(""), sz_b_code, sizeof(sz_b_code) / sizeof(TCHAR), _ini_file); obj.bantch_code = UnicodeToAnsi(sz_b_code); } else{ obj.bantch_code = UnicodeToAnsi(m_bantch_code); WritePrivateProfileString(_T("THRID"), _T("cur_bantch_code"), m_bantch_code, _ini_file); } m_upload_manager.UploadOnScanCmd(UPLOAD_ON_SCAN_CMD::CMD_START_SCAN, (const char*)&obj, m_nOnlineScanType); m_result_uploader->SetBatchCode(AnsiToUnicode(obj.bantch_code)); if (WaitForSingleObject(m_eventZXHXCreateDB, INFINITE) != WAIT_OBJECT_0){ LOGI("等待知心慧学创建数据库超时"); ::PostMessage(m_hwnd, WM_IDENTIFOR_STOPED, 0, 0); return IDF_LOAD_FAILURE; } else{ if (!m_upload_manager.IsZXHXCreateUploadDBSuccess()){ LOGI("知心慧学创建数据库错误,无法扫描OR扫描后无法上传"); ::PostMessage(m_hwnd, WM_IDENTIFOR_STOPED, 0, 0); return IDF_LOAD_FAILURE; } } } m_examId = examId; m_examCourseId = examCourseId; CSchemaLoader schemaLoader; if (!m_bOnlineCard){ int ret = schemaLoader.Load(schemaPath, m_muban_img_dir, m_schema0, m_schema, m_handleInfo); if (ret == SCH_LOAD_SUCCESS) { resetQueScore(m_schema0.questions, rule); saveQuestionStd(examId, examName, examCourseId, courseName, m_schema0.questions, rule); recordBarcodeFlag(0); for (int i = 0; i < m_schema0.pages.size(); i++) { if (m_schema0.pages[i].codes.size()>0) recordBarcodeFlag(1); } g_myindex = 1; mainService->SetFolderPageNumber(m_schema0.pages.size()); return IDF_LOAD_SUCCESS; } else { return IDF_LOAD_CLASS_SCHEMA | ret; } } else { if (m_onlineCardTemplate) { if (ParseTemplateFromJson(schemaPath)) { Online_saveQuestionStd(examId, examName, examCourseId, courseName, rule); mainService->SetFolderPageNumber(m_onlineCardTemplate->pages.size()); return IDF_LOAD_SUCCESS; } else { return IDF_LOAD_FAILURE; } } else return IDF_LOAD_FAILURE; } return IDF_LOAD_FAILURE; } #include "pugixml/pugixml.hpp" // void ParseTemplateOffset(const std::string&file_name, OnLineCard::PaperTemplate* m_onlineCard) // { // if (m_onlineCard->pages.size() <= 0)return; // if (!m_onlineCard) return; // pugi::xml_document doc; // auto result = doc.load_file(file_name.c_str()); // if (result.status != pugi::status_ok) // return; // for (auto child = doc.child("item_info").first_child(); child; child = child.next_sibling()) // { // std::string child_name = child.name(); // if (child_name == "dingweidian_w_max_rate"){ // std::string value = child.attribute("value").value(); // if (!value.empty()) // m_onlineCard->dingweidian_w_max_rate = std::stof(value); // } // else if (child_name == "dingweidian_w_min_rate"){ // std::string value = child.attribute("value").value(); // if (!value.empty()) // m_onlineCard->dingweidian_w_min_rate = std::stof(value); // } // else if (child_name == "dingweidian_h_max_rate"){ // std::string value = child.attribute("value").value(); // if (!value.empty()) // m_onlineCard->dingweidian_h_max_rate = std::stof(value); // } // else if (child_name == "dingweidian_h_min_rate"){ // std::string value = child.attribute("value").value(); // if (!value.empty()) // m_onlineCard->dingweidian_h_min_rate = std::stof(value); // } // else if (child_name == "dingweidian_range_top"){ // std::string value = child.attribute("value").value(); // if (!value.empty()) // m_onlineCard->dingweidian_range_top = std::stoi(value); // } // else if (child_name == "dingweidian_rang_buttom"){ // std::string value = child.attribute("value").value(); // if (!value.empty()) // m_onlineCard->dingweidian_rang_buttom = std::stoi(value); // } // else if (child_name == "open_save_debug_img"){ // std::string value = child.attribute("value").value(); // if (!value.empty()) // m_onlineCard->open_save_debug_img = (std::stoi(value) == 1); // } // else{ // Item_Pos_offset_Info info; // for (pugi::xml_attribute attr = child.first_attribute(); attr; attr = attr.next_attribute()){ // std::string attr_name = attr.name(); // if (attr_name == "type"){ // std::string value = attr.value(); // if (!value.empty()) // info.type = (item_type)std::stoi(value); // } // else if (attr_name == "x_offset"){ // std::string value = attr.value(); // if (!value.empty()) // info.x_offset = (item_type)std::stoi(value); // } // else if (attr_name == "y_offset"){ // std::string value = attr.value(); // if (!value.empty()) // info.y_offset = (item_type)std::stoi(value); // } // else if (attr_name == "w_offset"){ // std::string value = attr.value(); // if (!value.empty()) // info.w_offset = (item_type)std::stoi(value); // } // else if (attr_name == "h_offset"){ // std::string value = attr.value(); // if (!value.empty()) // info.h_offset = (item_type)std::stoi(value); // } // else if (attr_name == "score_x_offset"){ // std::string value = attr.value(); // if (!value.empty()) // info.x_offset_score = (item_type)std::stoi(value); // } // else if (attr_name == "score_y_offset"){ // std::string value = attr.value(); // if (!value.empty()) // info.y_offset_score = (item_type)std::stoi(value); // } // else if (attr_name == "score_w_offset"){ // std::string value = attr.value(); // if (!value.empty()) // info.w_offset_score = (item_type)std::stoi(value); // } // else if (attr_name == "score_h_offset"){ // std::string value = attr.value(); // if (!value.empty()) // info.h_offset_score = (item_type)std::stoi(value); // } // else if (attr_name == "id"){ // info.question_id = attr.value(); // } // else if (attr_name == "opt_x_offset"){ // std::string value = attr.value(); // if (!value.empty()) // info.x_offset_opt = (item_type)std::stoi(value); // } // else if (attr_name == "opt_y_offset"){ // std::string value = attr.value(); // if (!value.empty()) // info.y_offset_opt = (item_type)std::stoi(value); // } // else if (attr_name == "opt_w_offset"){ // std::string value = attr.value(); // if (!value.empty()) // info.w_offset_opt = (item_type)std::stoi(value); // } // else if (attr_name == "opt_h_offset"){ // std::string value = attr.value(); // if (!value.empty()) // info.h_offset_opt = (item_type)std::stoi(value); // } // } // std::string key = info.question_id; // if (info.type == item_type::type_absent || //缺考标记 // info.type == item_type::type_qrbar || // 二维码 // info.type == item_type::type_tiaoxingma){ // 条形码 // Pos*pos = &m_onlineCard->pages[1].absent; // if (info.type == item_type::type_qrbar)pos = &m_onlineCard->pages[1].QrCode; // else if (info.type == item_type::type_tiaoxingma)pos = &m_onlineCard->pages[1].studentcode_bar; // pos->x += info.x_offset; // pos->y += info.y_offset; // pos->w += info.w_offset; // pos->h += info.h_offset; // continue; // } // else if (info.type == item_type::type_tiantukaohao){ // key = "tiantukaohao"; // } // else if (info.type == item_type::type_question_keguan){ // key = "question_keguan"; // } // else if (info.type == item_type::type_question_keguan_d){ // key = "question_keguan_d"; // } // else if (info.type == item_type::type_question_keguan_b){ // key = "question_keguan_b"; // } // m_onlineCard->_map_offset_info[key] = info; // } // } // // // 更新 // // 填涂考号 // auto it_find = m_onlineCard->_map_offset_info.find("tiantukaohao"); // if (it_find != m_onlineCard->_map_offset_info.end()){ // int nIndex = 0; // for (std::size_t row = 0; row < m_onlineCard->pages[1].studentcode_fill.size(); row++) // { // for (std::size_t col = 0; col < m_onlineCard->pages[1].studentcode_fill[row].size(); col++, nIndex++) // { // m_onlineCard->pages[1].studentcode_fill[row][col].pos.x += it_find->second.x_offset; // m_onlineCard->pages[1].studentcode_fill[row][col].pos.y += it_find->second.y_offset; // m_onlineCard->pages[1].studentcode_fill[row][col].pos.w += it_find->second.w_offset; // m_onlineCard->pages[1].studentcode_fill[row][col].pos.h += it_find->second.h_offset; // } // } // } // auto &it_keguanti = m_onlineCard->_map_offset_info.find("question_keguan"); // auto &it_keguanti_d = m_onlineCard->_map_offset_info.find("question_keguan_d"); // auto &it_keguanti_b = m_onlineCard->_map_offset_info.find("question_keguan_b"); // for (std::size_t n = 0; n < m_onlineCard->pages.size(); ++n) // { // for (std::size_t i = 0; i < m_onlineCard->pages[n + 1].vctQuestions.size(); ++i) // { // std::string id = m_onlineCard->pages[n + 1].vctQuestions[i].id; // auto it_find = m_onlineCard->_map_offset_info.find(id); // if (it_find != m_onlineCard->_map_offset_info.end()){ // // 主观题 // if ( m_onlineCard->pages[n + 1].vctQuestions[i].type == 1 || // m_onlineCard->pages[n + 1].vctQuestions[i].type == 3 || // m_onlineCard->pages[n + 1].vctQuestions[i].type == 2){ // m_onlineCard->pages[n + 1].vctQuestions[i].cut.pos.x += it_find->second.x_offset; // m_onlineCard->pages[n + 1].vctQuestions[i].cut.pos.y += it_find->second.y_offset; // m_onlineCard->pages[n + 1].vctQuestions[i].cut.pos.w += it_find->second.w_offset; // m_onlineCard->pages[n + 1].vctQuestions[i].cut.pos.h += it_find->second.h_offset; // // m_onlineCard->pages[n + 1].vctQuestions[i].scoreBox.pos.x += it_find->second.x_offset_score; // m_onlineCard->pages[n + 1].vctQuestions[i].scoreBox.pos.y += it_find->second.y_offset_score; // m_onlineCard->pages[n + 1].vctQuestions[i].scoreBox.pos.w += it_find->second.w_offset_score; // m_onlineCard->pages[n + 1].vctQuestions[i].scoreBox.pos.h += it_find->second.h_offset_score; // if (m_onlineCard->pages[n + 1].vctQuestions[i].type == 2){ // // 选做题 // for (std::size_t j = 0; j pages[n + 1].vctQuestions[i].opt.size(); ++j){ // m_onlineCard->pages[n + 1].vctQuestions[i].opt[j].pos.x += it_find->second.x_offset_opt; // m_onlineCard->pages[n + 1].vctQuestions[i].opt[j].pos.y += it_find->second.y_offset_opt; // m_onlineCard->pages[n + 1].vctQuestions[i].opt[j].pos.w += it_find->second.w_offset_opt; // m_onlineCard->pages[n + 1].vctQuestions[i].opt[j].pos.h += it_find->second.h_offset_opt; // } // } // } // } // // 单选题 // else if (m_onlineCard->pages[n + 1].vctQuestions[i].type==0 && it_keguanti != m_onlineCard->_map_offset_info.end()){ // for (std::size_t j = 0; j < m_onlineCard->pages[n + 1].vctQuestions[i].opt.size(); ++j){ // m_onlineCard->pages[n + 1].vctQuestions[i].opt[j].pos.x += it_keguanti->second.x_offset; // m_onlineCard->pages[n + 1].vctQuestions[i].opt[j].pos.y += it_keguanti->second.y_offset; // m_onlineCard->pages[n + 1].vctQuestions[i].opt[j].pos.w += it_keguanti->second.w_offset; // m_onlineCard->pages[n + 1].vctQuestions[i].opt[j].pos.h += it_keguanti->second.h_offset; // } // } // // 多选题 // else if (m_onlineCard->pages[n + 1].vctQuestions[i].type == 8 && it_keguanti_d != m_onlineCard->_map_offset_info.end()){ // for (std::size_t j = 0; j < m_onlineCard->pages[n + 1].vctQuestions[i].opt.size(); ++j){ // m_onlineCard->pages[n + 1].vctQuestions[i].opt[j].pos.x += it_keguanti_d->second.x_offset; // m_onlineCard->pages[n + 1].vctQuestions[i].opt[j].pos.y += it_keguanti_d->second.y_offset; // m_onlineCard->pages[n + 1].vctQuestions[i].opt[j].pos.w += it_keguanti_d->second.w_offset; // m_onlineCard->pages[n + 1].vctQuestions[i].opt[j].pos.h += it_keguanti_d->second.h_offset; // } // } // // 不定项选择题 // else if (m_onlineCard->pages[n + 1].vctQuestions[i].type == 5 && it_keguanti_b != m_onlineCard->_map_offset_info.end()){ // for (std::size_t j = 0; j < m_onlineCard->pages[n + 1].vctQuestions[i].opt.size(); ++j){ // m_onlineCard->pages[n + 1].vctQuestions[i].opt[j].pos.x += it_keguanti_b->second.x_offset; // m_onlineCard->pages[n + 1].vctQuestions[i].opt[j].pos.y += it_keguanti_b->second.y_offset; // m_onlineCard->pages[n + 1].vctQuestions[i].opt[j].pos.w += it_keguanti_b->second.w_offset; // m_onlineCard->pages[n + 1].vctQuestions[i].opt[j].pos.h += it_keguanti_b->second.h_offset; // } // } // } // } // } void ParseTemplateOffset(const std::string&file_name, OnLineCard::PaperTemplate* m_onlineCard) { if (m_onlineCard->pages.size() <= 0)return; if (!m_onlineCard) return; pugi::xml_document doc; auto result = doc.load_file(file_name.c_str()); if (result.status != pugi::status_ok) return; for (auto child = doc.child("item_info").first_child(); child; child = child.next_sibling()) { std::string child_name = child.name(); if (child_name == "dingweidian_w_max_rate"){ std::string value = child.attribute("value").value(); if (!value.empty()) m_onlineCard->dingweidian_w_max_rate = std::stof(value); } else if (child_name == "dingweidian_w_min_rate"){ std::string value = child.attribute("value").value(); if (!value.empty()) m_onlineCard->dingweidian_w_min_rate = std::stof(value); } else if (child_name == "dingweidian_h_max_rate"){ std::string value = child.attribute("value").value(); if (!value.empty()) m_onlineCard->dingweidian_h_max_rate = std::stof(value); } else if (child_name == "dingweidian_h_min_rate"){ std::string value = child.attribute("value").value(); if (!value.empty()) m_onlineCard->dingweidian_h_min_rate = std::stof(value); } else if (child_name == "dingweidian_range_top"){ std::string value = child.attribute("value").value(); if (!value.empty()) m_onlineCard->dingweidian_range_top = std::stoi(value); } else if (child_name == "dingweidian_rang_buttom"){ std::string value = child.attribute("value").value(); if (!value.empty()) m_onlineCard->dingweidian_rang_buttom = std::stoi(value); } else if (child_name == "open_save_debug_img"){ std::string value = child.attribute("value").value(); if (!value.empty()) m_onlineCard->open_save_debug_img = (std::stoi(value) == 1); } else{ Item_Pos_offset_Info info; for (pugi::xml_attribute attr = child.first_attribute(); attr; attr = attr.next_attribute()){ std::string attr_name = attr.name(); if (attr_name == "type"){ std::string value = attr.value(); if (!value.empty()) info.type = (item_type)std::stoi(value); } else if (attr_name == "x_offset"){ std::string value = attr.value(); if (!value.empty()) info.x_offset = (item_type)std::stoi(value); } else if (attr_name == "y_offset"){ std::string value = attr.value(); if (!value.empty()) info.y_offset = (item_type)std::stoi(value); } else if (attr_name == "w_offset"){ std::string value = attr.value(); if (!value.empty()) info.w_offset = (item_type)std::stoi(value); } else if (attr_name == "h_offset"){ std::string value = attr.value(); if (!value.empty()) info.h_offset = (item_type)std::stoi(value); } else if (attr_name == "score_x_offset"){ std::string value = attr.value(); if (!value.empty()) info.x_offset_score = (item_type)std::stoi(value); } else if (attr_name == "score_y_offset"){ std::string value = attr.value(); if (!value.empty()) info.y_offset_score = (item_type)std::stoi(value); } else if (attr_name == "score_w_offset"){ std::string value = attr.value(); if (!value.empty()) info.w_offset_score = (item_type)std::stoi(value); } else if (attr_name == "score_h_offset"){ std::string value = attr.value(); if (!value.empty()) info.h_offset_score = (item_type)std::stoi(value); } else if (attr_name == "id"){ info.question_id = attr.value(); } else if (attr_name == "opt_x_offset"){ std::string value = attr.value(); if (!value.empty()) info.x_offset_opt = (item_type)std::stoi(value); } else if (attr_name == "opt_y_offset"){ std::string value = attr.value(); if (!value.empty()) info.y_offset_opt = (item_type)std::stoi(value); } else if (attr_name == "opt_w_offset"){ std::string value = attr.value(); if (!value.empty()) info.w_offset_opt = (item_type)std::stoi(value); } else if (attr_name == "opt_h_offset"){ std::string value = attr.value(); if (!value.empty()) info.h_offset_opt = (item_type)std::stoi(value); } else if (attr_name == "link_param"){ std::string value = attr.value(); if (!value.empty()) info.link_param = (item_type)std::stoi(value); } } for (pugi::xml_node opt_info = child.first_child(); opt_info; opt_info = opt_info.next_sibling()){ Item_Pos_offset_Info _opt_info; for (pugi::xml_attribute attr = opt_info.first_attribute(); attr; attr = attr.next_attribute()){ std::string attr_name = attr.name(); if (attr_name == "index"){ // 选项序号 从0开始 _opt_info.question_id = attr.value(); } else if (attr_name == "x_offset"){ std::string value = attr.value(); if (!value.empty()) _opt_info.x_offset = (item_type)std::stoi(value); } else if (attr_name == "y_offset"){ std::string value = attr.value(); if (!value.empty()) _opt_info.y_offset = (item_type)std::stoi(value); } else if (attr_name == "w_offset"){ std::string value = attr.value(); if (!value.empty()) _opt_info.w_offset = (item_type)std::stoi(value); } else if (attr_name == "h_offset"){ std::string value = attr.value(); if (!value.empty()) _opt_info.h_offset = (item_type)std::stoi(value); } } info._child_info[std::stoi(_opt_info.question_id)] = _opt_info; } std::string key = info.question_id; if (info.type == item_type::type_absent || //缺考标记 info.type == item_type::type_qrbar || // 二维码 info.type == item_type::type_tiaoxingma){ // 条形码 Pos*pos = &m_onlineCard->pages[1].absent; if (info.type == item_type::type_qrbar)pos = &m_onlineCard->pages[1].QrCode; else if (info.type == item_type::type_tiaoxingma)pos = &m_onlineCard->pages[1].studentcode_bar; pos->x += info.x_offset; pos->y += info.y_offset; pos->w += info.w_offset; pos->h += info.h_offset; continue; } else if (info.type == item_type::type_tiantukaohao){ info.question_id = "tiantukaohao"; } if (info.link_param>1) { info.question_id += "_"; info.question_id += std::to_string(info.link_param); } m_onlineCard->_map_offset_info[info.question_id] = info; } } // 更新 // 填涂考号 auto it_find = m_onlineCard->_map_offset_info.find("tiantukaohao"); if (it_find != m_onlineCard->_map_offset_info.end()){ int nIndex = 0; for (std::size_t row = 0; row < m_onlineCard->pages[1].studentcode_fill.size(); row++) { for (std::size_t col = 0; col < m_onlineCard->pages[1].studentcode_fill[row].size(); col++, nIndex++) { m_onlineCard->pages[1].studentcode_fill[row][col].pos.x += it_find->second.x_offset; m_onlineCard->pages[1].studentcode_fill[row][col].pos.y += it_find->second.y_offset; m_onlineCard->pages[1].studentcode_fill[row][col].pos.w += it_find->second.w_offset; m_onlineCard->pages[1].studentcode_fill[row][col].pos.h += it_find->second.h_offset; auto it_opt_find = it_find->second._child_info.find(nIndex); if (it_opt_find != it_find->second._child_info.end()){ m_onlineCard->pages[1].studentcode_fill[row][col].pos.x += it_opt_find->second.x_offset; m_onlineCard->pages[1].studentcode_fill[row][col].pos.y += it_opt_find->second.y_offset; m_onlineCard->pages[1].studentcode_fill[row][col].pos.w += it_opt_find->second.w_offset; m_onlineCard->pages[1].studentcode_fill[row][col].pos.h += it_opt_find->second.h_offset; } } } } for (std::size_t n = 0; n < m_onlineCard->pages.size(); ++n) { for (std::size_t i = 0; i < m_onlineCard->pages[n + 1].vctQuestions.size(); ++i) { std::string id = m_onlineCard->pages[n + 1].vctQuestions[i].id; if ((m_onlineCard->pages[n + 1].vctQuestions[i].type == 1|| m_onlineCard->pages[n + 1].vctQuestions[i].type == 2) && m_onlineCard->pages[n + 1].vctQuestions[i].cut.linkparm>1){ id += "_"; id += std::to_string(m_onlineCard->pages[n + 1].vctQuestions[i].cut.linkparm); } auto it_find = m_onlineCard->_map_offset_info.find(id); if (it_find != m_onlineCard->_map_offset_info.end()){ // 主观题 if (m_onlineCard->pages[n + 1].vctQuestions[i].type == 1|| // 主观题 m_onlineCard->pages[n + 1].vctQuestions[i].type == 3|| // 填空题 m_onlineCard->pages[n + 1].vctQuestions[i].type == 2) // 选做题 { m_onlineCard->pages[n + 1].vctQuestions[i].cut.pos.x += it_find->second.x_offset; m_onlineCard->pages[n + 1].vctQuestions[i].cut.pos.y += it_find->second.y_offset; m_onlineCard->pages[n + 1].vctQuestions[i].cut.pos.w += it_find->second.w_offset; m_onlineCard->pages[n + 1].vctQuestions[i].cut.pos.h += it_find->second.h_offset; m_onlineCard->pages[n + 1].vctQuestions[i].scoreBox.pos.x += it_find->second.x_offset_score; m_onlineCard->pages[n + 1].vctQuestions[i].scoreBox.pos.y += it_find->second.y_offset_score; m_onlineCard->pages[n + 1].vctQuestions[i].scoreBox.pos.w += it_find->second.w_offset_score; m_onlineCard->pages[n + 1].vctQuestions[i].scoreBox.pos.h += it_find->second.h_offset_score; if (m_onlineCard->pages[n + 1].vctQuestions[i].type == 2){ // 选做题 for (std::size_t j = 0; j < m_onlineCard->pages[n + 1].vctQuestions[i].opt.size(); ++j) { auto it_opt_find = it_find->second._child_info.find(j); if (it_opt_find != it_find->second._child_info.end()){ m_onlineCard->pages[n + 1].vctQuestions[i].opt[j].pos.x += it_opt_find->second.x_offset; m_onlineCard->pages[n + 1].vctQuestions[i].opt[j].pos.y += it_opt_find->second.y_offset; m_onlineCard->pages[n + 1].vctQuestions[i].opt[j].pos.w += it_opt_find->second.w_offset; m_onlineCard->pages[n + 1].vctQuestions[i].opt[j].pos.h += it_opt_find->second.h_offset; } } } } else { // 选择题 多选题 不定项选择题 for (std::size_t j = 0; j < m_onlineCard->pages[n + 1].vctQuestions[i].opt.size(); ++j){ m_onlineCard->pages[n + 1].vctQuestions[i].opt[j].pos.x += it_find->second.x_offset; m_onlineCard->pages[n + 1].vctQuestions[i].opt[j].pos.y += it_find->second.y_offset; m_onlineCard->pages[n + 1].vctQuestions[i].opt[j].pos.w += it_find->second.w_offset; m_onlineCard->pages[n + 1].vctQuestions[i].opt[j].pos.h += it_find->second.h_offset; auto it_opt_find = it_find->second._child_info.find(j); if (it_opt_find != it_find->second._child_info.end()){ m_onlineCard->pages[n + 1].vctQuestions[i].opt[j].pos.x += it_opt_find->second.x_offset; m_onlineCard->pages[n + 1].vctQuestions[i].opt[j].pos.y += it_opt_find->second.y_offset; m_onlineCard->pages[n + 1].vctQuestions[i].opt[j].pos.w += it_opt_find->second.w_offset; m_onlineCard->pages[n + 1].vctQuestions[i].opt[j].pos.h += it_opt_find->second.h_offset; } } } } } } } bool CBatchService::ParseTemplateFromJsonAll(const std::string&fileName)//全学科在线答题卡 { extern bool g_isAllSubject;//是否是全学科 g_isAllSubject = 1; //1 单选 2 小题单选 3 多选 4 小题多选 5 单空 6 多空 7 小题多空 8 解答 9 小题解答 10 英语作文 11 语文作文 12 判断题 //0选择 1解答 2选作 3填空 4编组 5不定项 8不定项 map type_map;//新旧题型对应 type_map["1"] = 0; type_map["2"] = 0; type_map["3"] = 5; type_map["4"] = 5; type_map["5"] = 3; type_map["6"] = 3; type_map["7"] = 3; type_map["8"] = 1; type_map["9"] = 1; type_map["12"] = 0; /*type_map["10"] = 1; type_map["11"] = 1; */ CUnZipFile uzip(CString(fileName.c_str())); std::map> map1; while (uzip.HasMoreEntry()){ CString fileNam; uzip.GetNextEntry(fileNam); char buffer[1024 * 8]; int len; std::vector& data = map1[fileNam]; data.reserve(1024 * 128); while ((len = uzip.Read(buffer, 1024 * 8)) > 0){ if (data.capacity() < data.size() + len){ int c = data.capacity() + 1024 * 128; data.reserve(c); } int oldSize = data.size(); data.resize(oldSize + len); char * dst = (char *)data.data() + oldSize; memcpy(dst, buffer, len); } } uzip.Close(); auto schemabytes = map1.find(_T("json.txt")); if (schemabytes == map1.end()){ return SCH_LOAD_ERR_MISSINGFORMAT; } std::vector& data = schemabytes->second; auto strJson = std::string((char *)data.data(), data.size()); if (!m_onlineCardTemplate) return false; m_onlineCardTemplate->pages.clear(); auto pfGetPos = [](const rapidjson::Value&value)->std::tuple{ bool bRet = false; double x = 0.0, y = 0.0, w = 0.0, h = 0.0; auto itX = value.FindMember("x"); if (itX != value.MemberEnd() && (itX->value.IsInt() || itX->value.IsDouble())){ x = itX->value.GetDouble(); } auto itY = value.FindMember("y"); if (itY != value.MemberEnd() && (itY->value.IsInt() || itY->value.IsDouble())){ y = itY->value.GetDouble(); } auto itW = value.FindMember("width"); if (itW != value.MemberEnd() && (itW->value.IsInt() || itW->value.IsDouble())){ w = itW->value.GetDouble(); } auto itH = value.FindMember("height"); if (itH != value.MemberEnd() && (itH->value.IsInt() || itH->value.IsDouble())){ h = itH->value.GetDouble(); bRet = true; } return std::tie(bRet, Pos{ x, y, w, h }); }; rapidjson::Document doc; doc.Parse(strJson.c_str()); if (doc.HasParseError()) return false; m_onlineCardTemplate->subject_id = m_nSubjectID; m_onlineCardTemplate->_version = "3.1.0"; // 检测版本号 auto it_version = doc.FindMember("online_card_version"); if (it_version != doc.MemberEnd() && it_version->value.IsString()){ m_onlineCardTemplate->_version = it_version->value.GetString(); } LOGFMTI("在线答题卡版本号:%s", m_onlineCardTemplate->_version.c_str()); { // 总页数 auto itTotalPage = doc.FindMember("totalPage"); if (itTotalPage != doc.MemberEnd() && itTotalPage->value.IsInt()){ m_onlineCardTemplate->totalPage = itTotalPage->value.GetInt(); } // 是否使用二维码 auto itUseQrCode = doc.FindMember("useQrCode"); if (itUseQrCode != doc.MemberEnd() && itUseQrCode->value.IsBool()){ m_onlineCardTemplate->useQrCode = itUseQrCode->value.GetBool(); } if (itUseQrCode != doc.MemberEnd() && itUseQrCode->value.IsInt()){ m_onlineCardTemplate->useQrCode = (itUseQrCode->value.GetInt() != 0); } // 学校状态 auto itSchoolStatus = doc.FindMember("school_card_status"); if (itSchoolStatus != doc.MemberEnd() && itSchoolStatus->value.IsInt()){ m_onlineCardTemplate->schoolCardStatus = itSchoolStatus->value.GetInt(); } int n_duo_xuanti_index = 0; std::string temp_all_id = ""; // 页 auto itPages = doc.FindMember("pages"); if (itPages != doc.MemberEnd() && itPages->value.IsArray()/* && itPages->value.Size() == m_onlineCardTemplate->totalPage*/){ for (auto itPage = itPages->value.Begin(); itPage != itPages->value.End(); ++itPage){ if (!itPage->IsObject()) return false; PageTemplate page; // 页号 auto itPageNo = itPage->FindMember("pageNo"); if (itPageNo != itPage->MemberEnd() && itPageNo->value.IsInt()){ page.pageNo = itPageNo->value.GetInt(); } else { return false; } // 定位点 auto itLocations = itPage->FindMember("location"); if (itLocations != itPage->MemberEnd() && itLocations->value.IsArray()){ for (auto it = itLocations->value.Begin(); it != itLocations->value.End(); ++it){ Location lc; auto itType = it->FindMember("type"); if (itType != it->MemberEnd() && itType->value.IsInt()){ lc.type = itType->value.GetInt(); } auto tm = pfGetPos(*it); if (std::get<0>(tm)){ lc.pos = std::get<1>(tm); } page.location.push_back(lc); } } if (page.pageNo == 1){ if (!m_onlineCardTemplate->useQrCode){ // 条形码 auto itBar = itPage->FindMember("studentcode_bar"); if (itBar != itPage->MemberEnd() && itBar->value.IsObject()){ auto itObj = itBar->value.FindMember("object"); if (itObj != itBar->value.MemberEnd() && itObj->value.IsObject()){ auto t = pfGetPos(itObj->value); page.studentcode_bar = std::get<1>(t); } } // 填涂考号 auto itFill = itPage->FindMember("studentcode_fill"); if (itFill != itPage->MemberEnd() && itFill->value.IsObject()){ auto itObj = itFill->value.FindMember("object"); if (itObj != itFill->value.MemberEnd() && itObj->value.IsArray()){ for (auto itRow = itObj->value.Begin(); itRow != itObj->value.End(); ++itRow){ auto itGroup = itRow->FindMember("group"); if (itGroup != itRow->MemberEnd() && itGroup->value.IsArray()){ std::vector _vctOpt; for (auto itCol = itGroup->value.Begin(); itCol != itGroup->value.End(); ++itCol){ Opt opt; auto itOptName = itCol->FindMember("optName"); if (itOptName != itCol->MemberEnd() && itOptName->value.IsInt()) opt.optName = std::to_string(itOptName->value.GetInt()); auto t = pfGetPos(*itCol); if (std::get<0>(t)) opt.pos = std::get<1>(t); _vctOpt.push_back(opt); } page.studentcode_fill.push_back(_vctOpt); } } } } } // 缺考标记 auto itAbsent = itPage->FindMember("absent"); if (itAbsent != itPage->MemberEnd() && itAbsent->value.IsObject()){ auto t = pfGetPos(itAbsent->value); if (std::get<0>(t)){ page.absent = std::get<1>(t); } } // 二维码 auto itQrCode = itPage->FindMember("QrCode"); if (itQrCode != itPage->MemberEnd() && itQrCode->value.IsObject()){ auto t = pfGetPos(itQrCode->value); if (std::get<0>(t)){ page.QrCode = std::get<1>(t); } } } // end if page.pageNo == 0 // 长宽 auto itImge = itPage->FindMember("imge"); if (itImge != itPage->MemberEnd()){ auto t = std::get<1>(pfGetPos(itImge->value)); page.w = t.w; page.h = t.h; } else{ return false; } // 题目 auto itQuestion = itPage->FindMember("questions"); if (itQuestion != itPage->MemberEnd() && itQuestion->value.IsArray()) { for (auto it = itQuestion->value.Begin(); it != itQuestion->value.End(); ++it) { question q; // 题目类型 auto itType = it->FindMember("type"); string qType = "1"; if (itType != it->MemberEnd() && itType->value.IsString()) { qType = itType->value.GetString(); if (type_map.find(qType)!=type_map.end()) { q.type = type_map[qType]; } } else if (itType != it->MemberEnd() && itType->value.IsInt()) { qType = to_string(itType->value.GetInt()); if (type_map.find(qType) != type_map.end()) { q.type = type_map[qType]; } } else { return false; } q.marktype = 0; // 题目类型 auto itMarktype = it->FindMember("marktype"); if (itMarktype != it->MemberEnd() && itMarktype->value.IsInt()){ q.marktype = itMarktype->value.GetInt(); } if (qType=="10")//英文作文 { q.marktype = 10; q.type = 1; } else if (qType == "11")//语文作文 { q.marktype = 4; q.type = 1; } else if (qType == "12")//判断 { q.type = 0; } // 分数 auto itScore = it->FindMember("score"); if (itScore != it->MemberEnd() && itScore->value.IsObject()){ auto itFull = itScore->value.FindMember("full"); if (itFull != itScore->value.MemberEnd() && (itFull->value.IsDouble() || itFull->value.IsInt())) q.score = itFull->value.GetDouble(); else if (itFull != itScore->value.MemberEnd() && itFull->value.IsString()) q.score = atof(itFull->value.GetString()); } // 题目编号 2选做题 auto itId = it->FindMember((q.type == 2 || q.type == 4) ? "editorId" : "id"); if (itId != it->MemberEnd() && itId->value.IsString()){ q.id = itId->value.GetString(); } if (itId != it->MemberEnd() && itId->value.IsInt()){ q.id = std::to_string(itId->value.GetInt()); } if (q.type == 2 || q.type == 4){ auto itAllID = it->FindMember("id"); if (itAllID != it->MemberEnd() && itAllID->value.IsString()){ q.all_id = itAllID->value.GetString(); } } auto itSmallQtNo = it->FindMember("smallQtNo"); if (itSmallQtNo != it->MemberEnd() && !(itSmallQtNo->value.IsNull())) { q.smallQtNo = itSmallQtNo->value.GetInt(); } else { q.smallQtNo = -1; } auto itNickID = it->FindMember("name"); if (itNickID != it->MemberEnd() && !(itNickID->value.IsNull()) && itNickID->value.IsString()) { m_mapKeguantiNickName[q.id] = itNickID->value.GetString(); } // 打分区域 auto itScoreBox = it->FindMember("scorebox"); if (itScoreBox != it->MemberEnd() && itScoreBox->value.IsObject()){ // 打分框类型 auto itType = itScoreBox->value.FindMember("type"); if (itType != itScoreBox->value.MemberEnd() && itType->value.IsString()){ q.scoreBox.type = std::stoi(itType->value.GetString()); } else if (itType != itScoreBox->value.MemberEnd() && itType->value.IsInt()){ q.scoreBox.type = itType->value.GetInt(); } else{ return false; } if (q.smallQtNo != -1) { // 小问最大分值 auto itmaxScore = itScoreBox->value.FindMember("maxscore"); if (itmaxScore != itScoreBox->value.MemberEnd() && itmaxScore->value.IsString()){ q.scoreBox.maxsorce = std::stod(itmaxScore->value.GetString()); } else if (itmaxScore != itScoreBox->value.MemberEnd() && itmaxScore->value.IsDouble()){ q.scoreBox.maxsorce = itScoreBox->value.GetDouble(); } else if (itmaxScore != itScoreBox->value.MemberEnd() && itmaxScore->value.IsInt()){ q.scoreBox.maxsorce = itmaxScore->value.GetInt(); } else{ q.scoreBox.maxsorce = 0.0; } } else { q.scoreBox.maxsorce = 0.0; } // 分数上限 auto itLimit = itScoreBox->value.FindMember("limit"); if (itLimit != itScoreBox->value.MemberEnd() && itLimit->value.IsString()) q.scoreBox.limit = std::stoi(itLimit->value.GetString()); if (itLimit != itScoreBox->value.MemberEnd() && itLimit->value.IsInt()) q.scoreBox.limit = itLimit->value.GetInt(); // 最后一个格子是否为小数 1是 2否 auto itPoint = itScoreBox->value.FindMember("point"); if (itPoint != itScoreBox->value.MemberEnd()){ if (itPoint->value.IsInt()){ q.scoreBox.bPoint = (itPoint->value.GetInt() == 1); } else if (itPoint->value.IsString()){ std::string str = itPoint->value.GetString(); q.scoreBox.bPoint = (str == "1"); } } // 填空题带打分 if (q.scoreBox.type == 3){ auto itScore = itScoreBox->value.FindMember("Score"); if (itScore != itScoreBox->value.MemberEnd() && itScore->value.IsArray()){ for (auto it = itScore->value.Begin(); it != itScore->value.End(); ++it){ if (it->IsString()){ std::string str = it->GetString(); if (!str.empty()) q.scoreBox.vctScore.push_back(std::stoi(str)); } } } } // 打分位置 auto t = pfGetPos(itScoreBox->value); if (std::get<0>(t)) q.scoreBox.pos = std::get<1>(t); } // 几选几 if (q.type == 2 || q.type == 4){ // 选做题 rapidjson::Value::ConstMemberIterator itSel = it->FindMember("select"); if (itSel != it->MemberEnd() && itSel->value.IsInt()){ q.selItem = itSel->value.GetInt(); } rapidjson::Value::ConstMemberIterator itTotal = it->FindMember("total"); if (itTotal != it->MemberEnd() && itTotal->value.IsInt()){ q.selTotal = itTotal->value.GetInt(); } } // 剪裁区域 if (q.type == 1 || q.type == 3 || q.type == 2 || q.type == 4){ // 1 解答题 2 选做题 3 填空题 auto itCut = it->FindMember("cut"); if (itCut != it->MemberEnd() && itCut->value.IsObject()){ auto itLink = itCut->value.FindMember("linkparm"); if (itLink != itCut->value.MemberEnd() && itLink->value.IsInt()) q.cut.linkparm = itLink->value.GetInt(); if (itLink != itCut->value.MemberEnd() && itLink->value.IsString()) q.cut.linkparm = std::stoi(itLink->value.GetString()); auto t = pfGetPos(itCut->value); if (std::get<0>(t)) q.cut.pos = std::get<1>(t); if (q.type == 3 && m_onlineCardTemplate->subject_id == 8) { TCHAR FilePath[MAX_PATH]; GetModuleFileName(NULL, FilePath, MAX_PATH); (_tcsrchr(FilePath, '\\'))[1] = 0; lstrcat(FilePath, _T("config.ini")); int english = GetPrivateProfileInt(_T("USER"), _T("english_height"), 30, FilePath);//英语填空题高度加大比例 if (english > 0 && english <= 30) { q.cut.pos.h = q.cut.pos.h* (1.0 + english / 100.0); } } } if (q.type == 2){ if (temp_all_id != q.all_id) { temp_all_id = q.all_id; n_duo_xuanti_index = 0; } if (q.cut.linkparm < 2){ std::vector split_qr; split(q.all_id, (std::string)",", &split_qr); if (n_duo_xuanti_index < split_qr.size()) q.id = split_qr[n_duo_xuanti_index++]; } else { std::vector split_qr; split(q.all_id, (std::string)",", &split_qr); if (n_duo_xuanti_index - 1 >= 0 && n_duo_xuanti_index - 1 < split_qr.size()) q.id = split_qr[n_duo_xuanti_index - 1]; } } else if (q.type == 4) { if (temp_all_id != q.all_id) { temp_all_id = q.all_id; n_duo_xuanti_index = 0; } if (q.cut.linkparm < 1){ std::vector split_qr; split(q.all_id, (std::string)",", &split_qr); if (n_duo_xuanti_index < split_qr.size()) q.id = split_qr[n_duo_xuanti_index++]; } else { std::vector split_qr; split(q.all_id, (std::string)",", &split_qr); if (n_duo_xuanti_index - 1 >= 0 && n_duo_xuanti_index - 1 < split_qr.size()) q.id = split_qr[n_duo_xuanti_index - 1]; } } } // 选项 单选题 多选题 if (q.type == 0 || q.type == 8 || q.type == 5){ auto itOpts = it->FindMember("opt"); if (itOpts != it->MemberEnd() && itOpts->value.IsArray()){ for (auto itOpt = itOpts->value.Begin(); itOpt != itOpts->value.End(); ++itOpt){ Opt opt; auto t = pfGetPos(*itOpt); if (std::get<0>(t)) opt.pos = std::get<1>(t); auto itOptName = itOpt->FindMember("optName"); if (itOptName != itOpt->MemberEnd() && itOptName->value.IsString()) opt.optName = itOptName->value.GetString(); q.opt.push_back(opt); } } } else if (q.type == 2 || q.type == 4){ // 选作 auto itSelectqts = it->FindMember("selectqts"); if (itSelectqts != it->MemberEnd() && itSelectqts->value.IsArray() && itSelectqts->value.Size() > 0){ for (auto itOpt = itSelectqts->value.Begin(); itOpt != itSelectqts->value.End(); ++itOpt){ Opt opt; auto t = pfGetPos(*itOpt); if (std::get<0>(t)) opt.pos = std::get<1>(t); auto itOptName = itOpt->FindMember("optName"); if (itOptName != itOpt->MemberEnd() && itOptName->value.IsString()) opt.optName = itOptName->value.GetString(); q.opt.push_back(opt); } } } page.vctQuestions.push_back(q); } } m_onlineCardTemplate->pages.insert(std::make_pair(page.pageNo, page)); } } else{ return false; } } m_onlineCardTemplate->open_save_debug_img = false; m_onlineCardTemplate->dingweidian_range_top = 300; //上定位点范围 m_onlineCardTemplate->dingweidian_rang_buttom = 300;// 下定位点范围 m_onlineCardTemplate->dingweidian_w_max_rate = 1.0; m_onlineCardTemplate->dingweidian_h_max_rate = 1.0; m_onlineCardTemplate->dingweidian_w_min_rate = 0.7; m_onlineCardTemplate->dingweidian_h_min_rate = 0.7; CString _ini_file = GetExePath() + _T("\\config.ini"); TCHAR sz_offset_file_name[MAX_PATH] = { 0 }; GetPrivateProfileString(_T("USER"), _T("offset_file"), _T(""), sz_offset_file_name, sizeof(sz_offset_file_name) / sizeof(TCHAR), _ini_file); ParseTemplateOffset(UnicodeToAnsi(GetExePath() + _T("\\") + sz_offset_file_name), m_onlineCardTemplate); return true; } bool CBatchService::ParseTemplateFromJson(const std::string&fileName) { CUnZipFile uzip(CString(fileName.c_str())); std::map> map; while (uzip.HasMoreEntry()){ CString fileNam; uzip.GetNextEntry(fileNam); char buffer[1024 * 8]; int len; std::vector& data = map[fileNam]; data.reserve(1024 * 128); while ((len = uzip.Read(buffer, 1024 * 8)) > 0){ if (data.capacity() < data.size() + len){ int c = data.capacity() + 1024 * 128; data.reserve(c); } int oldSize = data.size(); data.resize(oldSize + len); char * dst = (char *)data.data() + oldSize; memcpy(dst, buffer, len); } } uzip.Close(); auto schemabytes = map.find(_T("json.txt")); if (schemabytes == map.end()){ return SCH_LOAD_ERR_MISSINGFORMAT; } std::vector& data = schemabytes->second; auto strJson = std::string((char *)data.data(), data.size()); if (!m_onlineCardTemplate) return false; m_onlineCardTemplate->pages.clear(); auto pfGetPos = [](const rapidjson::Value&value)->std::tuple{ bool bRet = false; double x = 0.0, y = 0.0, w = 0.0, h = 0.0; auto itX = value.FindMember("x"); if (itX != value.MemberEnd() && (itX->value.IsInt() || itX->value.IsDouble())){ x = itX->value.GetDouble(); } auto itY = value.FindMember("y"); if (itY != value.MemberEnd() && (itY->value.IsInt() || itY->value.IsDouble())){ y = itY->value.GetDouble(); } auto itW = value.FindMember("width"); if (itW != value.MemberEnd() && (itW->value.IsInt() || itW->value.IsDouble())){ w = itW->value.GetDouble(); } auto itH = value.FindMember("height"); if (itH != value.MemberEnd() && (itH->value.IsInt() || itH->value.IsDouble())){ h = itH->value.GetDouble(); bRet = true; } return std::tie(bRet, Pos{ x, y, w, h }); }; rapidjson::Document doc; doc.Parse(strJson.c_str()); if (doc.HasParseError()) return false; m_onlineCardTemplate->subject_id = m_nSubjectID; m_onlineCardTemplate->_version = "old"; auto isAllSubjectCard = doc.FindMember("isAllSubjectCard"); if (isAllSubjectCard != doc.MemberEnd() && isAllSubjectCard->value.IsInt()){ int nisAllSubjectCard = isAllSubjectCard->value.GetInt(); if (nisAllSubjectCard == 1) { return ParseTemplateFromJsonAll(fileName); } } // 检测版本号 auto it_version = doc.FindMember("online_card_version"); if (it_version!= doc.MemberEnd() && it_version->value.IsString()){ m_onlineCardTemplate->_version = it_version->value.GetString(); } LOGFMTI("在线答题卡版本号:%s",m_onlineCardTemplate->_version.c_str()); if (m_onlineCardTemplate->_version=="old"){ // 总页数 auto itTotalPage = doc.FindMember("totalPage"); if (itTotalPage != doc.MemberEnd() && itTotalPage->value.IsInt()){ m_onlineCardTemplate->totalPage = itTotalPage->value.GetInt(); } // 是否使用二维码 auto itUseQrCode = doc.FindMember("useQrCode"); if (itUseQrCode != doc.MemberEnd() && itUseQrCode->value.IsBool()){ m_onlineCardTemplate->useQrCode = itUseQrCode->value.GetBool(); } if (itUseQrCode != doc.MemberEnd() && itUseQrCode->value.IsInt()){ m_onlineCardTemplate->useQrCode = (itUseQrCode->value.GetInt() != 0); } // 学校状态 auto itSchoolStatus = doc.FindMember("school_card_status"); if (itSchoolStatus != doc.MemberEnd() && itSchoolStatus->value.IsInt()){ m_onlineCardTemplate->schoolCardStatus = itSchoolStatus->value.GetInt(); } int n_duo_xuanti_index = 0; // 页 auto itPages = doc.FindMember("pages"); if (itPages != doc.MemberEnd() && itPages->value.IsArray() && itPages->value.Size() == m_onlineCardTemplate->totalPage){ for (auto itPage = itPages->value.Begin(); itPage != itPages->value.End(); ++itPage){ if (!itPage->IsObject()) return false; PageTemplate page; // 页号 auto itPageNo = itPage->FindMember("pageNo"); if (itPageNo != itPage->MemberEnd() && itPageNo->value.IsInt()){ page.pageNo = itPageNo->value.GetInt(); } else { return false; } // 定位点 auto itLocations = itPage->FindMember("location"); if (itLocations != itPage->MemberEnd() && itLocations->value.IsArray()){ for (auto it = itLocations->value.Begin(); it != itLocations->value.End(); ++it){ Location lc; auto itType = it->FindMember("type"); if (itType != it->MemberEnd() && itType->value.IsInt()){ lc.type = itType->value.GetInt(); } auto tm = pfGetPos(*it); if (std::get<0>(tm)){ lc.pos = std::get<1>(tm); } page.location.push_back(lc); } } if (page.pageNo == 1){ if (!m_onlineCardTemplate->useQrCode){ // 条形码 auto itBar = itPage->FindMember("studentcode_bar"); if (itBar != itPage->MemberEnd() && itBar->value.IsObject()){ auto itObj = itBar->value.FindMember("object"); if (itObj != itBar->value.MemberEnd() && itObj->value.IsObject()){ auto t = pfGetPos(itObj->value); page.studentcode_bar = std::get<1>(t); } } // 填涂考号 auto itFill = itPage->FindMember("studentcode_fill"); if (itFill != itPage->MemberEnd() && itFill->value.IsObject()){ auto itObj = itFill->value.FindMember("object"); if (itObj != itFill->value.MemberEnd() && itObj->value.IsArray()){ for (auto itRow = itObj->value.Begin(); itRow != itObj->value.End(); ++itRow){ auto itGroup = itRow->FindMember("group"); if (itGroup != itRow->MemberEnd() && itGroup->value.IsArray()){ std::vector _vctOpt; for (auto itCol = itGroup->value.Begin(); itCol != itGroup->value.End(); ++itCol){ Opt opt; auto itOptName = itCol->FindMember("optName"); if (itOptName != itCol->MemberEnd() && itOptName->value.IsInt()) opt.optName = std::to_string(itOptName->value.GetInt()); auto t = pfGetPos(*itCol); if (std::get<0>(t)) opt.pos = std::get<1>(t); _vctOpt.push_back(opt); } page.studentcode_fill.push_back(_vctOpt); } } } } } // 缺考标记 auto itAbsent = itPage->FindMember("absent"); if (itAbsent != itPage->MemberEnd() && itAbsent->value.IsObject()){ auto t = pfGetPos(itAbsent->value); if (std::get<0>(t)){ page.absent = std::get<1>(t); } } // 二维码 auto itQrCode = itPage->FindMember("QrCode"); if (itQrCode != itPage->MemberEnd() && itQrCode->value.IsObject()){ auto t = pfGetPos(itQrCode->value); if (std::get<0>(t)){ page.QrCode = std::get<1>(t); } } } // end if page.pageNo == 0 // 长宽 auto itImge = itPage->FindMember("imge"); if (itImge != itPage->MemberEnd()){ auto t = std::get<1>(pfGetPos(itImge->value)); page.w = t.w; page.h = t.h; } else{ return false; } // 题目 auto itQuestion = itPage->FindMember("questions"); if (itQuestion != itPage->MemberEnd() && itQuestion->value.IsArray()){ for (auto it = itQuestion->value.Begin(); it != itQuestion->value.End(); ++it){ question q; // 题目类型 auto itType = it->FindMember("type"); if (itType != it->MemberEnd() && itType->value.IsInt()){ q.type = itType->value.GetInt(); } else{ return false; } q.marktype = 0; // 题目类型 auto itMarktype = it->FindMember("marktype"); if (itMarktype != it->MemberEnd() && itMarktype->value.IsInt()){ q.marktype = itMarktype->value.GetInt(); } // 分数 auto itScore = it->FindMember("score"); if (itScore != it->MemberEnd() && itScore->value.IsObject()){ auto itFull = itScore->value.FindMember("full"); if (itFull != itScore->value.MemberEnd() && (itFull->value.IsDouble() || itFull->value.IsInt())) q.score = itFull->value.GetDouble(); else if (itFull != itScore->value.MemberEnd() && itFull->value.IsString() ) q.score = atof(itFull->value.GetString()); } // 题目编号 2选做题 auto itId = it->FindMember(q.type == 2 ? "editorId" : "id"); if (itId != it->MemberEnd() && itId->value.IsString()){ q.id = itId->value.GetString(); } if (q.type == 2){ auto itAllID = it->FindMember("id"); if (itAllID != it->MemberEnd() && itAllID->value.IsString()){ q.all_id = itAllID->value.GetString(); } } // 目前应该只有填空题有这个参数 auto itSmallQtNo = it->FindMember("smallQtNo"); if (itSmallQtNo != it->MemberEnd() && !(itSmallQtNo->value.IsNull())) { q.smallQtNo = itSmallQtNo->value.GetInt(); } else { q.smallQtNo = -1; } // 打分区域 auto itScoreBox = it->FindMember("scorebox"); if (itScoreBox != it->MemberEnd() && itScoreBox->value.IsObject()){ // 打分框类型 auto itType = itScoreBox->value.FindMember("type"); if (itType != itScoreBox->value.MemberEnd() && itType->value.IsString()){ q.scoreBox.type = std::stoi(itType->value.GetString()); } else if (itType != itScoreBox->value.MemberEnd() && itType->value.IsInt()){ q.scoreBox.type = itType->value.GetInt(); } else{ return false; } // 分数上限 auto itLimit = itScoreBox->value.FindMember("limit"); if (itLimit != itScoreBox->value.MemberEnd() && itLimit->value.IsString()) q.scoreBox.limit = std::stoi(itLimit->value.GetString()); // 最后一个格子是否为小数 1是 2否 auto itPoint = itScoreBox->value.FindMember("point"); if (itPoint != itScoreBox->value.MemberEnd()){ if (itPoint->value.IsInt()){ if (itPoint->value.GetInt() == 1 || itPoint->value.GetInt() == 2) q.scoreBox.bPoint = (itPoint->value.GetInt() == 1); } else if (itPoint->value.IsString()){ std::string str = itPoint->value.GetString(); if (str == "1" || str == "2") q.scoreBox.bPoint = (str == "1"); } } // 填空题带打分 if (q.scoreBox.type == 3){ auto itScore = itScoreBox->value.FindMember("Score"); if (itScore != itScoreBox->value.MemberEnd() && itScore->value.IsArray()){ for (auto it = itScore->value.Begin(); it != itScore->value.End(); ++it){ if (it->IsString()){ std::string str = it->GetString(); if (!str.empty()) q.scoreBox.vctScore.push_back(std::stoi(str)); } } } } // 打分位置 auto t = pfGetPos(itScoreBox->value); if (std::get<0>(t)) q.scoreBox.pos = std::get<1>(t); } // 剪裁区域 if (q.type == 1 || q.type == 3){ auto itCut = it->FindMember("cut"); if (itCut != it->MemberEnd() && itCut->value.IsObject()){ auto itLink = itCut->value.FindMember("linkparm"); if (itLink != itCut->value.MemberEnd() && itLink->value.IsInt()) q.cut.linkparm = itLink->value.GetInt(); auto t = pfGetPos(itCut->value); if (std::get<0>(t)) q.cut.pos = std::get<1>(t); if (q.type == 3 && m_onlineCardTemplate->subject_id == 8) { TCHAR FilePath[MAX_PATH]; GetModuleFileName(NULL, FilePath, MAX_PATH); (_tcsrchr(FilePath, '\\'))[1] = 0; lstrcat(FilePath, _T("config.ini")); int english = GetPrivateProfileInt(_T("USER"), _T("english_height"), 30, FilePath);//英语填空题高度加大比例 if (english > 0 && english <= 30) { q.cut.pos.h = q.cut.pos.h* (1.0 + english / 100.0); } } } } else if (q.type == 2){ // 选做题 rapidjson::Value::ConstMemberIterator itSel = it->FindMember("select"); if (itSel != it->MemberEnd() && itSel->value.IsInt()){ q.selItem = itSel->value.GetInt(); } rapidjson::Value::ConstMemberIterator itTotal = it->FindMember("total"); if (itTotal != it->MemberEnd() && itTotal->value.IsInt()){ q.selTotal = itTotal->value.GetInt(); } auto itSelectqts = it->FindMember("selectqts"); if (itSelectqts != it->MemberEnd() && itSelectqts->value.IsArray() && itSelectqts->value.Size() > 0){ rapidjson::Value::ConstMemberIterator itCut = itSelectqts->value.Begin()->FindMember("cut"); if (itCut != itSelectqts->value.Begin()->MemberEnd() && itCut->value.IsObject()){ rapidjson::Value::ConstMemberIterator itLink = itCut->value.FindMember("linkparm"); if (itLink != itCut->value.MemberEnd() && itLink->value.IsInt()) q.cut.linkparm = itLink->value.GetInt(); auto t = pfGetPos(itCut->value); if (std::get<0>(t)) q.cut.pos = std::get<1>(t); } } if (q.cut.linkparm < 2){ std::vector split_qr; split(q.all_id, (std::string)",", &split_qr); if (n_duo_xuanti_index < split_qr.size()) q.id = split_qr[n_duo_xuanti_index++]; } else { std::vector split_qr; split(q.all_id, (std::string)",", &split_qr); if (n_duo_xuanti_index - 1 >= 0 && n_duo_xuanti_index - 1 < split_qr.size()) q.id = split_qr[n_duo_xuanti_index - 1]; } } // 选项 单选题 多选题 if (q.type == 0 || q.type == 8 || q.type == 5){ auto itOpts = it->FindMember("opt"); if (itOpts != it->MemberEnd() && itOpts->value.IsArray()){ int i = 0; for (auto itOpt = itOpts->value.Begin(); itOpt != itOpts->value.End(); ++itOpt,++i){ Opt opt; auto t = pfGetPos(*itOpt); if (std::get<0>(t)) opt.pos = std::get<1>(t); auto itOptName = itOpt->FindMember("optName"); if (itOptName != itOpt->MemberEnd() && itOptName->value.IsString()) opt.optName = itOptName->value.GetString(); q.opt.push_back(opt); } } } else if (q.type == 2){ // 多选题 auto itSelectqts = it->FindMember("selectqts"); if (itSelectqts != it->MemberEnd() && itSelectqts->value.IsArray() && itSelectqts->value.Size() > 0){ auto itOpts = itSelectqts->value.Begin()->FindMember("opt"); if (itOpts != itSelectqts->value.Begin()->MemberEnd() && itOpts->value.IsArray()){ q.selTotal = itOpts->value.Size(); for (auto itOpt = itOpts->value.Begin(); itOpt != itOpts->value.End(); ++itOpt){ Opt opt; auto t = pfGetPos(*itOpt); if (std::get<0>(t)) opt.pos = std::get<1>(t); auto itOptName = itOpt->FindMember("optName"); if (itOptName != itOpt->MemberEnd() && itOptName->value.IsString()) opt.optName = itOptName->value.GetString(); q.opt.push_back(opt); } } } } page.vctQuestions.push_back(q); } } m_onlineCardTemplate->pages.insert(std::make_pair(page.pageNo, page)); } } else{ return false; } } else{ // 总页数 auto itTotalPage = doc.FindMember("totalPage"); if (itTotalPage != doc.MemberEnd() && itTotalPage->value.IsInt()){ m_onlineCardTemplate->totalPage = itTotalPage->value.GetInt(); } // 是否使用二维码 auto itUseQrCode = doc.FindMember("useQrCode"); if (itUseQrCode != doc.MemberEnd() && itUseQrCode->value.IsBool()){ m_onlineCardTemplate->useQrCode = itUseQrCode->value.GetBool(); } if (itUseQrCode != doc.MemberEnd() && itUseQrCode->value.IsInt()){ m_onlineCardTemplate->useQrCode = (itUseQrCode->value.GetInt() != 0); } // 学校状态 auto itSchoolStatus = doc.FindMember("school_card_status"); if (itSchoolStatus != doc.MemberEnd() && itSchoolStatus->value.IsInt()){ m_onlineCardTemplate->schoolCardStatus = itSchoolStatus->value.GetInt(); } int n_duo_xuanti_index = 0; std::string temp_all_id = ""; // 页 auto itPages = doc.FindMember("pages"); if (itPages != doc.MemberEnd() && itPages->value.IsArray()/* && itPages->value.Size() == m_onlineCardTemplate->totalPage*/){ for (auto itPage = itPages->value.Begin(); itPage != itPages->value.End(); ++itPage){ if (!itPage->IsObject()) return false; PageTemplate page; // 页号 auto itPageNo = itPage->FindMember("pageNo"); if (itPageNo != itPage->MemberEnd() && itPageNo->value.IsInt()){ page.pageNo = itPageNo->value.GetInt(); } else { return false; } // 定位点 auto itLocations = itPage->FindMember("location"); if (itLocations != itPage->MemberEnd() && itLocations->value.IsArray()){ for (auto it = itLocations->value.Begin(); it != itLocations->value.End(); ++it){ Location lc; auto itType = it->FindMember("type"); if (itType != it->MemberEnd() && itType->value.IsInt()){ lc.type = itType->value.GetInt(); } auto tm = pfGetPos(*it); if (std::get<0>(tm)){ lc.pos = std::get<1>(tm); } page.location.push_back(lc); } } if (page.pageNo == 1){ if (!m_onlineCardTemplate->useQrCode){ // 条形码 auto itBar = itPage->FindMember("studentcode_bar"); if (itBar != itPage->MemberEnd() && itBar->value.IsObject()){ auto itObj = itBar->value.FindMember("object"); if (itObj != itBar->value.MemberEnd() && itObj->value.IsObject()){ auto t = pfGetPos(itObj->value); page.studentcode_bar = std::get<1>(t); } } // 填涂考号 auto itFill = itPage->FindMember("studentcode_fill"); if (itFill != itPage->MemberEnd() && itFill->value.IsObject()){ auto itObj = itFill->value.FindMember("object"); if (itObj != itFill->value.MemberEnd() && itObj->value.IsArray()){ for (auto itRow = itObj->value.Begin(); itRow != itObj->value.End(); ++itRow){ auto itGroup = itRow->FindMember("group"); if (itGroup != itRow->MemberEnd() && itGroup->value.IsArray()){ std::vector _vctOpt; for (auto itCol = itGroup->value.Begin(); itCol != itGroup->value.End(); ++itCol){ Opt opt; auto itOptName = itCol->FindMember("optName"); if (itOptName != itCol->MemberEnd() && itOptName->value.IsInt()) opt.optName = std::to_string(itOptName->value.GetInt()); auto t = pfGetPos(*itCol); if (std::get<0>(t)) opt.pos = std::get<1>(t); _vctOpt.push_back(opt); } page.studentcode_fill.push_back(_vctOpt); } } } } } // 缺考标记 auto itAbsent = itPage->FindMember("absent"); if (itAbsent != itPage->MemberEnd() && itAbsent->value.IsObject()){ auto t = pfGetPos(itAbsent->value); if (std::get<0>(t)){ page.absent = std::get<1>(t); } } // 二维码 auto itQrCode = itPage->FindMember("QrCode"); if (itQrCode != itPage->MemberEnd() && itQrCode->value.IsObject()){ auto t = pfGetPos(itQrCode->value); if (std::get<0>(t)){ page.QrCode = std::get<1>(t); } } } // end if page.pageNo == 0 // 长宽 auto itImge = itPage->FindMember("imge"); if (itImge != itPage->MemberEnd()){ auto t = std::get<1>(pfGetPos(itImge->value)); page.w = t.w; page.h = t.h; } else{ return false; } // 题目 auto itQuestion = itPage->FindMember("questions"); if (itQuestion != itPage->MemberEnd() && itQuestion->value.IsArray()){ for (auto it = itQuestion->value.Begin(); it != itQuestion->value.End(); ++it){ question q; // 题目类型 auto itType = it->FindMember("type"); if (itType != it->MemberEnd() && itType->value.IsInt()){ q.type = itType->value.GetInt(); } else{ return false; } q.marktype = 0; // 题目类型 auto itMarktype = it->FindMember("marktype"); if (itMarktype != it->MemberEnd() && itMarktype->value.IsInt()){ q.marktype = itMarktype->value.GetInt(); } // 分数 auto itScore = it->FindMember("score"); if (itScore != it->MemberEnd() && itScore->value.IsObject()){ auto itFull = itScore->value.FindMember("full"); if (itFull != itScore->value.MemberEnd() && (itFull->value.IsDouble() || itFull->value.IsInt())) q.score = itFull->value.GetDouble(); else if (itFull != itScore->value.MemberEnd() && itFull->value.IsString()) q.score = atof(itFull->value.GetString()); } // 题目编号 2选做题 4题组 auto itId = it->FindMember((q.type == 2 || q.type == 4 )? "editorId" : "id"); if (itId != it->MemberEnd() && itId->value.IsString()){ q.id = itId->value.GetString(); } if (itId != it->MemberEnd() && itId->value.IsInt()){ q.id = std::to_string(itId->value.GetInt()); } if (q.type == 2 || q.type == 4){ auto itAllID = it->FindMember("id"); if (itAllID != it->MemberEnd() && itAllID->value.IsString()){ q.all_id = itAllID->value.GetString(); } } auto itSmallQtNo = it->FindMember("smallQtNo"); if (itSmallQtNo != it->MemberEnd() && !(itSmallQtNo->value.IsNull())) { q.smallQtNo = itSmallQtNo->value.GetInt(); } else { q.smallQtNo = -1; } auto itNickID = it->FindMember("name"); if (itNickID != it->MemberEnd() && !(itNickID->value.IsNull()) && itNickID->value.IsInt()) { m_mapKeguantiNickName[q.id] = std::to_string(itNickID->value.GetInt()); } // 打分区域 auto itScoreBox = it->FindMember("scorebox"); if (itScoreBox != it->MemberEnd() && itScoreBox->value.IsObject()){ // 打分框类型 auto itType = itScoreBox->value.FindMember("type"); if (itType != itScoreBox->value.MemberEnd() && itType->value.IsString()){ q.scoreBox.type = std::stoi(itType->value.GetString()); } else if (itType != itScoreBox->value.MemberEnd() && itType->value.IsInt()){ q.scoreBox.type = itType->value.GetInt(); } else{ return false; } if (q.smallQtNo != -1) { // 小问最大分值 auto itmaxScore = itScoreBox->value.FindMember("maxscore"); if (itmaxScore != itScoreBox->value.MemberEnd() && itmaxScore->value.IsString()){ q.scoreBox.maxsorce = std::stod(itmaxScore->value.GetString()); } else if (itmaxScore != itScoreBox->value.MemberEnd() && itmaxScore->value.IsDouble()){ q.scoreBox.maxsorce = itScoreBox->value.GetDouble(); } else if (itmaxScore != itScoreBox->value.MemberEnd() && itmaxScore->value.IsInt()){ q.scoreBox.maxsorce = itmaxScore->value.GetInt(); } else{ q.scoreBox.maxsorce = 0.0; } } else { q.scoreBox.maxsorce = 0.0; } // 分数上限 auto itLimit = itScoreBox->value.FindMember("limit"); if (itLimit != itScoreBox->value.MemberEnd() && itLimit->value.IsString()) q.scoreBox.limit = std::stoi(itLimit->value.GetString()); if (itLimit != itScoreBox->value.MemberEnd() && itLimit->value.IsInt()) q.scoreBox.limit = itLimit->value.GetInt(); // 最后一个格子是否为小数 1是 2否 auto itPoint = itScoreBox->value.FindMember("point"); if (itPoint != itScoreBox->value.MemberEnd()){ if (itPoint->value.IsInt()){ q.scoreBox.bPoint = (itPoint->value.GetInt() == 1); } else if (itPoint->value.IsString()){ std::string str = itPoint->value.GetString(); q.scoreBox.bPoint = (str == "1"); } } // 填空题带打分 if (q.scoreBox.type == 3){ auto itScore = itScoreBox->value.FindMember("Score"); if (itScore != itScoreBox->value.MemberEnd() && itScore->value.IsArray()){ for (auto it = itScore->value.Begin(); it != itScore->value.End(); ++it){ if (it->IsString()){ std::string str = it->GetString(); if (!str.empty()) q.scoreBox.vctScore.push_back(std::stoi(str)); } } } } // 打分位置 auto t = pfGetPos(itScoreBox->value); if (std::get<0>(t)) q.scoreBox.pos = std::get<1>(t); } // 几选几 if (q.type == 2 || q.type == 4){ // 选做题 rapidjson::Value::ConstMemberIterator itSel = it->FindMember("select"); if (itSel != it->MemberEnd() && itSel->value.IsInt()){ q.selItem = itSel->value.GetInt(); } rapidjson::Value::ConstMemberIterator itTotal = it->FindMember("total"); if (itTotal != it->MemberEnd() && itTotal->value.IsInt()){ q.selTotal = itTotal->value.GetInt(); } } // 剪裁区域 if (q.type == 1 || q.type == 3 || q.type == 2 || q.type == 4){ // 1 解答题 2 选做题 3 填空题 auto itCut = it->FindMember("cut"); if (itCut != it->MemberEnd() && itCut->value.IsObject()){ auto itLink = itCut->value.FindMember("linkparm"); if (itLink != itCut->value.MemberEnd() && itLink->value.IsInt()) q.cut.linkparm = itLink->value.GetInt(); if (itLink != itCut->value.MemberEnd() && itLink->value.IsString()) q.cut.linkparm = std::stoi(itLink->value.GetString()); auto t = pfGetPos(itCut->value); if (std::get<0>(t)) q.cut.pos = std::get<1>(t); if (q.type == 3 && m_onlineCardTemplate->subject_id==8) { TCHAR FilePath[MAX_PATH]; GetModuleFileName(NULL, FilePath, MAX_PATH); (_tcsrchr(FilePath, '\\'))[1] = 0; lstrcat(FilePath, _T("config.ini")); int english = GetPrivateProfileInt(_T("USER"), _T("english_height"), 30, FilePath);//英语填空题高度加大比例 if (english > 0 && english <= 30) { q.cut.pos.h = q.cut.pos.h* (1.0 + english / 100.0); } } } if (q.type == 2){ if (temp_all_id != q.all_id) { temp_all_id = q.all_id; n_duo_xuanti_index = 0; } if (q.cut.linkparm < 2){ std::vector split_qr; split(q.all_id, (std::string)",", &split_qr); if (n_duo_xuanti_index < split_qr.size()) q.id = split_qr[n_duo_xuanti_index++]; } else { std::vector split_qr; split(q.all_id, (std::string)",", &split_qr); if (n_duo_xuanti_index - 1 >= 0 && n_duo_xuanti_index - 1 < split_qr.size()) q.id = split_qr[n_duo_xuanti_index - 1]; } } else if (q.type == 4) { if (temp_all_id != q.all_id) { temp_all_id = q.all_id; n_duo_xuanti_index = 0; } if (q.cut.linkparm < 1){ std::vector split_qr; split(q.all_id, (std::string)",", &split_qr); if (n_duo_xuanti_index < split_qr.size()) q.id = split_qr[n_duo_xuanti_index++]; } else { std::vector split_qr; split(q.all_id, (std::string)",", &split_qr); if (n_duo_xuanti_index - 1 >= 0 && n_duo_xuanti_index - 1 < split_qr.size()) q.id = split_qr[n_duo_xuanti_index - 1]; } } } // 选项 单选题 多选题 if (q.type == 0 || q.type == 8 || q.type == 5){ auto itOpts = it->FindMember("opt"); if (itOpts != it->MemberEnd() && itOpts->value.IsArray()){ for (auto itOpt = itOpts->value.Begin(); itOpt != itOpts->value.End(); ++itOpt){ Opt opt; auto t = pfGetPos(*itOpt); if (std::get<0>(t)) opt.pos = std::get<1>(t); auto itOptName = itOpt->FindMember("optName"); if (itOptName != itOpt->MemberEnd() && itOptName->value.IsString()) opt.optName = itOptName->value.GetString(); q.opt.push_back(opt); } } } else if (q.type == 2 || q.type == 4){ // 多选题 auto itSelectqts = it->FindMember("selectqts"); if (itSelectqts != it->MemberEnd() && itSelectqts->value.IsArray() && itSelectqts->value.Size() > 0){ for (auto itOpt = itSelectqts->value.Begin(); itOpt != itSelectqts->value.End(); ++itOpt){ Opt opt; auto t = pfGetPos(*itOpt); if (std::get<0>(t)) opt.pos = std::get<1>(t); auto itOptName = itOpt->FindMember("optName"); if (itOptName != itOpt->MemberEnd() && itOptName->value.IsString()) opt.optName = itOptName->value.GetString(); q.opt.push_back(opt); } } } page.vctQuestions.push_back(q); } } m_onlineCardTemplate->pages.insert(std::make_pair(page.pageNo, page)); } } else{ return false; } } m_onlineCardTemplate->open_save_debug_img = false; m_onlineCardTemplate->dingweidian_range_top = 300; //上定位点范围 m_onlineCardTemplate->dingweidian_rang_buttom = 300;// 下定位点范围 m_onlineCardTemplate->dingweidian_w_max_rate = 1.0; m_onlineCardTemplate->dingweidian_h_max_rate = 1.0; m_onlineCardTemplate->dingweidian_w_min_rate = 0.7; m_onlineCardTemplate->dingweidian_h_min_rate = 0.7; CString _ini_file = GetExePath() + _T("\\config.ini"); TCHAR sz_offset_file_name[MAX_PATH] = { 0 }; GetPrivateProfileString(_T("USER"), _T("offset_file"), _T(""), sz_offset_file_name, sizeof(sz_offset_file_name) / sizeof(TCHAR), _ini_file); ParseTemplateOffset(UnicodeToAnsi(GetExePath() + _T("\\") + sz_offset_file_name), m_onlineCardTemplate); return true; } int CBatchService::loadDuXueFirstMode() { TCHAR FilePath[MAX_PATH]; GetModuleFileName(NULL, FilePath, MAX_PATH); (_tcsrchr(FilePath, '\\'))[1] = 0; TCHAR FileName[50]; _stprintf(FileName, _T("\\mode\\student1.schema")); lstrcat(FilePath, FileName); CT2CA pszConvertedAnsiString(FilePath); std::string schemaPath(pszConvertedAnsiString); CSchemaLoader schemaLoader; int ret = schemaLoader.Load(schemaPath, m_muban_img_dir, m_schema0, m_schema, m_handleInfo); return ret; } //停止扫描处理函数 ServiceState CBatchService::OnStoping(void) { mainService->Stop(); while (mainService->GetServiceSate()!=stoped) { Sleep(10); } if (g_my_scan_type == 1&&g_myindex < MAX_STRUENTS_NUM) { TCHAR FilePath[MAX_PATH]; GetModuleFileName(NULL, FilePath, MAX_PATH); (_tcsrchr(FilePath, '\\'))[1] = 0; TCHAR FileName[50]; _stprintf(FileName, _T("\\mode\\student%d.schema"), g_myindex+1); lstrcat(FilePath, FileName); CT2CA pszConvertedAnsiString(FilePath); std::string schemaPath(pszConvertedAnsiString); CSchemaLoader schemaLoader; int ret = schemaLoader.Load(schemaPath, m_muban_img_dir, m_schema0, m_schema, m_handleInfo); g_myindex++; ServiceState nextState = OnStarting(); return nextState; } char sql[128]; sprintf_s(sql, "update database set database_state =%d where database_id =%d", DATABASE_STATE_SCAN_OVER, m_database_id); EnterCriticalSection(database_db_lock); database_db->execDML("begin transaction"); database_db->execDML(sql); database_db->execDML("commit transaction"); LeaveCriticalSection(database_db_lock); if (m_hwnd != NULL&&m_abnormal_stop == FALSE) { ::PostMessage(m_hwnd, WM_IDENTIFOR_COMPLETE, 0, 0); } ServiceState nextState = IService::OnStoping(); if (nextState == stoped&&m_hwnd != NULL) { ::PostMessage(m_hwnd, WM_IDENTIFOR_STOPED, 0, 0); } return nextState; } #include #include #include //设置消息接收窗口 int CBatchService::SetHandlerWnd(HWND hwnd) { m_hwnd = hwnd; if (mainService.get()){ mainService->SetHandlerWnd(hwnd); } return TRUE; } //检测服务是是否可以访问 bool testServerAvaiable2(const CString& serverAdd){ std::string response; CHttpClient httpClient; CString url; url.Format(_T("%s/course/findAllCourse"), serverAdd); httpClient.HttpGet(url, NULL, response); Json::Value root; Json::Reader(Json::Features()).parse(response, root); if (root["success"].isInt() && root["success"].asInt() == 1){ return true; } return false; } /* 准备扫描 1、检测本地服务器状态 2、创建当前批次目录 3、创建当前批次数据库 4、创建主要服务 */ int CBatchService::ReadyScan(FEEDER_TYPE feederType, const ScanParam & param) { m_examId = param.examId; m_examCourseId = param.examCourseId; m_examName = param.examName; m_courseName = param.courseName; // Log4cplusInitalizer::initalize(); std::string response; CHttpClient httpClient; CString url; url.Format(_T("%s/exam/getServerUrl?examId=%I64d"), CServerConfig::server_url, param.examId); // AfxMessageBox(url); #if 0 httpClient.HttpGet(url, NULL, response); AfxMessageBox(L"CBatchService::HttpGet after!"); Json::Value root; AfxMessageBox(L"CBatchService::ReadyScan"); Json::Reader(Json::Features()).parse(response, root); AfxMessageBox(L"CBatchService::Json::Reader"); if (root["success"].isInt() && root["success"].asInt() == 1){ CServerConfig::server_address_type = SAT_REMOTE; Json::Value object = root["object"]; //标记本地服务器是否是不可用状态 bool isLocalServerUnavailable = false; if (object["url"].isString() && object["url"].asCString() != (string)""){ CServerConfig::server_url_local_in = object["url"].asCString(); if (!testServerAvaiable2(CServerConfig::server_url_local_in)){ isLocalServerUnavailable = true; } CServerConfig::server_address_type = SAT_LOCAL_IN; } if (isLocalServerUnavailable&&object["outurl"].isString() && object["outurl"].asCString() != (string)""){ CServerConfig::server_url_local_out = object["outurl"].asCString(); if (testServerAvaiable2(CServerConfig::server_url_local_out)){ isLocalServerUnavailable = false; } else { isLocalServerUnavailable = true; } CServerConfig::server_address_type = SAT_LOCAL_OUT; } //本地服务器不可用,返回错误 if (isLocalServerUnavailable)return 2; } #endif m_feeder_type = feederType; CString moule_dir =CServerConfig::scan_data_dir; m_bantch_code = GetTimeString(); CString tempExamId; tempExamId.Format(_T("%llu"), param.examId); if (g_my_scan_type == 1) { m_bantch_dir = moule_dir + _T("\\duxueka") + tempExamId; } else { m_bantch_dir = moule_dir + _T("\\datika") + tempExamId; } m_norimg_dir = m_bantch_dir + _T("\\nor_imgs"); m_excimg_dir = m_bantch_dir + _T("\\") + m_bantch_code + _T("\\exc_imgs"); m_img_down_load_dir = m_bantch_dir + _T("\\img_down_load"); m_muban_img_dir = CT2A(m_bantch_dir + _T("\\muban_imgs")); m_img_clips_dir = m_bantch_dir + _T("\\clips"); m_img_alynasis_dir = m_bantch_dir + _T("\\alynasis"); m_img_alynasis_result_dir = m_bantch_dir + _T("\\alynasis_result"); CreateDirectory(m_bantch_dir, NULL); CreateDirectory(m_norimg_dir, NULL); CreateDirectory(m_bantch_dir + _T("\\") + m_bantch_code, NULL); CreateDirectory(m_excimg_dir, NULL); CreateDirectory(m_img_clips_dir, NULL); CreateDirectory(CA2T(m_muban_img_dir.c_str()), NULL); CreateDirectory(m_img_down_load_dir, NULL); CreateDirectory(m_img_alynasis_dir, NULL); CreateDirectory(m_img_alynasis_result_dir, NULL); CString path = m_bantch_dir + _T("\\result.db3"); CString uploadPath = m_excimg_dir + _T("\\upload.db3"); char db_file_name[520]; char db_file_name1[520]; char db_upload_file_name[520]; char db_upload_file_name1[520]; WideCharToMultiByte(CP_UTF8, 0, path, -1, db_file_name, 520, NULL, NULL); WideCharToMultiByte(CP_ACP, 0, path, -1, db_file_name1, 520, NULL, NULL); WideCharToMultiByte(CP_UTF8, 0, uploadPath, -1, db_upload_file_name, 520, NULL, NULL); WideCharToMultiByte(CP_ACP, 0, uploadPath, -1, db_upload_file_name1, 520, NULL, NULL); g_strUpLoadDbPathName = db_upload_file_name; if (_access(db_file_name1, 0) == -1) { // 不存在首次拷贝 CTemplateManager::ExtractResourceToFile(_T("database"), IDR_DATABASE_RESULT, path); } if (_access(db_upload_file_name1, 0) == -1) { CTemplateManager::ExtractResourceToFile(_T("database"), IDR_DATABASE_UPLOAD, uploadPath); } EnterCriticalSection(database_db_lock); database_db->execDML("begin transaction"); char * sql = "INSERT INTO DATABASE ( database_state, create_time, db_file_name, bantch_code, bantch_dir, exam_id, exam_name, exam_course_id, course_name, total_upload_count, scan_type, exam_course_id_from, batch_code_from, examinne_id_from, server_address ) VALUES ( :database_state, :create_time, :db_file_name, :bantch_code ,:bantch_dir ,:exam_id ,:exam_name ,:exam_course_id ,:course_name ,:total_upload_count, :scan_type, :exam_course_id_from, :batch_code_from, :examinne_id_from, :server_address )"; CppSQLite3Statement stmt = database_db->compileStatement(sql); CT2A szbantch_code(m_bantch_code); CT2A szbantch_dir(m_bantch_dir); CT2A server_address(CServerConfig::server_address_type == SAT_LOCAL_IN ? CServerConfig::server_url_local_in : CServerConfig::server_address_type == SAT_LOCAL_OUT ? CServerConfig::server_url_local_out : CServerConfig::server_url); stmt.bind(":database_state", DATABASE_STATE_CREATE); stmt.bind(":create_time", szbantch_code); stmt.bind(":db_file_name", db_file_name); stmt.bind(":bantch_code", szbantch_code); stmt.bind(":bantch_dir", szbantch_dir); stmt.bind(":server_address", server_address); switch (feederType&FEEDER_TYPE_MASK){ case Folder:stmt.bind(":scan_type", SCAN_TASK_TYPE_NORMAL); break; case Scanner:stmt.bind(":scan_type", SCAN_TASK_TYPE_NORMAL); break; case AdjustBatch: stmt.bind(":exam_id", param.examId); stmt.bind(":exam_course_id", param.examCourseId); stmt.bind(":scan_type", SCAN_TASK_TYPE_ADJUST_BATCH); stmt.bind(":exam_course_id_from", param.examCourseIdOld); stmt.bind(":batch_code_from", param.batch.c_str()); break; case AdjustExaminne: stmt.bind(":exam_id", param.examId); stmt.bind(":exam_course_id", param.examCourseId); stmt.bind(":scan_type", SCAN_TASK_TYPE_ADJUST_EXAMINNE); stmt.bind(":exam_course_id_from", param.examCourseIdOld); stmt.bind(":batch_code_from", param.batch.c_str()); stmt.bind(":examinne_id_from", param.examinneid.c_str()); break; } stmt.bind(":exam_name", param.examName.c_str()); stmt.bind(":course_name", param.courseName.c_str()); stmt.execDML(); CppSQLite3Query query = database_db->execQuery("select last_insert_rowId() from DATABASE"); m_database_id = query.getIntField(0); database_db->execDML("commit transaction"); LeaveCriticalSection(database_db_lock); strncpy(m_db_file_name, db_file_name, 520); bantch_db.open(db_file_name); bantch_db.execDML("pragma journal_mode = MEMORY"); if (g_my_continue_scan != 1) { //情况没有上传的 vector listpaper_id; char sql1[512]; sprintf_s(sql1, "select student_paper_id from student_paper where ret_upload = 0 OR paper_state !=0 OR Is_Covered=1"); EnterCriticalSection(&bantch_db_lock); CppSQLite3Query q = bantch_db.execQuery(sql1); std::string _param; while (!q.eof()){ int student_paper_id = q.getIntField("student_paper_id"); _param += std::to_string(student_paper_id) + ","; listpaper_id.push_back(q.getIntField("student_paper_id")); q.nextRow(); } if (!_param.empty()){ _param = std::string(_param, 0, _param.size() - 1); if (m_upload_manager.IsEanble()) m_upload_manager.UploadOnScanCmd(UPLOAD_ON_SCAN_CMD::CMD_DEL_UPLOAD_REPORT, _param.c_str()); std::string str1 = std::string("") + "delete from exception where student_paper_id in(" + _param + ")"; std::string str2 = std::string("") + "delete from result where page_id in (select pg.page_id from page pg where pg.student_paper_id in(" + _param + "))"; std::string str3 = std::string("") + "delete from page where student_paper_id in(" + _param + ")"; std::string str4 = std::string("") + "delete from student_paper where student_paper_id in(" + _param + ")"; bantch_db.execDML(str1.c_str()); bantch_db.execDML(str2.c_str()); bantch_db.execDML(str3.c_str()); bantch_db.execDML(str4.c_str()); bantch_db.execDML("delete from message"); } // while (!q.eof()){ // int student_paper_id = q.getIntField("student_paper_id"); // listpaper_id.push_back(q.getIntField("student_paper_id")); // q.nextRow(); // } // for (int i = 0; i < listpaper_id.size(); i++) // { // char sql1[512]; // char sql2[512]; // char sql3[512]; // char sql4[512]; // sprintf_s(sql1, "delete from exception where student_paper_id =%d ", listpaper_id[i]); // sprintf_s(sql2, "delete from result where page_id in (select pg.page_id from page pg where pg.student_paper_id =%d)", listpaper_id[i]); // sprintf_s(sql3, "delete from page where student_paper_id =%d", listpaper_id[i]); // sprintf_s(sql4, "delete from student_paper where student_paper_id =%d", listpaper_id[i]); // bantch_db.execDML(sql1); // bantch_db.execDML(sql2); // bantch_db.execDML(sql3); // bantch_db.execDML(sql4); // bantch_db.execDML("delete from message"); // m_upload_manager.UploadOnScanCmd(UPLOAD_ON_SCAN_CMD::CMD_DEL_UPLOAD_REPORT, std::to_string(listpaper_id[i]).c_str()); // } LeaveCriticalSection(&bantch_db_lock); } m_result_uploader->EnableOnLineCard(m_bOnlineCard, m_nSubjectID, m_nOnlineScanType); if (m_bOnlineCard){ mainService.reset(new OnLineCard::COnlineCardIdentifyService(this)); mainService->m_nOnlineScanType = m_nOnlineScanType; }else{ mainService.reset(new CIdentifyService(this)); } mainService->InitService(); mainService->SetBianShiBieBianShangChuan(m_upload_manager.IsEanble()); if (m_bOnlineCard){ static_cast(mainService.get())->SetQr(-1,false, std::to_string(m_examId)); static_cast(mainService.get())->SetTemplate(m_onlineCardTemplate); } mainService->SerErrorHandle(m_bErrorHandle); mainService->setMainService(true); mainService->SetDirs(m_bantch_dir, m_norimg_dir, m_excimg_dir, m_img_clips_dir, m_img_alynasis_dir, m_img_alynasis_result_dir, m_img_down_load_dir, m_muban_img_dir); mainService->SetDataBase(&bantch_db_lock, &bantch_db); mainService->ReadScan(feederType, param); m_scoreCounter.SetDataBase(&bantch_db_lock, &bantch_db); if (m_hwnd != NULL) ::PostMessage(m_hwnd, WM_IDENTIFOR_READY, 0, 0); return TRUE; } void DeleteDirectory(CString source); int CBatchService::PreErrorHandleRestoreSite(bool bcontinue, int scan_type, FEEDER_TYPE feederType, const ScanParam & param) { g_my_scan_type = scan_type; m_examId = param.examId; m_examCourseId = 0; m_examName = ""; m_courseName = ""; std::string response; CString moule_dir = CServerConfig::scan_data_dir; m_bantch_code = GetTimeString(); CString tempExamId; tempExamId.Format(_T("%llu"), m_examId); if (g_my_scan_type == 1) { m_bantch_dir = moule_dir + _T("\\duxueka_errorhandle") + m_bantch_code + tempExamId; } else { m_bantch_dir = moule_dir + _T("\\datika_errorhandle") + m_bantch_code + tempExamId; } m_norimg_dir = m_bantch_dir + _T("\\nor_imgs"); m_excimg_dir = m_bantch_dir + _T("\\") + m_bantch_code + _T("\\exc_imgs"); m_img_down_load_dir = m_bantch_dir + _T("\\img_down_load"); m_muban_img_dir = CT2A(m_bantch_dir + _T("\\muban_imgs")); m_img_clips_dir = m_bantch_dir + _T("\\clips"); m_img_alynasis_dir = m_bantch_dir + _T("\\alynasis"); m_img_alynasis_result_dir = m_bantch_dir + _T("\\alynasis_result"); //DeleteDirectory(m_bantch_dir); CreateDirectory(m_bantch_dir, NULL); CreateDirectory(m_norimg_dir, NULL); CreateDirectory(m_bantch_dir + _T("\\") + m_bantch_code, NULL); CreateDirectory(m_excimg_dir, NULL); CreateDirectory(m_img_clips_dir, NULL); CreateDirectory(CA2T(m_muban_img_dir.c_str()), NULL); CreateDirectory(m_img_down_load_dir, NULL); CreateDirectory(m_img_alynasis_dir, NULL); CreateDirectory(m_img_alynasis_result_dir, NULL); CString path = m_bantch_dir + _T("\\result.db3"); CString uploadPath = m_excimg_dir + _T("\\upload.db3"); char db_file_name[520]; char db_file_name1[520]; char db_upload_file_name[520]; char db_upload_file_name1[520]; WideCharToMultiByte(CP_UTF8, 0, path, -1, db_file_name, 520, NULL, NULL); WideCharToMultiByte(CP_ACP, 0, path, -1, db_file_name1, 520, NULL, NULL); WideCharToMultiByte(CP_UTF8, 0, uploadPath, -1, db_upload_file_name, 520, NULL, NULL); WideCharToMultiByte(CP_ACP, 0, uploadPath, -1, db_upload_file_name1, 520, NULL, NULL); g_strUpLoadDbPathName = db_upload_file_name; if (_access(db_file_name1, 0) == -1) { // 不存在首次拷贝 CTemplateManager::ExtractResourceToFile(_T("database"), IDR_DATABASE_RESULT, path); } if (_access(db_upload_file_name1, 0) == -1) { CTemplateManager::ExtractResourceToFile(_T("database"), IDR_DATABASE_UPLOAD, uploadPath); } EnterCriticalSection(database_db_lock); database_db->execDML("begin transaction"); char * sql = "INSERT INTO DATABASE ( database_state, create_time, db_file_name, bantch_code, bantch_dir, exam_id, exam_name, exam_course_id, course_name, total_upload_count, scan_type, exam_course_id_from, batch_code_from, examinne_id_from, server_address ) VALUES ( :database_state, :create_time, :db_file_name, :bantch_code ,:bantch_dir ,:exam_id ,:exam_name ,:exam_course_id ,:course_name ,:total_upload_count, :scan_type, :exam_course_id_from, :batch_code_from, :examinne_id_from, :server_address )"; CppSQLite3Statement stmt = database_db->compileStatement(sql); CT2A szbantch_code(m_bantch_code); CT2A szbantch_dir(m_bantch_dir); CT2A server_address(CServerConfig::server_address_type == SAT_LOCAL_IN ? CServerConfig::server_url_local_in : CServerConfig::server_address_type == SAT_LOCAL_OUT ? CServerConfig::server_url_local_out : CServerConfig::server_url); stmt.bind(":database_state", DATABASE_STATE_CREATE); stmt.bind(":create_time", szbantch_code); stmt.bind(":db_file_name", db_file_name); stmt.bind(":bantch_code", szbantch_code); stmt.bind(":bantch_dir", szbantch_dir); stmt.bind(":server_address", server_address); switch (feederType&FEEDER_TYPE_MASK){ case Folder:stmt.bind(":scan_type", SCAN_TASK_TYPE_NORMAL); break; case Scanner:stmt.bind(":scan_type", SCAN_TASK_TYPE_NORMAL); break; case AdjustBatch: stmt.bind(":exam_id", param.examId); stmt.bind(":exam_course_id", param.examCourseId); stmt.bind(":scan_type", SCAN_TASK_TYPE_ADJUST_BATCH); stmt.bind(":exam_course_id_from", param.examCourseIdOld); stmt.bind(":batch_code_from", param.batch.c_str()); break; case AdjustExaminne: stmt.bind(":exam_id", param.examId); stmt.bind(":exam_course_id", param.examCourseId); stmt.bind(":scan_type", SCAN_TASK_TYPE_ADJUST_EXAMINNE); stmt.bind(":exam_course_id_from", param.examCourseIdOld); stmt.bind(":batch_code_from", param.batch.c_str()); stmt.bind(":examinne_id_from", param.examinneid.c_str()); break; } stmt.bind(":exam_name", param.examName.c_str()); stmt.bind(":course_name", param.courseName.c_str()); stmt.execDML(); CppSQLite3Query query = database_db->execQuery("select last_insert_rowId() from DATABASE"); m_database_id = query.getIntField(0); database_db->execDML("commit transaction"); LeaveCriticalSection(database_db_lock); strncpy(m_db_file_name, db_file_name, 520); bantch_db.open(db_file_name); bantch_db.execDML("pragma journal_mode = MEMORY"); return 0; } //查询异常试卷 int CBatchService::QueryExceptionPaper(const long exception_type, vector& studentList) { EnterCriticalSection(&bantch_db_lock); char sql[512]; sprintf_s(sql, "select s.student_id,s.student_code,s.class_name,s.grade_name,s.student_name,s.class_id,pp.score_total,pp.student_paper_id,pp.location_id from student_paper pp left join student s on s.student_id=pp.student_id where not (pp.paper_state&%d) =0", exception_type); CppSQLite3Query q = bantch_db.execQuery(sql); while (!q.eof()){ STUDENT_INFO si; char class_name[64]; sprintf_s(class_name, "%s(%s)班", q.getStringField("grade_name"), q.getStringField("class_name")); si.class_name = class_name; si.student_id = q.getInt64Field("student_id"); si.student_name = q.getStringField("student_name"); si.student_code = q.getStringField("student_code"); si.class_id = q.getInt64Field("class_id"); si.score = (float)q.getFloatField("score_total", -1); si.paper_id = q.getIntField("student_paper_id", -1); si.location_id = q.getIntField("location_id", -1); studentList.push_back(si); q.nextRow(); } LeaveCriticalSection(&bantch_db_lock); return TRUE; } //查询试卷详情,包括异常信息,试卷图像信息,试卷题目信息 int CBatchService::QueryPaperDetail(const int paper_id, PAPER_DETAIL &paper_detail, vector &pageList, vector &questionList) { EnterCriticalSection(&bantch_db_lock); char sql[512]; sprintf_s(sql, "SELECT sp.student_paper_id,sp.Is_Covered, sp.ret_upload, img_upload, sp.paper_code, sp.student_code, sp.paper_state, sp.student_id, sp.file_name, sp.score_total,sp.location_id,s.schoolStudentCard, s.student_name,s.class_name,e.full_score,e.full_score_objective FROM student_paper sp LEFT JOIN student s ON s.student_id = sp.student_id left join exam e on 1=1 WHERE sp.student_paper_id = %d", paper_id); CppSQLite3Query q = bantch_db.execQuery(sql); if (!q.eof()) { if (m_onlineCardTemplate->useQrCode && m_onlineCardTemplate->schoolCardStatus == 1)//使用二维码 且使用学校准考证 { strcpy_s(paper_detail.examnumber, q.getStringField("schoolStudentCard")); } else { strcpy_s(paper_detail.examnumber, q.getStringField("student_code")); } paper_detail.exceptionsFlag = q.getInt64Field("paper_state"); strcpy_s(paper_detail.student_name, q.getStringField("student_name")); paper_detail.score = q.getFloatField("score_total"); strcpy_s(paper_detail.student_id, q.getStringField("student_id")); strcpy_s(paper_detail.class_name, q.getStringField("class_name")); paper_detail.fullScore = q.getFloatField("full_score"); paper_detail.fullScoreObjective = q.getFloatField("full_score_objective"); paper_detail.location_id = q.getInt64Field("location_id"); paper_detail.has_covered = (BatchServiceCmd(BATCH_SRV_CMD::BS_CMD_IS_HAS_COVERD, (void*)&paper_id, NULL)>0); } else{ strcpy_s(paper_detail.examnumber, ""); paper_detail.exceptionsFlag = 0; strcpy_s(paper_detail.student_name, ""); paper_detail.score = 0; strcpy_s(paper_detail.student_id, ""); paper_detail.fullScore = 0; paper_detail.fullScoreObjective = 0; paper_detail.location_id = 0; LeaveCriticalSection(&bantch_db_lock); return FALSE; } std::map mm; //页码信息 sprintf_s(sql, "select pg.* from student_paper pp left join page pg on pg.student_paper_id =pp.student_paper_id where pp.student_paper_id =%d", paper_id); q = bantch_db.execQuery(sql); while (!q.eof()){ PAGE_DETAIL pd; pd.page_id = q.getIntField("page_id"); pd.page_index = q.getIntField("page_index"); pd.img_path = q.getStringField("img_path"); pd.img_oldpath=q.getStringField("img_oldpath"); pd.phy_number = atoi(q.getStringField("phy_number")); pd.exceptions.clear(); mm[pd.page_id] = pd; q.nextRow(); } std::map mm2; std::vector quesitons; // 题目标准 sprintf_s(sql, "SELECT question_code, question_type, multi_answer, answer_all, answer_std, score_full, score_half, option_count FROM question_std ORDER BY question_code + 0"); q = bantch_db.execQuery(sql); while (!q.eof()){ QUESTION_INFO qi; qi.answer_std = q.getStringField("answer_std"); qi.answer_stu = ""; qi.is_mutil = q.getIntField("multi_answer"); qi.option_count = q.getIntField("option_count"); qi.question_code = q.getStringField("question_code"); //qi.question_id =-1; qi.question_type = (QUESTION_TYPE)q.getIntField("question_type"); qi.score_full = q.getFloatField("score_full"); qi.score_half = q.getFloatField("score_half"); qi.score_stu = 0; mm2[qi.question_code] = qi; quesitons.push_back(&mm2[qi.question_code]); q.nextRow(); } sprintf_s(sql, "SELECT count(0) FROM student_paper pp where pp.student_paper_id =%d and not (pp.paper_state&%d)=0", paper_id, MEX_BUKECHAXUNFENSHU); if (bantch_db.execScalar(sql) <= 0){//不存在定位点异常时,查询分数 // 题目得分信息 sprintf_s(sql, "SELECT r.* FROM student_paper pp LEFT JOIN page pg ON pg.student_paper_id = pp.student_paper_id LEFT JOIN result r ON r.page_id = pg.page_id WHERE pp.student_paper_id = %d AND r.type>0", paper_id, paper_id); q = bantch_db.execQuery(sql); while (!q.eof()){ string question_code = q.getStringField("question_code"); mm2[question_code].question_state = (QUESTION_STATE)q.getIntField("question_state"); mm2[question_code].score_stu = (mm2[question_code].question_state == QUESTION_STATE_NORMAL) ? q.getFloatField("score") : q.getFloatField("score_paper"); mm2[question_code].answer_stu = q.getStringField("answer"); q.nextRow(); } } //页面异常信息 sprintf_s(sql, "SELECT ex.exception_id, ex.exception_type, ex.exception_name, ex.page_id,pg.page_id FROM exception ex LEFT JOIN page pg ON pg.page_id = ex.page_id where ex.page_id is not null and ex.student_paper_id =%d", paper_id); q = bantch_db.execQuery(sql); while (!q.eof()){ int page_id = q.getIntField("page_id"); EXCEPTION_INFO ei; ei.exception_id = q.getIntField("exception_id"); ei.type = (EXCEPTION_TYPE)q.getInt64Field("exception_type"); ei.x = 0; ei.y = 0; ei.w = 0; ei.h = 0; mm[page_id].exceptions.push_back(ei); q.nextRow(); } //试卷异常信息 paper_detail.paper_id = paper_id; paper_detail.exceptions.clear(); sprintf_s(sql, "SELECT ex.exception_id, ex.exception_type, ex.exception_name, ex.page_id FROM exception ex where ex.page_id is null and ex.student_paper_id =%d", paper_id); q = bantch_db.execQuery(sql); while (!q.eof()){ EXCEPTION_INFO ei; ei.exception_id = q.getIntField("exception_id"); ei.type = (EXCEPTION_TYPE)q.getInt64Field("exception_type"); ei.x = 0; ei.y = 0; ei.w = 0; ei.h = 0; paper_detail.exceptions.push_back(ei); q.nextRow(); } for (map::iterator it = mm.begin(); it != mm.end(); it++) { pageList.push_back(it->second); } LeaveCriticalSection(&bantch_db_lock); memset(paper_detail.sz_upload_error_msg, 0, sizeof(paper_detail.sz_upload_error_msg)); if (m_upload_manager.IsEanble()){ paper_detail.paper_upload_state = m_upload_manager.GetPaperUploadState(paper_detail.paper_id,paper_detail.sz_upload_error_msg,512); bool isexception = 0 != (paper_detail.exceptionsFlag&(~EX_KAOHAODAIPIPEI)); if (isexception && paper_detail.paper_upload_state==0){ paper_detail.paper_upload_state = 4; } } return TRUE; } //重新识别 int CBatchService::ReIdentify(const int paper_id, const std::string& student_code, const std::vector& params) { CppSQLite3Statement statm = bantch_db.compileStatement("update student_paper set paper_state =:paper_state where student_paper_id=:student_paper_id"); statm.bind(":paper_state", EX_SHIJUANCHONGXINSHIBIEZHONG); statm.bind(":student_paper_id", paper_id); statm.execDML(); m_result_uploader->EnableOnLineCard(m_bOnlineCard, m_nSubjectID, m_nOnlineScanType); boost::shared_ptr subService_; if (m_bOnlineCard){ subService_ = boost::make_shared(this); } else{ subService_ = boost::make_shared(this); } subService_->m_nOnlineScanType = m_nOnlineScanType; subService_->InitService(); subService_->SerErrorHandle(m_bErrorHandle); subService_->SetBianShiBieBianShangChuan(m_upload_manager.IsEanble()); std::string qr; if (m_bOnlineCard){ static_cast(subService_.get())->SetTemplate(m_onlineCardTemplate); qr = std::to_string(m_examId) + "," + std::to_string(paper_id) + (student_code.empty() ? "" : ("," + student_code)); } else{ qr = student_code; } subService_->SetQr(paper_id,true, qr); CString newdbFile = CServerConfig::app_data_dir + _T("\\result_1111.db3"); CopyFile(m_bantch_dir + _T("\\result.db3"), newdbFile, FALSE); //CopyFile(m_bantch_dir + _T("\\result.db3"), _T("D:\\result_1111.db3"),FALSE); subService_->SetDirs(m_bantch_dir, m_norimg_dir, m_excimg_dir, m_img_clips_dir, m_img_alynasis_dir, m_img_alynasis_result_dir, m_img_down_load_dir, m_muban_img_dir); subService_->SetHandlerWnd(m_hwnd); subService_->SetDataBase(&bantch_db_lock, &bantch_db); subService_->ReIdentify(paper_id, params); subService.push_back(subService_); subService_->Start(); //if (m_hwnd != NULL)::PostMessage(m_hwnd, WM_IDENTIFOR_STARTED, 0, 0); return 1; } //更新试卷对应考试 int CBatchService::UpdatePaperStudent(const int paper_id, const std::string examinee_id, const std::string student_code, const std::string studentName, const long schoolId, const std::string stuCode, const std::string stuSchoolCode, const std::string className, const std::string gradeName, bool bReIdentify/* = false*/) { EnterCriticalSection(&bantch_db_lock); // 添加学生 char * sql3 = "INSERT INTO student ( student_id, student_code, class_name, school_id, grade_name, student_name, class_id, score_total,studentCard,schoolStudentCard ) SELECT t.student_id, t.student_code, t.class_name, t.school_id, t.grade_name, t.student_name, t.class_id, t.score_total,t.studentCard,t.schoolStudentCard FROM ( SELECT :student_id student_id, :student_code student_code, :class_name class_name, :school_id school_id, :grade_name grade_name, :student_name student_name, :class_id class_id, :score_total score_total , :studentCard studentCard,:schoolStudentCard schoolStudentCard ) t LEFT JOIN student s ON s.student_id = t.student_id WHERE s.student_id IS NULL"; CppSQLite3Statement statement = bantch_db.compileStatement(sql3); statement.bind(":student_id", examinee_id.c_str()); statement.bind(":student_code", student_code.c_str()); statement.bind(":school_id", schoolId); statement.bind(":student_name", studentName.c_str()); statement.bind(":studentCard", stuCode.c_str()); statement.bind(":schoolStudentCard", stuSchoolCode.c_str()); statement.bind(":class_name", className.c_str()); statement.bind(":grade_name", gradeName.c_str()); statement.execDML(); char sql[512]; char sqlTemp[512]; long exceptions = MEX_KAOHAOYICHANG; sprintf_s(sql, "select sp.student_paper_id,sp.paper_state,sp.student_id from student_paper sp where sp.student_paper_id = %d", paper_id); CppSQLite3Query query_student_paper = bantch_db.execQuery(sql); if (query_student_paper.eof()){ LeaveCriticalSection(&bantch_db_lock); return FALSE; } const std::string student_id_old = query_student_paper.getStringField("student_id"); long paper_state = query_student_paper.getInt64Field("paper_state"); bantch_db.execDML("begin transaction"); if (paper_state&EX_KAOHAOCHONGTU){ sprintf_s(sql, "select sp.student_paper_id,sp.paper_state,sp.student_id from student_paper sp where sp.student_id = '%s' and not sp.student_paper_id = %d", student_id_old, paper_id); CppSQLite3Query q2 = bantch_db.execQuery(sql); vector resolved_ids; int same_code_count = 0; while (!q2.eof()){ long paper_state_t = q2.getInt64Field("paper_state"); if (paper_state_t&EX_KAOHAOCHONGTU) resolved_ids.push_back(q2.getIntField("student_paper_id")); same_code_count++; q2.nextRow(); } if (same_code_count == 1 && resolved_ids.size() == 1){//解决了考号冲突 sprintf_s(sql, "update student_paper set paper_state =paper_state-(paper_state&%d),ret_upload = 0 where student_paper_id=%d", EX_KAOHAOCHONGTU, resolved_ids[0]); bantch_db.execDML(sql); sprintf_s(sql, "delete from exception where student_paper_id = %d and exception_type in(%d)", resolved_ids[0], SHIFT_KAOHAOCHONGTU); bantch_db.execDML(sql); } } sprintf_s(sql, "update student_paper set student_id ='%s',ret_upload = 0,student_code=(select student_code from student where student_id='%s'),paper_state =paper_state-(paper_state&%d) where student_paper_id=%d", examinee_id.c_str(), examinee_id.c_str(), exceptions, paper_id); bantch_db.execDML(sql); //更新这次修改消息 sprintf_s(sql, "update message set identified =1 , examnumber=\"%s\",exceptions=16 where student_paper_id=%d", student_code.c_str(), paper_id); bantch_db.execDML(sql); //删除 sprintf_s(sql, "delete from message where student_paper_id =%d and message_type = %d", paper_id, WM_IDENTIFOR_PAPER_STATE_CHAGED); bantch_db.execDML(sql); //添加 CppSQLite3Statement stmt4 = bantch_db.compileStatement("insert INTO message (student_paper_id , message_type) VALUES (:student_paper_id,:message_type)"); stmt4.bind(":student_paper_id", paper_id); stmt4.bind(":message_type", WM_IDENTIFOR_PAPER_STATE_CHAGED); stmt4.execDML(); sprintf_s(sql, "delete from exception where student_paper_id = %d and exception_type in(%d,%d,%d)", paper_id, SHIFT_KAOHAOBUCUNZAI, SHIFT_KAOHAOCHONGTU, SHIFT_KAOHAOWEISHIBIE); bantch_db.execDML(sql); sprintf_s(sql, "update result set answer ='%s' where student_paper_id=%d and type =3", student_code.c_str(), paper_id); logForDbg(sql); bantch_db.execDML(sql); sprintf_s(sql, "update result set answer ='%s' where student_paper_id=%d and type =0", student_code.c_str(), paper_id); logForDbg(sql); bantch_db.execDML(sql); //updatefile(&bantch_db, paper_id, (string)CT2A(m_norimg_dir), (string)CT2A(m_excimg_dir)); vector conflict_ids; {//更新考号后导致其他试卷考号冲突情况 sprintf_s(sql, "select sp.student_paper_id,sp.paper_state,sp.student_id from student_paper sp where sp.student_id = '%s' ", examinee_id.c_str()); CppSQLite3Query q2 = bantch_db.execQuery(sql); while (!q2.eof()){ long paper_state_t = q2.getInt64Field("paper_state"); if (!(paper_state_t&EX_KAOHAOCHONGTU)) conflict_ids.push_back(q2.getIntField("student_paper_id")); q2.nextRow(); } if (conflict_ids.size()>1){ for (int m = 0; m < conflict_ids.size(); m++) { sprintf_s(sql, "update student_paper set paper_state =paper_state|%d ,ret_upload = 0,Is_Covered=0 where student_paper_id=%d", EX_KAOHAOCHONGTU, conflict_ids[m]); bantch_db.execDML(sql); CppSQLite3Statement stmt3 = bantch_db.compileStatement("insert into exception (exception_type ,exception_name,page_id,student_paper_id) values(:exception_type ,:exception_name,:page_id,:student_paper_id)"); stmt3.bind(":student_paper_id", conflict_ids[m]); stmt3.bind(":exception_type", SHIFT_KAOHAOCHONGTU); stmt3.bind(":exception_name", "考号冲突"); stmt3.execDML(); { //删除 sprintf_s(sql, "delete from message where student_paper_id =%d and message_type = %d", conflict_ids[m], WM_IDENTIFOR_PAPER_STATE_CHAGED); bantch_db.execDML(sql); //添加 CppSQLite3Statement stmt4 = bantch_db.compileStatement("insert INTO message (student_paper_id , message_type) VALUES (:student_paper_id,:message_type)"); stmt4.bind(":student_paper_id", conflict_ids[m]); stmt4.bind(":message_type", WM_IDENTIFOR_PAPER_STATE_CHAGED); stmt4.execDML(); } } } } for (int m = 0; m < conflict_ids.size(); m++) { if (paper_id != conflict_ids[m]){ bantch_db.execDML(sql); if (m_upload_manager.IsEanble()){ m_upload_manager.UploadOnScanCmd(UPLOAD_ON_SCAN_CMD::CMD_DEL_UPLOAD_REPORT, std::to_string(conflict_ids[m]).c_str()); } } } bantch_db.execDML("commit transaction"); LeaveCriticalSection(&bantch_db_lock); for (int m = 0; m < conflict_ids.size(); m++) { if (m_hwnd != NULL)::PostMessage(m_hwnd, WM_IDENTIFOR_PAPER_STATE_CHAGED, (WPARAM)NULL, (LPARAM)conflict_ids[m]); } return TRUE; } int CBatchService::ClearDbTemp() { //情况没有上传的 vector listpaper_id; char sql1[512]; sprintf_s(sql1, "select student_paper_id from student_paper where ret_upload = 0"); EnterCriticalSection(&bantch_db_lock); CppSQLite3Query q = bantch_db.execQuery(sql1); while (!q.eof()){ listpaper_id.push_back(q.getIntField("student_paper_id")); q.nextRow(); } for (int i = 0; i < listpaper_id.size(); i++) { char sql1[512]; char sql2[512]; char sql3[512]; char sql4[512]; sprintf_s(sql1, "delete from exception where student_paper_id =%d ", listpaper_id[i]); sprintf_s(sql2, "delete from result where page_id in (select pg.page_id from page pg where pg.student_paper_id =%d)", listpaper_id[i]); sprintf_s(sql3, "delete from page where student_paper_id =%d", listpaper_id[i]); sprintf_s(sql4, "delete from student_paper where student_paper_id =%d", listpaper_id[i]); bantch_db.execDML(sql1); bantch_db.execDML(sql2); bantch_db.execDML(sql3); bantch_db.execDML(sql4); } LeaveCriticalSection(&bantch_db_lock); return TRUE; } //忽略试卷 int CBatchService::IgnorePaper(const int paper_id) { char sql1[512]; char sql2[512]; char sql3[512]; char sql4[512]; char sql5[512]; sprintf_s(sql1, "delete from exception where student_paper_id =%d ", paper_id); sprintf_s(sql2, "delete from result where page_id in (select pg.page_id from page pg where pg.student_paper_id =%d)", paper_id); sprintf_s(sql3, "delete from page where student_paper_id =%d", paper_id); sprintf_s(sql4, "delete from student_paper where student_paper_id =%d", paper_id); sprintf_s(sql5, "delete from message where student_paper_id =%d", paper_id); EnterCriticalSection(&bantch_db_lock); bantch_db.execDML(sql1); bantch_db.execDML(sql2); bantch_db.execDML(sql3); bantch_db.execDML(sql4); bantch_db.execDML(sql5); LeaveCriticalSection(&bantch_db_lock); return TRUE; } //忽略某类型的异常 int CBatchService::IgnoreException(const long exceptions) { char number_string[10]; //忽略必须处理的异常将删除试卷 EnterCriticalSection(&bantch_db_lock); if (exceptions&MEX_BIXUCHULIYICHANG){ char sql0[512]; sprintf_s(sql0, "update student_paper set paper_state=(paper_state|%d) where paper_state&%d=0 and paper_state&%d>0", EX_SHIJUANSHANCHU, EX_SHIJUANSHANCHU, MEX_BIXUCHULIYICHANG); bantch_db.execDML(sql0); } //忽略非必须处理异常,只删除异常 const long non_must_handle_exceptions[3] = { EX_LOUTU, EX_LOUPI, EX_WUPAN }; const long non_must_handle_exception_shifts[3] = { SHIFT_LOUTU, SHIFT_LOUPI, SHIFT_WUPAN }; if (exceptions&MEX_FEIBIXUCHULIYICHANG){ char sql0[512]; sprintf_s(sql0, "update student_paper set paper_state=paper_state-(paper_state&%d) where paper_state&%d=0 and paper_state&%d>0", MEX_FEIBIXUCHULIYICHANG, EX_SHIJUANSHANCHU, MEX_FEIBIXUCHULIYICHANG); bantch_db.execDML(sql0); } LeaveCriticalSection(&bantch_db_lock); return TRUE; } vector CBatchService::GetAllConfictPaper(int student_paper_id, string student_id)//获取冲突试卷 { char sql5[1024] = { 0 }; sprintf_s(sql5, "select sp.student_paper_id,sp.paper_state,sp.student_id from student_paper sp where sp.student_id = '%s' and not sp.student_paper_id = %d", student_id.c_str(), student_paper_id); CppSQLite3Query q2 = bantch_db.execQuery(sql5); vector all_conflict_ids; vector conflict_ids; while (!q2.eof()){ long paper_state_t = q2.getInt64Field("paper_state"); all_conflict_ids.push_back(q2.getIntField("student_paper_id")); if (!(paper_state_t&EX_KAOHAOCHONGTU)) conflict_ids.push_back(q2.getIntField("student_paper_id")); q2.nextRow(); } return all_conflict_ids; } int CBatchService::BatchServiceCmd(int cmd, void*param, void*ret) { switch (cmd){ // 获取被覆盖的试卷 case BATCH_SRV_CMD::BS_CMD_GET_BE_COVERD_PAPERS: { if (param && ret){ std::vector& vctRetStuInfo = *static_cast*>(ret); vctRetStuInfo.clear(); int student_paper_id = *(int*)param; std::string sql_fmt = "select student_paper_id from student_paper where student_id in(select student_id from student_paper where student_paper_id=%d) and student_paper_id!=%d and Is_Covered=1"; char sz_sql[512] = { 0 }; sprintf_s(sz_sql, sql_fmt.c_str(), student_paper_id, student_paper_id);; EnterCriticalSection(&bantch_db_lock); if (bantch_db.is_open()){ CppSQLite3Query q = bantch_db.execQuery(sz_sql); while (!q.eof()){ vctRetStuInfo.push_back(q.getIntField("student_paper_id")); q.nextRow(); } } LeaveCriticalSection(&bantch_db_lock); } } break; // 判断是否有被覆盖的 case BATCH_SRV_CMD::BS_CMD_IS_HAS_COVERD: { int nRet = 0; if (param){ int student_paper_id = *(int*)param; EnterCriticalSection(&bantch_db_lock); if (bantch_db.is_open()){ std::string sql_fmt = "select count(*) from student_paper where student_id in(select student_id from student_paper where student_paper_id=%d) and student_paper_id!=%d and Is_Covered=1"; char sz_sql[512] = { 0 }; sprintf_s(sz_sql, sql_fmt.c_str(), student_paper_id, student_paper_id); nRet = bantch_db.execScalar(sz_sql); } LeaveCriticalSection(&bantch_db_lock); } return nRet; } break; // 判断是否有考号冲突 case BATCH_SRV_CMD::BS_CMD_IS_HAS_KAOHAOCHONGTU: { int nRet = 0; EnterCriticalSection(&bantch_db_lock); if (bantch_db.is_open()){ std::string sql = "select count(*) from exception where exception_type="; sql += std::to_string(SHIFT_KAOHAOCHONGTU); nRet = bantch_db.execScalar(sql.c_str()); } LeaveCriticalSection(&bantch_db_lock); return nRet; } break; // 覆盖所有考号冲突 case BATCH_SRV_CMD::BS_CMD_COVERD_ALL_KAOHAOCHONGTU: CoverdAllKaohaochongtu(); break; } return 0; } // 覆盖所有考号冲突 void CBatchService::CoverdAllKaohaochongtu() { // m_coverd_all_kaohaochongtu = std::async(std::launch::async, [&]()->int{ LOGI("全部覆盖操作开始"); std::map>> _map_student_id; std::string str_qry_sql = "select student_id,student_paper_id,task_id from student_paper where paper_state=128 order by student_id ,student_paper_id desc"; EnterCriticalSection(&bantch_db_lock); auto _qry = bantch_db.execQuery(str_qry_sql.c_str()); if (_qry.eof()){ LeaveCriticalSection(&bantch_db_lock); // 覆盖操作结束 if (m_hwnd != NULL) ::PostMessage(m_hwnd, WM_IDENTIFOR_PAPER_COVERD_ALL_KAOHAOCHONGTU, (WPARAM)0, (LPARAM)0); return -1; } while (!_qry.eof()){ std::string student_id = _qry.getStringField("student_id"); std::string task_id = _qry.getStringField("task_id"); _map_student_id[student_id].push_back(std::make_pair(task_id, _qry.getIntField("student_paper_id"))); _qry.nextRow(); } std::string str_coverd = ""; std::string str_update = ""; for (auto it : _map_student_id){ for (std::size_t i = 0; i < it.second.size(); ++i){ std::string task_id = it.second[i].first; int student_paper_id = it.second[i].second; if (i == 0){ if (m_bErrorHandle){ // 云处理模式- 被覆盖的更新云端状态 if (UpateErrorStudentData(task_id)){ str_update += std::to_string(student_paper_id); } } else{ str_update += std::to_string(student_paper_id); } } else{ str_coverd += std::to_string(student_paper_id); str_coverd += ","; } } str_update += ","; } bantch_db.execDML("begin transaction"); try{ if (!str_coverd.empty()){ str_coverd = std::string(str_coverd, 0, str_coverd.size() - 1); std::string str_sql_coverd = "update student_paper set paper_state=0, Is_Covered=1 where student_paper_id in("; str_sql_coverd += str_coverd + ")"; bantch_db.execDML(str_sql_coverd.c_str()); LOGFMTI("被覆盖sql语句:%s", str_sql_coverd.c_str()); std::string sql_del = "delete from message where student_paper_id in("; sql_del += str_coverd + ")"; bantch_db.execDML(sql_del.c_str()); LOGFMTI("被覆盖sql语句 message表:%s", sql_del.c_str()); } if (!str_update.empty()){ str_update = std::string(str_update, 0, str_update.size() - 1); std::string str_sql_update = "update student_paper set paper_state=0, Is_Covered=0 where student_paper_id in("; str_sql_update += str_update + ")"; bantch_db.execDML(str_sql_update.c_str()); LOGFMTI("覆盖sql语句:%s", str_sql_update.c_str()); } } catch (...){ LOGI("全部覆盖操作SQL执行异常"); bantch_db.execDML("rollback transaction"); } bantch_db.execDML("commit transaction"); LOGI("全部覆盖操作SQL执行成功-更新界面"); LeaveCriticalSection(&bantch_db_lock); // 删除被覆盖的数据 // 将最后一条移动到成功列表 int _update_len = str_update.size() + 1, _coverd_len = str_coverd.size() + 1; char *_update = new char[_update_len]; memset(_update, 0, _update_len); char *_coverd = new char[_coverd_len]; memset(_coverd, 0, _coverd_len); strcpy_s(_update, _update_len, str_update.c_str()); strcpy_s(_coverd, _coverd_len, str_coverd.c_str()); ::PostMessage(m_hwnd, WM_IDENTIFOR_PAPER_COVERD_ALL_KAOHAOCHONGTU, (WPARAM)_update, (LPARAM)_coverd); LOGI("全部覆盖操作结束"); // 覆盖操作结束 if (m_hwnd != NULL) ::PostMessage(m_hwnd, WM_IDENTIFOR_PAPER_COVERD_ALL_KAOHAOCHONGTU, (WPARAM)0, (LPARAM)0); return 0; }); } // 覆盖试卷 int CBatchService::ReplacePaper(const int paper_id, int &paper_id_ret) { BOOL bRet = FALSE; paper_id_ret = paper_id; char sql1[512] = { 0 }; char sql5[512] = { 0 }; sprintf_s(sql1, "delete from exception where student_paper_id =%d ", paper_id); sprintf_s(sql5, "update student_paper set paper_state=0 where student_paper_id = %d AND paper_state = 128", paper_id); EnterCriticalSection(&bantch_db_lock); if (bantch_db.execDML(sql5) > 0){ bantch_db.execDML(sql1); char sql0[512]; sprintf_s(sql0, "select student_paper_id,task_id from student_paper where student_id in (select student_id from student_paper where student_paper_id = %d ) and paper_state = 0 and student_paper_id != %d and Is_Covered != 1 ", paper_id, paper_id); CppSQLite3Query q = bantch_db.execQuery(sql0); if (!q.eof()){ int couvered_paper_id = q.getIntField("student_paper_id"); bool bSendToClientUpdate = true; if (m_bErrorHandle){ // 云处理模式- 被覆盖的更新云端状态 auto task_id = std::to_string(q.getIntField("task_id")); if (!UpateErrorStudentData(task_id)){ //printf("更新状态失败,所以不更新覆盖标记\n"); bSendToClientUpdate = false; } } if(bSendToClientUpdate){ std::string sql_del = "delete from message where student_paper_id="; sql_del += std::to_string(couvered_paper_id); bantch_db.execDML(sql_del.c_str()); sprintf_s(sql5, "update student_paper set Is_Covered=1 where student_paper_id = %d", couvered_paper_id); int nRet = bantch_db.execDML(sql5); LOGFMTI("被覆盖paper_id=%d 成功paper_id=%d 数据库更新状况:%d", couvered_paper_id, paper_id, nRet); if (m_hwnd != NULL)::PostMessage(m_hwnd, WM_IDENTIFOR_PAPER_COVERD, (WPARAM)paper_id, (LPARAM)couvered_paper_id); } } else{ if (m_hwnd != NULL)::PostMessage(m_hwnd, WM_IDENTIFOR_PAPER_COVERD, (WPARAM)paper_id, (LPARAM)paper_id); } bRet = TRUE; if (m_hwnd != NULL)::PostMessage(m_hwnd, WM_IDENTIFOR_PAPER_STATE_CHAGED, (WPARAM)NULL, (LPARAM)paper_id); } LeaveCriticalSection(&bantch_db_lock); return bRet; } // 全部覆盖试卷 int CBatchService::ReplaceAllKaoHaoChongTu(vector &paper_id_List) { char mysql0[512]; sprintf_s(mysql0, "select student_paper_id from student_paper where paper_state = 128"); EnterCriticalSection(&bantch_db_lock); char sql0[512]; char sql1[512]; char sql2[512]; char sql3[512]; char sql4[512]; char sql5[512]; int delete_paper; CppSQLite3Query q = bantch_db.execQuery(mysql0); while (!q.eof()) { int paper_id = q.getIntField("student_paper_id"); sprintf_s(sql1, "select * from student_paper where student_id in (select student_id from student_paper where student_paper_id = %d) and paper_state = 0 ", paper_id); sprintf_s(sql5, "update student_paper set paper_state=0 where student_paper_id = %d", paper_id); paper_id_List.push_back(paper_id); CppSQLite3Query q1 = bantch_db.execQuery(sql0); if (!q.eof()) { delete_paper = q1.getIntField("student_paper_id"); sprintf_s(sql1, "delete from exception where student_paper_id =%d ", delete_paper); sprintf_s(sql2, "delete from result where page_id in (select pg.page_id from page pg where pg.student_paper_id =%d)", delete_paper); sprintf_s(sql3, "delete from page where student_paper_id =%d", delete_paper); sprintf_s(sql4, "delete from student_paper where student_paper_id =%d", delete_paper); bantch_db.execDML(sql1); bantch_db.execDML(sql2); bantch_db.execDML(sql3); bantch_db.execDML(sql4); bantch_db.execDML(sql5); // 修改消息 sprintf_s(sql0, "delete from message where student_paper_id =%d", paper_id); sprintf_s(sql1, "UPDATE message SET student_paper_id = %d WHERE student_paper_id = %d ", paper_id, delete_paper); bantch_db.execDML(sql0); bantch_db.execDML(sql1); } q.nextRow(); } LeaveCriticalSection(&bantch_db_lock); return TRUE; } //开始上传成绩 int CBatchService::StartUploadPaper(HWND hWnd, int student_paper_id/* = -1*/, bool bErrorPaper /*= false*/) { m_result_uploader->SetResultHandler(mainService->GetResultHander()); m_result_uploader->SetDataBase(&bantch_db_lock, &bantch_db); m_result_uploader->SetDataBaseManager(database_db_lock, database_db,m_database_id); if (hWnd != NULL)m_result_uploader->SetHandlerWnd(hWnd); m_result_uploader->readNewUploadUrl(); m_result_uploader->SetUploadOnScan(m_upload_manager.IsEanble(), student_paper_id, bErrorPaper); return m_result_uploader->Start(); } //是否支持暂停 BOOL CBatchService::SupportPause(void) { return mainService->SupportPause(); } //暂停处理 ServiceState CBatchService::OnPausing(void) { mainService->Pause(); while (mainService->GetServiceSate() == pausing || mainService->GetServiceSate() == running){ Sleep(10); } ServiceState nextState = IService::OnPausing(); if (nextState == paused&&m_hwnd != NULL)::PostMessage(m_hwnd, WM_IDENTIFOR_PAUSED, 0, 0); return nextState; } //恢复扫描 ServiceState CBatchService::OnResuming(void) { mainService->Resume(); while (mainService->GetServiceSate() == resuming){ Sleep(10); } ServiceState nextState = IService::OnResuming(); if (nextState == running&&m_hwnd != NULL)::PostMessage(m_hwnd, WM_IDENTIFOR_RESUMED, 0, 0); return nextState; } //放弃本次考试 int CBatchService::GiveUpCurrentBatch() { char sql[128]; sprintf_s(sql, "update database set database_state =%d where database_id =%d", DATABASE_STATE_GIVEUP, m_database_id); EnterCriticalSection(database_db_lock); database_db->execDML("begin transaction"); database_db->execDML(sql); database_db->execDML("commit transaction"); LeaveCriticalSection(database_db_lock); return TRUE; } //设置继续扫描文件夹路径 int CBatchService::SetFolderScanDir(const std::string& img_dir) { mainService->continueScan(img_dir); mainService->Start(); return TRUE; } //停止服务 BOOL CBatchService::Stop(void) { if (IService::Stop()){ m_abnormal_stop = TRUE; return TRUE; } m_upload_manager.UploadOnScanCmd(UPLOAD_ON_SCAN_CMD::CMD_UPLOAD_STOP, NULL); return FALSE; } int CBatchService::QueryExptionPaperCount( int & exc_count, int & total_count) { EnterCriticalSection(&bantch_db_lock); exc_count = bantch_db.execScalar("select count(0) from student_paper pp where not pp.paper_state = 0 and ret_upload = 0"); total_count = bantch_db.execScalar("select count(0) from student_paper where ret_upload = 0"); LeaveCriticalSection(&bantch_db_lock); return TRUE; } //查询异常类型信息 int CBatchService::QueryExptionTypeInfo(vector & infos) { EnterCriticalSection(&bantch_db_lock); CppSQLite3Query query = bantch_db.execQuery("SELECT pe.exception_type, count(DISTINCT pe.student_paper_id) exception_paper_count FROM exception pe GROUP BY pe.exception_type"); while (!query.eof()){ EXCEPTION_TYPE_INFO ex_type_info; ex_type_info.exception_type = (1 << query.getInt64Field("exception_type")); ex_type_info.exception_count = query.getIntField("exception_paper_count"); switch (ex_type_info.exception_type){ case EX_DINGWEIDIAN:strcpy(ex_type_info.exception_name, "定位点异常"); break; case EX_FEIFASHIJUAN:strcpy(ex_type_info.exception_name, "非法试卷"); break; case EX_KAOHAOWEISHIBIE:strcpy(ex_type_info.exception_name, "考号未识别"); break; //case EX_KAOHAOBUCUNZAI:strcpy(ex_type_info.exception_name, "考号不存在"); break; //case EX_KAOHAOCHONGTU:strcpy(ex_type_info.exception_name, "考号冲突"); break; case EX_LOUTU:strcpy(ex_type_info.exception_name, "考生漏涂"); break; case EX_LOUPI:strcpy(ex_type_info.exception_name, "教师漏批"); break; case EX_WUPAN:strcpy(ex_type_info.exception_name, "教师误判"); break; case EX_WUFASHIBIE_ZHUGUANTI:strcpy(ex_type_info.exception_name, "无法识别解答题"); break; case EX_SHIJUANQUEYE:strcpy(ex_type_info.exception_name, "试卷缺页"); break; //case EX_SHIJUANQUEKAO:strcpy(ex_type_info.exception_name, "缺考"); break; //case EX_KEGUANTIYICHANG:strcpy(ex_type_info.exception_name, "客观题异常"); break; default: strcpy(ex_type_info.exception_name, "未知异常类型"); break; } infos.push_back(ex_type_info); query.nextRow(); } query = bantch_db.execQuery("SELECT count(DISTINCT student_paper_id) exception_paper_count FROM student_paper where paper_state&64>0"); if (!query.eof()) { EXCEPTION_TYPE_INFO ex_type_info; strcpy(ex_type_info.exception_name, "考号不存在"); ex_type_info.exception_type = 64; ex_type_info.exception_count = query.getIntField("exception_paper_count"); infos.push_back(ex_type_info); } query = bantch_db.execQuery("SELECT count(DISTINCT student_paper_id) exception_paper_count FROM student_paper where paper_state&32768>0"); if (!query.eof()) { EXCEPTION_TYPE_INFO ex_type_info; strcpy(ex_type_info.exception_name, "客观题异常"); ex_type_info.exception_type = 32768; ex_type_info.exception_count = query.getIntField("exception_paper_count"); infos.push_back(ex_type_info); } query = bantch_db.execQuery("SELECT count(DISTINCT student_paper_id) exception_paper_count FROM student_paper where absent=1"); if (!query.eof()) { EXCEPTION_TYPE_INFO ex_type_info; strcpy(ex_type_info.exception_name, "缺考"); ex_type_info.exception_type = 16384; ex_type_info.exception_count = query.getIntField("exception_paper_count"); infos.push_back(ex_type_info); } query = bantch_db.execQuery("SELECT count(DISTINCT student_paper_id) exception_paper_count FROM student_paper where paper_state&128>0 and ret_upload=0"); if (!query.eof()) { EXCEPTION_TYPE_INFO ex_type_info; strcpy(ex_type_info.exception_name, "考号冲突"); ex_type_info.exception_type = 128; ex_type_info.exception_count = query.getIntField("exception_paper_count"); infos.push_back(ex_type_info); } LeaveCriticalSection(&bantch_db_lock); return TRUE; } int CBatchService::SetCookie(CString path, CString name, CString value) { return InternetSetCookie(path, name, value); } int CBatchService::SetLocalServerCookie(CString name, CString value) { switch (CServerConfig::server_address_type){ case SAT_LOCAL_IN:InternetSetCookie(CServerConfig::server_url_local_in, name, value); break; case SAT_LOCAL_OUT:InternetSetCookie(CServerConfig::server_url_local_out, name, value); break; } return TRUE; } void CBatchService::Online_saveQuestionStd(long long examId, std::string examName, long examCourseId, std::string courseName, std::string rule /*= ""*/) { rapidjson::Document doc; doc.Parse(rule.c_str()); if (doc.HasParseError()) return; auto itObject = doc.FindMember("data");//全学科在线 if (itObject == doc.MemberEnd()) goto label; { auto itQuestion = itObject->value.FindMember("questions"); if (itQuestion == itObject->value.MemberEnd() || !itQuestion->value.IsArray()) return; CppSQLite3DB* bantch_db = &this->bantch_db; const char* sql_clear = "delete from question_std"; bantch_db->execDML(sql_clear); const char* sql_clear1 = "delete from exam"; bantch_db->execDML(sql_clear1); const char* sql_exam = "INSERT INTO exam ( exam_id, exam_name, exam_course_id, course_name, full_score ,full_score_objective) VALUES ( :exam_id, :exam_name, :exam_course_id, :course_name, :full_score ,:full_score_objective)"; CppSQLite3Statement statement_exam = bantch_db->compileStatement(sql_exam); const char* sql = "INSERT INTO question_std ( question_code,question_name, question_type, multi_answer, answer_all, answer_std, score_full, score_half, option_count,rule_type,basic_type_id ) VALUES ( :question_code,:question_name, :question_type, :multi_answer, :answer_all, :answer_std, :score_full, :score_half, :option_count,:rule_type,:basic_type_id )"; CppSQLite3Statement statement = bantch_db->compileStatement(sql); bantch_db->execDML("begin transaction"); float full_score = 0; float full_score_keguanti = 0; auto fGetQuestionType = [](int nType)->QuestionType{ switch (nType) { // //1 单选 2 小题单选 3 多选 4 小题多选 5 单空 6 多空 7 小题多空 8 解答 9 小题解答 10 英语作文 11 语文作文 12 判断题 //case 1: // 单选题 //case 2: return schema::DANXUANTI; break; // 单选题 //case 3: //case 4: return schema::DUOXUANTI; break; // 多选题 //case 5: //case 6: //case 7: return schema::TIANKONGTI; break; // 填空题 //case 8: //case 9: //case 10: //case 11: return schema::ZHUGUANTI; break; // 主观题 //case 17: return schema::XUANZUO_ZHUGUANTI; break; // 选做题 //case 27: return schema::BIZUOTI; break; case 1: return schema::DANXUANTI; break; // 单选题 case 11: case 2: return schema::DUOXUANTI; break; // 多选题 case 5: return schema::TIANKONGTI; break; // 填空题 case 7: return schema::ZHUGUANTI; break; // 主观题 case 17: return schema::XUANZUO_ZHUGUANTI; break; // 选做题 case 27: return schema::BIZUOTI; break; case 3: return schema::DANXUANTI; break;//判断 } return schema::DANXUANTI; }; for (auto it = itQuestion->value.Begin(); it != itQuestion->value.End(); ++it){ QuestionType question_type; double full_score = 0; auto itType = it->FindMember("type_id"); if (itType != it->MemberEnd() && itType->value.IsInt()){ question_type = fGetQuestionType(itType->value.GetInt()); } else{ continue; } auto itScore = it->FindMember("full_score"); if (itScore != it->MemberEnd() && itScore->value.IsString()) { string str = itScore->value.GetString(); if (!str.empty()) { full_score = atof(str.c_str()); } } if (question_type == schema::DANXUANTI || question_type == schema::DUOXUANTI || question_type == schema::PANDUANTI)full_score_keguanti += full_score; double half_score = 0.0; auto itHalfScore = it->FindMember("rule_score_half"); if (itHalfScore != it->MemberEnd()){ if (itHalfScore->value.IsInt() || itHalfScore->value.IsDouble()) half_score = itHalfScore->value.GetDouble(); else if (itHalfScore->value.IsString()){ std::string s = itHalfScore->value.GetString(); if (!s.empty()) half_score = std::stod(s); } } else { itHalfScore = it->FindMember("halfScore"); if (itHalfScore != it->MemberEnd() && (itHalfScore->value.IsInt() || itHalfScore->value.IsDouble())){ half_score = itHalfScore->value.GetDouble(); } } std::string question_code; auto itQuestionCode = it->FindMember("question_num"); if (itQuestionCode != it->MemberEnd() && itQuestionCode->value.IsString()){ question_code = itQuestionCode->value.GetString(); } std::string question_name = question_code; auto itQuestion_name = it->FindMember("alias"); if (itQuestion_name != it->MemberEnd() && itQuestion_name->value.IsString()){ question_name = itQuestion_name->value.GetString(); } std::string answer_all; auto itAnswer = it->FindMember("answer"); if (itAnswer != it->MemberEnd() && itAnswer->value.IsString()){ answer_all = itAnswer->value.GetString(); } int rule_type = 0; auto itRuleType = it->FindMember("rule_type"); if (itRuleType != it->MemberEnd() && itRuleType->value.IsInt()){ rule_type = itRuleType->value.GetInt(); } int basic_type_id = 0; auto itbasic_type_id = it->FindMember("basic_type_id"); if (itbasic_type_id != it->MemberEnd() && itbasic_type_id->value.IsInt()){ basic_type_id = itbasic_type_id->value.GetInt(); } int option_count = 0; auto itoption_count = it->FindMember("option_count"); if (itoption_count != it->MemberEnd() && itoption_count->value.IsInt()){ option_count = itoption_count->value.GetInt(); } if (basic_type_id==12) { option_count = 2; } auto rule_answer = it->FindMember("rule_answer"); if (rule_answer != it->MemberEnd() && rule_answer->value.IsString()){ string str = rule_answer->value.GetString(); if (str.length() > 0) { answer_all = str; } } statement.bind(":question_code", question_code.c_str()); statement.bind(":question_name", question_name.c_str()); statement.bind(":question_type", question_type); statement.bind(":multi_answer", question_type == schema::QuestionType::DUOXUANTI); statement.bind(":answer_all", answer_all.c_str()); statement.bind(":answer_std", answer_all.c_str()); statement.bind(":score_full", full_score); statement.bind(":score_half", half_score); statement.bind(":option_count", option_count); statement.bind(":rule_type", rule_type); statement.bind(":basic_type_id", basic_type_id); // 单选题、客观题 answer_all 从模板里面取 if (m_onlineCardTemplate && (question_type == schema::QuestionType::DANXUANTI || question_type == schema::QuestionType::DUOXUANTI)) { for (auto& page : m_onlineCardTemplate->pages) { for (auto& question : page.second.vctQuestions) { if (question_code == question.id.c_str()) { string std_answer_all(""); for (auto& option : question.opt) { if (std_answer_all.length() > 0) { std_answer_all.append(","); } std_answer_all.append(option.optName); } statement.bind(":answer_all", std_answer_all.c_str()); break; } } } } statement.execDML(); } statement_exam.bind(":exam_id", examId); statement_exam.bind(":exam_name", examName.c_str()); statement_exam.bind(":exam_course_id", examCourseId); statement_exam.bind(":course_name", courseName.c_str()); statement_exam.bind(":full_score", full_score); statement_exam.bind(":full_score_objective", full_score_keguanti); statement_exam.execDML(); bantch_db->execDML("commit transaction"); } label: if (m_nSubjectID == 0) { rapidjson::Document doc; doc.Parse(rule.c_str()); if (doc.HasParseError()) return; auto itObject = doc.FindMember("object"); if (itObject == doc.MemberEnd() || !itObject->value.IsArray() || itObject->value.Size() <= 0) return; auto itQuestion = itObject->value.Begin()->FindMember("questions"); if (itQuestion == itObject->value.Begin()->MemberEnd() || !itQuestion->value.IsArray()) return; CppSQLite3DB* bantch_db = &this->bantch_db; const char* sql_clear = "delete from question_std"; bantch_db->execDML(sql_clear); const char* sql_clear1 = "delete from exam"; bantch_db->execDML(sql_clear1); const char* sql_exam = "INSERT INTO exam ( exam_id, exam_name, exam_course_id, course_name, full_score ,full_score_objective) VALUES ( :exam_id, :exam_name, :exam_course_id, :course_name, :full_score ,:full_score_objective)"; CppSQLite3Statement statement_exam = bantch_db->compileStatement(sql_exam); const char* sql = "INSERT INTO question_std ( question_code,question_name, question_type, multi_answer, answer_all, answer_std, score_full, score_half, option_count,rule_type ) VALUES ( :question_code,:question_name, :question_type, :multi_answer, :answer_all, :answer_std, :score_full, :score_half, :option_count,:rule_type )"; CppSQLite3Statement statement = bantch_db->compileStatement(sql); bantch_db->execDML("begin transaction"); float full_score = 0; float full_score_keguanti = 0; auto fGetQuestionType = [](int nType)->QuestionType{ switch (nType){ case 1: return schema::DANXUANTI; break; // 单选题 case 11: case 2: return schema::DUOXUANTI; break; // 多选题 case 5: return schema::TIANKONGTI; break; // 填空题 case 7: return schema::ZHUGUANTI; break; // 主观题 case 17: return schema::XUANZUO_ZHUGUANTI; break; // 选做题 case 27: return schema::BIZUOTI; break; } return schema::DANXUANTI; }; for (auto it = itQuestion->value.Begin(); it != itQuestion->value.End(); ++it){ QuestionType question_type; int full_score = 0; auto itType = it->FindMember("questionTypeId"); if (itType != it->MemberEnd() && itType->value.IsInt()){ question_type = fGetQuestionType(itType->value.GetInt()); } else{ continue; } auto itScore = it->FindMember("fullScore"); if (itScore != it->MemberEnd() && itScore->value.IsInt()){ full_score = itScore->value.GetInt(); } if (question_type == schema::DANXUANTI || question_type == schema::DUOXUANTI || question_type == schema::PANDUANTI)full_score_keguanti += full_score; double half_score = 0.0; auto itHalfScore = it->FindMember("rule_score_half"); if (itHalfScore != it->MemberEnd() ){ if (itHalfScore->value.IsInt() || itHalfScore->value.IsDouble()) half_score = itHalfScore->value.GetDouble(); else if (itHalfScore->value.IsString()){ std::string s = itHalfScore->value.GetString(); if(!s.empty()) half_score = std::stod(s); } } else { itHalfScore = it->FindMember("halfScore"); if (itHalfScore != it->MemberEnd() && (itHalfScore->value.IsInt() || itHalfScore->value.IsDouble())){ half_score = itHalfScore->value.GetDouble(); } } std::string question_code; auto itQuestionCode = it->FindMember("questionNum"); if (itQuestionCode != it->MemberEnd() && itQuestionCode->value.IsString()){ question_code = itQuestionCode->value.GetString(); } std::string question_name= question_code; auto itQuestion_name = it->FindMember("alias"); if (itQuestion_name != it->MemberEnd() && itQuestion_name->value.IsString()){ question_name = itQuestion_name->value.GetString(); } std::string answer_all; auto itAnswer = it->FindMember("answer"); if (itAnswer != it->MemberEnd() && itAnswer->value.IsString()){ answer_all = itAnswer->value.GetString(); } int rule_type = 0; auto itRuleType = it->FindMember("rule_type"); if (itRuleType != it->MemberEnd() && itRuleType->value.IsInt()){ rule_type = itRuleType->value.GetInt(); } auto rule_answer = it->FindMember("rule_answer"); if (rule_answer != it->MemberEnd() && rule_answer->value.IsString()){ string str = rule_answer->value.GetString(); if (str.length()>0) { answer_all = str; } } statement.bind(":question_code", question_code.c_str()); statement.bind(":question_name", question_name.c_str()); statement.bind(":question_type", question_type); statement.bind(":multi_answer", question_type == schema::QuestionType::DUOXUANTI); statement.bind(":answer_all", answer_all.c_str()); statement.bind(":answer_std", answer_all.c_str()); statement.bind(":score_full", full_score); statement.bind(":score_half", half_score); statement.bind(":option_count", 3); statement.bind(":rule_type", rule_type); // 单选题、客观题 answer_all 从模板里面取 if (m_onlineCardTemplate && (question_type == schema::QuestionType::DANXUANTI || question_type == schema::QuestionType::DUOXUANTI)) { for (auto& page : m_onlineCardTemplate->pages) { for (auto& question : page.second.vctQuestions) { if (question_code == question.id.c_str()) { string std_answer_all(""); for (auto& option : question.opt) { if (std_answer_all.length() > 0) { std_answer_all.append(","); } std_answer_all.append(option.optName); } statement.bind(":answer_all", std_answer_all.c_str()); break; } } } } statement.execDML(); } statement_exam.bind(":exam_id", examId); statement_exam.bind(":exam_name", examName.c_str()); statement_exam.bind(":exam_course_id", examCourseId); statement_exam.bind(":course_name", courseName.c_str()); statement_exam.bind(":full_score", full_score); statement_exam.bind(":full_score_objective", full_score_keguanti); statement_exam.execDML(); bantch_db->execDML("commit transaction"); } else { rapidjson::Document doc; doc.Parse(rule.c_str()); if (doc.HasParseError()) return; auto itQuestion = doc.FindMember("questions"); if (itQuestion == doc.MemberEnd() || !itQuestion->value.IsArray() || itQuestion->value.Size() <= 0) return; //auto itQuestion = itObject->value.Begin()->FindMember("questions"); //if (itQuestion == itQuestion->value.Begin()->MemberEnd() || !itQuestion->value.IsArray()) return; CppSQLite3DB* bantch_db = &this->bantch_db; const char* sql_clear = "delete from question_std"; bantch_db->execDML(sql_clear); const char* sql_clear1 = "delete from exam"; bantch_db->execDML(sql_clear1); const char* sql_exam = "INSERT INTO exam ( exam_id, exam_name, exam_course_id, course_name, full_score ,full_score_objective) VALUES ( :exam_id, :exam_name, :exam_course_id, :course_name, :full_score ,:full_score_objective)"; CppSQLite3Statement statement_exam = bantch_db->compileStatement(sql_exam); const char* sql = "INSERT INTO question_std ( question_code, question_name,question_type, multi_answer, answer_all, answer_std, score_full, score_half, option_count,rule_type ) VALUES ( :question_code,:question_name, :question_type, :multi_answer, :answer_all, :answer_std, :score_full, :score_half, :option_count,:rule_type )"; CppSQLite3Statement statement = bantch_db->compileStatement(sql); bantch_db->execDML("begin transaction"); float full_score = 0; float full_score_keguanti = 0; auto fGetQuestionType = [](int nType)->QuestionType{ switch (nType){ case 1: return schema::DANXUANTI; break; // 单选题 case 11: case 2: return schema::DUOXUANTI; break; // 多选题 case 5: return schema::TIANKONGTI; break; // 填空题 case 7: return schema::ZHUGUANTI; break; // 主观题 case 17: return schema::XUANZUO_ZHUGUANTI; break; // 选做题 case 27: return schema::BIZUOTI; break; } return schema::DANXUANTI; }; for (auto it = itQuestion->value.Begin(); it != itQuestion->value.End(); ++it){ QuestionType question_type; int full_score = 0; auto itType = it->FindMember("questionTypeId"); if (itType != it->MemberEnd() && itType->value.IsInt()){ question_type = fGetQuestionType(itType->value.GetInt()); statement.bind(":question_type", question_type); } else{ continue; } auto itScore = it->FindMember("fullScore"); if (itScore != it->MemberEnd() && itScore->value.IsString()){ full_score = std::atoi(itScore->value.GetString()); statement.bind(":score_full", itScore->value.GetString()); } if (question_type == schema::DANXUANTI || question_type == schema::DUOXUANTI || question_type == schema::PANDUANTI)full_score_keguanti += full_score; double half_score = 0.0; auto itHalfScore = it->FindMember("rule_score_half"); if (itHalfScore != it->MemberEnd() && (itHalfScore->value.IsString())){ //half_score = itHalfScore->value.GetDouble(); statement.bind(":score_half", itHalfScore->value.GetString()); } else { auto itHalfScore1 = it->FindMember("halfScore"); if (itHalfScore1 != it->MemberEnd() && (itHalfScore1->value.IsString())){ //half_score = itHalfScore->value.GetDouble(); statement.bind(":score_half", itHalfScore1->value.GetString()); } } std::string question_code; int question_id(0); auto itQuestionCode = it->FindMember("questionNum"); if (itQuestionCode != it->MemberEnd() && itQuestionCode->value.IsInt()){ //question_code = itQuestionCode->value.GetString(); question_id = itQuestionCode->value.GetInt(); statement.bind(":question_code", itQuestionCode->value.GetInt()); } std::string question_name=to_string(question_id); auto itQuestion_name = it->FindMember("alias"); if (itQuestion_name != it->MemberEnd() && itQuestion_name->value.IsString()){ question_name = itQuestion_name->value.GetString(); } statement.bind(":question_name", question_name.c_str()); std::string answer_all; auto itAnswer = it->FindMember("answer"); if (itAnswer != it->MemberEnd() && itAnswer->value.IsString()){ answer_all = itAnswer->value.GetString(); } int rule_type = 0; auto itRuleType = it->FindMember("rule_type"); if (itRuleType != it->MemberEnd() && itRuleType->value.IsInt()){ //rule_type = itRuleType->value.GetInt(); statement.bind(":rule_type", itRuleType->value.GetInt()); } else statement.bind(":rule_type", 2); auto rule_answer = it->FindMember("rule_answer"); if (rule_answer != it->MemberEnd() && rule_answer->value.IsString()){ string str = rule_answer->value.GetString(); if (str.length() > 0) { answer_all = str; } } //statement.bind(":question_code", question_code.c_str()); //statement.bind(":question_type", question_type); statement.bind(":multi_answer", question_type == schema::QuestionType::DUOXUANTI); //statement.bind(":answer_all", answer_all.c_str()); statement.bind(":answer_std", answer_all.c_str()); //statement.bind(":score_full", full_score); //statement.bind(":score_half", half_score); statement.bind(":option_count", 3); //statement.bind(":rule_type", rule_type); // 单选题、客观题 answer_all 从模板里面取 if (m_onlineCardTemplate && (question_type == schema::QuestionType::DANXUANTI || question_type == schema::QuestionType::DUOXUANTI)) { for (auto& page : m_onlineCardTemplate->pages) { for (auto& question : page.second.vctQuestions) { if (question_id == atoi(question.id.c_str())) { string std_answer_all(""); for (auto& option : question.opt) { if (std_answer_all.length() > 0) { std_answer_all.append(","); } std_answer_all.append(option.optName); } statement.bind(":answer_all", std_answer_all.c_str()); break; } } } } statement.execDML(); } statement_exam.bind(":exam_id", examId); statement_exam.bind(":exam_name", examName.c_str()); statement_exam.bind(":exam_course_id", examCourseId); statement_exam.bind(":course_name", courseName.c_str()); statement_exam.bind(":full_score", full_score); statement_exam.bind(":full_score_objective", full_score_keguanti); statement_exam.execDML(); bantch_db->execDML("commit transaction"); } } void CBatchService::saveQuestionStd(long long examId, std::string examName, long examCourseId, std::string courseName, std::vector &questions, std::string rule) { CppSQLite3DB* bantch_db = &this->bantch_db; const char* sql_clear = "delete from question_std"; bantch_db->execDML(sql_clear); const char* sql_clear1 = "delete from exam"; bantch_db->execDML(sql_clear1); const char* sql_exam = "INSERT INTO exam ( exam_id, exam_name, exam_course_id, course_name, full_score ,full_score_objective) VALUES ( :exam_id, :exam_name, :exam_course_id, :course_name, :full_score ,:full_score_objective)"; CppSQLite3Statement statement_exam = bantch_db->compileStatement(sql_exam); const char* sql = "INSERT INTO question_std ( question_code, question_type, multi_answer, answer_all, answer_std, score_full, score_half, option_count,rule_type ) VALUES ( :question_code, :question_type, :multi_answer, :answer_all, :answer_std, :score_full, :score_half, :option_count,:rule_type )"; CppSQLite3Statement statement = bantch_db->compileStatement(sql); bantch_db->execDML("begin transaction"); float full_score = 0; float full_score_keguanti = 0; Json::Value ruleValue; if (!rule.empty()) { Json::Features features; Json::Reader re(features); Json::Value root; re.parse(rule, root); ruleValue = root["rules"]; } for (int i = 0; i < questions.size(); i++) { schema::SCHEMA_QUESTION& row = questions[i]; full_score += row.score; int question_type = row.questionType&schema::QTF_QUESTION_TYPE_MASK; if (question_type == schema::DANXUANTI || question_type == schema::DUOXUANTI || question_type == schema::PANDUANTI)full_score_keguanti += row.score; statement.bind(":question_code", row.question_code_new); statement.bind(":question_type", row.questionType); statement.bind(":multi_answer", question_type == schema::QuestionType::DUOXUANTI); statement.bind(":answer_all", row.answers.c_str()); statement.bind(":answer_std", row.answerA.c_str()); statement.bind(":score_full", row.score); statement.bind(":score_half", row.halfScore); statement.bind(":option_count", 3); statement.bind(":rule_type", 2); m_mapKeguantiNickName[row.question_code_new] = row.question_code; if (!ruleValue.isNull()) { if (ruleValue.size() > 0) { Json::Value rule = ruleValue[row.question_code_new]; if (!rule.isNull()) { int rule_type = rule["rule_type"].asInt(); //row["questionNum"].asString().c_str() statement.bind(":rule_type", rule_type); std::string answer = rule["rule_answer"].asString().c_str(); if (!answer.empty()) statement.bind(":answer_std", rule["rule_answer"].asString().c_str()); else { row.answerA = answer; statement.bind(":answer_std", row.answerA.c_str()); } std::string rule_score = rule["rule_score"].asString().c_str(); if (!rule_score.empty()) statement.bind(":score_full", atof(rule_score.c_str())); else { row.score = atof(rule_score.c_str()); statement.bind(":score_full", row.score); } std::string rule_score_half = rule["rule_score_half"].asString().c_str(); if (!rule_score_half.empty()) statement.bind(":score_half", atof(rule_score_half.c_str())); else { row.halfScore = atof(rule_score_half.c_str()); statement.bind(":score_half", row.halfScore); } } } // Json::Value rule = ruleValue[std::stoi(row.question_code_new)]; // if (!rule.isNull()) // { // int rule_type = rule["rule_type"].asInt(); // //row["questionNum"].asString().c_str() // statement.bind(":rule_type", rule_type); // std::string answer = rule["rule_answer"].asString().c_str(); // if (!answer.empty()) // statement.bind(":answer_std", rule["rule_answer"].asString().c_str()); // else // statement.bind(":answer_std", row.answerA.c_str()); // std::string rule_score = rule["rule_score"].asString().c_str(); // if (!rule_score.empty()) // statement.bind(":score_full", atof(rule_score.c_str())); // else // statement.bind(":score_full", row.score); // std::string rule_score_half = rule["rule_score_half"].asString().c_str(); // if (!rule_score_half.empty()) // statement.bind(":score_half", atof(rule_score_half.c_str())); // else // statement.bind(":score_half", row.halfScore); // // } } statement.execDML(); } statement_exam.bind(":exam_id", examId); statement_exam.bind(":exam_name", examName.c_str()); statement_exam.bind(":exam_course_id", examCourseId); statement_exam.bind(":course_name", courseName.c_str()); statement_exam.bind(":full_score", full_score); statement_exam.bind(":full_score_objective", full_score_keguanti); statement_exam.execDML(); bantch_db->execDML("commit transaction"); // getStdAnswerAndScore(); } int CBatchService::QueryNormalPaper(vector & studentList) { EnterCriticalSection(&bantch_db_lock); // 找考号考号冲突的并且已经上传的成功数据,和未上传的成功数据 string sql = "select s.student_id,s.student_code,s.class_name,s.grade_name,s.student_name,s.class_id,pp.score_total,pp.student_paper_id,pp.ret_upload,pp.paper_state,pp.location_id from student_paper pp left join student s on s.student_id=pp.student_id where pp.student_id in (select student_id from student_paper where paper_state = 128) and paper_state = 0 or (pp.paper_state = 0)"; CppSQLite3Query q = bantch_db.execQuery(sql.c_str()); while (!q.eof()){ STUDENT_INFO si; char class_name[64]; sprintf_s(class_name, "%s(%s)班", q.getStringField("grade_name"), q.getStringField("class_name")); si.class_name = class_name; si.student_id = q.getInt64Field("student_id"); si.student_name = q.getStringField("student_name"); si.student_code = q.getStringField("student_code"); si.class_id = q.getInt64Field("class_id"); si.score = (float)q.getFloatField("score_total", -1); si.paper_id = q.getIntField("student_paper_id", -1); si.location_id = q.getIntField("location_id", -1); studentList.push_back(si); q.nextRow(); } LeaveCriticalSection(&bantch_db_lock); return TRUE; } int CBatchService::QueryMubanImgPath(int page_index, std::string& imgPath) { CString imgFilePath; imgFilePath.Format(_T("%s\\%05d.jpg"), CString(m_muban_img_dir.c_str()), page_index); char fff[1024]; WideCharToMultiByte(CP_ACP, 0, imgFilePath, -1, fff, 1024, NULL, NULL); imgPath = fff; return TRUE; } int CBatchService::QueryMubanImgCount(int& page_count) { /*return page_count = m_identifor.GetMubanCount();*/ page_count = m_schema.get() ? m_schema->size() : 0; return 1; } const boost::shared_ptr& CBatchService::GetHandleInfo() { return m_handleInfo; } void CBatchService::getStdAnswerAndScore() { CppSQLite3DB* bantch_db = &this->bantch_db; CHttpClient httpClient; CString url_str_findPaperInfo, postData, strPaperId; string response; url_str_findPaperInfo.Format(_T("%s/coachio/iointerface/downLoadThirdPaperSheet"), CServerConfig::server_url); readPaperId(strPaperId); logForDbg("getStdAnswerAndScore" ); postData.Format(_T("paperIdStr=")); postData += strPaperId; httpClient.SetSendHeader(MarkHttpHeaderData()); httpClient.HttpPost(url_str_findPaperInfo, postData, response); Json::Features features; Json::Reader re(features); Json::Value root; re.parse(response, root); if (root["success"].isInt() && root["success"].asInt()){ Json::Value objects = root["object"]; Json::Value object = objects["paper_info"]; // for (int m = 0; mcompileStatement("update question_std set answer_std=:answer_std,score_full=:score_full where question_code=:question_code"); stmt.bind(":question_code", row["questionNum"].asString().c_str()); stmt.bind(":answer_std", row["answer"].asString().c_str()); stmt.bind(":score_full", row["fullScore"].asDouble()); logForDbg("question_code:" + row["questionNum"].asString()); logForDbg("answer_std:" + row["answer"].asString()); char strTemp[5] = {"\0"}; string str; sprintf(strTemp, "%.1f", row["fullScore"].asDouble()); str = strTemp; logForDbg("score_full:" + str); stmt.execDML(); } } } } CString CBatchService::MarkHttpHeaderData() { TCHAR FilePath[MAX_PATH]; GetModuleFileName(NULL, FilePath, MAX_PATH); CString ret; (_tcsrchr(FilePath, '\\'))[1] = 0; if (m_bErrorHandle){ lstrcat(FilePath, _T("paperinfo.ini")); WCHAR JSESSIONID[512]; GetPrivateProfileString(_T("paperinfo"), _T("session"), _T(""), JSESSIONID, 512, FilePath); ret = JSESSIONID; } else{ lstrcat(FilePath, _T("config.ini")); #ifndef BACK_STAGE WCHAR SIG[512]; GetPrivateProfileString(_T("SESSIONID"), _T("SIG"), _T(""), SIG, 512, FilePath); WCHAR TIME[512]; GetPrivateProfileString(_T("SESSIONID"), _T("TIME"), _T(""), TIME, 512, FilePath); WCHAR ID[512]; GetPrivateProfileString(L"SESSIONID", L"ID", L"", ID, 512, FilePath); WCHAR JSESSIONID[512]; GetPrivateProfileString(_T("SESSIONID"), _T("JSESSIONID"), _T(""), JSESSIONID, 512, FilePath); ret.Format(_T("userid=%s&time=%s&sig=%s&session=%s"), ID, TIME, SIG, JSESSIONID); #else WCHAR MYCOOK[512]; GetPrivateProfileString(_T("SESSIONID"), _T("MYCOOK"), _T(""), MYCOOK, 512, FilePath); CString ret; ret.Format(_T("%s"), MYCOOK); #endif } return ret; } bool CBatchService::readPaperId(CString& strPaperId) { TCHAR exeFullPath[MAX_PATH]; CString strPath; GetModuleFileName(NULL, exeFullPath, MAX_PATH); strPath = (CString)exeFullPath; int position = strPath.ReverseFind('\\'); strPath = strPath.Left(position + 1); TCHAR FilePath[MAX_PATH]; GetModuleFileName(NULL, FilePath, MAX_PATH); (_tcsrchr(FilePath, '\\'))[1] = 0; lstrcat(FilePath, _T("paperInfo.ini")); WCHAR PaperId[512]; GetPrivateProfileString(_T("paperinfo"), _T("paper_str"), _T(""), PaperId, 512, FilePath); strPaperId = PaperId; return false; } void CBatchService::logForDbg(string strLog) { char threadName[4*1024]; char logName[300]; char sYear[10], sMonth[10], sDay[25]; SYSTEMTIME st; GetLocalTime(&st); int j0 = 0; int m_nYear = st.wYear; ///年 int m_nMonth = st.wMonth; ///月 int m_nDay = st.wDay; ///日 int m_nHour = st.wHour; ///小时 int m_nMinute = st.wMinute; ///分钟 int m_nSecond = st.wSecond; ///秒 int m_nMillSecond = st.wMilliseconds; ///毫秒 sprintf_s(sYear, sizeof(sYear), "%d", m_nYear); sprintf_s(sMonth, sizeof(sMonth), "_%02d", m_nMonth); sprintf_s(sDay, sizeof(sDay), "_%02d_log.txt", m_nDay); strcpy(logName, sYear); strcat(logName, sMonth); strcat(logName, sDay); char strScore[MAX_PATH] = {0}; for (int i = 0; i < strLog.size(); i++) strScore[i] = strLog.at(i); sprintf_s(threadName, sizeof(threadName), "%s\n", strScore); ThreadLog2(threadName, logName); } void CBatchService::recordBarcodeFlag(int nFlag) { TCHAR exeFullPath[MAX_PATH]; CString strPath; GetModuleFileName(NULL, exeFullPath, MAX_PATH); strPath = (CString)exeFullPath; int position = strPath.ReverseFind('\\'); strPath = strPath.Left(position + 1); TCHAR FilePath[MAX_PATH]; GetModuleFileName(NULL, FilePath, MAX_PATH); (_tcsrchr(FilePath, '\\'))[1] = 0; lstrcat(FilePath, _T("paperInfo.ini")); if (nFlag==0) WritePrivateProfileString(_T("paperinfo"), _T("barcode_flag"), L"0", FilePath); else WritePrivateProfileString(_T("paperinfo"), _T("barcode_flag"), L"1", FilePath); return; } void CBatchService::getCurScanExam(std::string exam_code, std::vector> &stuInfo) { CHttpClient httpClient; httpClient.SetSendHeader(MarkHttpHeaderData()); string response; CString url_str; //url_str.Format(_T("%s/%s"),CServerConfig::server_url,_T("student!findStudentsByClazzId.action")); url_str.Format(_T("%s/%s"), CServerConfig::server_url, _T("coachio/iointerface_v2/getNotUploadStudentList")); CString postData; CString stExamCode(exam_code.data()); postData.Format(_T("examGroupId=%s&type=%d"), stExamCode, 1); httpClient.HttpPost(url_str, postData, response); Json::Features features; Json::Reader re(features); Json::Value root; re.parse(response, root); if (root["success"].isInt() && root["success"].asInt()){ Json::Value rows = root["object"]; if (rows.isArray()){ int array_size = rows.size(); std::vector stuVec; for (int i = 0; i stuVec; for (int i = 0; i &stuInfo) { EnterCriticalSection(&bantch_db_lock); char sql[256]; sprintf_s(sql, "select * from student where recoverFlag=1 "); CppSQLite3Query query = bantch_db.execQuery(sql); while (!query.eof()){ coverStu stu; stu.stu_name = query.getStringField("student_name"); stu.stu_code1 = query.getStringField("studentCard"); stu.stu_code2 = query.getStringField("schoolStudentCard"); stu.stu_class = query.getStringField("class_name"); stu.stu_grade = query.getStringField("grade_name"); stuInfo.push_back(stu); query.nextRow(); } LeaveCriticalSection(&bantch_db_lock); } static bool readFile(string & file, string & str) { ifstream in; string line; in.open(file, ifstream::in); if (!in.is_open()) return false; while (getline(in, line)) { str.append(line + "\n"); } in.close(); return true; } void CBatchService::RestoreFile(int paper_id, const std::string&path_rst, const std::string&path_ori) { std::string sql = std::string("update student_paper set file_name='") + path_rst + "', ori_img ='" + path_ori + "'where student_paper_id = " + std::to_string(paper_id); EnterCriticalSection(&bantch_db_lock); bantch_db.execDML(sql.c_str()); LeaveCriticalSection(&bantch_db_lock); } int CBatchService::RestoreStudentPaper(const std::string task_id, const std::string&task_type, rapidjson::Value&doc) { // 恢复 std::string str_student_paper_sql = "INSERT INTO student_paper (" "ori_img, picFlag, location_id, paper_type, absent, score_total, file_name," "student_id,paper_state,student_code,paper_code,img_upload,ret_upload,student_paper_id,task_id,task_type)VALUES " "(" ":ori_img, :picFlag, :location_id, :paper_type, :absent, :score_total, :file_name," ":student_id,:paper_state,:student_code,:paper_code,:img_upload,:ret_upload,:student_paper_id, :task_id, :task_type" ")"; EnterCriticalSection(&bantch_db_lock); CppSQLite3Statement smt_stu_paper = bantch_db.compileStatement(str_student_paper_sql.c_str()); smt_stu_paper.bind(":ret_upload", 0); smt_stu_paper.bind(":img_upload", 0); smt_stu_paper.bind(":task_id", task_id.c_str()); smt_stu_paper.bind(":task_type", task_type.c_str()); // student_code auto it_student_code = doc.FindMember("student_code"); if (it_student_code != doc.MemberEnd() && it_student_code->value.IsString()){ smt_stu_paper.bind(":student_code", it_student_code->value.GetString()); } //paper_code auto it_paper_code = doc.FindMember("paper_code"); if (it_paper_code != doc.MemberEnd() && it_paper_code->value.IsString()){ smt_stu_paper.bind(":paper_code", it_paper_code->value.GetString()); } //paper_state auto it_paper_state = doc.FindMember("paper_state"); if (it_paper_state != doc.MemberEnd() && it_paper_state->value.IsInt()){ smt_stu_paper.bind(":paper_state", it_paper_state->value.GetInt()); } // student_id auto it_student_id = doc.FindMember("student_id"); if (it_student_id != doc.MemberEnd() && it_student_id->value.IsString()){ smt_stu_paper.bind(":student_id", it_student_id->value.GetString()); } // picFlag auto it_picFlag = doc.FindMember("picFlag"); if (it_picFlag != doc.MemberEnd() && it_picFlag->value.IsString()){ smt_stu_paper.bind(":picFlag", it_picFlag->value.GetString()); } // location_id auto it_location_id = doc.FindMember("location_id"); if (it_location_id != doc.MemberEnd() && it_location_id->value.IsInt()){ smt_stu_paper.bind(":location_id", it_location_id->value.GetInt()); } // paper_type auto it_paper_type = doc.FindMember("paper_type"); if (it_paper_type != doc.MemberEnd() && it_paper_type->value.GetString()){ smt_stu_paper.bind(":paper_type", it_paper_type->value.GetString()); } // absent auto it_absent = doc.FindMember("absent"); if (it_absent != doc.MemberEnd() && it_absent->value.IsInt()){ smt_stu_paper.bind(":absent", it_absent->value.GetInt()); } // score_total auto it_score_total = doc.FindMember("score_total"); if (it_score_total != doc.MemberEnd() && (it_score_total->value.IsInt() || it_score_total->value.IsDouble())){ smt_stu_paper.bind(":score_total", it_score_total->value.GetDouble()); } smt_stu_paper.execDML(); CppSQLite3Query query = bantch_db.execQuery("select last_insert_rowId() from student_paper"); int student_paper_id = query.getIntField(0); LeaveCriticalSection(&bantch_db_lock); return student_paper_id; } BOOL CBatchService::UpateErrorStudentData(const std::string&task_id) { BOOL bRet = TRUE; if (!task_id.empty()){ TCHAR exeFullPath[MAX_PATH]; CString strPath; GetModuleFileName(NULL, exeFullPath, MAX_PATH); strPath = (CString)exeFullPath; int position = strPath.ReverseFind('\\'); strPath = strPath.Left(position + 1); TCHAR FilePath[MAX_PATH]; GetModuleFileName(NULL, FilePath, MAX_PATH); (_tcsrchr(FilePath, '\\'))[1] = 0; lstrcat(FilePath, _T("paperinfo.ini")); WCHAR szUrl[512] = { 0 }; GetPrivateProfileString(_T("paperinfo"), _T("errorhandleupdateurl"), _T(""), szUrl, 512, FilePath); WCHAR szSession[512] = { 0 }; GetPrivateProfileString(_T("paperinfo"), _T("session"), _T(""), szSession, 512, FilePath); std::string url = UnicodeToAnsi(szUrl), exam_id = std::to_string(m_examId), session = UnicodeToAnsi(szSession); CString postData; postData.Format(_T("examGroupId=%s&taskIds=%s"), AnsiToUnicode(exam_id), AnsiToUnicode(task_id)); postData.TrimRight(L","); std::string response; CHttpClient httpClient; httpClient.SetSendHeader(AnsiToUnicode(session)); httpClient.HttpPost(AnsiToUnicode(url), postData, response); if (!response.empty()){ Json::Features features; Json::Reader re(features); Json::Value root; re.parse(response, root); if (root.isMember("success") && root["success"].isInt() && root["success"].asUInt() == 1){ bRet = TRUE; //printf("更新状态成功: url=%s session=%s postdata=%s\n", url.c_str(), session.c_str(), UnicodeToAnsi(postData).c_str()); } else{ //printf("更新状态失败: url=%s session=%s postdata=%s\n",url.c_str(),session.c_str(), UnicodeToAnsi(postData).c_str()); } } } return bRet; } void CBatchService::InitUploadManager(bool bEanble, bool bCountiue, bool bErrorHanle, bool bOnlineCard, IUploudNotify*pNotify) { if (bEanble&&m_result_uploader){ m_result_uploader->SetUploadOnScan(bEanble, -1, 0); } m_upload_manager.Init(bEanble, bCountiue, bErrorHanle,bOnlineCard, m_nSubjectID, pNotify, &bantch_db, &bantch_db_lock); } void CBatchService::OnScanListFilter(bool bsuccess,int nUploadState) { m_upload_manager.ScanListFilter(bsuccess,nUploadState); } int CBatchService::UploadOnScanCmd(int nCmd, const char*param, void*ret) { return m_upload_manager.UploadOnScanCmd(nCmd, param, -1, ret); } void DeleteDirectory(CString source); void CBatchService::QuickHandle(bool bGetPath, char*path_nor, int nor_len, char*path_exc, int exc_len) { CString str_nor_dir; CString str_exc_dir; if (bGetPath){ str_nor_dir = m_excimg_dir + _T("\\nor\\"); str_exc_dir = m_excimg_dir + _T("\\exc\\"); DeleteDirectory(str_nor_dir); DeleteDirectory(str_exc_dir); CreateDirectory(str_nor_dir, NULL); CreateDirectory(str_exc_dir, NULL); if (str_exc_dir.GetLength()< nor_len){ strcpy(path_exc, UnicodeToAnsi(str_exc_dir).c_str()); } if (str_nor_dir.GetLength() < nor_len){ strcpy(path_nor, UnicodeToAnsi(str_nor_dir).c_str()); } } else{ str_nor_dir = AnsiToUnicode(path_nor); str_exc_dir = AnsiToUnicode(path_exc); static std::string sql = "select pa.img_oldpath,sp.paper_state from page pa LEFT JOIN student_paper sp ON pa.student_paper_id= sp.student_paper_id"; EnterCriticalSection(&bantch_db_lock); if (bantch_db.is_open()){ CppSQLite3Query qry = bantch_db.execQuery(sql.c_str()); int i = 1; while (!qry.eof()){ int state = qry.getIntField("paper_state"); std::string path = qry.getStringField("img_oldpath"); CString fileName; fileName.Format(_T("%09d.jpg"), i++); if (state == 0){ CopyFileA(path.c_str(), UnicodeToAnsi(str_nor_dir + fileName).c_str(), FALSE); } else{ CopyFileA(path.c_str(), UnicodeToAnsi(str_exc_dir + fileName).c_str(), FALSE); } qry.nextRow(); } } LeaveCriticalSection(&bantch_db_lock); if (m_hwnd && ::IsWindow(m_hwnd)) ::PostMessage(m_hwnd, WM_QUICK_HANDLE_STOPED, 0, 0); } } void CBatchService::SetErrorHandle(bool bErrorHandle) { m_bErrorHandle = bErrorHandle; m_result_uploader->SetErrorHandle(m_bErrorHandle); } static int g_page_id = 1; std::map CBatchService::RestorePages(int paper_id, const std::string&path, rapidjson::Value&value) { std::map ret; std::string sql_fmt = "INSERT INTO page(student_paper_id,identified,img_path,img_oldpath,page_id)VALUES(%d,%d,'%s','%s',%d)"; EnterCriticalSection(&bantch_db_lock); for (auto it_page = value.Begin(); it_page != value.End();++it_page) { std::string _path=""; int identified = -1; int page_id = 0; auto it_name = it_page->FindMember("name"); if (it_name != it_page->MemberEnd()&& it_name->value.IsString()){ auto name = it_name->value.GetString(); _path = path + "ori\\image_" +name; } auto it_identify = it_page->FindMember("identified"); if (it_identify != it_page->MemberEnd() && it_identify->value.IsInt()){ identified = it_identify->value.GetInt(); } auto it_page_id = it_page->FindMember("page_id"); if (it_page_id != it_page->MemberEnd() && it_page_id->value.IsInt()){ page_id = it_page_id->value.GetInt(); ret[page_id] = g_page_id++; } char sz_sql[256] = { 0 }; sprintf_s(sz_sql, sql_fmt.c_str(), paper_id, identified, _path.c_str(), _path.c_str(), ret[page_id]); bantch_db.execDML(sz_sql); } LeaveCriticalSection(&bantch_db_lock); std::string ori_path = path + "ori\\"; CreateDirectoryA(ori_path.c_str(),NULL); for (int i = 0; i < 10; ++i) { CString tmp_path = AnsiToUnicode(path + "image_"+ std::to_string(i+1)+".jpg"); if (PathFileExists(tmp_path)){ MoveFile(tmp_path, AnsiToUnicode(ori_path + "image_" + std::to_string(i + 1) + ".jpg")); } else{ break; } } return ret; } void CBatchService::RestoreException(int paper_id, rapidjson::Value&value, const std::map&mapPageID) { std::string sql_fmt1 = "INSERT INTO exception(exception_type,exception_name,page_id,student_paper_id)VALUES(%d,'%s',%d,%d)"; std::string sql_fmt2 = "INSERT INTO exception(exception_type,exception_name,student_paper_id)VALUES(%d,'%s',%d)"; EnterCriticalSection(&bantch_db_lock); for (auto it_ex = value.Begin(); it_ex != value.End();++it_ex) { std::string exception_name; int exception_type = -1, page_id = -1, student_paper_id = -1; auto it_type = it_ex->FindMember("exception_type"); if (it_type != it_ex->MemberEnd() && it_type->value.IsInt()){ exception_type = it_type->value.GetInt(); } auto it_page_id = it_ex->FindMember("page_id"); if (it_page_id != it_ex->MemberEnd() && it_page_id->value.IsInt()){ auto it_find_page_id = mapPageID.find(it_page_id->value.GetInt()); if (it_find_page_id != mapPageID.end()) { page_id = it_find_page_id->second; } } auto it_name = it_ex->FindMember("exception_name"); if (it_name != it_ex->MemberEnd() && it_name->value.IsString()){ exception_name = it_name->value.GetString(); } char sz_sql[256] = { 0 }; if (page_id==-1){ sprintf_s(sz_sql, sql_fmt2.c_str(), exception_type, exception_name.c_str(), paper_id); } else{ sprintf_s(sz_sql, sql_fmt1.c_str(), exception_type, exception_name.c_str(), page_id, paper_id); } bantch_db.execDML(sz_sql); } LeaveCriticalSection(&bantch_db_lock); } void CBatchService::RestoreResult(int paper_id, rapidjson::Value&value, const std::map&mapPageID) { EnterCriticalSection(&bantch_db_lock); std::string sql_fmt = "INSERT INTO result(student_paper_id,question_code,question_state,answer,type,score,score_paper,isright, page_id)VALUES(%d,'%s',%d,'%s',%d,%0.2f,%0.2f,%d, %d)"; for (auto it_rst = value.Begin(); it_rst != value.End(); ++it_rst) { std::string answer, question_code; float score_paper = 0.0, score = 0.0; int type = 0, isright = 0, question_state = 0; int page_id = 0; auto it_answer = it_rst->FindMember("answer"); if (it_answer != it_rst->MemberEnd() && it_answer->value.IsString()){ answer = it_answer->value.GetString(); } auto it_code = it_rst->FindMember("question_code"); if (it_code != it_rst->MemberEnd() && it_code->value.IsString()){ question_code = it_code->value.GetString(); } auto it_state = it_rst->FindMember("question_state"); if (it_state != it_rst->MemberEnd() && it_state->value.IsInt()){ question_state = it_state->value.GetInt(); } auto it_type = it_rst->FindMember("type"); if (it_type != it_rst->MemberEnd() && it_type->value.IsInt()){ type = it_type->value.GetInt(); } auto it_page_id = it_rst->FindMember("page_id"); if (it_page_id != it_rst->MemberEnd() && it_page_id->value.IsInt()){ auto it_find_page_id = mapPageID.find(it_page_id->value.GetInt()); if (it_find_page_id != mapPageID.end()) { page_id = it_find_page_id->second; } } auto it_score_paper = it_rst->FindMember("score_paper"); if (it_score_paper != it_rst->MemberEnd() && (it_score_paper->value.IsDouble() || it_score_paper->value.IsInt())){ score_paper = it_score_paper->value.GetDouble(); } auto it_score = it_rst->FindMember("score"); if (it_score != it_rst->MemberEnd() && (it_score->value.IsDouble() || it_score->value.IsInt())){ score = it_score->value.GetDouble(); } auto it_is_right = it_rst->FindMember("isright"); if (it_is_right != it_rst->MemberEnd() && it_is_right->value.IsBool()){ isright = it_is_right->value.GetBool() ? 1 : 0; } char sz_sql[256] = { 0 }; sprintf_s(sz_sql, sql_fmt.c_str(), paper_id, question_code.c_str(), question_state, answer.c_str(), type, score, score_paper, isright, page_id); bantch_db.execDML(sz_sql); } LeaveCriticalSection(&bantch_db_lock); } void CBatchService::RestoreStudent(rapidjson::Value&value) { EnterCriticalSection(&bantch_db_lock); std::string qry_sql = "select count(*) from student where "; std::string sql_fmt = "INSERT INTO student( studentCard,recoverFlag,student_id,student_code,class_name,school_id,grade_name,student_name,class_id,schoolStudentCard,score_total)VALUES('%s',%d ,'%s','%s','%s',%lld ,'%s','%s', %lld ,'%s', %f )"; std::string studentCard, student_id, student_code, class_name, grade_name, student_name, schoolStudentCard; int recoverFlag = 0; long long school_id = 0, class_id = 0; float score_total = 0.0; auto it_student_code = value.FindMember("student_code"); if (it_student_code != value.MemberEnd() && it_student_code->value.IsString()){ student_code = it_student_code->value.GetString(); } qry_sql += " student_code='" + student_code + "' and "; auto it_student_id = value.FindMember("student_id"); if (it_student_id != value.MemberEnd() && it_student_id->value.IsString()){ student_id = it_student_id->value.GetString(); } qry_sql += " student_id='" + student_id + "' and "; auto it_school_id = value.FindMember("school_id"); if (it_school_id != value.MemberEnd() && it_school_id->value.IsString()){ std::string tmp = it_school_id->value.GetString(); if (!tmp.empty()){ school_id = std::stoll(tmp); } } qry_sql += " school_id=" + std::to_string(school_id) + " and "; auto it_class_id = value.FindMember("class_id"); if (it_class_id != value.MemberEnd() && it_class_id->value.IsString()){ std::string tmp = it_class_id->value.GetString(); if (!tmp.empty()){ class_id = std::stoll(tmp); } } qry_sql += " class_id=" + std::to_string(class_id); auto it_class_name = value.FindMember("class_name"); if (it_class_name != value.MemberEnd() && it_class_name->value.IsString()){ class_name = it_class_id->value.GetString(); } auto it_grade_name = value.FindMember("grade_name"); if (it_grade_name != value.MemberEnd() && it_grade_name->value.IsString()){ grade_name = it_grade_name->value.GetString(); } auto it_recoverFlag = value.FindMember("recoverFlag"); if (it_recoverFlag != value.MemberEnd() && it_recoverFlag->value.IsInt()){ recoverFlag = it_recoverFlag->value.GetInt(); } auto it_schoolStudentCard = value.FindMember("schoolStudentCard"); if (it_schoolStudentCard != value.MemberEnd() && it_schoolStudentCard->value.IsString()){ schoolStudentCard = it_schoolStudentCard->value.GetString(); } auto it_score_total = value.FindMember("score_total"); if (it_score_total != value.MemberEnd() && (it_score_total->value.IsInt() || it_score_total->value.IsDouble())){ score_total = it_score_total->value.GetDouble(); } auto it_studentCard = value.FindMember("studentCard"); if (it_studentCard != value.MemberEnd() && it_studentCard->value.IsString()){ studentCard = it_studentCard->value.GetString(); } auto it_student_name = value.FindMember("student_name"); if (it_student_name != value.MemberEnd() && it_student_name->value.IsString()){ student_name = it_student_name->value.GetString(); } if (bantch_db.execScalar(qry_sql.c_str())<=0){ char sz_sql[512] = { 0 }; sprintf_s(sz_sql, sql_fmt.c_str(), studentCard.c_str(), recoverFlag, student_id.c_str(), student_code.c_str(), class_name.c_str(), school_id, grade_name.c_str(), student_name.c_str(), class_id, schoolStudentCard.c_str(), score_total); bantch_db.execDML(sz_sql); } LeaveCriticalSection(&bantch_db_lock); } void CBatchService::RestoreErrorHandleSite(const std::string& task_id, const std::string&type, const std::string& strPath) { std::string json_path = strPath + "json.txt"; std::string str_json; int stu_paper_id = -1; readFile(json_path, str_json); try{ if (!str_json.empty()){ rapidjson::Document doc; doc.Parse(str_json.c_str()); if (doc.HasParseError()) return; // 恢复student_paper表 auto it_stu_paper = doc.FindMember("student_paper"); if (it_stu_paper != doc.MemberEnd() && it_stu_paper->value.IsObject()) stu_paper_id = RestoreStudentPaper(task_id, type, it_stu_paper->value); std::map mapPageID; // 恢复page表 auto it_pages = doc.FindMember("pages"); if (it_pages != doc.MemberEnd() && it_pages->value.IsArray()){ mapPageID = RestorePages(stu_paper_id, strPath, it_pages->value); } //RestoreFile(stu_paper_id, strPath + "rst.zip", strPath + "ori.zip"); RestoreFile(stu_paper_id, strPath + "rst\\img", strPath + "ori"); // 恢复异常表 auto it_exception = doc.FindMember("exceptions"); if (stu_paper_id > 0 && it_exception != doc.MemberEnd() && it_exception->value.IsArray()) RestoreException(stu_paper_id, it_exception->value, mapPageID); // 恢复resut表 auto it_result = doc.FindMember("result"); if (stu_paper_id > 0 && it_result != doc.MemberEnd() && it_result->value.IsArray()) RestoreResult(stu_paper_id, it_result->value, mapPageID); // 恢复student表 auto it_student = doc.FindMember("student"); if (it_student != doc.MemberEnd() && it_student->value.IsObject()) RestoreStudent(it_student->value); } } catch (CppSQLite3Exception&e){ ::MessageBoxA(NULL, e.errorMessage(), "提示", MB_OK); } if (m_hwnd != NULL) ::PostMessage(m_hwnd, WM_IDENTIFOR_PAPER_STATE_CHAGED, 0, stu_paper_id); } void CBatchService::leaveCurrentBatch() { if (m_upload_manager.IsEanble()){ m_upload_manager.SetNotifyPtr(nullptr); NetOperator::SetClientNotifyPtr(nullptr); NetOperator::ClientStop(); } } void CBatchService::OnNetNotify(const char*data) { LOGFMTI("from zxhx:%s",data); if (!data) return; rapidjson::Document root; root.Parse(data); if (!root.HasParseError()){ auto it_task_type = root.FindMember("net_task_type"); auto it_cmd = root.FindMember("net_task_cmd"); if (it_cmd != root.MemberEnd() && it_task_type!= root.MemberEnd()){ std::string task_type = it_task_type->value.GetString(); std::string cmd = it_cmd->value.GetString(); if (task_type == "systerm_notify"){ if (cmd == "server_error"||cmd =="server_close"){ LOGI("IPC出错,开始重连"); m_upload_manager.OnTcpError(); std::async(std::launch::async, [&](){ NetOperator::ClientStop(); int nIndex = 1; while (NetOperator::InitClient("127.0.0.1", 99995, this) < 0 && nIndex < 100){ LOGFMTI("第%d次重连失败 %d秒后再次重连", nIndex, nIndex * 2000); Sleep(nIndex * 2000); nIndex++; } if (nIndex < 100){ LOGI("IPC出错,重连成功"); m_upload_manager.OnReConnect(true); } else{ LOGE("IPC出错,重连失败"); m_upload_manager.OnReConnect(false); } }); } } else{ // 边扫描边上传服务 if (m_upload_manager.IsEanble()){ if (task_type == "upload_on_scan_upload"){ m_upload_manager.OnNetNotify(data); } } // 未来可能添加的其他服务 } } else{ LOGE("data from zxhx is 非法数据包 "); } } else{ LOGE("data from zxhx is not a json"); } } int CBatchService::ExamineThisScan(PAPER_DETAIL &paper_detail) { EnterCriticalSection(&bantch_db_lock); char sql[512] = { 0 }; sprintf_s(sql, "select * from student_paper where student_id='%s' and ret_upload=0", paper_detail.student_id); bool bExsit(false); CppSQLite3Query q = bantch_db.execQuery(sql); while (!q.eof()) { int paper_id = q.getIntField(0); if (paper_detail.paper_id == paper_id) { bExsit = true; break; } q.nextRow(); } LeaveCriticalSection(&bantch_db_lock); return bExsit; } int CBatchService::SetAbsentExam(PAPER_DETAIL &paper_detail, int absent) { EnterCriticalSection(&bantch_db_lock); int state = paper_detail.exceptionsFlag; if (1 == absent || 2 == absent) { if (state & EX_SHIJUANQUEKAO) { state ^= EX_SHIJUANQUEKAO; } if (2 == absent) { if (state & EX_KEGUANTIYICHANG) { state ^= EX_KEGUANTIYICHANG; } } } if (3 == absent) { if (state & EX_KEGUANTIYICHANG) { state ^= EX_KEGUANTIYICHANG; } } char sql[512] = { 0 }; if (1 == absent){ sprintf_s(sql, "update student_paper set paper_state=%d, absent=0 where student_paper_id=%d", state, paper_detail.paper_id); } else if (2 == absent){ sprintf_s(sql, "update student_paper set paper_state=%d where student_paper_id=%d", state, paper_detail.paper_id); } else if (3 == absent){ sprintf_s(sql, "update student_paper set paper_state=%d, absent=1 where student_paper_id=%d", state, paper_detail.paper_id); } int rlt = bantch_db.execDML(sql); LeaveCriticalSection(&bantch_db_lock); if (m_hwnd != NULL)::PostMessage(m_hwnd, WM_IDENTIFOR_PAPER_STATE_CHAGED, (WPARAM)100, (LPARAM)paper_detail.paper_id); return rlt; } int CBatchService::QueryKeGuanTiYiChang(const int paper_id, std::vector& keguantiList) { EnterCriticalSection(&bantch_db_lock); char sql[1024] = { 0 }; sprintf_s(sql, "select question_std.*, result.answer, (select count(1) from result where result.student_paper_id = %d and result.answer = '' and result.type IN(4, 8)) as empty_count, " \ " (select count(1) from result where result.student_paper_id = %d and result.type IN(4, 8)) as orgin_count" \ " from result left join question_std on result.question_code = question_std.question_code" \ " where result.student_paper_id = %d" \ " and result.type in(4, 8)" \ " and ((result.type = 4 and (empty_count = orgin_count or result.answer = question_std.answer_all)) or (result.type = 8 and empty_count = orgin_count))", paper_id, paper_id, paper_id); CppSQLite3Query q = bantch_db.execQuery(sql); while (!q.eof()) { KEGUANTI_DETAIL keguanti; strcpy_s(keguanti.question_code, q.getStringField("question_code")); strcpy_s(keguanti.answer_all, q.getStringField("answer_all")); strcpy_s(keguanti.answer_std, q.getStringField("answer_std")); strcpy_s(keguanti.answer, q.getStringField("answer")); keguanti.question_type = q.getIntField("question_type"); keguanti.score_full = q.getFloatField("score_full"); keguanti.score_half = q.getFloatField("score_half"); keguanti.question_nick_code = m_mapKeguantiNickName[keguanti.question_code]; keguantiList.push_back(keguanti); q.nextRow(); } LeaveCriticalSection(&bantch_db_lock); return TRUE; } int CBatchService::UpdateKeGuanTiYiChang(const int paper_id, std::vector& keguantiList) { try { EnterCriticalSection(&bantch_db_lock); m_scoreCounter.Load(); database_db->execDML("begin transaction"); float score_total = 0; // 本次客观题异常经过修正后所增加的分数 for (auto& iter : keguantiList) { // 更新客观题分数 iter.score = m_scoreCounter.GetScore(iter.question_code, iter.answer, 0, 0); CppSQLite3Statement stmt = bantch_db.compileStatement("update result set answer=:answer, score=:score, score_paper=:score_paper where question_code=:question_code and student_paper_id=:student_paper_id and type in(4, 8)"); stmt.bind(":answer", iter.answer); stmt.bind(":score", iter.score); stmt.bind(":score_paper", iter.score); stmt.bind(":question_code", iter.question_code); stmt.bind(":student_paper_id", paper_id); stmt.execDML(); score_total += iter.score; } CppSQLite3Statement stmt = bantch_db.compileStatement("update student_paper set paper_state =paper_state-(paper_state&:paper_state), score_total =score_total+:score_total where student_paper_id=:student_paper_id"); stmt.bind(":paper_state", EX_KEGUANTIYICHANG); stmt.bind(":score_total", score_total); stmt.bind(":student_paper_id", paper_id); stmt.execDML(); database_db->execDML("commit transaction"); } catch (...) { database_db->execDML("rollback transaction"); OutputDebugString(_T("IResultHandler.SavePaper.catch CppSQLite3Exception")); } LeaveCriticalSection(&bantch_db_lock); if (m_hwnd != NULL)::PostMessage(m_hwnd, WM_IDENTIFOR_PAPER_STATE_CHAGED, (WPARAM)100, (LPARAM)paper_id); return TRUE; }