WebScaleResultController.java 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. package com.rf.psychological.scale.rest;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONArray;
  4. import com.alibaba.fastjson.JSONObject;
  5. import com.alibaba.fastjson.serializer.SerializerFeature;
  6. import com.fasterxml.jackson.databind.ObjectMapper;
  7. import com.rf.psychological.base.rest.BaseController;
  8. import com.rf.psychological.dao.dto.InstitutionRecordingUsersDTO;
  9. import com.rf.psychological.enums.UserRole;
  10. import com.rf.psychological.file.excel.ExcelClass;
  11. import com.rf.psychological.dao.model.*;
  12. import com.rf.psychological.institution.service.InstitutionService;
  13. import com.rf.psychological.opLog.annotation.OperationLogAnnotation;
  14. import com.rf.psychological.plan.dao.model.TestPlanEntity;
  15. import com.rf.psychological.plan.dao.model.TestPlanUserEntity;
  16. import com.rf.psychological.plan.service.TestPlanContendService;
  17. import com.rf.psychological.plan.service.TestPlanService;
  18. import com.rf.psychological.plan.service.TestPlanUserService;
  19. import com.rf.psychological.scale.dao.dto.SubjectEntityDto2;
  20. import com.rf.psychological.scale.dao.model.*;
  21. import com.rf.psychological.scale.service.*;
  22. import com.rf.psychological.security.AesEncryptUtils;
  23. import com.rf.psychological.security.SafetyProcess;
  24. import com.rf.psychological.user.dao.model.UserEntity;
  25. import com.rf.psychological.user.dao.model.UserFileEntity;
  26. import com.rf.psychological.user.service.UserFileService;
  27. import com.rf.psychological.user.service.UserService;
  28. import com.rf.psychological.utils.*;
  29. import com.rf.psychological.utils.DateUtil;
  30. import com.rf.psychological.wxpay.model.PromotionInfo;
  31. import com.rf.psychological.wxpay.service.PromotionInfoService;
  32. import com.rf.psychological.wxpay.service.WxPayService;
  33. import io.swagger.annotations.Api;
  34. import io.swagger.annotations.ApiOperation;
  35. import jodd.util.StringUtil;
  36. import lombok.SneakyThrows;
  37. import lombok.extern.slf4j.Slf4j;
  38. import org.apache.commons.io.FileUtils;
  39. import org.apache.commons.lang.StringUtils;
  40. import org.apache.poi.ss.usermodel.*;
  41. import org.apache.poi.xssf.usermodel.XSSFSheet;
  42. import org.apache.poi.xssf.usermodel.XSSFWorkbook;
  43. import org.springframework.beans.factory.annotation.Autowired;
  44. import org.springframework.beans.factory.annotation.Value;
  45. import org.springframework.transaction.annotation.Transactional;
  46. import org.springframework.web.bind.annotation.*;
  47. import javax.servlet.http.HttpServletResponse;
  48. import java.io.*;
  49. import java.lang.reflect.Constructor;
  50. import java.lang.reflect.InvocationTargetException;
  51. import java.lang.reflect.Method;
  52. import java.nio.file.Files;
  53. import java.nio.file.Path;
  54. import java.nio.file.Paths;
  55. import java.text.DecimalFormat;
  56. import java.text.SimpleDateFormat;
  57. import java.util.*;
  58. import java.util.stream.Collectors;
  59. import java.util.stream.Stream;
  60. import java.util.zip.ZipEntry;
  61. import java.util.zip.ZipOutputStream;
  62. import static com.rf.psychological.utils.FileUtil.html2pdf;
  63. /**
  64. * @author zsf
  65. * {@code @description:接收测试结果计算结果--量表测试}
  66. * @date 2021/1/21 16:07
  67. */
  68. @Slf4j
  69. @RestController
  70. @RequestMapping("/result")
  71. @Api(tags = "web端量表测试结果计算")
  72. public class WebScaleResultController extends BaseController {
  73. @Autowired
  74. private SubjectService subjectService;
  75. @Autowired
  76. private UserRecordService userRecordService;
  77. @Autowired
  78. private UserService userService;
  79. @Autowired
  80. private ScaleService scaleService;
  81. @Autowired
  82. private AnswerService answerService;
  83. @Autowired
  84. private ScaleMarksService scaleMarksService;
  85. @Autowired
  86. private DimensionService dimensionService;
  87. @Autowired
  88. private ScaleConfigService scaleConfigService;
  89. @Autowired
  90. private ScaleScoringVersion scaleScoringVersion;
  91. @Autowired
  92. private TestPlanContendService testPlanContendService;
  93. @Autowired
  94. private TestPlanUserService testPlanUserService;
  95. @Autowired
  96. private TestPlanService testPlanService;
  97. @Autowired
  98. private WarnService warnService;
  99. @Autowired
  100. private DimensionOrgService dimensionOrgService;
  101. @Autowired
  102. private InstitutionService institutionService;
  103. @Autowired
  104. private ScaleDetailsService scaleDetailsService;
  105. @SafetyProcess
  106. @Transactional(rollbackFor = Exception.class)
  107. @OperationLogAnnotation("保存量表记录")
  108. @PostMapping("/{flag}")
  109. @ApiOperation(value = "flag:量表标志,jsonObject:测试结果")
  110. public Result completeTest(@RequestBody String json, @PathVariable String flag) throws Exception {
  111. String data = AesEncryptUtils.decrypt(JSONObject.parseObject(json).getString("data"));
  112. JSONObject jsonObject = JSONObject.parseObject(data);
  113. System.out.println("----------------result-------------------");
  114. System.out.println(jsonObject);
  115. String testPlanId = "0";
  116. UserEntity userEntity = this.userService.getOne(jsonObject.getString("userId"));
  117. if (userEntity == null) {
  118. return fail("用户不存在");
  119. }
  120. String userName = userEntity.getPetName();
  121. String userBirthday = userEntity.getBirthday();
  122. String userSex = userEntity.getGender();
  123. String institutionNo = userEntity.getInstitutionNo();
  124. //提交是校验测试次数是否达到上限
  125. if (institutionService.checkTestNum(institutionNo)){
  126. return fail(Constant.DEFAULT_VALUE_ZERO,"测试次数已达上限,请联系机构管理员");
  127. }
  128. if (userSex.equals("0")) {
  129. userSex = "男";
  130. } else if (userSex.equals("1")) {
  131. userSex = "女";
  132. }else {
  133. userSex = "性别";
  134. }
  135. String phone = userEntity.getPhone();
  136. if (jsonObject.containsKey("testPlanId") && StringUtils.isNotBlank(jsonObject.getString("testPlanId"))) {
  137. testPlanId = jsonObject.getString("testPlanId");
  138. TestPlanEntity testPlanEntity = this.testPlanService.findById(testPlanId);
  139. if (testPlanEntity == null) {
  140. return fail("测试计划不存在");
  141. }
  142. if (testPlanEntity.getStatus() == Constant.TEST_PLAN_STATUS_UNSTART)
  143. return fail("测试计划尚未开始");
  144. if (testPlanEntity.getStatus() < Constant.TEST_PLAN_STATUS_UNSTART)
  145. return fail("测试计划已结束");
  146. UserRecordEntity checkTestPlanId = userRecordService.findByPhoneAndTestPlanIdAndInstitution(institutionNo, phone, testPlanId, flag);
  147. if (checkTestPlanId != null) {
  148. return fail("", "该测试已完成");
  149. }
  150. //更新测试计划状态
  151. updateUserPlanStatus(testPlanId, institutionNo, phone, flag, userEntity.getId(), testPlanContendService, testPlanUserService);
  152. }
  153. String testTime = new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒").format(new Date());
  154. if (jsonObject.containsKey("startTime")) {
  155. testTime = new SimpleDateFormat("yyyy年MM月dd日HH时mm分ss秒").format(jsonObject.getDate("startTime"));
  156. }
  157. String fileName = userName + Constant.SPLIT_CHAR + userBirthday + Constant.SPLIT_CHAR + userSex + Constant.SPLIT_CHAR + testTime;
  158. String testResult = "";
  159. JSONArray jsonArray = jsonObject.getJSONArray("scale_result");
  160. // 创建返回的json对象
  161. JSONObject resultJson = new JSONObject(true);
  162. //根据flag获取全部选项
  163. List<ScaleEntity> scaleEntities = this.scaleService.getScaleByFlag(flag);
  164. //根据flag获取全部答案
  165. List<AnswerEntity> answerEntities = this.answerService.getAnswerByFlag(flag);
  166. //根据flag获取全部评分规则
  167. List<ScaleMarksEntity> scaleMarksEntities = this.scaleMarksService.getScaleMarksByFlag(flag);
  168. //根据flag获取全部维度信息
  169. List<DimensionEntity> dimensionEntities = this.dimensionService.getDimensionByFlag(flag);
  170. //根据flag获取量表名称
  171. //List<SubjectEntity> subjectEntities = this.subjectService.getSubjectByFlag(flag);
  172. ScaleDetailsEntity detailsEntity = this.scaleDetailsService.getSubjectDetailsByFlag(flag);
  173. resultJson.put("scaleEntities", scaleEntities);
  174. resultJson.put("answerEntities", answerEntities);
  175. resultJson.put("scaleMarksEntities", scaleMarksEntities);
  176. resultJson.put("dimensionEntities", dimensionEntities);
  177. //性别,用于MMPI量表计算
  178. resultJson.put("gender", userEntity.getGender());
  179. //机构编号,用于预警信息判断
  180. resultJson.put("institutionNo", institutionNo);
  181. //用户id用于预警信息保存
  182. resultJson.put("userId", userEntity.getId());
  183. resultJson.put("dimensionOrgService", dimensionOrgService);
  184. //答题结果列表
  185. List<ScaleEntity> dataList = jsonArray.toJavaList(ScaleEntity.class);
  186. ScaleConfigEntity scaleConfigByFlag = scaleConfigService.findScaleConfigByFlag(flag);
  187. String className = (scaleConfigByFlag == null ? "com.rf.psychological.scale.resultBusiness.scaleResult.COMMONScale" : scaleConfigByFlag.getResultConfig());
  188. Class<?> cls; // 取得Class对象
  189. try {
  190. cls = Class.forName(className);
  191. Constructor<?> cons = cls.getConstructor(JSONArray.class, JSONObject.class);
  192. // Object obj = cons.newInstance(); // 为构造方法传递参数
  193. Object obj = cons.newInstance(jsonArray, resultJson);
  194. //cls.getDeclaredMethods();
  195. Method method = null;
  196. //通过配置文件获取量表计分规则使用的版本
  197. ObjectMapper objectMapper = new ObjectMapper();
  198. String str = objectMapper.writeValueAsString(scaleScoringVersion.getVersionmap());
  199. HashMap mapScale = JSON.parseObject(str, HashMap.class);
  200. Set<Map.Entry<String, String>> en = mapScale.entrySet();
  201. for (Map.Entry<String, String> entry : en) {
  202. String[] flags = entry.getValue().split(", ");
  203. for (String obtainFlag : flags) {
  204. if (obtainFlag.equals(flag)) {
  205. method = cls.getDeclaredMethod(entry.getKey());
  206. break;
  207. }
  208. }
  209. }
  210. if (method == null) {
  211. method = cls.getDeclaredMethod("scaleCalculate");
  212. }
  213. resultJson = (JSONObject) method.invoke(obj);
  214. } catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InstantiationException |
  215. InvocationTargetException e) {
  216. e.printStackTrace();
  217. }
  218. JSONObject dimensionScore = null;
  219. if (resultJson.getJSONObject("resultJson").containsKey("dimensionScoreMap")) {
  220. dimensionScore = resultJson.getJSONObject("resultJson").getJSONObject("dimensionScoreMap");
  221. resultJson.getJSONObject("resultJson").remove("dimensionScoreMap");
  222. }
  223. resultJson.getJSONObject("resultJson").remove("scaleEntities");
  224. resultJson.getJSONObject("resultJson").remove("answerEntities");
  225. resultJson.getJSONObject("resultJson").remove("scaleMarksEntities");
  226. resultJson.getJSONObject("resultJson").remove("dimensionEntities");
  227. resultJson.getJSONObject("resultJson").remove("gender");
  228. resultJson.getJSONObject("resultJson").remove("institutionNo");
  229. resultJson.getJSONObject("resultJson").remove("userId");
  230. resultJson.getJSONObject("resultJson").remove("dimensionOrgService");
  231. if (resultJson.getJSONObject("resultJson").containsKey("resultJson") && resultJson.getJSONObject("resultJson").get("测试结果指导").equals("请认真按照实际情况如实回答")) {
  232. resultJson = resultJson.getJSONObject("resultJson");
  233. return success(resultJson, "完成");
  234. }
  235. fileName = fileName + "-" + detailsEntity.getScaleName() + ".xlsx";
  236. //导出文件
  237. ExcelUtil.createExcelFile(ScaleEntity.class, dataList, (List<Map<String, String>>) resultJson.get("resultMapList"), new ExcelClass().contentExcel(), fileName, detailsEntity.getScaleName());
  238. //计算结果
  239. JSONArray dbJsonList = new JSONArray();
  240. JSONObject dbJson = new JSONObject(true);
  241. boolean versionFlag = false;
  242. Map<String, Object> newResultJson = null;
  243. if (!resultJson.containsKey("newResultJson")) {
  244. dbJson.put("version", 1.0);
  245. dbJson.put("newTableContext", "");
  246. } else {
  247. newResultJson = (Map<String, Object>) resultJson.get("newResultJson");
  248. dbJson.put("version", 2.0);
  249. dbJson.put("newTableContext", newResultJson);
  250. versionFlag = true;
  251. }
  252. resultJson = resultJson.getJSONObject("resultJson");
  253. List<WarnEntity> warnEntityList = new ArrayList<WarnEntity>();
  254. if(resultJson.containsKey("warnEntityList")) {
  255. warnEntityList = resultJson.getJSONArray("warnEntityList").toJavaList(WarnEntity.class);
  256. resultJson.remove("warnEntityList");
  257. }
  258. // 获取JSON第一层所有的key
  259. Set<String> keys = resultJson.keySet();
  260. //列名
  261. List colNames = new ArrayList();
  262. colNames.add("项目");
  263. colNames.add("内容");
  264. dbJson.put("colNames", colNames);
  265. JSONArray tableContext = new JSONArray();
  266. // 获取第一层每个key对应的值 的类型
  267. for (String key : keys) {
  268. //列值
  269. List colValue = new ArrayList();
  270. colValue.add(resultJson.get(key));
  271. JSONObject row = new JSONObject();
  272. row.put("name", key);
  273. row.put("value", colValue);
  274. tableContext.add(row);
  275. }
  276. dbJson.put("tableContext", tableContext);
  277. dbJsonList.add(dbJson);
  278. //测试记录
  279. int i = 1;
  280. // 获取第一层每个key对应的值 的类型
  281. for (String key : keys) {
  282. if (i == keys.size()) {
  283. testResult += key + ":" + resultJson.get(key);
  284. } else {
  285. testResult += key + ":" + resultJson.get(key) + ";";
  286. }
  287. i++;
  288. }
  289. String filePath;
  290. filePath = "./心理检测/检测结果/" + new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + "/" + detailsEntity.getScaleName() + "/" + fileName;
  291. UserRecordEntity userRecordEntity = testRecord(flag, phone, institutionNo, testTime, filePath, JSON.toJSONString(dbJsonList, SerializerFeature.DisableCircularReferenceDetect), detailsEntity.getScaleName(), JSON.toJSONString(dataList, SerializerFeature.DisableCircularReferenceDetect), testResult, testPlanId);
  292. //预警信息处理
  293. if (dimensionScore != null && dimensionScore.size() > 0) {
  294. if (dimensionEntities != null && dimensionEntities.size() > 0) {
  295. for (int y = 0; y < dimensionEntities.size(); y++) {
  296. //计算维度逻辑是否需要预警
  297. DimensionOrgEntity byInstitutionNoAndDimensionId = dimensionOrgService.findByInstitutionNoAndDimensionId(institutionNo, dimensionEntities.get(y).getId());
  298. if (byInstitutionNoAndDimensionId != null) {
  299. switch (byInstitutionNoAndDimensionId.getLogic()) {
  300. case "lt":
  301. if (dimensionScore.getDouble(dimensionEntities.get(y).getId()) < Double.parseDouble(byInstitutionNoAndDimensionId.getThreshold())) {
  302. //添加预警信息
  303. warnEntityList.add(createWarnEntry(dimensionEntities.get(y).getFlag(), institutionNo, jsonObject.getString("userId"), dimensionEntities.get(y).getId(), dimensionScore.getDouble(dimensionEntities.get(y).getId())));
  304. }
  305. break;
  306. case "le":
  307. if (dimensionScore.getDouble(dimensionEntities.get(y).getId()) <= Double.parseDouble(byInstitutionNoAndDimensionId.getThreshold())) {
  308. //添加预警信息
  309. warnEntityList.add(createWarnEntry(dimensionEntities.get(y).getFlag(), institutionNo, jsonObject.getString("userId"), dimensionEntities.get(y).getId(), dimensionScore.getDouble(dimensionEntities.get(y).getId())));
  310. }
  311. break;
  312. case "eq":
  313. if (dimensionScore.getDouble(dimensionEntities.get(y).getId()) == Double.parseDouble(byInstitutionNoAndDimensionId.getThreshold())) {
  314. //添加预警信息
  315. warnEntityList.add(createWarnEntry(dimensionEntities.get(y).getFlag(), institutionNo, jsonObject.getString("userId"), dimensionEntities.get(y).getId(), dimensionScore.getDouble(dimensionEntities.get(y).getId())));
  316. }
  317. break;
  318. case "ne":
  319. if (dimensionScore.getDouble(dimensionEntities.get(y).getId()) != Double.parseDouble(byInstitutionNoAndDimensionId.getThreshold())) {
  320. //添加预警信息
  321. warnEntityList.add(createWarnEntry(dimensionEntities.get(y).getFlag(), institutionNo, jsonObject.getString("userId"), dimensionEntities.get(y).getId(), dimensionScore.getDouble(dimensionEntities.get(y).getId())));
  322. }
  323. break;
  324. case "ge":
  325. if (dimensionScore.getDouble(dimensionEntities.get(y).getId()) >= Double.parseDouble(byInstitutionNoAndDimensionId.getThreshold())) {
  326. //添加预警信息
  327. warnEntityList.add(createWarnEntry(dimensionEntities.get(y).getFlag(), institutionNo, jsonObject.getString("userId"), dimensionEntities.get(y).getId(), dimensionScore.getDouble(dimensionEntities.get(y).getId())));
  328. }
  329. break;
  330. case "gt":
  331. if (dimensionScore.getDouble(dimensionEntities.get(y).getId()) > Double.parseDouble(byInstitutionNoAndDimensionId.getThreshold())) {
  332. //添加预警信息
  333. warnEntityList.add(createWarnEntry(dimensionEntities.get(y).getFlag(), institutionNo, jsonObject.getString("userId"), dimensionEntities.get(y).getId(), dimensionScore.getDouble(dimensionEntities.get(y).getId())));
  334. }
  335. break;
  336. }
  337. }
  338. }
  339. // resultJson.put("warnEntityList",warnEntityList);
  340. }
  341. if (warnEntityList.size() > 0) {
  342. warnEntityList.forEach(item -> {
  343. item.setResultId(userRecordEntity.getId());
  344. item.setCreateTime(userRecordEntity.getTestDate());
  345. DimensionOrgEntity dimensionOrgEntity = this.dimensionOrgService.findByInstitutionNoAndDimensionId(institutionNo,item.getDimensionId());
  346. item.setThreshold(dimensionOrgEntity.getThreshold());
  347. item.setLogic(dimensionOrgEntity.getLogic());
  348. this.warnService.save(item);
  349. });
  350. }
  351. }
  352. //获取下测试记录
  353. userRecordService.getUserRecordById(userRecordEntity.getId());
  354. return success(userRecordEntity.getId(), "完成");
  355. }
  356. private UserRecordEntity testRecord(String flag, String phone, String institutionNo, String testTime, String fileName, String testResult, String name, String dataList, String testResults, String testPlanId) {
  357. //根据flag记录测试数
  358. this.subjectService.addTestNum(flag);
  359. //添加用户测试记录
  360. UserRecordEntity userRecordEntity = new UserRecordEntity();
  361. userRecordEntity.setFlag(flag);
  362. userRecordEntity.setPhone(phone);
  363. userRecordEntity.setInstitutionNo(institutionNo);
  364. userRecordEntity.setTestDate(testTime);
  365. userRecordEntity.setTestResult(testResult);
  366. userRecordEntity.setType("0");
  367. userRecordEntity.setFileName(fileName);
  368. userRecordEntity.setName(name);
  369. if (!flag.equals("20230327160727")) {
  370. userRecordEntity.setTestRecord(dataList);
  371. }
  372. userRecordEntity.setTestResults(testResults);
  373. if (testPlanId == null || testPlanId.equals("")) {
  374. userRecordEntity.setTestPlanId("0");
  375. } else {
  376. userRecordEntity.setTestPlanId(testPlanId);
  377. }
  378. this.userRecordService.save(userRecordEntity);
  379. return userRecordEntity;
  380. }
  381. public static void updateUserPlanStatus(String testPlanId, String institutionNo, String phone, String flag, String uId,TestPlanContendService testPlanContendService,TestPlanUserService testPlanUserService){
  382. if (!"0".equals(testPlanId) && !StringUtils.isEmpty(testPlanId)) {
  383. //检查测试内容里的任务是否完成
  384. //测试计划任务总数
  385. int contentCount = testPlanContendService.countContent(testPlanId);
  386. //用户已完成测试总数
  387. int completedCount = testPlanContendService.getUserDoTestPlanContendNum(institutionNo,phone,testPlanId)+1;
  388. if(contentCount == completedCount){
  389. //更新用户状态为完成状态
  390. Optional<TestPlanUserEntity> testPlanUserByTestIdAndUserId = testPlanUserService.findTestPlanUserByTestIdAndUserId(testPlanId, uId);
  391. TestPlanUserEntity entity = testPlanUserByTestIdAndUserId.orElse(null);
  392. if(entity != null){
  393. entity.setIsComplete(Constant.USER_PLAN_STATUS_COMPLETED);
  394. testPlanUserService.save(entity);
  395. }
  396. }
  397. }
  398. }
  399. private WarnEntity createWarnEntry(String flag, String institutionNo, String userId, String id, double score) {
  400. WarnEntity warn = new WarnEntity();
  401. warn.setFlag(flag);
  402. warn.setInstitutionNo(institutionNo);
  403. warn.setUserId(userId);
  404. warn.setDimensionId(id);
  405. warn.setScore(String.valueOf(score));
  406. return warn;
  407. }
  408. }