package com.goafanti.evaluation.controller; import java.math.BigDecimal; import java.math.MathContext; import java.math.RoundingMode; import java.util.ArrayList; import java.util.List; import javax.validation.Valid; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.Assert; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.goafanti.common.bo.Result; import com.goafanti.common.constant.ErrorConstants; import com.goafanti.common.controller.BaseApiController; import com.goafanti.common.model.IndustryCategory; import com.goafanti.common.model.ValueEvaluation; import com.goafanti.common.service.IndustryCategoryService; import com.goafanti.common.utils.LoggerUtils; import com.goafanti.core.shiro.token.TokenManager; import com.goafanti.evaluation.bo.ForecastIncome; import com.goafanti.evaluation.bo.Step1; import com.goafanti.evaluation.bo.Step2; import com.goafanti.evaluation.bo.Step3; import com.goafanti.evaluation.bo.Step4; import com.goafanti.evaluation.bo.Step5; import com.goafanti.evaluation.bo.Step6; import com.goafanti.evaluation.bo.Step7; import com.goafanti.evaluation.bo.YearIncome; import com.goafanti.evaluation.service.ValueEvaluationService; @RestController @RequestMapping(value = "/api/user/evaluate") public class EvaluationController extends BaseApiController { private static final Logger logger = LoggerFactory.getLogger(EvaluationController.class); private static final MathContext DEFAULT_PRECISION = new MathContext(3, RoundingMode.HALF_UP); @Autowired ValueEvaluationService valueEvaluationService; @Autowired private IndustryCategoryService industryCategoryService; @RequestMapping(value = "/create", method = RequestMethod.GET) public Result create() { ValueEvaluation ve = new ValueEvaluation(); ve.setUid(TokenManager.getUserId()); ve.setStep(0); ve.setLog("{}"); valueEvaluationService.insert(ve); return new Result(ve.getId().toString()); } @RequestMapping(value = "/list", method = RequestMethod.GET) public Result list(String pageNo, String pageSize) { return new Result().data(valueEvaluationService.list(handlePageNo(pageNo), handlePageSize(pageSize))); } @RequestMapping(value = "/info/{id}", method = RequestMethod.GET, produces = "application/json;charset=UTF-8") public String info(@PathVariable String id) { Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID); return valueEvaluationService.getMyEvaluationSteps(Long.valueOf(id)); } @RequestMapping(value = "/remove", method = RequestMethod.POST) public Result remove(String ids) { Assert.isTrue(StringUtils.isNotBlank(ids), ErrorConstants.EVALUATE_PARAM); Result res = new Result(); List idList = new ArrayList<>(); String[] idArr = ids.split(","); for (String id : idArr) { Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_PARAM); idList.add(Long.valueOf(id)); } res.data(valueEvaluationService.deleteMySteps(idList)); return res; } @RequestMapping(value = "/step1", method = RequestMethod.POST) public Result step1(String id, @Valid Step1 data, BindingResult bindingResult) { Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID); Result res = new Result(); if (handleBindingError(res, bindingResult)) { return res; } ValueEvaluation ve = valueEvaluationService.getEvaluation(Long.valueOf(id)); Assert.notNull(ve, ErrorConstants.EVALUATE_ID); ve.setName(data.getName()); ve.setStep(1); JSONObject jo = JSON.parseObject(ve.getLog()); jo.put("0", data); ve.setLog(jo.toJSONString()); res.data(valueEvaluationService.update(ve)); return res; } @RequestMapping(value = "/step2", method = RequestMethod.POST) public Result step2(String id, @Valid Step2 data, BindingResult bindingResult) { Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID); Result res = new Result(); if (handleBindingError(res, bindingResult)) { return res; } updateSteps(data, 2, "1", res, id); return res; } @RequestMapping(value = "/step3", method = RequestMethod.POST) public Result step3(String id, @Valid Step3 data, BindingResult bindingResult) { Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID); Result res = new Result(); if (handleBindingError(res, bindingResult)) { return res; } updateSteps(data, 3, "2", res, id); return res; } @RequestMapping(value = "/step4", method = RequestMethod.POST) public Result step4(String id, String hasIncome, String incomes) { Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID); Result res = new Result(); Step4 step = new Step4(); try { step.setHasIncome(Integer.valueOf(hasIncome)); if (step.getHasIncome().equals(2)) { List ja = JSON.parseArray(incomes, YearIncome.class); if (ja.size() != 3) { res.error(buildError(ErrorConstants.EVALUATE_PARAM)); } else { step.setIncomes(ja); } } } catch (Exception e) { res.error(buildError(ErrorConstants.EVALUATE_PARAM)); } if (res.getError().isEmpty()) { updateSteps(step, 4, "3", res, id); } return res; } @RequestMapping(value = "/step5", method = RequestMethod.POST) public Result step5(String id, String type, String forecastIncomes) { Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID); Result res = new Result(); Step5 step = new Step5(); try { step.setType(Integer.valueOf(type)); List ja = JSON.parseArray(forecastIncomes, ForecastIncome.class); if (ja.size() != 3) { res.error(buildError(ErrorConstants.EVALUATE_PARAM)); } else { step.setForecastIncomes(ja); } } catch (Exception e) { res.error(buildError(ErrorConstants.EVALUATE_PARAM)); } if (res.getError().isEmpty()) { updateSteps(step, 5, "4", res, id); } return res; } @RequestMapping(value = "/step5/{id}", method = RequestMethod.GET) public Result step5Info(@PathVariable String id) { Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID); Result res = new Result(); ValueEvaluation ve = valueEvaluationService.getEvaluation(Long.valueOf(id)); try { JSONObject jo = JSON.parseObject(ve.getLog()); Step4 step4 = ((JSON) jo.get("3")).toJavaObject(Step4.class); if (step4.getHasIncome().equals(2)) { Step1 step1 = ((JSON) jo.get("0")).toJavaObject(Step1.class); res.data(getPredicateIncome(step4.getIncomes(), getIndustryCategoryValue(step1))); } } catch (Exception e) { res.error(buildError(ErrorConstants.EVALUATE_PARAM)); } return res; } @RequestMapping(value = "/step6", method = RequestMethod.POST) public Result step6(String id, @Valid Step6 data, BindingResult bindingResult) { Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID); Result res = new Result(); if (handleBindingError(res, bindingResult)) { return res; } updateSteps(data, 6, "5", res, id); return res; } @RequestMapping(value = "/step7", method = RequestMethod.POST) public Result step7(String id, @Valid Step7 data, BindingResult bindingResult) { Assert.isTrue(StringUtils.isNumeric(id), ErrorConstants.EVALUATE_ID); Result res = new Result(); if (handleBindingError(res, bindingResult)) { return res; } updateSteps(data, 7, "6", res, id); return res; } private void updateSteps(Object step, Integer nextStep, String key, Result res, String id) { ValueEvaluation ve = valueEvaluationService.getEvaluation(Long.valueOf(id)); Assert.notNull(ve, ErrorConstants.EVALUATE_ID); ve.setStep(Math.max(nextStep, ve.getStep())); JSONObject jo = JSON.parseObject(ve.getLog()); jo.put(key, step); ve.setLog(jo.toJSONString()); res.data(valueEvaluationService.update(ve)); } private boolean handleBindingError(Result res, BindingResult bindingResult) { if (bindingResult.hasErrors()) { LoggerUtils.debug(logger, "参数错误:[%s], [%s], [%s]", bindingResult.getFieldError().getDefaultMessage(), bindingResult.getFieldError().getField(), bindingResult.getFieldError().getRejectedValue()); res.getError().add(buildError(ErrorConstants.EVALUATE_PARAM)); return true; } return false; } private BigDecimal getIndustryCategoryValue(Step1 step1) { List cates = industryCategoryService.list(step1.getIndustry()); String[] subs = step1.getSubIndustry().split(","); Integer[] subIds = new Integer[subs.length]; for (int i = 0; i < subs.length; i++) { subIds[i] = Integer.valueOf(subs[i]); } BigDecimal average = BigDecimal.ZERO; for (IndustryCategory ic : cates) { for (int i = 0; i < subIds.length; i++) { if (ic.getId().equals(subIds[i])) { average = average.add(ic.getValue()); } } } return average.divide(new BigDecimal(3), 2, RoundingMode.HALF_UP); } private Long[] getPredicateIncome(List incomes, BigDecimal growth) { BigDecimal useGrowth = growth.divide(new BigDecimal(100), 2, RoundingMode.CEILING); BigDecimal base = new BigDecimal(incomes.get(0).getIncome()); if (!incomes.get(1).getIncome().equals(0)) { useGrowth = base.divide(new BigDecimal(incomes.get(1).getIncome()), 2, RoundingMode.CEILING) .subtract(BigDecimal.ONE); } Long[] res = new Long[3]; BigDecimal one = base.multiply(useGrowth.add(BigDecimal.ONE)); useGrowth = useGrowth.multiply(new BigDecimal(0.9, DEFAULT_PRECISION)); BigDecimal two = one.multiply(useGrowth.add(BigDecimal.ONE)); useGrowth = useGrowth.multiply(new BigDecimal(0.8, DEFAULT_PRECISION)); res[2] = two.multiply(useGrowth.add(BigDecimal.ONE)).longValue(); res[0] = one.longValue(); res[1] = two.longValue(); return res; } }