#include "StdAfx.h" #include "SmartEvaluationService.h" #include "ScoreCounter.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" using namespace schema; CSmartEvaluationService::CSmartEvaluationService(void) { InitializeCriticalSection(&bantch_db_lock); m_identifor.IdentifyTaskManager(&taskManager); m_result_handler.IdentifyTaskManager(&taskManager); } CSmartEvaluationService::~CSmartEvaluationService(void) { DeleteCriticalSection(&bantch_db_lock); } //开始扫描处理函数 ServiceState CSmartEvaluationService::OnStarting(void) { m_abnormal_stop = FALSE; unsigned _int64 i64FreeBytesToCaller; unsigned _int64 i64TotalBytes; unsigned _int64 i64FreeBytes; BOOL check_success = GetDiskFreeSpaceEx(m_bantch_dir, (PULARGE_INTEGER)&i64FreeBytesToCaller, (PULARGE_INTEGER)&i64TotalBytes, (PULARGE_INTEGER)&i64FreeBytes); //空余空间小于2G提示不能扫描 const unsigned long long limit = 1024Ui64 * 1024 * 1024 * 2; if (check_success){ if (i64FreeBytesToCaller < limit){ IDENTIFOR_ERROR_MSG* msg = new IDENTIFOR_ERROR_MSG; msg->type = 1; strcpy(msg->msg, "当前空余空间不足2G,请清理磁盘再进行扫描"); PostMessage(m_hwnd, WM_IDENTIFOR_ERROR, (WPARAM)msg, 0); return stoping; } } else{ IDENTIFOR_ERROR_MSG* msg = new IDENTIFOR_ERROR_MSG; msg->type = 1; strcpy(msg->msg, "检查磁盘剩余空间失败!"); PostMessage(m_hwnd, WM_IDENTIFOR_ERROR, (WPARAM)msg, 0); return stoping; } switch (m_feeder_type){ case Folder: m_current_feeder = &m_folder_feeder; break; case Scanner: m_current_feeder = &m_twain_feeder; break; case AdjustBatch: m_current_feeder = &m_server_feeder; break; case AdjustExaminne: m_current_feeder = &m_server_feeder; break; default:m_current_feeder = NULL; break; } if (m_current_feeder != NULL){ m_current_feeder->Start(); m_current_feeder->SetHandlerWnd(m_hwnd); m_identifor.SetExcImgDir(m_excimg_dir); CIdentifyTask* main_task = taskManager.createTask(); main_task->SetFeeder(m_current_feeder); taskManager.setMainTask(main_task); } m_identifor.Start(); m_result_handler.SetImgClipsDir(m_img_clips_dir); m_result_handler.SetIdentifor(&m_identifor); m_result_handler.Start(); m_result_uploader.SetResultHandler(&m_result_handler); m_student_matcher.SetResultHandler(&m_result_handler); Sleep(10); m_student_matcher.setExamId(m_examId); m_student_matcher.Start(); char sql[128]; 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); if (m_hwnd != NULL)::PostMessage(m_hwnd, WM_IDENTIFOR_STARTED, 0, 0); return running; } ServiceState CSmartEvaluationService::OnRunning(void) { ServiceState nextState = IService::OnRunning(); if (nextState == pausing) return nextState; if (nextState == stoping) { m_current_feeder->Stop(); return nextState; } if (m_identifor.GetServiceSate() == stoped&&m_result_handler.GetServiceSate() == stoped&&m_result_uploader.GetServiceSate() == stoped){ return stoping; } Sleep(10); return running; } int CSmartEvaluationService::LoadSchema(long long examId, std::string examName, long examCourseId, std::string courseName, std::string schemaPath) { m_examId = examId; m_examCourseId = examCourseId; CSchemaLoader schemaLoader; int ret = schemaLoader.Load(schemaPath, m_muban_img_dir, m_schema0, m_schema, m_handleInfo); if (ret == SCH_LOAD_SUCCESS){ if (m_identifor.LoadSchema(m_schema)){ saveQuestionStd(examId, examName, examCourseId, courseName, m_schema0.questions); m_result_handler.setHandlInfo(m_handleInfo); return IDF_LOAD_SUCCESS; } } else { return IDF_LOAD_CLASS_SCHEMA | ret; } return IDF_LOAD_FAILURE; } //停止扫描处理函数 ServiceState CSmartEvaluationService::OnStoping(void) { if (m_current_feeder != NULL&&m_current_feeder->GetServiceSate() != stoped){ m_current_feeder->Stop(); } if (m_result_handler.GetServiceSate() != stoped){ m_result_handler.Stop(); } if (m_result_uploader.GetServiceSate() != stoped){ m_result_uploader.Stop(); } while ((m_current_feeder != NULL&&m_current_feeder->GetServiceSate() != stoped) || m_result_handler.GetServiceSate() != stoped || m_result_uploader.GetServiceSate() != stoped){ Sleep(10); } while (m_student_matcher.GetServiceSate() != stoped){ Sleep(10); } 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; } //设置消息接收窗口 int CSmartEvaluationService::SetHandlerWnd(HWND hwnd) { m_hwnd = hwnd; m_twain_feeder.SetHandlerWnd(m_hwnd); m_result_handler.SetHandlerWnd(m_hwnd); m_result_uploader.SetHandlerWnd(m_hwnd); m_student_matcher.SetHandlerWnd(m_hwnd); return TRUE; } //检测服务是是否可以访问 bool testServerAvaiable(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; } int CSmartEvaluationService::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); httpClient.HttpGet(url, NULL, response); Json::Value root; Json::Reader(Json::Features()).parse(response, root); 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 (!testServerAvaiable(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 (testServerAvaiable(CServerConfig::server_url_local_out)){ isLocalServerUnavailable = false; } else { isLocalServerUnavailable = true; } CServerConfig::server_address_type = SAT_LOCAL_OUT; } //本地服务器不可用,返回错误 if (isLocalServerUnavailable)return 2; } m_identifor.Reset(); m_feeder_type = feederType; CString moule_dir =CServerConfig::scan_data_dir; m_bantch_code = GetTimeString(); m_bantch_dir = moule_dir + _T("\\") + m_bantch_code; m_norimg_dir = m_bantch_dir + _T("\\nor_imgs"); m_excimg_dir = m_bantch_dir + _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_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"); CTemplateManager::ExtractResourceToFile(_T("database"), IDR_DATABASE_RESULT, path); char db_file_name[520]; WideCharToMultiByte(CP_UTF8, 0, path, -1, db_file_name, 520, NULL, NULL); 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); bantch_db.open(db_file_name); bantch_db.execDML("pragma journal_mode = MEMORY"); m_result_handler.SetDataBase(&bantch_db_lock, &bantch_db); m_student_matcher.SetDataBase(&bantch_db_lock, &bantch_db); m_student_matcher.SetImgDir(m_norimg_dir, m_excimg_dir); m_result_uploader.SetDataBase(&bantch_db_lock, &bantch_db); m_result_uploader.SetDataBaseManager(database_db_lock, database_db, m_database_id); switch (feederType&FEEDER_TYPE_MASK){ case Folder: m_folder_feeder.SetFolder(param.img_dir); break; case Scanner: m_twain_feeder.SetScannerIndex(param.scanner_id); break; case AdjustBatch: m_server_feeder.SetImageDownloadDir(m_img_down_load_dir); m_server_feeder.SetParam(param.examId, param.examCourseIdOld, CString(param.batch.c_str())); break; case AdjustExaminne: m_server_feeder.SetImageDownloadDir(m_img_down_load_dir); m_server_feeder.SetParam(param.examId, param.examCourseIdOld, CString(param.batch.c_str()), CString(param.examinneid.c_str())); break; } if (m_hwnd != NULL) ::PostMessage(m_hwnd, WM_IDENTIFOR_READY, 0, 0); return TRUE; } //查询异常试卷 int CSmartEvaluationService::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 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); studentList.push_back(si); q.nextRow(); } LeaveCriticalSection(&bantch_db_lock); return TRUE; } //查询试卷详情,包括异常信息,试卷图像信息,试卷题目信息 int CSmartEvaluationService::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.ret_upload, img_upload, sp.paper_code, sp.student_code, sp.paper_state, sp.student_id, sp.file_name, sp.score_total, s.student_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()){ 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")); paper_detail.fullScore = q.getFloatField("full_score"); paper_detail.fullScoreObjective = q.getFloatField("full_score_objective"); } 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; 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.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); return TRUE; } //重新识别 int CSmartEvaluationService::ReIdentify(const int paper_id, 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_manualmatch_feeder.SetImgList(params); m_feeder_type = (FEEDER_TYPE)(ManualMatch | (m_feeder_type&AutoSchemaFlag)); CIdentifyTask* task = taskManager.createTask(); m_manualmatch_feeder.SetHandlerWnd(m_hwnd); m_manualmatch_feeder.Start(); task->SetFeeder(&m_manualmatch_feeder); taskManager.ExcuTask(task); return Start(); } //更新试卷对应考试 int CSmartEvaluationService::UpdatePaperStudent(const int paper_id, const std::string examinee_id, const std::string student_code, const std::string studentName, const long schoolId) { EnterCriticalSection(&bantch_db_lock); char sql[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"); char * sql3 = "INSERT INTO student ( student_id, student_code, class_name, school_id, grade_name, student_name, class_id, score_total ) 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 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 ) 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.execDML(); 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) 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); //updatefile(&bantch_db, resolved_ids[0], (string)CT2A(m_norimg_dir), (string)CT2A(m_excimg_dir)); } } sprintf_s(sql, "update student_paper set student_id ='%s',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, "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); //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' and not sp.student_paper_id = %d", examinee_id.c_str(), paper_id); 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(); } for (int m = 0; m < conflict_ids.size(); m++) { sprintf_s(sql, "update student_paper set paper_state =paper_state|%d 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(); //updatefile(&bantch_db, conflict_ids[m], (string)CT2A(m_norimg_dir), (string)CT2A(m_excimg_dir)); } } 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 CSmartEvaluationService::IgnorePaper(const int paper_id) { char sql1[512]; char sql2[512]; char sql3[512]; char sql4[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); EnterCriticalSection(&bantch_db_lock); bantch_db.execDML(sql1); bantch_db.execDML(sql2); bantch_db.execDML(sql3); bantch_db.execDML(sql4); LeaveCriticalSection(&bantch_db_lock); return TRUE; } //忽略某类型的异常 int CSmartEvaluationService::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; } //开始上传成绩 int CSmartEvaluationService::StartUploadPaper(HWND hWnd) { if (hWnd != NULL)m_result_uploader.SetHandlerWnd(hWnd); return m_result_uploader.Start(); } //是否支持暂停 BOOL CSmartEvaluationService::SupportPause(void) { BOOL supportPause = FALSE; switch (m_feeder_type){ case Folder:supportPause = m_folder_feeder.SupportPause(); break; case Scanner:supportPause = m_twain_feeder.SupportPause(); break; //case Restart:supportPause = m_restart_feeder.SupportPause(); break; case AdjustBatch: supportPause = m_server_feeder.SupportPause(); break; case AdjustExaminne: supportPause = m_server_feeder.SupportPause(); break; case ManualMatch: supportPause = (m_current_feeder==0)?FALSE:m_current_feeder->SupportPause(); break; } return supportPause; } //暂停处理 ServiceState CSmartEvaluationService::OnPausing(void) { m_current_feeder->Pause(); while (m_current_feeder->GetServiceSate() == pausing || m_current_feeder->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 CSmartEvaluationService::OnResuming(void) { m_current_feeder->Resume(); while (m_current_feeder->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 CSmartEvaluationService::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 CSmartEvaluationService::SetFolderScanDir(const std::string& img_dir) { m_folder_feeder.SetFolder(img_dir); m_feeder_type = (FEEDER_TYPE)(Folder | (m_feeder_type&AutoSchemaFlag)); return TRUE; } //停止服务 BOOL CSmartEvaluationService::Stop(void) { if (IService::Stop()){ m_abnormal_stop = TRUE; return TRUE; } return FALSE; } int CSmartEvaluationService::QueryExptionPaperCount(int & total_count) { EnterCriticalSection(&bantch_db_lock); total_count = bantch_db.execScalar("select count(0) from student_paper pp where not pp.paper_state = 0"); LeaveCriticalSection(&bantch_db_lock); return TRUE; } //查询异常类型信息 int CSmartEvaluationService::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_KEGUANTIYICHANG:strcpy(ex_type_info.exception_name, "客观题异常"); break; default: strcpy(ex_type_info.exception_name, "未知异常类型"); break; } infos.push_back(ex_type_info); query.nextRow(); } CppSQLite3Query query2 = 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 = 6; ex_type_info.exception_count = query2.getIntField("exception_paper_count"); infos.push_back(ex_type_info); } CppSQLite3Query query3 = bantch_db.execQuery("SELECT count(DISTINCT student_paper_id) exception_paper_count FROM student_paper where paper_state&32768>0"); if (!query3.eof()) { EXCEPTION_TYPE_INFO ex_type_info; strcpy(ex_type_info.exception_name, "客观题异常"); ex_type_info.exception_type = 15; ex_type_info.exception_count = query3.getIntField("exception_paper_count"); infos.push_back(ex_type_info); } LeaveCriticalSection(&bantch_db_lock); return TRUE; } int CSmartEvaluationService::SetCookie(CString path, CString name, CString value) { return InternetSetCookie(path, name, value); } int CSmartEvaluationService::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 CSmartEvaluationService::saveQuestionStd(long long examId, std::string examName, long examCourseId, std::string courseName, std::vector &questions) { 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 ) VALUES ( :question_code, :question_type, :multi_answer, :answer_all, :answer_std, :score_full, :score_half, :option_count )"; CppSQLite3Statement statement = bantch_db->compileStatement(sql); bantch_db->execDML("begin transaction"); float full_score = 0; float full_score_keguanti = 0; 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); 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.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"); } int CSmartEvaluationService::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 from student_paper pp left join student s on s.student_id=pp.student_id where 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); studentList.push_back(si); q.nextRow(); } LeaveCriticalSection(&bantch_db_lock); return TRUE; } int CSmartEvaluationService::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 CSmartEvaluationService::QueryMubanImgCount(int& page_count) { return page_count = m_identifor.GetMubanCount(); }