ParseapiController.php 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588
  1. <?php
  2. /**
  3. * word试题解析入库操作类
  4. * @author Andy
  5. * @date 2021-08-20
  6. * @company 上海互教教育科技有限公司.
  7. */
  8. class ParseapiController extends CController
  9. {
  10. public $supportTypeName = array(1=>'选择题','2'=>'多选题',11=>'多选题',5=>'填空题',7=>'解答题');
  11. public $charToNum = array('A'=>0,'B'=>1,'C'=>2,'D'=>3,'E'=>4,'F'=>5,'G'=>6,'H'=>7,'I'=>8,'J'=>9,'K'=>10,'L'=>11,'M'=>12,'N'=>13);
  12. public function init()
  13. {
  14. set_time_limit(0);
  15. @ini_set('memory_limit', '512M');
  16. }
  17. public function actionIndex()
  18. {
  19. // 获取curl过来值
  20. $wordId = isset($_GET['wid']) ? intval($_GET['wid']) : 0;
  21. $schoolId = isset($_GET['sid']) ? intval($_GET['sid']) : 0;
  22. if (!$wordId || !$schoolId) {
  23. exit('word或学校ID异常');
  24. }
  25. // 连接业务库
  26. // $busDsn = 'mysql:host=' . Yii::app()->params["businessDb"]['addr'] . ';dbname=' . Yii::app()->params["default_db"]['name'] . ';';
  27. // $busDbh = new PDO($busDsn, Yii::app()->params["default_server"]['username'], Yii::app()->params["default_server"]['password'], array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES "utf8";'));
  28. $busDbh = Yii::app()->businessDb;
  29. $dataBaseInfo = $busDbh->createCommand('SELECT * FROM `database` WHERE `school_id`=' . $schoolId)->queryOne();
  30. if (empty($dataBaseInfo)) {
  31. exit('未找到数据库链接信息!');
  32. }
  33. // 连接学校库
  34. $busDbh = null;
  35. $schDsn = 'mysql:host=' . $dataBaseInfo['database_host'] . ';dbname=' . $dataBaseInfo['database_name'] . ';';
  36. $schDbh = new PDO($schDsn, $dataBaseInfo['database_user'], $dataBaseInfo['database_password'], array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES "utf8";'));
  37. $wordInfo = $schDbh->query('SELECT `word_id`,`word_name`,`subject_id`,`uploader_id`,`type_id`,`exam_group_id` FROM `topic_word` WHERE `word_id`=' . $wordId)->fetch(PDO::FETCH_ASSOC);
  38. if (empty($wordInfo)) {
  39. exit('未找到上传word信息!');
  40. }
  41. $parseJson = file_get_contents('php://input');
  42. $result = json_decode($parseJson, true);
  43. if (empty($result) || $result['errcode'] > 0) { // 解析失败
  44. $stmt = $schDbh->prepare('UPDATE `topic_word` SET `status` = 3,`wrong_reason` = :reason,`content` = :content,parse_time=:time WHERE `word_id` =:wid');
  45. $stmt->execute(array(':wid' => $wordId, ':reason' => $result['errmsg'], ':content' => $parseJson, ':time' => time()));
  46. exit('解析失败!');
  47. } else {
  48. if ($result['callback_type'] == 1) { // 表示人工智能解析完成,更新当前试卷为可预览状态
  49. $sctmt = $schDbh->prepare('UPDATE `topic_word` SET `status` = 5,`content` = :content,parse_time=:time WHERE `word_id` =:wid');
  50. $sctmt->execute(array(':wid' => $wordId, ':time' => time(), ':content' => $parseJson));
  51. exit('更新试卷解析完成状态成功');
  52. } elseif ($result['callback_type'] == 2) { // 试卷解析确认完成,返回试题结构处理
  53. // 验证试题内容是否为空
  54. if (empty($result['items'])) {
  55. $stmt = $schDbh->prepare('UPDATE `topic_word` SET `status` = 3,`wrong_reason` = :reason,`content` = :content,parse_time=:time WHERE `word_id` =:wid');
  56. $stmt->execute(array(':wid' => $wordId, ':reason' => '返回word试题内容为空', ':content' => $parseJson, ':time' => time()));
  57. exit('返回试题内容为空');
  58. } else {
  59. $sctmt = $schDbh->prepare('UPDATE `topic_word` SET `content` = :content,parse_time=:time WHERE `word_id` =:wid');
  60. $sctmt->execute(array(':wid' => $wordId, ':time' => time(), ':content' => $parseJson));
  61. }
  62. // 处理各个端口上传的试题解析
  63. if ($wordInfo['exam_group_id']) { // 助教端第三方试卷解析
  64. if ($wordInfo['subject_id'] == 8) { // 高中英语解析单独处理
  65. self::thirdpartyEnglish($schDbh, $result['items'], $wordInfo,$schoolId);
  66. } else {
  67. self::thirdpartyPaper($schDbh, $result['items'], $wordInfo,$schoolId);
  68. }
  69. }
  70. } else {
  71. exit('解析请求异常,请指定合法的callback_type类型');
  72. }
  73. // 处理完
  74. $resu = $schDbh->prepare('UPDATE `topic_word` SET `status` = 2,`parse_time`=:time WHERE `word_id` =:wid');
  75. $resu->execute(array(':wid' => $wordId, ':time' => time()));
  76. // 插入解析时间记录
  77. $resPro = $schDbh->prepare("INSERT INTO `exam_process` (`exam_group_id`, `action_type`, `action_time`) VALUES (:exam_group_id, :tempType, :time)");
  78. $resPro->execute(array(':exam_group_id' => $wordInfo['exam_group_id'], ':tempType' => 4, ':time' => time()));
  79. $schDbh = null;
  80. exit('解析完成!');
  81. }
  82. }
  83. /**
  84. * 第三方试卷试题解析
  85. * @param $topics
  86. * @return string
  87. */
  88. public function thirdpartyPaper($schDbh, $topics, $word,$schoolId)
  89. {
  90. $apiTopics = array();
  91. $errorMsg = null;
  92. $apiParam = Yii::app()->params['api'][0];
  93. $apiParam['prefix'] .= 'topic_clear_redis/ctopic';
  94. $mathSubject = Yii::app()->params['math_subjects'];
  95. $topicDiffculty = array('超易'=>1,'易'=>2,'中档偏易'=>3,'中档偏难'=>4,'难'=>5,'超难'=>6);
  96. // 获取试卷试题并做相关验证等
  97. $paperTopics = $schDbh->query('select pt.topic_id,pt.type,pp.paper_id from paper_topic_relation pt JOIN (select p.paper_id from exam e left JOIN paper p on e.exam_id = p.exam_id where e.exam_group_id = ' . $word['exam_group_id'] . ' GROUP BY e.exam_group_id) as pp on pt.paper_id = pp.paper_id order by pt.order asc')->fetchAll(PDO::FETCH_ASSOC);
  98. if (empty($paperTopics)) {
  99. $errorMsg = '未找到考试试题';
  100. } elseif (count($paperTopics) != count($topics)) {
  101. $errorMsg = 'WORD题量与试卷题量不同';
  102. }
  103. if ($errorMsg) {
  104. $stmt = $schDbh->prepare('UPDATE `topic_word` SET `status` = 3,`wrong_reason` = :reason,parse_time=:time WHERE `word_id` =:wid');
  105. $stmt->execute(array(':wid' => $word['word_id'], ':reason' => $errorMsg, ':time' => time()));
  106. exit($errorMsg);
  107. }
  108. // 删除试题缓存
  109. $tempTopicIds = array();
  110. foreach ($paperTopics as $tempTopic) {
  111. $tempTopicIds[] = $tempTopic['topic_id'];
  112. }
  113. if ($tempTopicIds) {
  114. self::getApiData($apiParam, 2, json_encode(array('topicIds' => $tempTopicIds)), 3);
  115. }
  116. // 更新试题操作
  117. foreach($topics as $key => $item) {
  118. $topicId = $paperTopics[$key]['topic_id'];
  119. $apiTopics[] = $topicId;
  120. $bankType = (int)$item['topic_type_id'];
  121. $diffName = isset($item['difficulty']) ? $item['difficulty'] : '中档偏易';
  122. $difficulty = isset($topicDiffculty[$diffName]) ? $topicDiffculty[$diffName] : 3;
  123. // 对高中数学与全学科题型及选项设置不同处理
  124. $optionsRank = isset($item['options_rank']) ? (int)$item['options_rank'] : 1;
  125. //if (in_array($word['subject_id'], $mathSubject)) {
  126. // $optionsRank = $item['options_rank'] - 1;
  127. //} else {
  128. // $optionsRank = isset($item['options_rank']) ? (int)$item['options_rank'] : 1;
  129. //}
  130. try {
  131. $schDbh->beginTransaction(); // 开启事务
  132. // topic表
  133. $exeTopic = $schDbh->prepare('UPDATE `topic` SET `topic_title` = :topic_title,`topic_difficulty` = :topic_difficulty,`source_title`=:source_title,`bank_type`=:bank_type,`parse_content`=:parse_content,`update_time`=:update_time WHERE `topic_id` =:topic_id');
  134. $exeTopic->execute(array(':topic_id' => $topicId, ':topic_title' => $item['stem'],':topic_difficulty'=>$difficulty,':bank_type'=>$bankType, ':source_title' => 'word上传试题', ':parse_content' => $item['parse'], ':update_time' => time()));
  135. // topic_item
  136. $exeItem = $schDbh->prepare('UPDATE `topic_item` SET `topic_title` = :topic_title WHERE `topic_id` =:topic_id');
  137. $exeItem->execute(array(':topic_id' => $topicId, ':topic_title' => $item['stem']));
  138. // 选项及答案处理
  139. $exeOption = $schDbh->prepare('delete from `topic_item_option` WHERE `topic_id` =:topic_id');
  140. $exeOption->execute(array(':topic_id' => $topicId));
  141. // 选择题选项处理
  142. if (isset($item['options']) && $item['options']) { // 含有选项的试题
  143. $optionKeys = array();
  144. foreach ($this->charToNum as $char => $num) {
  145. if (strpos($item['key'], $char) !== false) {
  146. $optionKeys[] = $char;
  147. }
  148. }
  149. $correct = 'A';
  150. $rowThr = $schDbh->prepare('INSERT INTO `topic_item_option`(`topic_id`, `option_content`, `option_correct`,`sort_order`) VALUES (:tpid,:content,:correct,:sort_order)');
  151. foreach ($item['options'] as $vk => $option) {
  152. $isTrue = in_array($correct, $optionKeys) ? 1 : 0;
  153. $getRowThr = $rowThr->execute(array(':tpid'=>$topicId,':content'=>$option,':correct'=>$isTrue,':sort_order'=>$vk));
  154. ++$correct;
  155. }
  156. } else {
  157. $rowFiv = $schDbh->prepare('INSERT INTO `topic_item_option`(`topic_id`, `option_content`) VALUES (:tpid,:content)');
  158. if (is_array($item['key']) && $item['key']) {
  159. foreach ($item['key'] as $topicKey) {
  160. $getRowFiv = $rowFiv->execute(array(':tpid' => $topicId, ':content' => $topicKey));
  161. }
  162. } else {
  163. $getRowFiv = $rowFiv->execute(array(':tpid' => $topicId, ':content' => $item['key']));
  164. if (!$getRowFiv) {
  165. throw new PDOException('插入topic_item_option表失败!');
  166. }
  167. }
  168. }
  169. // 组卷完成标识
  170. $resu = $schDbh->prepare('UPDATE `exam_group` SET `is_answersheet` = 1 WHERE `exam_group_id` =:exam_group_id');
  171. $exeSheet = $resu->execute(array(':exam_group_id' => $word['exam_group_id']));
  172. if (!$exeSheet) {
  173. throw new PDOException('更新exam_group表失败!');
  174. }
  175. // word与试题关系
  176. $rowFor = $schDbh->prepare('INSERT INTO `word_topic_relation`(`word_id`, `topic_id`) VALUES (:wid,:toid)');
  177. $getRowFor = $rowFor->execute(array(':wid' => $word['word_id'], ':toid' => $topicId));
  178. if (!$getRowFor) {
  179. throw new PDOException('插入word_to_topic表失败!');
  180. }
  181. $schDbh->commit();
  182. } catch (PDOException $e) {
  183. $schDbh->rollback();
  184. $exeReason = $schDbh->prepare('UPDATE `topic_word` SET `status` = 3,`wrong_reason` = :reason,parse_time=:time WHERE `word_id` =:wid');
  185. $exeReason->execute(array(':wid' => $word['word_id'], ':reason' => $e->getMessage(), ':time' => time()));
  186. exit($e->getMessage());
  187. }
  188. }
  189. if($apiTopics){
  190. //调用试题检索接口
  191. $this->searchTopics($apiTopics,$schoolId);
  192. }
  193. }
  194. // 第三方英语新解析处理
  195. public function thirdpartyEnglish($schDbh, $topics, $word,$schoolId)
  196. {
  197. $errorMsg = null;
  198. $apiParam = Yii::app()->params['api'][0];
  199. $mathSubject = Yii::app()->params['math_subjects'];
  200. $topicDiffculty = array('超易'=>1,'易'=>2,'中档偏易'=>3,'中档偏难'=>4,'难'=>5,'超难'=>6,);
  201. // 获取全学科英语题型
  202. $basicType = array();
  203. $topicTypeConfig = array();
  204. $topicTypeJson = self::getApiData(array(
  205. 'username' => $apiParam['username'],
  206. 'password' => $apiParam['password'],
  207. 'prefix' => $apiParam['prefix'] . 'all_subject/topic_type/subjectId/' . $word['subject_id']
  208. ), 1, '', 3);
  209. $topicTypeRes = json_decode($topicTypeJson, true);
  210. if (isset($topicTypeRes['status']) && $topicTypeRes['status'] == 1 && $topicTypeRes['data']) {
  211. foreach ($topicTypeRes['data'] as $topicType) {
  212. $basicType[$topicType['topic_type_id']] = $topicType['btt_id'];
  213. $topicTypeConfig[$topicType['topic_type_id']] = $topicType;
  214. }
  215. unset($topicTypeJson,$topicTypeRes);
  216. }
  217. // 获取试卷试题并做相关验证等
  218. $paperTopics = $schDbh->query('select pt.topic_id,pt.stem_id,pt.paper_id from paper_topic_relation pt JOIN (select p.paper_id from exam e left JOIN paper p on e.exam_id = p.exam_id where e.exam_group_id = ' . $word['exam_group_id'] . ' GROUP BY e.exam_group_id) as pp on pt.paper_id = pp.paper_id order by pt.order asc')->fetchAll(PDO::FETCH_ASSOC);
  219. if (empty($paperTopics)) {
  220. $stmt = $schDbh->prepare('UPDATE `topic_word` SET `status` = 3,`wrong_reason` = :reason,parse_time=:time WHERE `word_id` =:wid');
  221. $stmt->execute(array(':wid' => $word['word_id'], ':reason' => '未找到考试试题', ':time' => time()));
  222. exit('未找到考试试题');
  223. }
  224. $paperId = 0;
  225. $stemTopicIds = array();
  226. //$packItemRelate = array();
  227. foreach ($paperTopics as $paperTopic) {
  228. $paperId = $paperTopic['paper_id'];
  229. $stemTopicIds[] = $paperTopic['topic_id'];
  230. //$packItemRelate[$paperTopic['topic_id']] = $paperTopic['stem_id'];
  231. }
  232. // 更新试题内容
  233. foreach ($topics as $topic) {
  234. $slaveNum = isset($topic['slave']) && $topic['slave'] ? count($topic['slave']) : 0;
  235. $diffName = isset($topic['difficulty']) ? $topic['difficulty'] : '中';
  236. $difficulty = isset($topicDiffculty[$diffName]) ? $topicDiffculty[$diffName] : 3;
  237. $answerType = isset($topic['answer_type']) && $topic['answer_type'] ? (int)$topic['answer_type'] : 0;
  238. $basicTypeId = isset($basicType[$topic['topic_type_id']]) ? $basicType[$topic['topic_type_id']] : 0;
  239. try {
  240. // 判断并处理当前题目是否含有大小题
  241. //$schDbh->beginTransaction();
  242. if ($slaveNum > 0) {
  243. $slaveTopicIds = array_splice($stemTopicIds, 0, $slaveNum);
  244. if (empty($slaveTopicIds)) continue;
  245. $largeTopicId = self::insertLargeTopic($schDbh, $slaveTopicIds, array(
  246. 'title' => $topic['content'],
  247. 'analysis' => $topic['parse'],
  248. 'answer_type' => $answerType,
  249. 'word_id' => $word['word_id'],
  250. 'exam_group_id' => $word['exam_group_id'],
  251. 'difficulty' => $difficulty,
  252. 'bank_type' => $topic['topic_type_id'],
  253. 'type_id' => $basicTypeId
  254. ));
  255. // 更新小题试题内容
  256. foreach ($topic['slave'] as $skey => $slaveTopic) {
  257. if (!isset($slaveTopicIds[$skey])) continue;
  258. $tempSlaveTopicId = $slaveTopicIds[$skey];
  259. $parse = isset($slaveTopic['parse']) ? $slaveTopic['parse'] : '';
  260. $slaveAnswerType = isset($slaveTopic['answer_type']) ? (int)$slaveTopic['answer_type'] : 0;
  261. $slaveTitle = isset($slaveTopic['content']) ? $slaveTopic['content'] : '';
  262. $slaveOption = isset($slaveTopic['options']) && $slaveTopic['options'] ? $slaveTopic['options'] : '';
  263. // 特殊处理七选五等题型选项问题
  264. if ($basicTypeId == 2 && empty($slaveOption)) {
  265. if (isset($topicTypeConfig[$topic['topic_type_id']]['config']['general_setting']['slave_setting'])) {
  266. $slaveConfig = $topicTypeConfig[$topic['topic_type_id']]['config']['general_setting']['slave_setting'];
  267. $optionFixation = isset($slaveConfig['option_number']['fixation'])?$slaveConfig['option_number']['fixation']:array();
  268. if (isset($optionFixation['is_checked']) && $optionFixation['is_checked'] && isset( $optionFixation['number']) && $optionFixation['number']) {
  269. $letter = 'A';
  270. for ($i=0; $i<$optionFixation['number']; $i++){
  271. $slaveOption[] = array('option' => $letter, 'content' => '');
  272. ++$letter;
  273. }
  274. }
  275. }
  276. }
  277. self::updateTopicInfo($schDbh, array(
  278. 'topic_id' => $tempSlaveTopicId,
  279. 'parse' => $parse,
  280. 'answer_type' => $slaveAnswerType,
  281. 'title' => $slaveTitle,
  282. 'difficulty' => $difficulty,
  283. 'bank_type' => $topic['topic_type_id'],
  284. 'type_id' => $basicTypeId,
  285. 'options' => $slaveOption,
  286. 'answer' => isset($slaveTopic['answer']) ? $slaveTopic['answer'] : array()
  287. ));
  288. }
  289. } else {
  290. $spliceTopicIds = array_splice($stemTopicIds, 0, 1);
  291. if (!isset($spliceTopicIds[0])) continue;
  292. $topicId = $spliceTopicIds[0];
  293. self::updateTopicInfo($schDbh, array(
  294. 'topic_id' => $topicId,
  295. 'parse' => isset($topic['parse']) ? $topic['parse'] : '',
  296. 'answer_type' => $answerType,
  297. 'title' => isset($topic['content']) ? $topic['content'] : '',
  298. 'difficulty' => $difficulty,
  299. 'bank_type' => $topic['topic_type_id'],
  300. 'type_id' => $basicTypeId,
  301. 'options' => isset($topic['options']) && $topic['options'] ? $topic['options'] : '',
  302. 'answer' => isset($topic['answer']) ? $topic['answer'] : array()
  303. ));
  304. // 大题对应大题id更新
  305. $schDbh->prepare("UPDATE `paper_topic_relation` SET `logic_type` = {$topic['topic_type_id']} WHERE `topic_id` = '{$topicId}'")->execute();
  306. }
  307. //$schDbh->commit();
  308. } catch (PDOException $e) {
  309. //$schDbh->rollback();
  310. $exeReason = $schDbh->prepare('UPDATE `topic_word` SET `status` = 3,`wrong_reason` = :reason,parse_time=:time WHERE `word_id` =:wid');
  311. $exeReason->execute(array(':wid' => $word['word_id'], ':reason' => $e->getMessage(), ':time' => time()));
  312. exit($e->getMessage());
  313. }
  314. }
  315. // 获取试卷的大题信息
  316. $paperLargeTopic = $schDbh->query('SELECT `stem_id`,`topic_id`,`logic_type`,`order` FROM `paper_topic_relation` pt WHERE pt.`paper_id`="'.$paperId.'" order by pt.order asc')->fetchAll(PDO::FETCH_ASSOC);
  317. if ($paperLargeTopic) {
  318. $largerRelate = array();
  319. $largeTopicInfo = array();
  320. $taskCheckTopics = array();
  321. $paperLargeTopicIds = array();
  322. foreach ($paperLargeTopic as $ptlInfo) {
  323. $paperLargeTopicIds[] = $ptlInfo['stem_id'];
  324. $largerRelate[$ptlInfo['topic_id']] = $ptlInfo['stem_id'];
  325. if (!isset($largeTopicInfo[$ptlInfo['stem_id']])) {
  326. $largeTopicInfo[$ptlInfo['stem_id']] = array(
  327. 'stem_id' => $ptlInfo['stem_id'],
  328. 'logic_type' => $ptlInfo['logic_type'],
  329. 'order' => $ptlInfo['order']
  330. );
  331. $taskCheckTopics[] = array('topic_id' => $ptlInfo['stem_id'], 'topic_type_id' => $ptlInfo['logic_type']);
  332. }
  333. }
  334. // 如果是全学科题库标注任务推送给题库
  335. $zsyapiParam = Yii::app()->params['api'][1];
  336. $zsyapiParam['prefix'] .= 'task_exam/check_topic';
  337. self::getApiData($zsyapiParam, 2, json_encode(array('examGroupId' => $word['exam_group_id'], 'topics' => $taskCheckTopics)), 5);
  338. // 更新试卷大题关联表
  339. $examInfo = array();
  340. $paperLargeSql = 'INSERT INTO `paper_topic_large` (`paper_id`, `large_topic_id`, `topic_no`, `logic_type`) VALUES ';
  341. $papers = $schDbh->query('select p.paper_id,e.exam_id,e.tpl_data from exam e left JOIN paper p on e.exam_id = p.exam_id where e.exam_group_id = ' . $word['exam_group_id'])->fetchAll(PDO::FETCH_ASSOC);
  342. foreach ($papers as $paper) {
  343. $examInfo[] = array('exam_id' => $paper['exam_id'], 'tpl_data' => $paper['tpl_data']);
  344. $exsitNum = $schDbh->query("SELECT count(*) as num FROM `paper_topic_large` WHERE `paper_id`='{$paper['paper_id']}'")->fetch(PDO::FETCH_ASSOC);
  345. if ($exsitNum['num'] > 0) continue;
  346. $paperLargeVal = array();
  347. foreach ($largeTopicInfo as $plTopic) {
  348. $paperLargeVal[] = "('{$paper['paper_id']}', '{$plTopic['stem_id']}', '{$plTopic['order']}', '{$plTopic['logic_type']}')";
  349. }
  350. $schDbh->prepare($paperLargeSql . implode(',', $paperLargeVal))->execute();
  351. }
  352. // 更新tpl_data new_items大小题关系及题型
  353. $packTopicBasic = array();
  354. $paperLargeTopicIdStr = implode(',', array_unique($paperLargeTopicIds));
  355. $topicBasic = $schDbh->query('SELECT `topic_id`,`topic_type`,`bank_type` FROM `topic` WHERE `topic_id` in ('.$paperLargeTopicIdStr.')')->fetchAll(PDO::FETCH_ASSOC);
  356. foreach ($topicBasic as $loopBasic) {
  357. $packTopicBasic[$loopBasic['topic_id']] = $loopBasic;
  358. }
  359. foreach ($examInfo as $tempExam) {
  360. $tplArr = json_decode($tempExam['tpl_data'], true);
  361. if ($tplArr && isset($tplArr['new_items']) && $tplArr['new_items']) {
  362. foreach ($tplArr['new_items'] as &$loopNewItem) {
  363. if (isset($loopNewItem['topicId'])) {
  364. $tplTopicId = (string)$loopNewItem['topicId'];
  365. if (isset($largerRelate[$tplTopicId]) && $largerRelate[$tplTopicId] != $loopNewItem['stemId']) {
  366. $loopNewItem['stemAlias'] = '';
  367. $loopNewItem['stemId'] = $largerRelate[$tplTopicId];
  368. }
  369. }
  370. if (isset($loopNewItem['stemId'])) {
  371. $tplStemId = (string)$loopNewItem['stemId'];
  372. if (isset($packTopicBasic[$loopNewItem['stemId']])) {
  373. $loopNewItem['topic_type'] = $packTopicBasic[$loopNewItem['stemId']]['bank_type'];
  374. // $loopNewItem['basicTopicType'] = $packTopicBasic[$loopNewItem['stemId']]['topic_type'];
  375. }
  376. }
  377. }
  378. $tplData = self::jsonEncode($tplArr);
  379. $schDbh->prepare("UPDATE `exam` SET `tpl_data` ='{$tplData}' WHERE `exam_id` ='{$tempExam['exam_id']}'")->execute();
  380. }
  381. }
  382. // 删除试题缓存
  383. self::getApiData(array(
  384. 'username' => $apiParam['username'],
  385. 'password' => $apiParam['password'],
  386. 'prefix' => $apiParam['prefix'] . 'topic_clear_redis/ctopic'
  387. ), 2, json_encode(array('topicIds' => array_keys($largeTopicInfo))), 3);
  388. //调用试题检索接口
  389. $this->searchTopics(array_keys($largeTopicInfo),$schoolId);
  390. }
  391. // 组卷完成标识
  392. $resu = $schDbh->prepare('UPDATE `exam_group` SET `is_answersheet` = 1 WHERE `exam_group_id` =:exam_group_id');
  393. $exeSheet = $resu->execute(array(':exam_group_id' => $word['exam_group_id']));
  394. if (!$exeSheet) {
  395. $stmt = $schDbh->prepare('UPDATE `topic_word` SET `status` = 3,`wrong_reason` = :reason,parse_time=:time WHERE `word_id` =:wid');
  396. $stmt->execute(array(':wid' => $word['word_id'], ':reason' => '更新exam_group表失败!', ':time' => time()));
  397. exit('更新exam_group表失败!');
  398. }
  399. }
  400. // 更新试题内容
  401. private static function updateTopicInfo($schDbh, $topic)
  402. {
  403. // topic
  404. $exeTopic = $schDbh->prepare('UPDATE `topic` SET `topic_title` = :topic_title,`topic_difficulty` = :topic_difficulty,`source_title`=:source_title,`bank_type`=:bank_type,`parse_content`=:parse_content,`update_time`=:update_time,`answer_type`=:answer_type,`topic_type`=:topic_type WHERE `topic_id` =:topic_id');
  405. $exeTopic->execute(array(':topic_id' => $topic['topic_id'], ':topic_title' => $topic['title'],':topic_difficulty'=>$topic['difficulty'],':bank_type'=>$topic['bank_type'], ':source_title' => 'word上传试题', ':parse_content' => $topic['parse'], ':update_time' => time(), ':answer_type'=>$topic['answer_type'], ':topic_type'=>$topic['type_id']));
  406. $slaItem = $schDbh->prepare('UPDATE `topic_item` SET `topic_title` = :topic_title WHERE `topic_id` =:topic_id');
  407. $slaItem->execute(array(':topic_id' => $topic['topic_id'], ':topic_title' => $topic['title']));
  408. // topic_item_option
  409. if (isset($topic['options']) && $topic['options']) { // 含有选项的试题
  410. $slaOption = $schDbh->prepare('delete from `topic_item_option` WHERE `topic_id` =:topic_id');
  411. $slaOption->execute(array(':topic_id' => $topic['topic_id']));
  412. $tempAnswer = isset($topic['answer']) ? $topic['answer'] : array();
  413. $rowThr = $schDbh->prepare('INSERT INTO `topic_item_option`(`topic_id`, `option_content`, `option_correct`,`sort_order`) VALUES (:tpid,:content,:correct,:sort_order)');
  414. foreach ($topic['options'] as $svk => $seOption) {
  415. $isslaTrue = in_array($seOption['option'], $tempAnswer) ? 1 : 0;
  416. $rowThr->execute(array(':tpid'=>$topic['topic_id'],':content'=>$seOption['content'],':correct'=>$isslaTrue,':sort_order'=>$svk));
  417. }
  418. } elseif (isset($topic['answer']) && $topic['answer']) {
  419. $slaOption = $schDbh->prepare('delete from `topic_item_option` WHERE `topic_id` =:topic_id');
  420. $slaOption->execute(array(':topic_id' => $topic['topic_id']));
  421. $slaFiv = $schDbh->prepare('INSERT INTO `topic_item_option`(`topic_id`, `option_content`) VALUES (:tpid,:content)');
  422. foreach ($topic['answer'] as $vk => $slaAnswer) {
  423. $slaFiv->execute(array(':tpid'=>$topic['topic_id'],':content'=>$slaAnswer));
  424. }
  425. }
  426. return true;
  427. }
  428. // 新增大题并更新相关信息
  429. private static function insertLargeTopic($schDbh, $slaveTopic, $topic)
  430. {
  431. // 获取文件夹id
  432. $defaultFolder = $schDbh->query('SELECT `folder_id` FROM `topic_folder` WHERE `subject_id`=8 and `is_system`=1')->fetch(PDO::FETCH_ASSOC);
  433. $folderId = empty($defaultFolder) ? 0 : $defaultFolder['folder_id'];
  434. // 获取组卷教师id
  435. $groupInfo = $schDbh->query("SELECT `teacher_id` FROM `exam_group` WHERE `exam_group_id`='{$topic['exam_group_id']}'")->fetch(PDO::FETCH_ASSOC);
  436. $teacherId = empty($groupInfo) ? 0 : $groupInfo['teacher_id'];
  437. // 创建大题
  438. $largeRow = $schDbh->prepare('INSERT INTO `topic`(`topic_type`, `topic_difficulty`, `folder_id`, `subject_id`,`source_title`, `parse_content`, `creator_id`,`updater_id`, `create_time`,`update_time`,`is_word_topic`,`answer_type`,`bank_type`) VALUES (:ttype,:diff,:fid,:sid,:sotitle,:ana,:ceid,:upid,:time,:utime,1,:answer_type,:bank_type)');
  439. $largeRow->execute(array(':ttype' => $topic['type_id'], ':diff' => $topic['difficulty'], ':fid' => $folderId, ':sid' => 8, ':sotitle' => 'word上传试题', ':ana' => $topic['analysis'], ':ceid' => $teacherId, ':upid' => $teacherId, ':time' => time(), ':utime' => time(), ':answer_type'=>$topic['answer_type'], ':bank_type'=>$topic['bank_type']));
  440. $largeTopicId = $schDbh->lastInsertId();
  441. if (!$largeTopicId) {
  442. throw new PDOException('新增大题信息异常!');
  443. }
  444. // 更新大题相关表
  445. $tempSlaveTopicStr = implode(',', $slaveTopic);
  446. $tRelate = $schDbh->prepare("UPDATE `topic` SET `stem_id` = {$largeTopicId} WHERE `topic_id` in ({$tempSlaveTopicStr})");
  447. $tRelate->execute();
  448. $ptRelate = $schDbh->prepare("UPDATE `paper_topic_relation` SET `stem_id`={$largeTopicId},`logic_type`={$topic['bank_type']} WHERE `topic_id` in ({$tempSlaveTopicStr})");
  449. $ptRelate->execute();
  450. // 插入解析时间记录
  451. $tsInsert = $schDbh->prepare("INSERT INTO `topic_stem` (`stem_id`, `topic_ids`, `stem_content`, `subject_id`) VALUES (:stem_id, :topic_ids, :stem_content, :subject_id)");
  452. $tsInsert->execute(array(':stem_id' => $largeTopicId, ':topic_ids' => $tempSlaveTopicStr, ':stem_content' => $topic['title'], ':subject_id' => 8));
  453. // word与试题关系
  454. $rowFor = $schDbh->prepare('INSERT INTO `word_topic_relation`(`word_id`, `topic_id`) VALUES (:wid,:toid)');
  455. $rowFor->execute(array(':wid' => $topic['word_id'], ':toid' => $largeTopicId));
  456. return true;
  457. }
  458. private static function getApiData($apiParam, $flag = 1, $data, $timeOut = 0,$extraHeaders = array())
  459. {
  460. $result = FALSE;
  461. $ch = @curl_init();
  462. if ($ch) {
  463. $headers = array(
  464. 'Content-Type: application/json',
  465. 'Content-Length: ' . strlen($data),
  466. );
  467. if($extraHeaders){
  468. $headers = array_merge($headers,$extraHeaders);
  469. }
  470. // Digest认证
  471. curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
  472. curl_setopt($ch, CURLOPT_USERPWD, $apiParam['username'] . ':' . $apiParam['password']);
  473. // 不输出头部
  474. curl_setopt($ch, CURLOPT_HEADER, 0);
  475. if ($timeOut) {
  476. curl_setopt($ch, CURLOPT_TIMEOUT, $timeOut);
  477. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
  478. }
  479. curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  480. // curl_exec 获取到的内容不直接输出, 而是返回
  481. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  482. // 请求重启路由器的地址 传参 进行重启
  483. curl_setopt($ch, CURLOPT_URL, $apiParam['prefix']);
  484. curl_setopt($ch, CURLOPT_USERAGENT, 'Api Client/1.0.0 (chengfei@liancaitech.com)');
  485. if ($flag == 2) {
  486. curl_setopt($ch, CURLOPT_POST, 1);
  487. curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
  488. }
  489. $result = curl_exec($ch);
  490. if (curl_errno($ch)) {
  491. return 'curl_errno:' . curl_errno($ch);
  492. }
  493. // 释放资源
  494. curl_close($ch);
  495. }
  496. return $result;
  497. }
  498. // json中文处理
  499. private static function jsonEncode($arr)
  500. {
  501. $jsonSupport = version_compare(PHP_VERSION, '5.4', '>=');
  502. if ($jsonSupport) {
  503. $result = json_encode($arr, JSON_UNESCAPED_UNICODE);
  504. } else {
  505. $result = json_encode($arr);
  506. $result = preg_replace("#\\\u([0-9a-f]{4})#ie", "iconv('UCS-2BE', 'UTF-8', pack('H4', '\\1'))", $result);
  507. }
  508. return $result;
  509. }
  510. //全学科试题调用java检索缓存接口
  511. public function searchTopics($topicIds = array(),$schoolId = 0){
  512. $apiParam = Yii::app()->params['api'][3];
  513. if($apiParam && $topicIds && $schoolId){
  514. $url = $apiParam['prefix'].'cgi/teacher/schtk/qxk/school-topic-flush/'.$schoolId;
  515. self::getApiData(array(
  516. 'username' => $apiParam['username'],
  517. 'password' => $apiParam['password'],
  518. 'prefix' => $url
  519. ), 2, json_encode($topicIds), 3,array('X-Basic-V:2'));
  520. }
  521. }
  522. }