UserEvaluationApiController.java 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  1. package com.goafanti.evaluation.controller;
  2. import com.alibaba.fastjson.JSON;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.goafanti.common.bo.Result;
  5. import com.goafanti.common.constant.ErrorConstants;
  6. import com.goafanti.common.controller.BaseApiController;
  7. import com.goafanti.common.model.DistrictGlossory;
  8. import com.goafanti.common.model.IndustryCategory;
  9. import com.goafanti.common.model.ValueEvaluation;
  10. import com.goafanti.common.service.DistrictGlossoryService;
  11. import com.goafanti.common.service.IndustryCategoryService;
  12. import com.goafanti.common.utils.HttpUtils;
  13. import com.goafanti.common.utils.LoggerUtils;
  14. import com.goafanti.core.shiro.token.TokenManager;
  15. import com.goafanti.evaluation.bo.*;
  16. import com.goafanti.evaluation.enums.ProfitRate;
  17. import com.goafanti.evaluation.service.ValueEvaluationService;
  18. import org.apache.commons.lang3.StringUtils;
  19. import org.slf4j.Logger;
  20. import org.slf4j.LoggerFactory;
  21. import org.springframework.beans.factory.annotation.Autowired;
  22. import org.springframework.util.Assert;
  23. import org.springframework.validation.BindingResult;
  24. import org.springframework.web.bind.annotation.PathVariable;
  25. import org.springframework.web.bind.annotation.RequestMapping;
  26. import org.springframework.web.bind.annotation.RequestMethod;
  27. import org.springframework.web.bind.annotation.RestController;
  28. import javax.validation.Valid;
  29. import java.math.BigDecimal;
  30. import java.math.MathContext;
  31. import java.math.RoundingMode;
  32. import java.util.ArrayList;
  33. import java.util.HashMap;
  34. import java.util.List;
  35. import java.util.Map;
  36. import java.util.stream.Collectors;
  37. import java.util.stream.Stream;
  38. @RestController
  39. @RequestMapping(value = "/api/user/evaluate")
  40. public class UserEvaluationApiController extends BaseApiController {
  41. // private static final String GOVERNMENT_LOAN_ROR = "government_loan_ror"; //政府贷款利率
  42. private static final String GOVERNMENT_LOAN_ROR = "4.6"; //政府贷款利率
  43. private static final Logger logger = LoggerFactory.getLogger(UserEvaluationApiController.class);
  44. private static final MathContext DEFAULT_PRECISION = new MathContext(4, RoundingMode.HALF_UP); //默认精度
  45. private static final String STEP1 = "0";
  46. private static final String STEP2 = "1";
  47. private static final String STEP3 = "2";
  48. private static final String STEP4 = "3";
  49. private static final String STEP5 = "4";
  50. private static final String STEP6 = "5";
  51. private static final String STEP7 = "6";
  52. private static final Integer[] SCORES = new Integer[] { 100, 80, 60, 40, 20, 0 };
  53. private static final Integer[] DISCOUNT_SCORES = new Integer[] { 1, 2, 3, 4, 5 }; //折扣分数
  54. private static final BigDecimal MIN_RATE = new BigDecimal(2); //最小速率
  55. private static final BigDecimal MAX_RATE = new BigDecimal(6); //最大速率
  56. private static final BigDecimal HUNDRED = new BigDecimal(100);
  57. private static final BigDecimal PERCENTAGE = new BigDecimal(0.01, DEFAULT_PRECISION);//百分比
  58. @Autowired
  59. ValueEvaluationService valueEvaluationService; //价值评估
  60. @Autowired
  61. private DistrictGlossoryService districtGlossoryService; //地区词汇
  62. @Autowired
  63. private IndustryCategoryService industryCategoryService; //行业分类
  64. /**
  65. * 新增评估数据
  66. * @return
  67. */
  68. @RequestMapping(value = "/create", method = RequestMethod.GET)
  69. public Result create() {
  70. ValueEvaluation ve = new ValueEvaluation();
  71. ve.setUid(TokenManager.getUserId());
  72. ve.setStep(0);
  73. ve.setValue(0l);
  74. ve.setLog("{}");
  75. valueEvaluationService.insert(ve);
  76. return new Result(ve.getId().toString());
  77. }
  78. /**
  79. * 通过用户id获得列表数据
  80. * @param pageNo
  81. * @param pageSize
  82. * @return
  83. */
  84. @RequestMapping(value = "/list", method = RequestMethod.GET)
  85. public Result list(String pageNo, String pageSize) {
  86. return new Result().data(valueEvaluationService.list(handlePageNo(pageNo), handlePageSize(pageSize)));
  87. }
  88. /**
  89. * 根据用户和id获得评估信息
  90. * @param id
  91. * @return
  92. */
  93. @RequestMapping(value = "/info/{id}", method = RequestMethod.GET, produces = "application/json;charset=UTF-8")
  94. public Result info(@PathVariable String id) {
  95. Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID);
  96. ValueEvaluation ve = valueEvaluationService.getMyEvaluation(Long.valueOf(id));
  97. Assert.notNull(ve, ErrorConstants.EVALUATE_ID);
  98. Map<String, Object> res = new HashMap<>();
  99. res.put("name", ve.getName());
  100. res.put("step", ve.getStep());
  101. res.put("value", ve.getValue());
  102. res.put("steps", JSON.parse(ve.getLog()));
  103. return new Result().data(res);
  104. }
  105. /**
  106. * 删除评估信息(可批量)
  107. * @param ids
  108. * @return
  109. */
  110. @RequestMapping(value = "/remove", method = RequestMethod.POST)
  111. public Result remove(String ids) {
  112. Assert.isTrue(StringUtils.isNotBlank(ids), ErrorConstants.EVALUATE_PARAM);
  113. Result res = new Result();
  114. List<Long> idList = new ArrayList<>();
  115. String[] idArr = ids.split(",");
  116. for (String id : idArr) {
  117. Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_PARAM);
  118. idList.add(Long.valueOf(id));
  119. }
  120. res.data(valueEvaluationService.deleteMySteps(idList));
  121. return res;
  122. }
  123. @RequestMapping(value = "/step1", method = RequestMethod.POST)
  124. public Result step1(String id, @Valid Step1 data, BindingResult bindingResult) {
  125. Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID);
  126. Result res = new Result();
  127. if (handleBindingError(res, bindingResult)) {
  128. return res;
  129. }
  130. updateSteps(data, 1, "0", res, id);
  131. return res;
  132. }
  133. @RequestMapping(value = "/step2", method = RequestMethod.POST)
  134. public Result step2(String id, @Valid Step2 data, BindingResult bindingResult) {
  135. Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID);
  136. Result res = new Result();
  137. if (handleBindingError(res, bindingResult)) {
  138. return res;
  139. }
  140. updateSteps(data, 2, STEP2, res, id);
  141. return res;
  142. }
  143. @RequestMapping(value = "/step3", method = RequestMethod.POST)
  144. public Result step3(String id, @Valid Step3 data, BindingResult bindingResult) {
  145. Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID);
  146. Result res = new Result();
  147. if (handleBindingError(res, bindingResult)) {
  148. return res;
  149. }
  150. updateSteps(data, 3, STEP3, res, id);
  151. return res;
  152. }
  153. /**
  154. * 到第4步时验证hasIncome为2时加入年收入
  155. * @param id
  156. * @param hasIncome
  157. * @param incomes
  158. * @return
  159. */
  160. @RequestMapping(value = "/step4", method = RequestMethod.POST)
  161. public Result step4(String id, String hasIncome, String incomes) {
  162. Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID);
  163. Result res = new Result();
  164. Step4 step = new Step4(); //年收入(年份,收入,利润)
  165. try {
  166. step.setHasIncome(Integer.valueOf(hasIncome));
  167. if (step.getHasIncome().equals(2)) {
  168. List<YearIncome> ja = JSON.parseArray(incomes, YearIncome.class);
  169. if (ja.size() != 3) {
  170. res.error(buildError(ErrorConstants.EVALUATE_PARAM));
  171. } else {
  172. step.setIncomes(ja);
  173. }
  174. }
  175. } catch (Exception e) {
  176. res.error(buildError(ErrorConstants.EVALUATE_PARAM));
  177. }
  178. if (res.getError().isEmpty()) {
  179. updateSteps(step, 4, STEP4, res, id);
  180. }
  181. return res;
  182. }
  183. @RequestMapping(value = "/step5", method = RequestMethod.POST)
  184. public Result step5(String id, String type, String forecastIncomes) {
  185. Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID);
  186. Result res = new Result();
  187. Step5 step = new Step5(); //预测收入(市场规模,市场利率,单价,销量,收入)
  188. try {
  189. step.setType(Integer.valueOf(type));
  190. List<ForecastIncome> ja = JSON.parseArray(forecastIncomes, ForecastIncome.class);
  191. if (ja.size() != 3) {
  192. res.error(buildError(ErrorConstants.EVALUATE_PARAM));
  193. } else {
  194. step.setForecastIncomes(ja);
  195. }
  196. } catch (Exception e) {
  197. res.error(buildError(ErrorConstants.EVALUATE_PARAM));
  198. }
  199. if (res.getError().isEmpty()) {
  200. updateSteps(step, 5, STEP5, res, id);
  201. }
  202. return res;
  203. }
  204. /**
  205. *
  206. * @param id
  207. * @return
  208. */
  209. @RequestMapping(value = "/step5/{id}", method = RequestMethod.GET)
  210. public Result step5Info(@PathVariable String id) {
  211. Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID);
  212. Result res = new Result();
  213. ValueEvaluation ve = valueEvaluationService.getMyEvaluation(Long.valueOf(id));
  214. try {
  215. JSONObject jo = JSON.parseObject(ve.getLog());
  216. Step4 step4 = ((JSON) jo.get(STEP4)).toJavaObject(Step4.class);
  217. if (step4.getHasIncome().equals(2)) {
  218. Step1 step1 = ((JSON) jo.get(STEP1)).toJavaObject(Step1.class);
  219. res.data(calcForecastIncome(step4.getIncomes(), getIndustryCategoryValue(step1)));
  220. }
  221. } catch (Exception e) {
  222. res.error(buildError(ErrorConstants.EVALUATE_PARAM));
  223. }
  224. return res;
  225. }
  226. @RequestMapping(value = "/step6", method = RequestMethod.POST)
  227. public Result step6(String id, @Valid Step6 data, BindingResult bindingResult) {
  228. Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID);
  229. Result res = new Result();
  230. if (handleBindingError(res, bindingResult)) {
  231. return res;
  232. }
  233. updateSteps(data, 6, STEP6, res, id);
  234. return res;
  235. }
  236. @RequestMapping(value = "/step7", method = RequestMethod.POST)
  237. public Result step7(String id, @Valid Step7 data, BindingResult bindingResult) {
  238. Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID);
  239. Result res = new Result();
  240. if (handleBindingError(res, bindingResult)) {
  241. return res;
  242. }
  243. updateSteps(data, 7, STEP7, res, id);
  244. return res;
  245. }
  246. @RequestMapping(value = "/calc/{id}", method = RequestMethod.GET)
  247. public Result calc(@PathVariable String id) {
  248. Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID);
  249. Result res = new Result();
  250. ValueEvaluation ve = valueEvaluationService.getMyEvaluation(Long.valueOf(id));
  251. if (ve == null || ve.getStep() < 7) {
  252. res.error(buildError(ErrorConstants.EVALUATE_ID));
  253. } else {
  254. Long value = calcValue(ve, new HashMap<>());
  255. res.data(value);
  256. ValueEvaluation upt = new ValueEvaluation();
  257. upt.setId(ve.getId());
  258. upt.setValue(value);
  259. valueEvaluationService.update(upt);//修改评估价值
  260. }
  261. return res;
  262. }
  263. @RequestMapping(value = "/report/{id}", method = RequestMethod.GET)
  264. public Result report(@PathVariable String id, String noCache) {
  265. Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID);
  266. Result res = new Result();
  267. ValueEvaluation ve = valueEvaluationService.getMyEvaluation(Long.valueOf(id));
  268. if (ve == null || ve.getStep() < 7) {
  269. res.error(buildError(ErrorConstants.EVALUATE_ID));
  270. } else {
  271. if (noCache != null) {
  272. /*sysDictService.clear(GOVERNMENT_LOAN_ROR);*/
  273. }
  274. Map<String, Object> map = new HashMap<>();
  275. map.put("customer", TokenManager.getUserToken().getNickname());
  276. calcValue(ve, map);
  277. res.data(map);
  278. }
  279. return res;
  280. }
  281. private Long calcValue(ValueEvaluation ve, Map<String, Object> result) {
  282. JSONObject log = JSON.parseObject(ve.getLog());
  283. Step1 step1 = ((JSON) log.get(STEP1)).toJavaObject(Step1.class);
  284. Step2 step2 = ((JSON) log.get(STEP2)).toJavaObject(Step2.class);
  285. Step3 step3 = ((JSON) log.get(STEP3)).toJavaObject(Step3.class);
  286. Step5 step5 = ((JSON) log.get(STEP5)).toJavaObject(Step5.class);
  287. Step6 step6 = ((JSON) log.get(STEP6)).toJavaObject(Step6.class);
  288. Step7 step7 = ((JSON) log.get(STEP7)).toJavaObject(Step7.class);
  289. Integer timeLeft = step1.getTimeLeft();
  290. timeLeft = timeLeft < 3 ? 3 : timeLeft > 10 ? 10 : timeLeft; // 剩余经济寿命最低3,最大10年
  291. Map<Integer, IndustryCategory> subs = getIndustryCates(step1.getIndustry());
  292. Map<Integer, DistrictGlossory> provinces = getProvinces();
  293. result.put("subIndustries", Stream.of(step1.getSubIndustry().split(",")).map(it -> {
  294. return subs.get(Integer.valueOf(it)).getName();
  295. }).collect(Collectors.joining(",")));
  296. result.put("transferArea", Stream.of(step1.getTransferArea().split(",")).map(it -> {
  297. return it.equals("0") ? "中国全境" : provinces.get(Integer.valueOf(it)).getName();
  298. }).collect(Collectors.joining(",")));
  299. result.put("industry", industryCategoryService.list(0).stream().filter(it -> {
  300. return it.getId().equals(step1.getIndustry());
  301. }).findFirst().get().getName());
  302. //获得行业分类平均值 -10.43
  303. BigDecimal industryAverageRate = getIndustryCategoryValue(step1, subs);
  304. //获取用户预测收入
  305. List<Long> userForecast = step5.getForecastIncomes().stream().map(fc -> {
  306. return fc.getIncome();
  307. }).collect(Collectors.toList());
  308. //使用行业平均值+预测收入+剩余年份做计算
  309. List<Long> sysForecast = calcSysForecast(userForecast, industryAverageRate, timeLeft);
  310. calcUserForecast(userForecast, timeLeft);
  311. List<Long> measuredForecast = calcMeasuredForecast(userForecast, sysForecast);
  312. Map<String, Integer> profitScores = getProfitScores(step2, step3);
  313. //用户预测+系统预测 >>位移获得值
  314. Map<String, Integer> discountRates = getDiscountRates(step7);
  315. //利润率
  316. BigDecimal profitRate = calcProfitRate(profitScores, step1.getIndustry(), result);
  317. BigDecimal governmentLoanRoR = new BigDecimal(GOVERNMENT_LOAN_ROR,
  318. MathContext.DECIMAL32);
  319. // BigDecimal governmentLoanRoR = new BigDecimal(0);
  320. BigDecimal taxRate = new BigDecimal(step6.getTaxRate());
  321. //折扣率
  322. BigDecimal discountRate = calcDiscountRate(discountRates, taxRate, governmentLoanRoR);
  323. result.put("userForecast", userForecast);
  324. result.put("sysForecast", sysForecast);
  325. result.put("measuredForecast", measuredForecast);
  326. result.put("profitRate", profitRate);
  327. result.put("governmentLoanRoR", governmentLoanRoR);
  328. result.put("industryAverageRate", industryAverageRate);
  329. result.put("discountRate", discountRate);
  330. result.put("benchmarkDate", step1.getBenchmarkDate());
  331. result.put("timeLeft", timeLeft);
  332. result.put("name", step1.getName());
  333. Long value = calcTotal(measuredForecast, profitRate, discountRate, result);
  334. result.put("value", value);
  335. result.put("log", log);
  336. return value;
  337. }
  338. /**
  339. *
  340. * @param measuredForecast 测量预测
  341. * @param profitRate 利润率
  342. * @param discountRate 折扣率
  343. * @param result
  344. * @return
  345. */
  346. private Long calcTotal(List<Long> measuredForecast, BigDecimal profitRate, BigDecimal discountRate,
  347. Map<String, Object> result) {
  348. List<Long> profitList = new ArrayList<>();
  349. BigDecimal total = BigDecimal.ZERO;
  350. BigDecimal incomeDiscount = BigDecimal.ZERO;
  351. double discountTerm = 0.5;
  352. int index = 0;
  353. BigDecimal discountFactor = BigDecimal.ZERO;
  354. for (Long val : measuredForecast) {
  355. incomeDiscount = new BigDecimal(val).multiply(profitRate);
  356. profitList.add(incomeDiscount.longValue());
  357. discountFactor = BigDecimal.ONE.divide(BigDecimal.ONE.add(discountRate), 4, RoundingMode.FLOOR);
  358. discountTerm += index;
  359. double pow = Math.pow(discountFactor.doubleValue(), discountTerm);
  360. total = total.add(incomeDiscount.multiply(new BigDecimal(pow)));
  361. index++;
  362. }
  363. result.put("profitList", profitList); // 收入分成额
  364. return Math.abs(total.longValue());
  365. }
  366. private BigDecimal calcDiscountRate(Map<String, Integer> discountRates, BigDecimal taxRate,
  367. BigDecimal governmentLoanRoR) {
  368. BigDecimal discountRate = new BigDecimal(discountRates.get("capital"))
  369. .add(new BigDecimal(discountRates.get("management"))).add(new BigDecimal(discountRates.get("market")))
  370. .add(new BigDecimal(discountRates.get("political")))
  371. .add(new BigDecimal(discountRates.get("technical")));
  372. discountRate = discountRate.add(governmentLoanRoR).divide(HUNDRED.subtract(taxRate), 4, RoundingMode.FLOOR);
  373. double rate = discountRate.doubleValue();
  374. rate = rate > 0.3 ? 0.3 : rate < 0.17 ? 0.17 : rate;
  375. discountRate = new BigDecimal(rate, DEFAULT_PRECISION);
  376. return discountRate;
  377. }
  378. private Map<String, Integer> getDiscountRates(Step7 step7) {
  379. Map<String, Integer> profitScores = new HashMap<>();
  380. profitScores.put("capital", getDiscountScore(step7.getCapital()));// 资金风险
  381. profitScores.put("management", getDiscountScore(step7.getManagement()));// 管理风险
  382. profitScores.put("market", getDiscountScore(step7.getMarket()));// 市场风险
  383. profitScores.put("political", getDiscountScore(step7.getPolitical()));// 政策风险
  384. profitScores.put("technical", getDiscountScore(step7.getTechnical()));// 技术风险
  385. return profitScores;
  386. }
  387. private BigDecimal calcProfitRate(Map<String, Integer> profitScores, Integer industry, Map<String, Object> map) {
  388. BigDecimal legalFactor = new BigDecimal(0.2, DEFAULT_PRECISION);
  389. BigDecimal techFactor = new BigDecimal(0.6, DEFAULT_PRECISION);
  390. BigDecimal fundFactor = legalFactor;
  391. BigDecimal profitRate = new BigDecimal(profitScores.get("confidentiality")).multiply(legalFactor)
  392. .multiply(new BigDecimal(0.4, DEFAULT_PRECISION));
  393. profitRate = profitRate.add(new BigDecimal(profitScores.get("legalStatus")).multiply(legalFactor)
  394. .multiply(new BigDecimal(0.3, DEFAULT_PRECISION)));
  395. profitRate = profitRate.add(new BigDecimal(profitScores.get("decidability")).multiply(legalFactor)
  396. .multiply(new BigDecimal(0.3, DEFAULT_PRECISION)));
  397. profitRate = profitRate.add(new BigDecimal(profitScores.get("prospect")).multiply(techFactor)
  398. .multiply(new BigDecimal(0.1, DEFAULT_PRECISION)));
  399. profitRate = profitRate.add(new BigDecimal(profitScores.get("alternatives")).multiply(techFactor)
  400. .multiply(new BigDecimal(0.2, DEFAULT_PRECISION)));
  401. profitRate = profitRate.add(new BigDecimal(profitScores.get("progressiveness")).multiply(techFactor)
  402. .multiply(new BigDecimal(0.2, DEFAULT_PRECISION)));
  403. profitRate = profitRate.add(new BigDecimal(profitScores.get("innovativeness")).multiply(techFactor)
  404. .multiply(new BigDecimal(0.1, DEFAULT_PRECISION)));
  405. profitRate = profitRate.add(new BigDecimal(profitScores.get("ripeness")).multiply(techFactor)
  406. .multiply(new BigDecimal(0.2, DEFAULT_PRECISION)));
  407. profitRate = profitRate.add(new BigDecimal(profitScores.get("rangeOfApplication")).multiply(techFactor)
  408. .multiply(new BigDecimal(0.1, DEFAULT_PRECISION)));
  409. profitRate = profitRate.add(new BigDecimal(profitScores.get("defensive")).multiply(techFactor)
  410. .multiply(new BigDecimal(0.1, DEFAULT_PRECISION)));
  411. profitRate = profitRate.add(new BigDecimal(profitScores.get("supplyAndDemand")).multiply(fundFactor)
  412. .multiply(new BigDecimal(0.6, DEFAULT_PRECISION)));
  413. profitRate = profitRate.add(new BigDecimal(profitScores.get("profitability")).multiply(fundFactor)
  414. .multiply(new BigDecimal(0.4, DEFAULT_PRECISION)));
  415. BigDecimal minRate = MIN_RATE;
  416. BigDecimal maxRate = MAX_RATE;
  417. if (ProfitRate.containsType(industry)) {
  418. ProfitRate pr = ProfitRate.getProfitRate(industry);
  419. minRate = new BigDecimal(pr.getMinRate());
  420. maxRate = new BigDecimal(pr.getMaxRate());
  421. }
  422. map.put("minRate", minRate);
  423. map.put("maxRate", maxRate);
  424. profitRate = maxRate.subtract(minRate).multiply(profitRate.multiply(PERCENTAGE)).add(minRate)
  425. .multiply(PERCENTAGE).setScale(4, RoundingMode.FLOOR);
  426. return profitRate;
  427. }
  428. private Map<String, Integer> getProfitScores(Step2 step2, Step3 step3) {
  429. // 法律因素权重 20%
  430. Map<String, Integer> profitScores = new HashMap<>();
  431. profitScores.put("legalStatus", getScore(step2.getLegalStatus()));// 法律状态
  432. profitScores.put("confidentiality", getScore(step2.getConfidentiality()));// 保密性
  433. profitScores.put("decidability", getScore(step2.getDecidability()));// 侵权可判定性
  434. // 技术因素权重 60%
  435. profitScores.put("prospect", getScore(step3.getProspect()));// 领域前景
  436. profitScores.put("alternatives", getScore(step3.getAlternatives()));// 可替代性
  437. profitScores.put("progressiveness", getScore(step3.getProgressiveness()));// 先进性
  438. profitScores.put("innovativeness", getScore(step3.getInnovativeness()));// 创新性
  439. profitScores.put("ripeness", getScore(step3.getRipeness()));// 成熟度
  440. profitScores.put("rangeOfApplication", getScore(step3.getRangeOfApplication()));// 应用范围
  441. profitScores.put("defensive", getScore(step3.getDefensive()));// 应用范围
  442. // 经济因素 20%
  443. profitScores.put("supplyAndDemand", getScore(step3.getSupplyAndDemand()));// 供求关系
  444. profitScores.put("profitability", getScore(step3.getProfitability()));// 独立获利能力
  445. return profitScores;
  446. }
  447. private Integer getScore(int option) {
  448. int idx = option - 1;
  449. idx = idx < 0 ? 0 : idx >= SCORES.length ? SCORES.length - 1 : idx;
  450. return SCORES[idx];
  451. }
  452. private Integer getDiscountScore(int option) {
  453. int idx = option - 1;
  454. idx = idx < 0 ? 0 : idx >= DISCOUNT_SCORES.length ? DISCOUNT_SCORES.length - 1 : idx;
  455. return DISCOUNT_SCORES[idx];
  456. }
  457. private void calcUserForecast(List<Long> userForecast, Integer timeLeft) {
  458. Assert.isTrue(userForecast.get(0) > 0 && userForecast.get(1) > 0, ErrorConstants.EVALUATE_PARAM);
  459. BigDecimal second = new BigDecimal(userForecast.get(1));
  460. BigDecimal lastYear = new BigDecimal(userForecast.get(2));
  461. BigDecimal rate = lastYear.divide(second, 2, RoundingMode.HALF_UP)
  462. .subtract(BigDecimal.ONE).add(second
  463. .divide(new BigDecimal(userForecast.get(0)), 2, RoundingMode.HALF_UP).subtract(BigDecimal.ONE))
  464. .divide(new BigDecimal(2));
  465. BigDecimal step = new BigDecimal(0.1, DEFAULT_PRECISION);
  466. int size = userForecast.size();
  467. for (int i = size; i < timeLeft; i++) {
  468. if (i < 6) {
  469. lastYear = lastYear.multiply(
  470. BigDecimal.ONE.add(rate.multiply(rate.subtract(step.multiply(new BigDecimal(i - size))))));
  471. }
  472. userForecast.add(lastYear.longValue());
  473. }
  474. }
  475. private List<Long> calcSysForecast(List<Long> userForecast, BigDecimal industryAverageRate, Integer timeLeft) {
  476. List<Long> sysForecast = new ArrayList<>();
  477. BigDecimal lastYear = BigDecimal.ZERO;
  478. BigDecimal step = new BigDecimal(0.1, DEFAULT_PRECISION);
  479. //
  480. industryAverageRate = industryAverageRate.multiply(PERCENTAGE);
  481. for (int i = 0; i < timeLeft; i++) {
  482. if (i == 0) {
  483. lastYear = new BigDecimal(userForecast.get(0)).multiply(new BigDecimal(0.9, DEFAULT_PRECISION));
  484. } else if (i < 6) {
  485. lastYear = lastYear.multiply(BigDecimal.ONE.add(
  486. industryAverageRate.multiply(BigDecimal.ONE.subtract(step.multiply(new BigDecimal(i - 1))))));
  487. }
  488. sysForecast.add(lastYear.longValue());
  489. }
  490. return sysForecast;
  491. }
  492. private List<Long> calcMeasuredForecast(List<Long> userForecast, List<Long> sysForecast) {
  493. List<Long> measuredForecast = new ArrayList<>();
  494. for (int i = 0; i < sysForecast.size(); i++) {
  495. measuredForecast.add((userForecast.get(i) + sysForecast.get(i)) >> 1);
  496. }
  497. return measuredForecast;
  498. }
  499. /**
  500. * 更新评估步骤
  501. * @param step
  502. * @param nextStep
  503. * @param key
  504. * @param res
  505. * @param id
  506. */
  507. private void updateSteps(Object step, Integer nextStep, String key, Result res, String id) {
  508. ValueEvaluation ve = valueEvaluationService.getMyEvaluation(Long.valueOf(id));
  509. Assert.notNull(ve, ErrorConstants.EVALUATE_ID);
  510. ve.setStep(Math.max(nextStep, ve.getStep()));
  511. if (nextStep == 1) {
  512. ve.setName(((Step1) step).getName());
  513. }
  514. ve.setValue(0l);
  515. JSONObject jo = JSON.parseObject(ve.getLog());
  516. jo.put(key, step);
  517. ve.setLog(jo.toJSONString());
  518. res.data(valueEvaluationService.update(ve));
  519. }
  520. private boolean handleBindingError(Result res, BindingResult bindingResult) {
  521. if (bindingResult.hasErrors()) {
  522. LoggerUtils.debug(logger, "参数错误:[%s], [%s], [%s]", bindingResult.getFieldError().getDefaultMessage(),
  523. bindingResult.getFieldError().getField(), bindingResult.getFieldError().getRejectedValue());
  524. res.getError().add(buildError(ErrorConstants.EVALUATE_PARAM));
  525. return true;
  526. }
  527. return false;
  528. }
  529. private BigDecimal getIndustryCategoryValue(Step1 step1) {
  530. return getIndustryCategoryValue(step1, getIndustryCates(step1.getIndustry()));
  531. }
  532. /**
  533. * 获得行业分类
  534. * @param pid
  535. * @return
  536. */
  537. private Map<Integer, IndustryCategory> getIndustryCates(Integer pid) {
  538. return industryCategoryService.list(pid).stream()
  539. .collect(Collectors.toMap(IndustryCategory::getId, (it) -> it));
  540. }
  541. private Map<Integer, DistrictGlossory> getProvinces() {
  542. return districtGlossoryService.list(0).stream().collect(Collectors.toMap(DistrictGlossory::getId, (it) -> it));
  543. }
  544. /**
  545. * 获得行业分类平均值
  546. * @param step1
  547. * @param cates
  548. * @return
  549. */
  550. private BigDecimal getIndustryCategoryValue(Step1 step1, Map<Integer, IndustryCategory> cates) {
  551. List<Integer> subIds = Stream.of(step1.getSubIndustry().split(",")).map(it -> {
  552. return Integer.valueOf(it);
  553. }).collect(Collectors.toList());
  554. BigDecimal average = BigDecimal.ZERO;
  555. int count = 0;
  556. for (Integer id : subIds) {
  557. if (cates.containsKey(id)) {
  558. average = average.add(cates.get(id).getValue());
  559. count++;
  560. }
  561. }
  562. return average.divide(new BigDecimal(count == 0 ? 1 : count), 2, RoundingMode.HALF_UP);//average四舍五入保留2位小数
  563. }
  564. /**
  565. * 预计收入处理
  566. * @param incomes
  567. * @param growth
  568. * @return
  569. */
  570. private Long[] calcForecastIncome(List<YearIncome> incomes, BigDecimal growth) {
  571. BigDecimal useGrowth = growth.multiply(PERCENTAGE);
  572. BigDecimal base = new BigDecimal(incomes.get(0).getIncome());
  573. if (!incomes.get(1).getIncome().equals(0)) {
  574. useGrowth = base.divide(new BigDecimal(incomes.get(1).getIncome()), 2, RoundingMode.CEILING)
  575. .subtract(BigDecimal.ONE);//保留2位天花板数减去1
  576. }
  577. Long[] res = new Long[3];
  578. BigDecimal one = base.multiply(useGrowth.add(BigDecimal.ONE));
  579. useGrowth = useGrowth.multiply(new BigDecimal(0.9, DEFAULT_PRECISION));
  580. BigDecimal two = one.multiply(useGrowth.add(BigDecimal.ONE));
  581. useGrowth = useGrowth.multiply(new BigDecimal(0.8, DEFAULT_PRECISION));
  582. res[2] = two.multiply(useGrowth.add(BigDecimal.ONE)).longValue();
  583. res[0] = one.longValue();
  584. res[1] = two.longValue();
  585. return res;
  586. }
  587. }