Commit 21b63d21 by zhangkb

提交指标计算接口代码

parent 421445c3
...@@ -20,13 +20,14 @@ ...@@ -20,13 +20,14 @@
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<spring-cloud.version>Finchley.RELEASE</spring-cloud.version> <spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
<akka.version>2.6.0-M4</akka.version>
</properties> </properties>
<dependencies> <dependencies>
<!--<dependency>--> <dependency>
<!--<groupId>org.springframework.boot</groupId>--> <groupId>org.springframework.boot</groupId>
<!--<artifactId>spring-boot-starter-data-mongodb</artifactId>--> <artifactId>spring-boot-starter-data-mongodb</artifactId>
<!--</dependency>--> </dependency>
<dependency> <dependency>
<groupId>org.springframework.cloud</groupId> <groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
...@@ -141,6 +142,27 @@ ...@@ -141,6 +142,27 @@
<optional>true</optional> <optional>true</optional>
<version>1.16.18</version> <version>1.16.18</version>
</dependency> </dependency>
<!-- aviator -->
<dependency>
<groupId>com.googlecode.aviator</groupId>
<artifactId>aviator</artifactId>
<version>4.2.10</version>
</dependency>
<!-- aviator -->
<!-- akka -->
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-actor_2.12</artifactId>
<version>${akka.version}</version>
</dependency>
<dependency>
<groupId>com.typesafe.akka</groupId>
<artifactId>akka-testkit_2.12</artifactId>
<version>${akka.version}</version>
<scope>test</scope>
</dependency>
<!-- akka -->
</dependencies> </dependencies>
<dependencyManagement> <dependencyManagement>
<dependencies> <dependencies>
......
package com.keymobile.indicators.akka.actor;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Maps;
import com.googlecode.aviator.AviatorEvaluator;
import com.keymobile.indicators.akka.message.DriveIndCalculateMsg;
import com.keymobile.indicators.akka.message.IndGetValueMsg;
import com.keymobile.indicators.akka.message.IndValueMsg;
import com.keymobile.indicators.akka.message.specific.DriveIndAverageAndRankMsg;
import com.keymobile.indicators.model.entity.DriveIndCalResult;
import com.keymobile.indicators.model.entity.IndAcsDef;
import com.keymobile.indicators.model.entity.IndAcsScoreInfo;
import com.keymobile.indicators.service.cmbkpi.IndAcsDefService;
import com.keymobile.indicators.service.cmbkpi.IndAcsScoreInfoService;
import com.keymobile.indicators.service.hytobacco.DriveIndCalResultService;
import com.keymobile.indicators.utils.SpringUtil;
import akka.actor.AbstractActor;
import akka.actor.ActorRef;
import akka.actor.Props;
public class DriveIndCalculateActor extends AbstractActor{
private Logger logger = LoggerFactory.getLogger(DriveIndCalculateActor.class);
private IndAcsDefService indAcsDefService = SpringUtil.getBean(IndAcsDefService.class);
private IndAcsScoreInfoService indAcsScoreInfoService = SpringUtil.getBean(IndAcsScoreInfoService.class);
private DriveIndCalResultService driveIndCalResultService = SpringUtil.getBean(DriveIndCalResultService.class);
private int numberOfConfirm = 0;//定义返回确认消息的子actor
private int indIdSize = 0;//考核指标内包含的基础指标id的个数
//定义线程安全的收集反馈确认消息list
private List<Integer> confirmList = new CopyOnWriteArrayList<>();
private String driveIndFormula;//考核指标公式
private String driveIndDataType;//考核指标数据类型
private String compareId ;
private String compareObj;
private int date;
private String unit;
private String driveIndId;
private Map<String, Object> env = Maps.newHashMap();
private String indType;//正向,反向
private final ActorRef driveIndCalculateRegionActor;//定义schemaActor,用于返回给schemaActor确认信息
static public Props props(ActorRef driveIndCalculateRegionActor) {
return Props.create(DriveIndCalculateActor.class,()->new DriveIndCalculateActor(driveIndCalculateRegionActor));
}
public DriveIndCalculateActor(ActorRef driveIndCalculateRegionActor) {
this.driveIndCalculateRegionActor = driveIndCalculateRegionActor;
}
@Override
public Receive createReceive() {
return receiveBuilder()
.match(DriveIndCalculateMsg.class,driveIndCalculateMsg -> {
compareId = driveIndCalculateMsg.getCompareId();
compareObj = driveIndCalculateMsg.getCompareObj();
date = driveIndCalculateMsg.getDate();
driveIndId = driveIndCalculateMsg.getDriveIndId();
List<String> indIdList = new ArrayList<>();
IndAcsDef indAcsDef = indAcsDefService.getById(driveIndId);
unit = indAcsDef.getUnt();
indType = indAcsDef.getIndType();
List<IndAcsScoreInfo> acsSoreInfoList = indAcsScoreInfoService.getListByIndId(
driveIndId);
//获取考核指标的公式
driveIndFormula = acsSoreInfoList.get(0).getScoreFormula();
Pattern p = Pattern.compile("(\\[[^\\]]*\\])");
Matcher m = p.matcher(driveIndFormula);
while(m.find()){
indIdList.add(m.group().substring(1, m.group().length()-1));
}
//获取公式中的基础指标id
indIdSize =indIdList.size();
if(!indIdList.isEmpty()) {
for(String indId : indIdList) {
//根据基础指标id获取基础指标
String indValueType = null;//基础指标值的数据类型
IndGetValueMsg indGetValueMsg = new IndGetValueMsg(indId,
driveIndCalculateMsg.getDimValues(),indValueType);
ActorRef indGetValueActor = this.getContext()
.actorOf(Props.create(IndGetValueActor.class,
()->new IndGetValueActor()));
indGetValueActor.tell(indGetValueMsg, getSelf());
}
}
})
.match(IndValueMsg.class,indValueMsg->{
if(indValueMsg.getIsFinish()==0) {
logger.info(indValueMsg.getConfirmMessage());
}else {
//判断类型,进行转换
String indValueDataType = indValueMsg.getType();
String indValue = indValueMsg.getValue();
if(StringUtils.isBlank(indValue)) {
indValue="0.0";
}
try {
driveIndFormula = driveIndFormula.replace("["+indValueMsg.getIndId()+"]", indValueMsg.getIndId());
//替换公式中的基础指标id为确定指标值
env.put(indValueMsg.getIndId(), Double.valueOf(indValue));
}catch(Exception e) {
e.printStackTrace();
logger.error(driveIndFormula+";"+env);
}
}
confirmList.add(indValueMsg.getIsFinish());
if (++numberOfConfirm >= indIdSize) {//子actor全部返回
if(!confirmList.contains(0)) {//取所有基础指标值没错
driveIndDataType = null;
//进行考核指标值计算
try {
String driveIndValue = AviatorEvaluator.execute(driveIndFormula,env).toString();
//保留四位小数
if(!driveIndValue.equals("NaN")) {
driveIndValue = String.format("%.4f",
new BigDecimal((Double)AviatorEvaluator.execute(driveIndFormula,env)));
}
//保存进考核指标结果表中
DriveIndCalResult driveIndCalResult = new DriveIndCalResult(compareId,
driveIndId,compareObj,date,driveIndValue,unit,"1","1","admin");
driveIndCalResult = driveIndCalResultService.saveOrUpdate(driveIndCalResult);
//返回指标值回去算平均值和排名
DriveIndAverageAndRankMsg driveIndAverageAndRankMsg =
new DriveIndAverageAndRankMsg(driveIndCalResult.getId(),
compareId,driveIndId,compareObj,date,driveIndValue,unit,indType);
driveIndCalculateRegionActor.tell(driveIndAverageAndRankMsg,ActorRef.noSender());
} catch (Exception e) {
DriveIndCalResult driveIndCalResult = new DriveIndCalResult(compareId,
driveIndId,compareObj,date,"0(Error)",unit,"1","0","admin");
driveIndCalResult = driveIndCalResultService.saveOrUpdate(driveIndCalResult);
DriveIndAverageAndRankMsg driveIndAverageAndRankMsg =
new DriveIndAverageAndRankMsg(driveIndCalResult.getId(),
compareId,driveIndId,compareObj,date,"0(Error)",unit,indType);
driveIndCalculateRegionActor.tell(driveIndAverageAndRankMsg,ActorRef.noSender());
logger.error("env:"+env+";formula:"+driveIndFormula);
}
}
}
})
.build();
}
}
package com.keymobile.indicators.akka.actor;
import java.util.Map;
import com.keymobile.indicators.akka.message.IndGetValueMsg;
import com.keymobile.indicators.akka.message.IndValueMsg;
import com.keymobile.indicators.service.hytobacco.IndicatorsValueService;
import com.keymobile.indicators.utils.SpringUtil;
import akka.actor.AbstractActor;
public class IndGetValueActor extends AbstractActor{
private IndicatorsValueService indicatorsValueService = SpringUtil.getBean(IndicatorsValueService.class);
@Override
public Receive createReceive() {
return receiveBuilder()
.match(IndGetValueMsg.class,indCalculateMsg -> {
//根据维度值和基础指标id获取指标值
Map<String,Object> indValueMap = indicatorsValueService.getIndicatorsValue(
indCalculateMsg.getIndId(), indCalculateMsg.getDimValue());
if(indValueMap!=null) {
//返回指标值结果
getSender().tell(new IndValueMsg(indCalculateMsg.getIndId()
,indValueMap.get("value").toString()
,indCalculateMsg.getIndValueType(),1,""),getSelf());
}else {
//返回指标值结果
getSender().tell(new IndValueMsg(indCalculateMsg.getIndId(),null
,indCalculateMsg.getIndValueType(),0,"无法获取指标id:"+
indCalculateMsg.getIndId()+";维度:"+
indCalculateMsg.getDimValue().get(0).getDimvalue()+","+
indCalculateMsg.getDimValue().get(1).getDimvalue()+" 的指标值"),getSelf());
}
})
.build();
}
}
package com.keymobile.indicators.akka.actor.specific;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.keymobile.indicators.akka.actor.DriveIndCalculateActor;
import com.keymobile.indicators.akka.message.DriveIndCalculateMsg;
import com.keymobile.indicators.akka.message.specific.DriveIndAverageAndRankMsg;
import com.keymobile.indicators.akka.message.specific.DriveIndCalculateRegionMsg;
import com.keymobile.indicators.model.entity.DimValue;
import com.keymobile.indicators.model.entity.DriveIndCalResult;
import com.keymobile.indicators.service.hytobacco.DriveIndCalResultService;
import com.keymobile.indicators.utils.CalculateUtils;
import com.keymobile.indicators.utils.SpringUtil;
import akka.actor.AbstractActor;
import akka.actor.ActorRef;
import akka.actor.Props;
public class DriveIndCalculateRegionActor extends AbstractActor{
private DriveIndCalResultService driveIndCalResultService = SpringUtil.getBean(DriveIndCalResultService.class);
private int numberOfConfirm = 0;//定义返回确认消息的子actor
private int compareObjSize = 0;//对标对象个数
private List<String> values = new ArrayList<>();
private Map<String,String> valueMap = new HashMap<>();
@Override
public Receive createReceive() {
return receiveBuilder()
.match(DriveIndCalculateRegionMsg.class,driveIndCalculateRegionMsg -> {
String compareId = driveIndCalculateRegionMsg.getCompareId();
String driveIndId = driveIndCalculateRegionMsg.getDriveIndId();
List<String> compareObjs = driveIndCalculateRegionMsg.getCompareObj();
int date = driveIndCalculateRegionMsg.getDate();
compareObjSize = compareObjs.size();
for(String compareObj : compareObjs) {
List<DimValue> dimValueList = new ArrayList<>();
DimValue dimCompareObj = new DimValue("dim1",compareObj,"varchar");
DimValue dimDateObj = new DimValue("dim2",date,"number");
dimValueList.add(dimCompareObj);
dimValueList.add(dimDateObj);
DriveIndCalculateMsg driveIndCalculateMsg = new DriveIndCalculateMsg(compareId,
driveIndId,compareObj,date,dimValueList);
//启动akka
ActorRef driveIndCalculateActor = this.getContext()
.actorOf(Props.create(DriveIndCalculateActor.class,
()->new DriveIndCalculateActor(getSelf())));
driveIndCalculateActor.tell(driveIndCalculateMsg,getSelf());
}
})
.match(DriveIndAverageAndRankMsg.class,driveIndAverageAndRankMsg -> {
String value = driveIndAverageAndRankMsg.getDriveIndValue();
String id = driveIndAverageAndRankMsg.getId();
String indType = driveIndAverageAndRankMsg.getIndType();
valueMap.put(id, value);
values.add(value);
if (++numberOfConfirm >= compareObjSize) {//子actor全部返回
//算平均数
String average = CalculateUtils.averageValue(values);
//算组内排名
Map<String,Integer> rankValue = CalculateUtils.rankValue(valueMap, indType);
for(Entry<String,Integer> entry : rankValue.entrySet()) {
//根据id获取指标值结果
DriveIndCalResult driveIndCalResult = driveIndCalResultService.findById(entry.getKey());
if(driveIndCalResult!=null) {
driveIndCalResult.setAverage(average);
driveIndCalResult.setRank(entry.getValue());
driveIndCalResultService.saveOrUpdate(driveIndCalResult);
}
}
}
})
.build();
}
}
package com.keymobile.indicators.akka.actor.specific;
import java.util.List;
import com.keymobile.indicators.akka.message.specific.DriveIndCalculateRegionMsg;
import com.keymobile.indicators.akka.message.specific.DriveIndCompareObjMsg;
import akka.actor.AbstractActor;
import akka.actor.ActorRef;
import akka.actor.Props;
public class DriveIndCompareObjActor extends AbstractActor{
@Override
public Receive createReceive() {
return receiveBuilder()
.match(DriveIndCompareObjMsg.class,driveIndCompareObjMsg->{
String compareId = driveIndCompareObjMsg.getCompareId();
List<String> driveIndIds = driveIndCompareObjMsg.getDriveIndIds();
List<String> compareObj = driveIndCompareObjMsg.getCompareObj();
int date = driveIndCompareObjMsg.getDate();
for(String driveIndId:driveIndIds) {
DriveIndCalculateRegionMsg driveIndCalculateRegionMsg = new DriveIndCalculateRegionMsg(
compareId,driveIndId,compareObj,date);
//start akka
ActorRef driveIndCalculateRegionActor = this.getContext()
.actorOf(Props.create(DriveIndCalculateRegionActor.class,
()->new DriveIndCalculateRegionActor()));
driveIndCalculateRegionActor.tell(driveIndCalculateRegionMsg,getSelf());
}
})
.build();
}
}
package com.keymobile.indicators.akka.message;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import com.keymobile.indicators.model.entity.DimValue;
public class DriveIndCalculateMsg implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String compareId;//对标id
private String driveIndId;//考核指标id
private String compareObj;//对标对象
private int date;
private List<DimValue> dimValues = new ArrayList<>();//维度值list
public DriveIndCalculateMsg(String compareId,String driveIndId,String compareObj,int date,
List<DimValue> dimValues) {
this.compareId = compareId;
this.driveIndId = driveIndId;
this.compareObj = compareObj;
this.setDate(date);
this.dimValues.addAll(dimValues);
}
public String getCompareId() {
return compareId;
}
public void setCompareId(String compareId) {
this.compareId = compareId;
}
public String getDriveIndId() {
return driveIndId;
}
public void setDriveIndId(String driveIndId) {
this.driveIndId = driveIndId;
}
public List<DimValue> getDimValues() {
return dimValues;
}
public void setDimValues(List<DimValue> dimValues) {
this.dimValues.addAll(dimValues);
}
public String getCompareObj() {
return compareObj;
}
public void setCompareObj(String compareObj) {
this.compareObj = compareObj;
}
public int getDate() {
return date;
}
public void setDate(int date) {
this.date = date;
}
}
package com.keymobile.indicators.akka.message;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import com.keymobile.indicators.model.entity.DimValue;
public class IndGetValueMsg implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String indId;//基础指标id
private List<DimValue> dimValue = new ArrayList<>();//维度值
private String indValueType;//基础指标值类型
public IndGetValueMsg(String indId,List<DimValue> dimValue,String indValueType) {
this.indId = indId;
this.dimValue.addAll(dimValue);
this.setIndValueType(indValueType);
}
public List<DimValue> getDimValue() {
return dimValue;
}
public void setDimValue(List<DimValue> dimValue) {
this.dimValue.addAll(dimValue);
}
public String getIndId() {
return indId;
}
public void setIndId(String indId) {
this.indId = indId;
}
public String getIndValueType() {
return indValueType;
}
public void setIndValueType(String indValueType) {
this.indValueType = indValueType;
}
}
package com.keymobile.indicators.akka.message;
import java.io.Serializable;
public class IndValueMsg implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String indId;//基础指标id
private String value;//指标值
private String type;//指标值类型
//是否完成标识:1.完成 0.未完成
private Integer isFinish;
//日志报告
private String confirmMessage;
public IndValueMsg(String indId,String value,String type,Integer isFinish,String confirmMessage) {
this.setIndId(indId);
this.value = value;
this.type = type;
this.isFinish = isFinish;
this.confirmMessage = confirmMessage;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Integer getIsFinish() {
return isFinish;
}
public void setIsFinish(Integer isFinish) {
this.isFinish = isFinish;
}
public String getConfirmMessage() {
return confirmMessage;
}
public void setConfirmMessage(String confirmMessage) {
this.confirmMessage = confirmMessage;
}
public String getIndId() {
return indId;
}
public void setIndId(String indId) {
this.indId = indId;
}
}
package com.keymobile.indicators.akka.message.specific;
import java.io.Serializable;
public class DriveIndAverageAndRankMsg implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String id;//mongodb id
private String compareId;
private String driveIndId;
private String compareObj;
private int date;
private String driveIndValue;
private String unit;
private String indType;
public DriveIndAverageAndRankMsg(String id,String compareId,String driveIndId,String compareObj,
int date,String driveIndValue,String unit,String indType) {
this.id = id;
this.compareId = compareId;
this.driveIndId = driveIndId;
this.compareObj = compareObj;
this.date = date;
this.driveIndValue = driveIndValue;
this.unit = unit;
this.setIndType(indType);
}
public String getCompareId() {
return compareId;
}
public void setCompareId(String compareId) {
this.compareId = compareId;
}
public String getDriveIndId() {
return driveIndId;
}
public void setDriveIndId(String driveIndId) {
this.driveIndId = driveIndId;
}
public String getCompareObj() {
return compareObj;
}
public void setCompareObj(String compareObj) {
this.compareObj = compareObj;
}
public int getDate() {
return date;
}
public void setDate(int date) {
this.date = date;
}
public String getDriveIndValue() {
return driveIndValue;
}
public void setDriveIndValue(String driveIndValue) {
this.driveIndValue = driveIndValue;
}
public String getUnit() {
return unit;
}
public void setUnit(String unit) {
this.unit = unit;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getIndType() {
return indType;
}
public void setIndType(String indType) {
this.indType = indType;
}
}
package com.keymobile.indicators.akka.message.specific;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class DriveIndCalculateRegionMsg implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String compareId;//对标id
private String driveIndId;//考核指标id
private List<String> compareObj = new ArrayList<>();//对标对象list
private int date;//年份
public DriveIndCalculateRegionMsg(String compareId,String driveIndId,
List<String> compareObj,int date) {
this.compareId = compareId;
this.driveIndId = driveIndId;
this.compareObj.addAll(compareObj);
this.date = date;
}
public String getCompareId() {
return compareId;
}
public void setCompareId(String compareId) {
this.compareId = compareId;
}
public String getDriveIndId() {
return driveIndId;
}
public void setDriveIndId(String driveIndId) {
this.driveIndId = driveIndId;
}
public List<String> getCompareObj() {
return compareObj;
}
public void setCompareObj(List<String> compareObj) {
this.compareObj.addAll(compareObj);
}
public int getDate() {
return date;
}
public void setDate(int date) {
this.date = date;
}
}
package com.keymobile.indicators.akka.message.specific;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
public class DriveIndCompareObjMsg implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String compareId;//对标id
private List<String> driveIndIds = new ArrayList<>();
private List<String> compareObj = new ArrayList<>();//对标对象list
private int date;//年份
public DriveIndCompareObjMsg(String compareId,List<String> driveIndIds,List<String> compareObj,int date) {
this.compareId = compareId;
this.driveIndIds.addAll(driveIndIds);
this.compareObj.addAll(compareObj);
this.date = date;
}
public String getCompareId() {
return compareId;
}
public void setCompareId(String compareId) {
this.compareId = compareId;
}
public List<String> getDriveIndIds() {
return driveIndIds;
}
public void setDriveIndIds(List<String> driveIndIds) {
this.driveIndIds.addAll(driveIndIds);
}
public List<String> getCompareObj() {
return compareObj;
}
public void setCompareObj(List<String> compareObj) {
this.compareObj.addAll(compareObj);
}
public int getDate() {
return date;
}
public void setDate(int date) {
this.date = date;
}
}
package com.keymobile.indicators.api.hytobacco;
import java.util.Date;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.keymobile.indicators.model.entity.IndAcsDef;
import com.keymobile.indicators.model.entity.IndAcsScoreInfo;
import com.keymobile.indicators.model.entity.IndAnaDef;
import com.keymobile.indicators.service.cmbkpi.IndAcsDefService;
import com.keymobile.indicators.service.cmbkpi.IndAcsScoreInfoService;
import com.keymobile.indicators.service.cmbkpi.IndAnaDefService;
import com.keymobile.indicators.service.hytobacco.DriveIndCalResultService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@Api(tags={"指标定义接口"})
@RestController
@RequestMapping(value = "/indDef")
public class IndicatorsDefCtrl {
@Autowired
private IndAnaDefService indAnaDefService;
@Autowired
private IndAcsDefService indAcsDefService;
@Autowired
private IndAcsScoreInfoService indAscScoreService;
@Autowired
private DriveIndCalResultService driveIndCalResultService;
@ApiOperation(value = "新建基础指标", notes = "新建基础指标")
@PostMapping(value = "/createAnaInd")
public void createAnaInd(@RequestParam String indId,@RequestParam String indName,
@RequestParam(required=false) String unt) throws Exception{
IndAnaDef indAnaDef = new IndAnaDef();
indAnaDef.setIndId(indId);
indAnaDef.setIndName(indName);
indAnaDef.setUnt(unt);
indAnaDef.setDefTime(new Date());
indAnaDef.setUpdTime(new Date());
indAnaDef.setDefStaTime(202004);
indAnaDef.setDefEndTime(999904);
indAnaDefService.saveOrUpdate(indAnaDef);
}
@ApiOperation(value = "新建考核指标", notes = "新建考核指标")
@PostMapping(value = "/createAcsInd")
public void createAcsInd(@RequestParam String indId,@RequestParam String indName,
@RequestParam(required=false) String unt,@RequestParam(required=false) String indType,
@RequestParam String formula) throws Exception{
IndAcsDef indAcsDef = new IndAcsDef();
indAcsDef.setIndId(indId);
indAcsDef.setIndName(indName);
indAcsDef.setUnt(unt);
if(StringUtils.isNotBlank(indType)) {
indAcsDef.setIndType(indType);//0:正向 1:反向
}
indAcsDef.setWeight(1.0);
indAcsDef.setDefTime(new Date());
indAcsDef.setUpdTime(new Date());
indAcsDefService.saveOrUpdate(indAcsDef);
IndAcsScoreInfo indAcsScoreInfo = new IndAcsScoreInfo();
indAcsScoreInfo.setAppraisalsDate(202004);
indAcsScoreInfo.setIndexId(indId);
indAcsScoreInfo.setScoreFormula(formula);
indAcsScoreInfo.setWeight(1.0);
indAcsScoreInfo.setUpdateTime(new Date());
indAscScoreService.save(indAcsScoreInfo);
}
@ApiOperation(value = "对标计算", notes = "对标计算")
@PostMapping(value = "/calculateComp")
public void calculateComp(@RequestParam String compareId,@RequestParam String compareObjsString,
@RequestParam String driveIndIdsString,@RequestParam int date) {
driveIndCalResultService.calculateComp(compareId, compareObjsString, driveIndIdsString, date);
}
}
package com.keymobile.indicators.api.hytobacco;
import java.io.InputStream;
import java.util.List;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.keymobile.indicators.service.hytobacco.IndicatorsValueService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@Api(tags={"指标值录入接口"})
@RestController
@RequestMapping(value = "/indicatorsValue")
public class IndicatorsValueCtrl {
@Autowired
private IndicatorsValueService indicatorsValueService;
@ApiOperation(value = "上传解析基础指标数据", notes = "上传解析基础指标数据")
@PostMapping(value = "/importIndiValue")
public void importIndicatorsData(@RequestParam("file") MultipartFile file)throws Exception{
try (InputStream is = file.getInputStream()){
XSSFWorkbook xssfWorkbook = new XSSFWorkbook(is);
indicatorsValueService.importIndicatorsData(xssfWorkbook);
}
}
@ApiOperation(value = "上传解析市基础指标数据", notes = "上传解析市基础指标数据")
@PostMapping(value = "/importShiIndiValue")
public void importShiIndicatorsData(@RequestParam("file") MultipartFile file)throws Exception{
try (InputStream is = file.getInputStream()){
XSSFWorkbook xssfWorkbook = new XSSFWorkbook(is);
indicatorsValueService.importShiIndicatorsData(xssfWorkbook);
}
}
@ApiOperation(value = "填充excel file1数据", notes = "填充excel file1数据")
@PostMapping(value = "/fillExcelFileOne")
public void fillExcelFileOne(@RequestBody List<String> indIds,@RequestParam int date,
@RequestParam String type,@RequestParam(required=false) String compareId) throws Exception{
indicatorsValueService.fillExcelFileOne(indIds, date, type,compareId);
}
}
//package com.keymobile.indicators.conf; package com.keymobile.indicators.conf;
//import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
//import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
//import org.springframework.data.mongodb.MongoDbFactory; import org.springframework.data.mongodb.MongoDbFactory;
//import org.springframework.data.mongodb.config.AbstractMongoConfiguration; import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
//import org.springframework.data.mongodb.core.SimpleMongoDbFactory; import org.springframework.data.mongodb.core.SimpleMongoDbFactory;
//import org.springframework.data.mongodb.gridfs.GridFsTemplate; import org.springframework.data.mongodb.gridfs.GridFsTemplate;
//
//import com.mongodb.MongoClient; import com.mongodb.MongoClient;
//import com.mongodb.MongoClientOptions; import com.mongodb.MongoClientOptions;
//import com.mongodb.MongoClientURI; import com.mongodb.MongoClientURI;
//import com.mongodb.client.MongoDatabase; import com.mongodb.client.MongoDatabase;
//import com.mongodb.client.gridfs.GridFSBucket; import com.mongodb.client.gridfs.GridFSBucket;
//import com.mongodb.client.gridfs.GridFSBuckets; import com.mongodb.client.gridfs.GridFSBuckets;
//
//@Configuration @Configuration
//public class MongoDBConfig extends AbstractMongoConfiguration { public class MongoDBConfig extends AbstractMongoConfiguration {
//
// @Value("${mongodb.uri}") @Value("${mongodb.uri}")
// private String host; private String host;
// @Value("${mongodb.database}") @Value("${mongodb.database}")
// private String database; private String database;
// @Value("${mongodb.username}") @Value("${mongodb.username}")
// private String user; private String user;
// @Value("${mongodb.password}") @Value("${mongodb.password}")
// private String pswd; private String pswd;
// @Value("${mongodb.maxConnectionIdleTime}") @Value("${mongodb.maxConnectionIdleTime}")
// private Integer maxConnectionIdleTime = 60000; private Integer maxConnectionIdleTime = 60000;
//
// @Override @Override
// protected String getDatabaseName() { protected String getDatabaseName() {
// return database; return database;
// } }
//
//
// @Bean @Bean
// public MongoDbFactory mongoDbFactory() { public MongoDbFactory mongoDbFactory() {
// return new SimpleMongoDbFactory(this.mongoClient(), this.getDatabaseName()); return new SimpleMongoDbFactory(this.mongoClient(), this.getDatabaseName());
// } }
//
// @Bean @Bean
// public GridFsTemplate gridFsTemplate() throws Exception { public GridFsTemplate gridFsTemplate() throws Exception {
// return new GridFsTemplate(mongoDbFactory(), mappingMongoConverter()); return new GridFsTemplate(mongoDbFactory(), mappingMongoConverter());
// } }
//
// @Bean @Bean
// public GridFSBucket getGridFSBuckets() { public GridFSBucket getGridFSBuckets() {
// MongoDatabase db = mongoDbFactory().getDb(); MongoDatabase db = mongoDbFactory().getDb();
// return GridFSBuckets.create(db); return GridFSBuckets.create(db);
// } }
//
//
// @Override @Override
// public MongoClient mongoClient() { public MongoClient mongoClient() {
// String uri = String.format("mongodb://%s:%s@%s/%s", user, pswd, host, database); String uri = String.format("mongodb://%s:%s@%s/%s", user, pswd, host, database);
// MongoClientOptions.Builder builder = new MongoClientOptions.Builder(); MongoClientOptions.Builder builder = new MongoClientOptions.Builder();
// builder.maxConnectionIdleTime(maxConnectionIdleTime); builder.maxConnectionIdleTime(maxConnectionIdleTime);
// MongoClientURI clientURI = new MongoClientURI(uri, builder); MongoClientURI clientURI = new MongoClientURI(uri, builder);
// return new MongoClient(clientURI); return new MongoClient(clientURI);
// } }
//
//} }
package com.keymobile.indicators.model.entity;
public class DimValue {
private String dimName;
private Object dimvalue;
private String dimvalueType;
public DimValue(String dimName,Object dimvalue,String dimvalueType) {
this.dimName = dimName;
this.dimvalue = dimvalue;
this.dimvalueType = dimvalueType;
}
public Object getDimvalue() {
return dimvalue;
}
public void setDimvalue(Object dimvalue) {
this.dimvalue = dimvalue;
}
public String getDimvalueType() {
return dimvalueType;
}
public void setDimvalueType(String dimvalueType) {
this.dimvalueType = dimvalueType;
}
public String getDimName() {
return dimName;
}
public void setDimName(String dimName) {
this.dimName = dimName;
}
}
package com.keymobile.indicators.model.entity;
import java.io.Serializable;
import java.util.Date;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import com.keymobile.indicators.utils.DateUtils;
import lombok.Data;
/**
*author:zhangkb time:2020-4-27 desc:考核指标计算结果表
*/
@Data
@Document(collection="drive_ind_cal_result")
public class DriveIndCalResult implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
@Id
private String id;
private String compareId;
private String indId;
private String compareObj;
private int date;
private String value;
private String unit;
private String type;//0:季度 1:年度
private String isRight;//表示考核指标的值是否计算正常得到的 0:计算有误 1:计算正常
private String lastUpdateTime = DateUtils.formatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
private String lastUpdater;
private String average;//平均数
private int rank;//同组排名
public DriveIndCalResult(String compareId,String indId,String compareObj,int date,String value,
String unit,String type,String isRight,String lastUpdater) {
this.compareId = compareId;
this.indId = indId;
this.compareObj = compareObj;
this.date = date;
this.value = value;
this.unit = unit;
this.type = type;
this.isRight = isRight;
this.lastUpdater = lastUpdater;
}
}
package com.keymobile.indicators.persistence.hyindicators;
import java.util.List;
import org.springframework.data.mongodb.repository.MongoRepository;
import com.keymobile.indicators.model.entity.DriveIndCalResult;
public interface DriveIndCalResultRepository extends MongoRepository<DriveIndCalResult,String>{
public List<DriveIndCalResult> findByIndIdAndDate(String indId,int date);
public List<DriveIndCalResult> findByIndIdAndDateAndCompareId(String indId,int date,String compareId);
}
...@@ -28,20 +28,20 @@ public class IndAcsScoreInfoService { ...@@ -28,20 +28,20 @@ public class IndAcsScoreInfoService {
private IndAcsDefMapper indAcsDefMapper; private IndAcsDefMapper indAcsDefMapper;
public String save(IndAcsScoreInfo indAcsScoreInfo) throws Exception{ public String save(IndAcsScoreInfo indAcsScoreInfo) throws Exception{
if(StringUtils.isBlank(indAcsScoreInfo.getOrgId())|| // if(StringUtils.isBlank(indAcsScoreInfo.getOrgId())||
StringUtils.isBlank(indAcsScoreInfo.getIndexId())|| // StringUtils.isBlank(indAcsScoreInfo.getIndexId())||
StringUtils.isBlank(indAcsScoreInfo.getIndexAttrId())) { // StringUtils.isBlank(indAcsScoreInfo.getIndexAttrId())) {
return "orgId,indexId,indexAttrId can not be null"; // return "orgId,indexId,indexAttrId can not be null";
}else { // }else {
//根据组织机构id,指标编号和指标类型判断是否有公式存在 // //根据组织机构id,指标编号和指标类型判断是否有公式存在
IndAcsScoreInfo dbIndAcsScoreInfo = this.selectOneByOrgIdAndIndidAndIndtype( // IndAcsScoreInfo dbIndAcsScoreInfo = this.selectOneByOrgIdAndIndidAndIndtype(
indAcsScoreInfo.getOrgId(),indAcsScoreInfo.getIndexId(),indAcsScoreInfo.getIndexAttrId()); // indAcsScoreInfo.getOrgId(),indAcsScoreInfo.getIndexId(),indAcsScoreInfo.getIndexAttrId());
if(dbIndAcsScoreInfo!=null) { // if(dbIndAcsScoreInfo!=null) {
return "the indicators have exist,can not save to the database"; // return "the indicators have exist,can not save to the database";
}else { // }else {
indAcsScoreInfoMapper.insert(indAcsScoreInfo); indAcsScoreInfoMapper.insert(indAcsScoreInfo);
} // }
} // }
return "save success"; return "save success";
} }
......
package com.keymobile.indicators.service.hytobacco;
import java.util.Arrays;
import java.util.Optional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.keymobile.indicators.akka.actor.specific.DriveIndCompareObjActor;
import com.keymobile.indicators.akka.message.specific.DriveIndCompareObjMsg;
import com.keymobile.indicators.model.entity.DriveIndCalResult;
import com.keymobile.indicators.persistence.hyindicators.DriveIndCalResultRepository;
import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;
@Service
public class DriveIndCalResultService {
private Logger logger = LoggerFactory.getLogger(DriveIndCalResultService.class);
@Autowired
private DriveIndCalResultRepository driveIndCalResultRepo;
public DriveIndCalResult saveOrUpdate(DriveIndCalResult driveIndCalResult) {
return driveIndCalResultRepo.save(driveIndCalResult);
}
public DriveIndCalResult findById(String id) {
Optional<DriveIndCalResult> resultOp = driveIndCalResultRepo.findById(id);
if(resultOp.isPresent()) {
return resultOp.get();
}
return null;
}
public void calculateComp(String compareId,String compareObjsString,String driveIndIdsString,
int date) {
String[] compareObjs = compareObjsString.split(";");
String[] driveIndIds = driveIndIdsString.split(";");
//启动回流actor
final ActorSystem system = ActorSystem.create("DriveIndCompareAkka");//创建akka
DriveIndCompareObjMsg driveIndCompareObjMsg = new DriveIndCompareObjMsg(compareId,
Arrays.asList(driveIndIds),Arrays.asList(compareObjs),date);
ActorRef driveIndCompareObjActor = system.actorOf(Props.create(DriveIndCompareObjActor.class,
()->new DriveIndCompareObjActor()));
driveIndCompareObjActor.tell(driveIndCompareObjMsg, ActorRef.noSender());
logger.info("开始对标计算...");
}
}
package com.keymobile.indicators.utils;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import com.googlecode.aviator.AviatorEvaluator;
public class CalculateUtils {
//考虑同分并列的情况,type:0 正向排序:从大到小 1:反向排序:从小到大
public static Map<String,Integer> rankValue(Map<String,String> valueMap,String type){
Map<String,Integer> result = new HashMap<>();
Map<String,Double> compareMap = new HashMap<>();
Map<String,String> invalidMap = new HashMap<>();
//将map中的无效值挑出来
for(Entry<String,String> entry : valueMap.entrySet()) {
if("NaN".equals(entry.getValue())||"0(Error)".equals(entry.getValue())
|| "0.0000".equals(entry.getValue()) || "0".equals(entry.getValue())) {
invalidMap.put(entry.getKey(),entry.getValue());
}else {
compareMap.put(entry.getKey(), Double.valueOf(entry.getValue()));
}
}
if("0".equals(type)) {
compareMap = sortByValueDesc(compareMap);
}else {
compareMap = sortByValueAsc(compareMap);
}
//进行排名
int order = 0;
Double headIndValue = 0.0;
int i=0;
for(Entry<String,Double> entry : compareMap.entrySet()) {
if(i==0) {
result.put(entry.getKey(), 1);
order+=1;
i++;
continue;
}
if(entry.getValue().equals(headIndValue)) {
result.put(entry.getKey(), order);
}else {
order+=1;
result.put(entry.getKey(), order);
}
headIndValue = entry.getValue();
}
order+=1;
if(!invalidMap.isEmpty()) {
for(Entry<String,String> entry : invalidMap.entrySet()) {
result.put(entry.getKey(), order);
}
}
return result;
}
public static String averageValue(List<String> values) {
String calValue = "0.0";
StringBuilder formula = new StringBuilder();
if(!values.isEmpty()) {
int size = values.size();
formula.append("(");
for(int i=0;i<values.size();i++) {
if("NaN".equals(values.get(i)) || "0(Error)".equals(values.get(i))
|| "0.0000".equals(values.get(i)) || "0".equals(values.get(i))) {
size -= 1;
continue;
}
if(i==values.size()-1) {//最后一个不加+号
formula.append("(").append(values.get(i)).append(")");
}else {
formula.append("(").append(values.get(i)).append(")").append("+");
}
}
if(formula.toString().endsWith("+")) {
formula.deleteCharAt(formula.length()-1);
}
formula.append(")");
if(!"()".equals(formula.toString())) {
formula.append("/").append(size).append(".0");
//计算平均值
calValue = String.format("%.4f",
new BigDecimal((Double)AviatorEvaluator.execute(formula.toString())));
}
}
return calValue;
}
private static Comparator<Map.Entry> comparatorByValueAsc = (Map.Entry o1, Map.Entry o2) -> {
if (o1.getValue() instanceof Comparable) {
return ((Comparable) o1.getValue()).compareTo(o2.getValue());
}
throw new UnsupportedOperationException("值的类型尚未实现Comparable接口");
};
private static Comparator<Map.Entry> comparatorByValueDesc = (Map.Entry o1, Map.Entry o2) -> {
if (o1.getValue() instanceof Comparable) {
return ((Comparable) o2.getValue()).compareTo(o1.getValue());
}
throw new UnsupportedOperationException("值的类型尚未实现Comparable接口");
};
/**
* 按键降序排列
*/
public static <K, V> Map<K, V> sortByValueDesc(Map<K, V> originMap) {
if (originMap == null) {
return null;
}
return sort(originMap, comparatorByValueDesc);
}
/**
* 按值升序排列
*/
public static <K, V> Map<K, V> sortByValueAsc(Map<K, V> originMap) {
if (originMap == null) {
return null;
}
return sort(originMap, comparatorByValueAsc);
}
private static <K, V> Map<K, V> sort(Map<K, V> originMap, Comparator<Map.Entry> comparator) {
return originMap.entrySet()
.stream()
.sorted(comparator)
.collect(
Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e2,
LinkedHashMap::new));
}
public static void main(String[] args) {
// System.out.println(AviatorEvaluator.execute("0/1.0"));
// Map<String, Object> env = Maps.newHashMap();
// env.put("F004", 18471.8080);
// env.put("F002", 197125.8532);
// // 输出的是6.333333333333333
// System.out.println(AviatorEvaluator.execute("F004/F002*100", env));
List<String> values = new ArrayList<>();
values.add("0");
values.add("18");
values.add("18");
CalculateUtils cal = new CalculateUtils();
String average = cal.averageValue(values);
System.out.println(average);
// Map<String,String> map = new HashMap<>();
// map.put("1", "NaN");
// map.put("2", "12.3345");
// map.put("3", "9.2349");
// map.put("4", "10.2457");
// map.put("5", "7.2221");
// map.put("6", "10.2457");
// map.put("7", "NaN");
// map.put("8", "8.343");
// CalculateUtils cal = new CalculateUtils();
// Map<String,Integer> result = cal.rankValue(map, "1");
// System.out.println(result);
}
}
...@@ -3,11 +3,33 @@ package com.keymobile.indicators.utils; ...@@ -3,11 +3,33 @@ package com.keymobile.indicators.utils;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import org.apache.commons.lang3.time.DateFormatUtils;
public class DateUtils { public class DateUtils {
private static final String PARSE_PATTERN_DD = "yyyy-MM-dd";
private static final String PARSE_PATTERN_SS = "yyyy-MM-dd HH:mm:ss";
private static String[] parsePatterns = { PARSE_PATTERN_DD, PARSE_PATTERN_SS, "yyyy-MM-dd HH:mm",
"yyyy/MM/dd", "yyyy/MM/dd HH:mm:ss", "yyyy/MM/dd HH:mm" };
public static Date getDate(String dateStr,String format) throws Exception{ public static Date getDate(String dateStr,String format) throws Exception{
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format); SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);
Date date = simpleDateFormat.parse(dateStr); Date date = simpleDateFormat.parse(dateStr);
return date; return date;
} }
/**
* 得到日期字符串 默认格式(yyyy-MM-dd) pattern可以为:parse_pattern_dd "HH:mm:ss" "E"
*/
public static String formatDate(Date date, Object... pattern) {
String formatDate = null;
if (pattern != null && pattern.length > 0) {
formatDate = DateFormatUtils.format(date, pattern[0].toString());
} else {
formatDate = DateFormatUtils.format(date, PARSE_PATTERN_DD);
}
return formatDate;
}
} }
package com.keymobile.indicators.utils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class SpringUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (SpringUtil.applicationContext == null) {
SpringUtil.applicationContext = applicationContext;
}
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}
spring: mongodb:
application: uri: 139.198.127.54:9017
name: indicators database: dev0
jpa: username: root
hibernate: password: dataPlatform
ddl-auto: update maxConnectionIdleTime: 600000
datasource:
url: jdbc:mysql://139.198.127.54:9306/indicators?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8 spring:
username: test application:
password: test name: indicators
hikari: jpa:
maximum-pool-size: 3 hibernate:
servlet: ddl-auto: update
multipart: datasource:
max-file-size: 20Mb url: jdbc:mysql://139.198.127.54:9306/hyindicators?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8
max-request-size: 100Mb username: test
session: password: test
store-type: redis hikari:
redis: maximum-pool-size: 3
namespace: dataplatformdev servlet:
redis: multipart:
host: 139.198.127.54 max-file-size: 20Mb
port: 9379 max-request-size: 100Mb
server: session:
port: 8667 store-type: redis
servlet: redis:
context-path: /indicators/ namespace: dataplatformdev
redis:
eureka: host: 139.198.127.54
client: port: 9379
registerWithEureka: true server:
region: default port: 8667
registryFetchIntervalSeconds: 5 servlet:
serviceUrl: context-path: /indicators/
defaultZone: http://192.168.0.230:8081/eureka/
enabled: false eureka:
instance: client:
prefer-ip-address: true registerWithEureka: true
hostname: 192.168.0.230 region: default
registryFetchIntervalSeconds: 5
security: serviceUrl:
permit: true defaultZone: http://192.168.0.230:8081/eureka/
authUser: root enabled: false
authPwd: pwd instance:
prefer-ip-address: true
mybatis: hostname: 192.168.0.230
config-location: classpath:/mybatis/mybatis-config.xml
mapper-locations: classpath:/mybatis/mapping/*.xml security:
permit: true
authUser: root
authPwd: pwd
mybatis:
config-location: classpath:/mybatis/mybatis-config.xml
mapper-locations: classpath:/mybatis/mapping/*.xml
type-aliases-package: com.keymobile.indicators.model.entity type-aliases-package: com.keymobile.indicators.model.entity
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment