ToolsService.java 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  1. package com.qxgmat.service.extend;
  2. import com.alibaba.fastjson.JSONArray;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.qxgmat.data.constants.enums.*;
  5. import com.qxgmat.data.dao.entity.*;
  6. import com.qxgmat.data.relation.entity.QuestionNoRelation;
  7. import com.qxgmat.data.relation.entity.SentenceQuestionRelation;
  8. import com.qxgmat.data.relation.entity.TextbookQuestionRelation;
  9. import com.qxgmat.service.inline.RankService;
  10. import com.qxgmat.service.inline.SettingService;
  11. import org.springframework.beans.factory.annotation.Value;
  12. import org.springframework.stereotype.Service;
  13. import javax.annotation.Resource;
  14. import java.math.BigDecimal;
  15. import java.util.List;
  16. @Service
  17. public class ToolsService {
  18. @Value("${examination.verbalA}")
  19. private Integer verbalA;
  20. @Value("${examination.verbalB}")
  21. private Integer verbalB;
  22. @Value("${examination.quantC}")
  23. private Integer quantC;
  24. @Value("${examination.quantD}")
  25. private Integer quantD;
  26. private Integer scoreMax = 51;
  27. private Integer scoreMin = 6;
  28. @Resource
  29. private SettingService settingService;
  30. @Resource
  31. private RankService rankService;
  32. /**
  33. * 根据练习时间设置计算考题考试时间
  34. * setting: {struct: {difficult: ""}}
  35. * @param relationList
  36. * @return
  37. */
  38. public Integer computerTime(QuestionNoRelation[] relationList){
  39. Setting setting = settingService.getByKey(SettingKey.EXERCISE_TIME);
  40. JSONObject value = setting.getValue();
  41. Integer time = 0;
  42. for(QuestionNoRelation relation:relationList){
  43. JSONObject difficultMap = null;
  44. for (Integer struct : relation.getModuleStruct()){
  45. // 判断结构体
  46. difficultMap = value.getJSONObject(String.valueOf(struct));
  47. if (difficultMap != null) break;
  48. }
  49. if (difficultMap == null) continue;
  50. // 判断难度
  51. String t = difficultMap.getString(relation.getQuestion().getDifficult());
  52. if (t == null || t.isEmpty()) continue;
  53. time += Integer.valueOf(t);
  54. }
  55. return time;
  56. }
  57. /**
  58. * 根据练习时间设置获取单个考题时间
  59. * setting: {struct: {difficult: ""}}
  60. * @param relation
  61. * @return
  62. */
  63. public Integer computerTime(QuestionNoRelation relation){
  64. Setting setting = settingService.getByKey(SettingKey.EXERCISE_TIME);
  65. JSONObject value = setting.getValue();
  66. JSONObject difficultMap = null;
  67. for (Integer struct : relation.getModuleStruct()){
  68. // 判断结构体
  69. difficultMap = value.getJSONObject(String.valueOf(struct));
  70. if (difficultMap != null) break;
  71. }
  72. if (difficultMap == null) return 0;
  73. // 判断难度
  74. String t = difficultMap.getString(relation.getQuestion().getDifficult());
  75. if (t == null || t.isEmpty()) return 0;
  76. return Integer.valueOf(t);
  77. }
  78. /**
  79. * 根据练习时间设置获取单个考题时间
  80. * setting: {struct: {difficult: ""}}
  81. * @param relation
  82. * @return
  83. */
  84. public Integer computerTime(TextbookQuestionRelation relation){
  85. Setting setting = settingService.getByKey(SettingKey.TEXTBOOK_TIME);
  86. JSONObject value = setting.getValue();
  87. String t = value.getString("time");
  88. if (t == null || t.isEmpty()) return 0;
  89. return Integer.valueOf(t);
  90. }
  91. /**
  92. * 根据练习时间设置计算考题考试时间
  93. * setting: {struct: {difficult: ""}}
  94. * @param relationList
  95. * @return
  96. */
  97. public Integer computerTime(TextbookQuestionRelation[] relationList){
  98. Setting setting = settingService.getByKey(SettingKey.TEXTBOOK_TIME);
  99. JSONObject value = setting.getValue();
  100. String t = value.getString("time");
  101. if (t == null || t.isEmpty()) return 0;
  102. return Integer.valueOf(t) * relationList.length;
  103. }
  104. /**
  105. * 根据长难句时间设置获取单个考题时间
  106. * setting: {time: ""}
  107. * @param relation
  108. * @return
  109. */
  110. public Integer computerTime(SentenceQuestionRelation relation){
  111. Setting scoreSwitch = settingService.getByKey(SettingKey.SCORE_SWITCH);
  112. if (scoreSwitch.getValue().getBooleanValue("all")){
  113. // todo 计算全站平均时间
  114. return 0;
  115. } else {
  116. Setting setting = settingService.getByKey(SettingKey.SENTENCE_TIME);
  117. JSONObject value = setting.getValue();
  118. String t = value.getString("time");
  119. if (t == null || t.isEmpty()) return 0;
  120. return Integer.valueOf(t);
  121. }
  122. }
  123. /**
  124. * 根据长难句时间设置获取考题考试时间
  125. * setting: {time: ""}
  126. * @param relationList
  127. * @return
  128. */
  129. public Integer computerTime(SentenceQuestionRelation[] relationList){
  130. Setting scoreSwitch = settingService.getByKey(SettingKey.SCORE_SWITCH);
  131. if (scoreSwitch.getValue().getBooleanValue("all")){
  132. // todo 计算全站平均时间
  133. return 0;
  134. } else {
  135. Setting setting = settingService.getByKey(SettingKey.SENTENCE_TIME);
  136. JSONObject value = setting.getValue();
  137. String t = value.getString("time");
  138. if (t == null || t.isEmpty()) return 0;
  139. return Integer.valueOf(t) * relationList.length;
  140. }
  141. }
  142. /**
  143. * 根据后台设置剔除时间,判断试题统计情况
  144. * @param question
  145. * @return
  146. */
  147. public boolean filterTime(UserQuestion question){
  148. Setting setting = settingService.getByKey(SettingKey.FILTER_TIME);
  149. JSONObject value = setting.getValue();
  150. if (value.getInteger("min")> question.getTime()) return false;
  151. if (value.getInteger("max") < question.getTime()) return false;
  152. return true;
  153. }
  154. /**
  155. * 根据考试设置,得到做题时间,做题数量
  156. * setting: {subject: { time: "", number: "" }}
  157. * @param order
  158. */
  159. public void examinationReportInit(UserReport userReport, JSONArray order){
  160. Setting setting = settingService.getByKey(SettingKey.EXAMINATION_TIME);
  161. JSONObject value = setting.getValue();
  162. Integer number = 0;
  163. Integer time = 0;
  164. for(String subject : order.toJavaList(String.class)){
  165. JSONObject one = value.getJSONObject(subject);
  166. if(one!= null && !one.isEmpty()){
  167. number += one.getInteger("number");
  168. time += one.getInteger("time");
  169. }
  170. }
  171. userReport.setQuestionNumber(number);
  172. userReport.setTime(time);
  173. }
  174. /**
  175. * 得到单个科目做题总时间
  176. * @param subject
  177. * @return
  178. */
  179. public Integer examinationSubjectTime(String subject){
  180. Setting setting = settingService.getByKey(SettingKey.EXAMINATION_TIME);
  181. JSONObject value = setting.getValue();
  182. JSONObject info = value.getJSONObject(subject);
  183. return info.getInteger("time");
  184. }
  185. /**
  186. * 得到单个科目做题总题数
  187. * @param subject
  188. * @return
  189. */
  190. public Integer examinationSubjectNumber(String subject){
  191. Setting setting = settingService.getByKey(SettingKey.EXAMINATION_TIME);
  192. JSONObject value = setting.getValue();
  193. JSONObject info = value.getJSONObject(subject);
  194. return info.getInteger("number");
  195. }
  196. /**
  197. * 获取模考学科数据:
  198. * { time: '', number: '' }
  199. * @param subject
  200. * @return
  201. */
  202. public JSONObject examinationSubjectInit(QuestionSubject subject){
  203. Setting setting = settingService.getByKey(SettingKey.EXAMINATION_TIME);
  204. JSONObject value = setting.getValue();
  205. return value.getJSONObject(subject.key);
  206. }
  207. /**
  208. * Quant分数计算:系数c * Quant部分平均正确率 + 系数d * Quant部分题目平均难度
  209. * @param number
  210. * @param userNumber
  211. * @param difficultScore
  212. * @param correctNumber
  213. * @return
  214. */
  215. // public Integer quantScore(Integer number, Integer userNumber, Integer difficultScore, Integer correctNumber){
  216. // return quantC * correctNumber / number + quantD * difficultScore / userNumber;
  217. // }
  218. /**
  219. * Quant分数计算:17+平均正确率*19.45+平均难度*0.72
  220. * @param number
  221. * @param userNumber
  222. * @param difficultScore
  223. * @param correctNumber
  224. * @return
  225. */
  226. public Integer quantScore(Integer number, Integer userNumber, float difficultScore, Integer correctNumber){
  227. int score = (int)Math.round(17 + 19.45 * correctNumber / number + 0.72 * difficultScore / userNumber);
  228. if (score > scoreMax) return scoreMax;
  229. if (score < scoreMin) return scoreMin;
  230. return score;
  231. }
  232. /**
  233. * Verbal分数计算:系数a * Verbal部分题目平均正确率 + 系数b * Verbal部分题目平均难度
  234. * @param number
  235. * @param userNumber
  236. * @param difficultScore
  237. * @param correctNumber
  238. * @return
  239. */
  240. // public Integer verbalScore(Integer number, Integer userNumber, Integer difficultScore, Integer correctNumber){
  241. // return verbalA * correctNumber / number + verbalB * difficultScore / userNumber;
  242. // }
  243. /**
  244. * Verbal分数计算:23.59 + 平均正确率*29.6+平均难度*1.72
  245. * @param number
  246. * @param userNumber
  247. * @param difficultScore
  248. * @param correctNumber
  249. * @return
  250. */
  251. public Integer verbalScore(Integer number, Integer userNumber, float difficultScore, Integer correctNumber){
  252. int score = (int)Math.round(23.59 + 29.6 * correctNumber / number + 1.72 * difficultScore / userNumber);
  253. if (score > scoreMax) return scoreMax;
  254. if (score < scoreMin) return scoreMin;
  255. return score;
  256. }
  257. /**
  258. * IR分数计算:最高8分
  259. * @param number
  260. * @param userNumber
  261. * @param difficultScore
  262. * @param correctNumber
  263. * @return
  264. */
  265. public int irScore(Integer number, Integer userNumber, Integer difficultScore, Integer correctNumber){
  266. switch(correctNumber){
  267. case 0:
  268. case 1:
  269. return 1;
  270. case 2:
  271. return 2;
  272. case 3:
  273. case 4:
  274. return 3;
  275. case 5:
  276. return 4;
  277. case 6:
  278. return 5;
  279. case 7:
  280. return 6;
  281. case 8:
  282. return 7;
  283. case 9:
  284. default:
  285. return 8;
  286. }
  287. }
  288. /**
  289. * avg diff correct= [500 + 10*(1-0.7)+500+10*(1-0.6)+500+10*(1-0.5)
  290. * +600+10*(1-0.4)+600+10*(1-0.7)+700+10*(1-0.1)+700+10*(1-0.9)] / (3+2+2)
  291. * { all: '' }
  292. * @param totalNumber
  293. * @param totalCorrect
  294. * @param questionDifficult
  295. * @return
  296. */
  297. public float diffScore(Integer totalNumber, Integer totalCorrect, QuestionDifficult questionDifficult){
  298. Setting setting = settingService.getByKey(SettingKey.SCORE_SWITCH);
  299. JSONObject value = setting.getValue();
  300. if (value.getBooleanValue("all")){
  301. Integer difficultScore = QuestionDifficult.GetScore(questionDifficult);
  302. return difficultScore + 10 * (1 - (float)totalCorrect / totalNumber);
  303. }else{
  304. return QuestionDifficult.GetScoreBase(questionDifficult);
  305. }
  306. }
  307. /**
  308. * 当这个结果低于500的时候统一显示为500,
  309. * 高于500时,是多少就显示多少,且必须为10的倍数,722=720,754=750,756=760
  310. * 四舍五入
  311. * @param totalDiffScore
  312. * @param number
  313. * @return
  314. */
  315. public int avgDiffScore(float totalDiffScore, Integer number){
  316. int avg = (int)(totalDiffScore / number);
  317. if (avg < 500){
  318. return 500;
  319. }
  320. return (int) (Math.round((int)(avg / 10)) * 10);
  321. }
  322. /**
  323. * 得出V小分和Q小分后根据总分-小分excel对应表(我方提供)算出最后考试的总分
  324. * @param quantScore
  325. * @param verbalScore
  326. * @return
  327. */
  328. public Rank totalScore(Integer quantScore, Integer verbalScore){
  329. Rank rank = rankService.search(quantScore, verbalScore);
  330. return rank != null ? rank : new Rank();
  331. }
  332. /**
  333. * 根据模考分数获取排名
  334. * @param score
  335. * @return
  336. */
  337. public Rank scoreRank(JSONObject score){
  338. Rank rank = rankService.search(score.getInteger("quant"), score.getInteger("verbal"));
  339. return rank != null ? rank : new Rank();
  340. }
  341. /**
  342. * 获取视频课程优惠文字说明:{video: {text:}}
  343. * @return
  344. */
  345. public String videoMoneyMessage(){
  346. Setting setting = settingService.getByKey(SettingKey.PROMOTE);
  347. JSONObject value = setting.getValue();
  348. JSONObject video = value.getJSONObject("video");
  349. return video.getString("text");
  350. }
  351. /**
  352. * 计算视频课程优惠:{video_list: [{"number":32,"percent":2}]}
  353. * @param list
  354. * @return
  355. */
  356. public Integer computeVideoMoney(List<UserOrderCheckout> list){
  357. Setting setting = settingService.getByKey(SettingKey.PROMOTE);
  358. JSONObject value = setting.getValue();
  359. JSONArray settings = value.getJSONArray("video_list");
  360. int max = 0;
  361. int maxIndex = -1;
  362. for(int i = 0; i < settings.size(); i++){
  363. JSONObject o = settings.getJSONObject(i);
  364. int number = o.getIntValue("number");
  365. if(number < list.size()){
  366. if (number > max){
  367. max = number;
  368. maxIndex = i;
  369. }
  370. }
  371. }
  372. if (maxIndex >= 0){
  373. JSONObject o = settings.getJSONObject(maxIndex);
  374. return o.getIntValue("percent");
  375. }else{
  376. return 100;
  377. }
  378. }
  379. /**
  380. * 计算1v1课程优惠:{vs_list: [{"number":32,"percent":2}]},单个课程计算
  381. * @param checkout
  382. * @return
  383. */
  384. public Integer computeVsMoney(UserOrderCheckout checkout){
  385. Setting setting = settingService.getByKey(SettingKey.PROMOTE);
  386. JSONObject value = setting.getValue();
  387. JSONArray settings = value.getJSONArray("vs_list");
  388. int max = 0;
  389. int maxIndex = -1;
  390. for(int i = 0; i < settings.size(); i++){
  391. JSONObject o = settings.getJSONObject(i);
  392. int number = o.getIntValue("number");
  393. if(number < checkout.getNumber()){
  394. if (number > max){
  395. max = number;
  396. maxIndex = i;
  397. }
  398. }
  399. }
  400. if (maxIndex >= 0){
  401. JSONObject o = settings.getJSONObject(maxIndex);
  402. return o.getIntValue("percent");
  403. }else{
  404. return 100;
  405. }
  406. }
  407. /**
  408. * @return
  409. */
  410. public String askTimeMessage(){
  411. return "{}小时内问答快速回复";
  412. }
  413. /**
  414. * @return
  415. */
  416. public String vsRecordMessage(){
  417. return "指定1v1辅导{}课时";
  418. }
  419. /**
  420. * @return
  421. */
  422. public String coachMessage(){
  423. return "课前1v1语音复习规划辅导";
  424. }
  425. /**
  426. * 计算回复时长:{ask_time: [{"money":32,"hour":2}]}
  427. * 单位:小时
  428. * @param totalMoney 课程总金额
  429. * @return
  430. */
  431. public JSONObject getAskTime(BigDecimal totalMoney){
  432. Setting setting = settingService.getByKey(SettingKey.PROMOTE);
  433. JSONObject value = setting.getValue();
  434. JSONArray settings = value.getJSONArray("ask_time");
  435. int max = 0;
  436. int maxIndex = -1;
  437. for(int i = 0; i < settings.size(); i++){
  438. JSONObject o = settings.getJSONObject(i);
  439. int money = o.getIntValue("money");
  440. if(money < totalMoney.intValue()){
  441. if (money > max){
  442. max = money;
  443. maxIndex = i;
  444. }
  445. }
  446. }
  447. if (maxIndex >= 0){
  448. JSONObject o = settings.getJSONObject(maxIndex);
  449. return o;
  450. }
  451. return null;
  452. }
  453. /**
  454. * 计算赠送1v1课时:{vs_record: [{"money":32,"number":2}]}
  455. * @param totalMoney 课程总金额
  456. * @return
  457. */
  458. public JSONObject getVsNumber(BigDecimal totalMoney){
  459. Setting setting = settingService.getByKey(SettingKey.PROMOTE);
  460. JSONObject value = setting.getValue();
  461. JSONArray settings = value.getJSONArray("vs_record");
  462. int max = 0;
  463. int maxIndex = -1;
  464. for(int i = 0; i < settings.size(); i++){
  465. JSONObject o = settings.getJSONObject(i);
  466. int money = o.getIntValue("money");
  467. if(money < totalMoney.intValue()){
  468. if (money > max){
  469. max = money;
  470. maxIndex = i;
  471. }
  472. }
  473. }
  474. if (maxIndex >= 0){
  475. JSONObject o = settings.getJSONObject(maxIndex);
  476. return o;
  477. }
  478. return null;
  479. }
  480. /**
  481. * 计算赠送满课时辅导:{toach: {number: 2}}
  482. * @param vsNumber 总课时数
  483. * @return
  484. */
  485. public Boolean getCoach(Integer vsNumber){
  486. Setting setting = settingService.getByKey(SettingKey.PROMOTE);
  487. JSONObject value = setting.getValue();
  488. JSONObject settings = value.getJSONObject("toach");
  489. if (vsNumber >= settings.getIntValue("number")){
  490. return true;
  491. }else{
  492. return false;
  493. }
  494. }
  495. /**
  496. * 获取服务对应价格: { image: , package: [{price: }] }
  497. * @param service
  498. * @param param
  499. * @return
  500. */
  501. public Integer getServicePrice(String service, String param){
  502. ServiceKey serviceKey = ServiceKey.ValueOf(service);
  503. Integer index = 0;
  504. if(serviceKey == ServiceKey.VIP){
  505. ServiceVipKey vipKey = ServiceVipKey.ValueOf(param);
  506. index = vipKey.index;
  507. }
  508. Setting setting = settingService.getByKey(SettingKey.WithService(serviceKey));
  509. JSONObject value = setting.getValue();
  510. JSONArray p = value.getJSONArray("package");
  511. JSONObject info = p.getJSONObject(index);
  512. if (info == null){
  513. return null;
  514. }else{
  515. return info.getIntValue("price");
  516. }
  517. }
  518. }