Commit 7432a1b1 by liushaowei

需求1756:TKIO增加试用流量报表

需求1758:TKIO合同导入主账号为空时全部收入计算在合同截止日期 需求1759:TKIO补充协议录入时关联合同必填 需求1772:TKIO补充协议录入后原始合同及补充协议均不能补充作废、中止
parent 787093b6
......@@ -51,6 +51,11 @@
<tkio.username>root</tkio.username>
<tkio.password>reyun123</tkio.password>
<etl.url>jdbc:mysql://192.168.2.57:3306/trackingio?characterEncoding=utf-8</etl.url>
<etl.username>root</etl.username>
<elt.password>reyun123</elt.password>
<track.url>jdbc:mysql://192.168.2.57:3306/track?characterEncoding=utf-8</track.url>
<track.username>root</track.username>
<track.password>reyun123</track.password>
......@@ -113,6 +118,10 @@
<tkio.username>root</tkio.username>
<tkio.password>reyun.123</tkio.password>
<etl.url>jdbc:mysql://10.3.20.32:3306/tkio?characterEncoding=utf-8</etl.url>
<etl.username>root</etl.username>
<etl.password>reyun.123</etl.password>
<office.url>jdbc:mysql://10.3.20.32:3306/office?characterEncoding=utf-8</office.url>
<office.username>root</office.username>
<office.password>reyun.123</office.password>
......@@ -145,8 +154,6 @@
<!-- 单位是分钟-->
<mail.valid_time>3</mail.valid_time>
<!--<report.url>http://localhost:9010</report.url>-->
<report.url>http://10.3.20.41:9010</report.url>
<import.temp.url>http://10.3.20.41:9001</import.temp.url>
......@@ -811,6 +818,11 @@
<artifactId>jcommander</artifactId>
<version>1.48</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
</dependencies>
<!-- 配置构建 -->
......
......@@ -6,6 +6,7 @@ import common.service.ShareIncomeService;
import dic.AuthMenuEnmm;
import dic.ContractStatusEnum;
import dic.OperateObjectTypeEnum;
import offline.model.TrackFlowVO;
import org.apache.commons.io.IOUtils;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
......@@ -738,4 +739,44 @@ public class ContractController {
}
/**
* 试用流量
*/
@GetMapping(value = "/trialFlow")
@ResponseBody
@AuthKey(AuthMenuEnmm.SHARED_INCOME_V)
public ResultModel trialFlow(@CurrentAccount User loginAccount, @PathVariable String platform,
@RequestParam String startDate, @RequestParam String endDate,
String email) {
return ResultModel.OK(shareIncomeService.trialFlow(loginAccount, startDate, endDate, platform,email));
}
/**
* 试用流量导出
*/
@GetMapping(value = "trialFlowExport", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
@AuthKey(AuthMenuEnmm.CONTRACTMNG_EX)
public void trialFlowExport(@CurrentAccount User loginAccount, @PathVariable String platform,
@RequestParam String startDate, @RequestParam String endDate,String email, HttpServletRequest request, HttpServletResponse response) {
List<TrackFlowVO> list = shareIncomeService.trialFlow(loginAccount, startDate, endDate, platform, email);
List<String> title = Arrays.asList("主账号,流量(万次)".split(","));
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet();
HSSFRow row = sheet.createRow(0);
int lineSize = title.size();
for (int i = 0; i < lineSize; i++) {
row.createCell(i).setCellValue(title.get(i));
}
for (int i = 0; i < list.size(); i++) {
TrackFlowVO flow = list.get(i);
HSSFRow rowBody = sheet.createRow(i + 1);
rowBody.createCell(0).setCellValue(flow.getEmail());
rowBody.createCell(1).setCellValue(flow.getTrackFlow());
}
String fileName = "试用流量_" + new DateTime(startDate).toString("yyyyMMdd")+ "_" + new DateTime(endDate).toString("yyyyMMdd") + ".xls";
this.exportWrite(fileName, workbook, "试用流量_", response);
}
}
......@@ -97,6 +97,7 @@ public class Contract {
private Double trackFlow;//流量,tkio的,万单位
private Double unitPrice;//单价,tkio
private Double clickFlow;//区间点击数,tkio
private Boolean operate = true;
@Id
@GeneratedValue
......@@ -606,6 +607,15 @@ public class Contract {
this.incomeGross = incomeGross;
}
@Transient
public Boolean getOperate() {
return operate;
}
public void setOperate(Boolean operate) {
this.operate = operate;
}
@Override
public String toString() {
return "Contract{" +
......
......@@ -128,4 +128,11 @@ public interface ContractRepository extends JpaRepository<Contract, Long> {
@Query(value = "SELECT * from contract where platform = ?1 and email = ?2", nativeQuery = true)
List<Contract> findByPlatformAndEmail(String platform, String email);
@Query(value = "select id from contract where (email is null or email='null') and ( end_date >= ?1 and end_date <= ?2 )", nativeQuery = true)
List<Long> findAllEmailIsNull(String startDate, String endDate);
@Query(value = "SELECT relation_contract FROM contract where contract_type=2 and status!='del'", nativeQuery = true)
List<Long> findRelationContractBySideAgre();
}
......@@ -2,6 +2,7 @@ package common.service;
import common.model.Contract;
import common.model.User;
import offline.model.TrackFlowVO;
import org.joda.time.DateTime;
import java.util.List;
......@@ -11,4 +12,6 @@ public interface ShareIncomeService {
List<Contract> shareIncomeList(User loginAccount, String startDate, String endDate, String platform, String bodyCode, String serchName);
boolean checkLateContract(DateTime dateTime, DateTime creatTime);
List<TrackFlowVO> trialFlow(User loginAccount, String startDate, String endDate, String platform, String email);
}
......@@ -499,6 +499,25 @@ public class ContractServiceImpl implements ContractService {
return null;
}
//补充协议
if("2".equals(resource.getContractType())){
//关联合同不能为空
if(null == resource.getRelationContract() || "".equals(resource.getRelationContract())|| -1L == resource.getRelationContract()){
Contract contractExist = new Contract();
contractExist.setId(-100L);
contractExist.setErroMessage("关联合同为必填项");
return contractExist;
}
//补充协议开始日期不能晚于原始合同的结束日期
Contract relationContract = contractRepository.findOne(resource.getRelationContract());
if(relationContract.getEndDate().compareTo(resource.getStartDate())<0){
Contract contractExist = new Contract();
contractExist.setId(-100L);
contractExist.setErroMessage("补充协议开始日期不能晚于原始合同的结束日期");
return contractExist;
}
}
if (!StringUtils.isEmpty(resource.getContractCode())
&& !ContractStatusEnum.MONEY_BACK_FIRST.getKey().equals(resource.getStatus())) {
Contract contractExist = contractRepository.findByCode(resource.getContractCode().trim());
......@@ -1466,6 +1485,20 @@ public class ContractServiceImpl implements ContractService {
result.add(c);
}
}
//对结果二次加工
List<Long> relationContracts = contractRepository.findRelationContractBySideAgre();//查询被补充协议关联的合同
for(Contract contract:result){
if(null ==contract.getContractType() || !"2".equals(contract.getContractType())){ //非补充协议
if(relationContracts.contains(BigInteger.valueOf(contract.getId()))){
contract.setOperate(false);//如果合同 被补充协议关联
}
}else {
if(contract.getRelationContract()!=null && contract.getRelationContract()>0){ //补充协议
contract.setOperate(false);//如果补充协议被关联
}
}
}
return result;
}
......@@ -2426,9 +2459,17 @@ public class ContractServiceImpl implements ContractService {
String sheetTitle = titleKey.get(w);
Cell cell = row_data.getCell(w);
int line_num = j + 1;
if (null == cell || cell.getCellTypeEnum().equals(CellType.BLANK)) {
return ResultModel.ERROR("第" + line_num + "行【" +
SHEET_TITLE_RESERVE.get(sheetTitle) + "】不能为空,请重新上传");
if (null == cell || cell.getCellTypeEnum().equals(CellType.BLANK) || "null".equalsIgnoreCase(formatter.formatCellValue(cell).trim())) {
//主账号为空,额外处理
if ("email".equals(sheetTitle) && "tkio".equals(platformexcl) && "null".equalsIgnoreCase(formatter.formatCellValue(cell).trim())) {
String dataSTR = "null";
s_data[w] = dataSTR;
moreEmail.add(dataSTR.trim());
accountsEmail.add(dataSTR.trim());
}else{
//非主账号 按照之前逻辑不变
return ResultModel.ERROR("第" + line_num + "行【" + SHEET_TITLE_RESERVE.get(sheetTitle) + "】不能为空,请重新上传");
}
} else {
String dataSTR = formatter.formatCellValue(cell).trim();
//校验合同编号
......@@ -2436,14 +2477,12 @@ public class ContractServiceImpl implements ContractService {
if (!codeUniqueDic.containsKey(dataSTR)) {
codeUniqueDic.put(dataSTR, "1");
} else {
return ResultModel.ERROR(ResultStatus.CCODE_EXITS.getCode(),
"合同编号【" + dataSTR + "】已存在,请重新上传");
return ResultModel.ERROR(ResultStatus.CCODE_EXITS.getCode(),"合同编号【" + dataSTR + "】已存在,请重新上传");
}
Contract contractExist = contractRepository.checkByCode(dataSTR);
if (contractExist != null) {
return ResultModel.ERROR(ResultStatus.CCODE_EXITS.getCode(),
"合同编号【" + dataSTR + "】已存在,请重新上传");
return ResultModel.ERROR(ResultStatus.CCODE_EXITS.getCode(),"合同编号【" + dataSTR + "】已存在,请重新上传");
}
}
......@@ -2523,8 +2562,8 @@ public class ContractServiceImpl implements ContractService {
return ResultModel.ERROR("第" + line_num + "行【行政区域】code错误");
}
} else {
//主账号不为空,按照之前逻辑不变
s_data[w] = dataSTR;
if ("email".equals(sheetTitle) && !StringUtils.isEmpty(dataSTR) && "tkio".equals(platformexcl)) {
if (!accountsEmail.contains(dataSTR.trim())) {
moreEmail.add(dataSTR.trim());
......@@ -2557,17 +2596,22 @@ public class ContractServiceImpl implements ContractService {
for (int i = 0; i < accountsEmail.size(); i++) {
String e = accountsEmail.get(i);
if ("tkio".equals(platformexcl) && "null".equals(e)) {
// tiko允许主账号email是空
}else{
//按照之前逻辑
if (!emailDic.containsKey(e)) {
return ResultModel.ERROR("第" + (i + 1) + "行 客户主账号【" + e + "】在Office运营后台未找到,请重新上传");
}
}
}
}
//platform,product,my_body_code,create_time,code_num,type,status,back_status,ds,
s_data[row_already] = platform;
s_data[row_already + 1] = "tkio".equals(platform) ? "trackingio" : platform;
s_data[row_already + 2] = bodyCode;
s_data[row_already + 3] = createTime;
s_data[row_already + 3] = DateUtil.getCurrentDateStr(DateUtil.C_TIME_PATTON_DEFAULT);
s_data[row_already + 4] = 0;
s_data[row_already + 5] = "main";
s_data[row_already + 6] = ContractStatusEnum.NFORMAL.getKey(); //常规合同
......@@ -2617,7 +2661,7 @@ public class ContractServiceImpl implements ContractService {
calculationFlow.setEmail(email);
calculationFlow.setStatus(0);
calculationFlow.setTriggerType("导入");
calculationFlow.setCreateTime(DateUtil.getCurrentDateStr());
calculationFlow.setCreateTime(DateUtil.getCurrentDateStr(DateUtil.C_TIME_PATTON_DEFAULT));
calculationFlow.setIsAll(true);
calculationFlowRepository.save(calculationFlow);
}
......@@ -2626,7 +2670,6 @@ public class ContractServiceImpl implements ContractService {
}
private boolean parseRowData(Row row, int length, StringBuffer content, List<String> titleKey) {
if (row == null) {
......
......@@ -6,6 +6,9 @@ import common.service.ShareIncomeService;
import dic.ContractStatusEnum;
import dic.RoleEnum;
import net.sf.json.JSONArray;
import offline.model.AccountVO;
import offline.model.TrackFlowVO;
import offline.repository.TkioOfflineRepository;
import org.joda.time.DateTime;
import org.joda.time.DateTimeUtils;
import org.joda.time.Days;
......@@ -22,11 +25,13 @@ import tkio.repository.AppRepository;
import tkio.service.AccountFlowRestrictService;
import util.ContractBranchUtil;
import util.DateUtil;
import util.StringUtil;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
......@@ -58,6 +63,8 @@ public class ShareIncomeServiceImpl implements ShareIncomeService {
private PackageBaseRepository packageBaseRepository;
@Autowired
private TkioFlowRepository tkioFlowRepository;
@Autowired
private TkioOfflineRepository tkioOfflineRepository;
@Override
public List<Contract> shareIncomeList(User loginAccount, String startDate, String endDate, String platform, String bodyCode, String serchName) {
......@@ -152,6 +159,24 @@ public class ShareIncomeServiceImpl implements ShareIncomeService {
}
logger.info("计算分摊收入耗时:{}", (System.currentTimeMillis() - start_));
//结果集result二次加工
if ("tkio".equals(platform)) {
//查询主账号为空的 并且 结束日期在查询范围内的
List<Long> allEmailIsNullIds = contractRepository.findAllEmailIsNull(startDate, endDate);
for(Contract contract : contracts){
if(StringUtil.isEmpty(contract.getEmail()) || "null".equals(contract.getEmail())){
//不在查询范围内的数据,全部置空
if(allEmailIsNullIds ==null || !allEmailIsNullIds.contains(BigInteger.valueOf(contract.getId()))) {
contract.setClickFlow(0D); //区间点击数(万次)
contract.setIntervaIncomeShare(0L);//区间分摊收入
contract.setAdjustmentFund(0L);//区间调整金额
contract.setIncomeShareAll(0L);//区间总收入
contract.setIncomeGross(0L);//累计总收入(元)
}
}
}
}
return contracts;
}
......@@ -1028,6 +1053,58 @@ public class ShareIncomeServiceImpl implements ShareIncomeService {
return dateTime1.isBefore(dateTime2) || dateTime1.isEqual(dateTime2);
}
@Override
public List<TrackFlowVO> trialFlow(User loginAccount, String startDate, String endDate, String platform, String email) {
//离线数据值
Map<String, Double> offlineResult = tkioOfflineRepository.findOfflineResult(startDate, endDate);
//查询主账号
List<Map<String,String>> list = null;
if(StringUtil.isEmpty(email)){
list = accountRepository.findAllAccountAppKeys();
}else{
list = accountRepository.findAccountAppKeysByEmail(email);
}
JSONArray jsonObject = JSONArray.fromObject(list);
Iterator it= jsonObject.iterator();
List<AccountVO> avs = new ArrayList<>();
while (it.hasNext()){
JSONArray array = JSONArray.fromObject(it.next());
String e = array.getString(0);
String k = array.getString(1);
AccountVO vo = new AccountVO();
vo.setEmail(e);
vo.setAppKey(k);
avs.add(vo);
}
//汇总计算
List<TrackFlowVO> result = new ArrayList<>();
for(AccountVO ac:avs){
TrackFlowVO tf = new TrackFlowVO(ac.getEmail());
String appKeys = ac.getAppKey();
//如果appKey为空,流量为0
if("".equals(appKeys.trim())){
tf.setTrackFlow(0.0);
result.add(tf);
continue;
}
Double sum = 0.0;
String[] keyArr = appKeys.split(",");
for(String k:keyArr){
Double v = offlineResult.get(k);
if(v==null){
v = 0.0;
}
sum +=v;
}
tf.setTrackFlow(new BigDecimal(sum/10000).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue());
result.add(tf);
}
return result;
}
public static void main(String[] args) {
System.out.println(new BigDecimal(34009003 / 10000.0));
......
package offline.model;
/**
* @Author shaowei.Liu
* @Date 2020/11/5 13:57
* @Description 主账号对应的appKey
*/
public class AccountVO {
private String email;
private String appKey;
public AccountVO() {
}
public AccountVO(String email, String appKey) {
this.email = email;
this.appKey = appKey;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAppKey() {
return appKey;
}
public void setAppKey(String appKey) {
this.appKey = appKey;
}
@Override
public String toString() {
return email+"=>"+appKey;
}
}
package offline.model;
/**
* @Author shaowei.Liu
* @Date 2020/11/5 15:54
* @Description 试用流量返回结果
*/
public class TrackFlowVO {
private String email; //主账号
private Double trackFlow;//流量
public TrackFlowVO() {}
public TrackFlowVO(String email) {
this.email = email;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Double getTrackFlow() {
return trackFlow;
}
public void setTrackFlow(Double trackFlow) {
this.trackFlow = trackFlow;
}
}
package offline.repository;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Author shaowei.Liu
* @Date 2020/11/5 19:48
* @Description 查询离线数据: appKey对应的流量
*/
public class TkioOfflineRepository extends JdbcDaoSupport {
public Map<String,Double> findOfflineResult(String startDate,String endDate){
String sql = "SELECT appid as appkey,sum(if(click_num is null,0,click_num))+sum(if(num_impression is null,0,num_impression)) as appVal " +
"FROM measures_trackingio_new " +
"where DATE_FORMAT(ds,'%Y-%m-%d')>='"+startDate+"' and DATE_FORMAT(ds,'%Y-%m-%d')<='"+endDate+"' " +
"GROUP BY appid";
List<Map<String, Double>> list = this.getJdbcTemplate().query(sql, new RowMapper<Map<String, Double>>() {
@Override
public Map<String, Double> mapRow(ResultSet rs, int rowNum) throws SQLException {
String key = rs.getString("appkey");
Double val = rs.getDouble("appVal");
Map<String,Double> row = new HashMap<>();
row.put(key, val);
return row;
}
});
Map<String,Double> result = new HashMap<>();
for(Map<String,Double> map:list){
for(String key:map.keySet()){
result.put(key,map.get(key));
}
}
return result;
}
}
......@@ -9,6 +9,7 @@ import tkio.model.Account;
import java.math.BigInteger;
import java.util.Date;
import java.util.List;
import java.util.Map;
@Transactional
public interface AccountRepository extends JpaRepository<Account, Long> {
......@@ -42,4 +43,35 @@ public interface AccountRepository extends JpaRepository<Account, Long> {
@Query(value = "select email from account where is_super_user is true and email in ?1", nativeQuery = true)
List<String> findEmailByEmails(List<String> accountsEmail);
@Query(value = "" +
"select xy.email,IF(group_concat(xy.appkey separator ',') is not NULL,group_concat(xy.appkey separator ','),'') as appkey " +
"from(" +
" select x.appkey,y.pid,y.email,y.id" +
" from(" +
" select DISTINCT a.id pid,a.email,b.id" +
" from(select id,email from account where id = root_parent and role_category <> 5 and email not in (select distinct email from manager.contract where platform='tkio'))a " +
" join(select id,root_parent from account)b on a.id=b.root_parent " +
" )y " +
" left join app x " +
" on x.account=y.id " +
")xy " +
"group by xy.pid,xy.email", nativeQuery = true)
List<Map<String,String>> findAllAccountAppKeys();
@Query(value = "" +
"select xy.email,IF(group_concat(xy.appkey separator ',') is not NULL,group_concat(xy.appkey separator ','),'') as appkey " +
"from(" +
" select x.appkey,y.pid,y.email,y.id" +
" from(" +
" select DISTINCT a.id pid,a.email,b.id" +
" from(select id,email from account where id = root_parent and role_category <> 5 and email not in (select distinct email from manager.contract where platform='tkio')and email=?1)a " +
" join(select id,root_parent from account)b on a.id=b.root_parent " +
" )y " +
" left join app x " +
" on x.account=y.id " +
")xy " +
"group by xy.pid,xy.email", nativeQuery = true)
List<Map<String, String>> findAccountAppKeysByEmail(String email);
}
......@@ -29,3 +29,7 @@ io.dataSource.password=${io.password}
qcloudatasource.dataSource.url=${qcloudatasource.url}
qcloudatasource.dataSource.username=${qcloudatasource.username}
qcloudatasource.dataSource.password=${qcloudatasource.password}
etl.dataSource.url=${etl.url}
etl.dataSource.username=${etl.username}
etl.dataSource.password=${etl.password}
\ No newline at end of file
......@@ -27,6 +27,24 @@
<context:property-placeholder location="classpath:persistence.properties,classpath:redis.properties"/>
<bean id="tikoDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${dataSource.driverClassName}"></property>
<property name="jdbcUrl" value="${etl.dataSource.url}"></property>
<property name="user" value="${etl.dataSource.username}"></property>
<property name="password" value="${etl.dataSource.password}"></property>
</bean>
<!-- 将连接池注入 jdbcTemplate -->
<bean id="tikoTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="tikoDataSource"></property>
</bean>
<!-- 配置DAO -->
<bean id="tkioOfflineRepository" class="offline.repository.TkioOfflineRepository">
<property name="jdbcTemplate" ref="tikoTemplate"></property>
</bean>
<!--Redis配置-->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="300"/>
......
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