完成责任量化功能
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
package com.njcn.advance.controller.responsibility;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.njcn.advance.pojo.dto.responsibility.RespDataDTO;
|
||||
import com.njcn.advance.pojo.dto.responsibility.ResponsibilityResult;
|
||||
import com.njcn.advance.pojo.param.ResponsibilityCalculateParam;
|
||||
import com.njcn.advance.pojo.param.ResponsibilitySecondCalParam;
|
||||
import com.njcn.advance.service.responsibility.IRespDataResultService;
|
||||
import com.njcn.advance.service.responsibility.IRespDataService;
|
||||
import com.njcn.common.pojo.annotation.OperateInfo;
|
||||
import com.njcn.common.pojo.enums.common.LogEnum;
|
||||
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
||||
import com.njcn.common.pojo.response.HttpResult;
|
||||
import com.njcn.common.utils.HttpResultUtil;
|
||||
import com.njcn.web.controller.BaseController;
|
||||
import com.njcn.web.pojo.param.BaseParam;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* @author hongawen
|
||||
* @version 1.0.0
|
||||
* @date 2023年07月21日 10:06
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("responsibility")
|
||||
@Api(tags = "谐波责任划分-谐波责任数据处理")
|
||||
@RequiredArgsConstructor
|
||||
public class ResponsibilityController extends BaseController {
|
||||
|
||||
private final IRespDataService respDataService;
|
||||
|
||||
private final IRespDataResultService respDataResultService;
|
||||
|
||||
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
|
||||
@PostMapping("/responsibilityList")
|
||||
@ApiOperation("列表分页")
|
||||
@ApiImplicitParam(name = "queryParam", value = "查询参数", required = true)
|
||||
public HttpResult<Page<RespDataDTO>> responsibilityList(@RequestBody @Validated BaseParam queryParam) {
|
||||
String methodDescribe = getMethodDescribe("responsibilityList");
|
||||
Page<RespDataDTO> list = respDataService.responsibilityList(queryParam);
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, list, methodDescribe);
|
||||
}
|
||||
|
||||
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
|
||||
@PostMapping("/deleteByIds")
|
||||
@ApiOperation("删除责任划分数据")
|
||||
@ApiImplicitParam(name = "ids", value = "待删除的责任id集合", required = true)
|
||||
public HttpResult<Page<RespDataDTO>> deleteByIds(@RequestBody List<String> ids) {
|
||||
String methodDescribe = getMethodDescribe("deleteByIds");
|
||||
respDataService.deleteByIds(ids);
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@PostMapping("getDynamicData")
|
||||
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
|
||||
@ApiOperation("动态谐波责任划分")
|
||||
@ApiImplicitParam(name = "responsibilityCalculateParam", value = "谐波责任动态划分参数", required = true)
|
||||
public HttpResult<ResponsibilityResult> getDynamicData(@RequestBody @Validated ResponsibilityCalculateParam responsibilityCalculateParam) {
|
||||
String methodDescribe = getMethodDescribe("getDynamicData");
|
||||
ResponsibilityResult datas = respDataService.getDynamicData(responsibilityCalculateParam);
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, datas, methodDescribe);
|
||||
}
|
||||
|
||||
@PostMapping("getResponsibilityData")
|
||||
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
|
||||
@ApiOperation("二次计算责任划分")
|
||||
@ApiImplicitParam(name = "responsibilitySecondCalParam", value = "二次计算责任划分参数", required = true)
|
||||
public HttpResult<ResponsibilityResult> getResponsibilityData(@RequestBody @Validated ResponsibilitySecondCalParam responsibilitySecondCalParam) {
|
||||
String methodDescribe = getMethodDescribe("getResponsibilityData");
|
||||
ResponsibilityResult datas = respDataService.getResponsibilityData(responsibilitySecondCalParam);
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, datas, methodDescribe);
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("displayHistoryData")
|
||||
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
|
||||
@ApiOperation("回显历史责任划分结果")
|
||||
@ApiImplicitParam(name = "id", value = "责任数据id", required = true)
|
||||
public HttpResult<List<ResponsibilityResult>> displayHistoryData(String id,Integer time) {
|
||||
String methodDescribe = getMethodDescribe("displayHistoryData");
|
||||
List<ResponsibilityResult> datas = respDataResultService.displayHistoryData(id,time);
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, datas, methodDescribe);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
package com.njcn.advance.controller.responsibility;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.njcn.advance.pojo.dto.responsibility.RespDataDTO;
|
||||
import com.njcn.advance.pojo.param.UserDataIntegrityParam;
|
||||
import com.njcn.advance.pojo.po.responsibility.RespUserData;
|
||||
import com.njcn.advance.pojo.po.responsibility.RespUserDataIntegrity;
|
||||
import com.njcn.advance.service.responsibility.IRespUserDataIntegrityService;
|
||||
import com.njcn.advance.service.responsibility.IRespUserDataService;
|
||||
import com.njcn.common.pojo.annotation.OperateInfo;
|
||||
import com.njcn.common.pojo.dto.SelectOption;
|
||||
import com.njcn.common.pojo.enums.common.LogEnum;
|
||||
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
||||
import com.njcn.common.pojo.exception.BusinessException;
|
||||
import com.njcn.common.pojo.response.HttpResult;
|
||||
import com.njcn.common.utils.HttpResultUtil;
|
||||
import com.njcn.web.controller.BaseController;
|
||||
import com.njcn.web.pojo.param.BaseParam;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author hongawen
|
||||
* @version 1.0.0
|
||||
* @date 2023年07月13日 14:11
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("responsibility")
|
||||
@Api(tags = "谐波责任划分-用采数据处理")
|
||||
@RequiredArgsConstructor
|
||||
public class UserDataController extends BaseController {
|
||||
|
||||
|
||||
private final IRespUserDataService respUserDataService;
|
||||
|
||||
private final IRespUserDataIntegrityService respUserDataIntegrityService;
|
||||
|
||||
|
||||
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
|
||||
@PostMapping("/userDataList")
|
||||
@ApiOperation("列表分页")
|
||||
@ApiImplicitParam(name = "queryParam", value = "查询参数", required = true)
|
||||
public HttpResult<Page<RespUserData>> userDataList(@RequestBody @Validated BaseParam queryParam) {
|
||||
String methodDescribe = getMethodDescribe("userDataList");
|
||||
Page<RespUserData> list = respUserDataService.userDataList(queryParam);
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, list, methodDescribe);
|
||||
}
|
||||
|
||||
|
||||
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
|
||||
@GetMapping("/userDataIntegrityList")
|
||||
@ApiOperation("用采完整性不足列表")
|
||||
@ApiImplicitParam(name = "userDataIntegrityParam", value = "查询参数", required = true)
|
||||
public HttpResult<Page<RespUserDataIntegrity>> userDataIntegrityList(@RequestBody @Validated UserDataIntegrityParam userDataIntegrityParam) {
|
||||
String methodDescribe = getMethodDescribe("userDataIntegrityList");
|
||||
Page<RespUserDataIntegrity> list = respUserDataIntegrityService.userDataIntegrityList(userDataIntegrityParam);
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, list, methodDescribe);
|
||||
}
|
||||
|
||||
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
|
||||
@PostMapping("/deleteUserDataByIds")
|
||||
@ApiOperation("删除用采数据")
|
||||
@ApiImplicitParam(name = "ids", value = "待删除用采数据id集合", required = true)
|
||||
public HttpResult<Page<RespDataDTO>> deleteUserDataByIds(@RequestBody List<String> ids) {
|
||||
String methodDescribe = getMethodDescribe("deleteUserDataByIds");
|
||||
respUserDataService.deleteUserDataByIds(ids);
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
|
||||
}
|
||||
|
||||
|
||||
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
|
||||
@GetMapping("/userDataSelect")
|
||||
@ApiOperation("用采数据下拉")
|
||||
public HttpResult<List<SelectOption>> userDataSelect() {
|
||||
String methodDescribe = getMethodDescribe("userDataSelect");
|
||||
List<SelectOption> listOption = respUserDataService.userDataSelect();
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, listOption, methodDescribe);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传用采数据,并对用采数据进行数据分析并缓存
|
||||
*
|
||||
* @param file 上传的表格
|
||||
*/
|
||||
@PostMapping("uploadUserData")
|
||||
@OperateInfo(info = LogEnum.BUSINESS_COMMON)
|
||||
@ApiOperation("上传用采数据")
|
||||
public HttpResult<Object> uploadUserData(@ApiParam(value = "文件", required = true) @RequestPart("file") MultipartFile file, HttpServletResponse response) {
|
||||
String methodDescribe = getMethodDescribe("uploadUserData");
|
||||
String fileName = file.getOriginalFilename();
|
||||
long fileSize = file.getSize() / 1024;
|
||||
//判断文件大小
|
||||
if (fileSize > 3072) {
|
||||
throw new BusinessException(CommonResponseEnum.FILE_SIZE_ERROR);
|
||||
}
|
||||
if (!fileName.matches("^.+\\.(?i)(xlsx)$") && !fileName.matches("^.+\\.(?i)(xls)$")) {
|
||||
throw new BusinessException(CommonResponseEnum.FILE_XLSX_ERROR);
|
||||
}
|
||||
respUserDataService.uploadUserData(file, response);
|
||||
return HttpResultUtil.assembleCommonResponseResult(CommonResponseEnum.SUCCESS, null, methodDescribe);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.njcn.advance.mapper.responsibility;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.njcn.advance.pojo.dto.responsibility.RespDataDTO;
|
||||
import com.njcn.advance.pojo.po.responsibility.RespData;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author hongawen
|
||||
* @since 2023-07-21
|
||||
*/
|
||||
public interface RespDataMapper extends BaseMapper<RespData> {
|
||||
|
||||
Page<RespDataDTO> page(@Param("page") Page<Object> objectPage, @Param("ew")QueryWrapper<RespDataDTO> queryWrapper);
|
||||
|
||||
void deleteByIds(@Param("ids") List<String> ids);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.njcn.advance.mapper.responsibility;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.njcn.advance.pojo.po.responsibility.RespDataResult;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author hongawen
|
||||
* @since 2023-07-24
|
||||
*/
|
||||
public interface RespDataResultMapper extends BaseMapper<RespDataResult> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.njcn.advance.mapper.responsibility;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.njcn.advance.pojo.po.responsibility.RespUserDataIntegrity;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author hongawen
|
||||
* @since 2023-07-13
|
||||
*/
|
||||
public interface RespUserDataIntegrityMapper extends BaseMapper<RespUserDataIntegrity> {
|
||||
|
||||
Page<RespUserDataIntegrity> page(@Param("page") Page<Object> objectPage, @Param("ew") QueryWrapper<RespUserDataIntegrity> lambdaQueryWrapper);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.njcn.advance.mapper.responsibility;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.njcn.advance.pojo.po.responsibility.RespUserData;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author hongawen
|
||||
* @since 2023-07-13
|
||||
*/
|
||||
public interface RespUserDataMapper extends BaseMapper<RespUserData> {
|
||||
|
||||
Page<RespUserData> page(@Param("page")Page<Object> objectPage, @Param("ew")QueryWrapper<RespUserData> respUserDataQueryWrapper);
|
||||
|
||||
void deleteUserDataByIds(@Param("ids") List<String> ids);
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.njcn.advance.mapper.responsibility.RespDataMapper">
|
||||
|
||||
<select id="page" resultType="RespDataDTO">
|
||||
SELECT pqs_resp_data.*,
|
||||
pqs_resp_user_data.name userDataName
|
||||
FROM pqs_resp_data pqs_resp_data
|
||||
,pqs_resp_user_data pqs_resp_user_data
|
||||
WHERE pqs_resp_data.user_data_id = pqs_resp_user_data.id
|
||||
AND ${ew.sqlSegment}
|
||||
</select>
|
||||
|
||||
<update id="deleteByIds" >
|
||||
update
|
||||
pqs_resp_data
|
||||
set state = 0
|
||||
where
|
||||
id
|
||||
in
|
||||
<foreach collection="ids" item="item" separator="," open="(" close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
</update>
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.njcn.advance.mapper.responsibility.RespDataResultMapper">
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.njcn.advance.mapper.responsibility.RespUserDataIntegrityMapper">
|
||||
|
||||
<select id="page" resultType="RespUserDataIntegrity">
|
||||
SELECT pqs_resp_user_data_integrity.*
|
||||
FROM pqs_resp_user_data_integrity pqs_resp_user_data_integrity
|
||||
WHERE ${ew.sqlSegment}
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.njcn.advance.mapper.responsibility.RespUserDataMapper">
|
||||
|
||||
<select id="page" resultType="RespUserData">
|
||||
SELECT pqs_resp_user_data.*
|
||||
FROM pqs_resp_user_data pqs_resp_user_data
|
||||
WHERE ${ew.sqlSegment}
|
||||
</select>
|
||||
|
||||
<update id="deleteUserDataByIds" >
|
||||
update
|
||||
pqs_resp_user_data
|
||||
set state = 0
|
||||
where
|
||||
id
|
||||
in
|
||||
<foreach collection="ids" item="item" separator="," open="(" close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
</update>
|
||||
|
||||
|
||||
</mapper>
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.njcn.advance.service.responsibility;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.njcn.advance.pojo.dto.responsibility.ResponsibilityResult;
|
||||
import com.njcn.advance.pojo.po.responsibility.RespDataResult;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author hongawen
|
||||
* @since 2023-07-24
|
||||
*/
|
||||
public interface IRespDataResultService extends IService<RespDataResult> {
|
||||
|
||||
List<ResponsibilityResult> displayHistoryData(String id, Integer time);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package com.njcn.advance.service.responsibility;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.njcn.advance.pojo.dto.responsibility.RespDataDTO;
|
||||
import com.njcn.advance.pojo.dto.responsibility.ResponsibilityResult;
|
||||
import com.njcn.advance.pojo.param.ResponsibilityCalculateParam;
|
||||
import com.njcn.advance.pojo.param.ResponsibilitySecondCalParam;
|
||||
import com.njcn.advance.pojo.po.responsibility.RespData;
|
||||
import com.njcn.web.pojo.param.BaseParam;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author hongawen
|
||||
* @since 2023-07-21
|
||||
*/
|
||||
public interface IRespDataService extends IService<RespData> {
|
||||
|
||||
ResponsibilityResult getDynamicData(ResponsibilityCalculateParam responsibilityCalculateParam);
|
||||
|
||||
ResponsibilityResult getResponsibilityData(ResponsibilitySecondCalParam responsibilitySecondCalParam);
|
||||
|
||||
Page<RespDataDTO> responsibilityList(BaseParam queryParam);
|
||||
|
||||
void deleteByIds(List<String> ids);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.njcn.advance.service.responsibility;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.njcn.advance.pojo.param.UserDataIntegrityParam;
|
||||
import com.njcn.advance.pojo.po.responsibility.RespUserDataIntegrity;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author hongawen
|
||||
* @since 2023-07-13
|
||||
*/
|
||||
public interface IRespUserDataIntegrityService extends IService<RespUserDataIntegrity> {
|
||||
|
||||
Page<RespUserDataIntegrity> userDataIntegrityList(UserDataIntegrityParam userDataIntegrityParam);
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.njcn.advance.service.responsibility;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.njcn.advance.pojo.po.responsibility.RespUserData;
|
||||
import com.njcn.common.pojo.dto.SelectOption;
|
||||
import com.njcn.web.pojo.param.BaseParam;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author hongawen
|
||||
* @since 2023-07-13
|
||||
*/
|
||||
public interface IRespUserDataService extends IService<RespUserData> {
|
||||
|
||||
/**
|
||||
* 解析用采数据并保存
|
||||
* @author hongawen
|
||||
* @date 2023/7/13 19:48
|
||||
* @param file 用采数据
|
||||
*/
|
||||
void uploadUserData(MultipartFile file, HttpServletResponse response);
|
||||
|
||||
Page<RespUserData> userDataList(BaseParam queryParam);
|
||||
|
||||
List<SelectOption> userDataSelect();
|
||||
|
||||
void deleteUserDataByIds(List<String> ids);
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,21 @@
|
||||
package com.njcn.advance.service.responsibility.impl;
|
||||
|
||||
import com.njcn.advance.pojo.bo.responsibility.QvvrStruct;
|
||||
import com.sun.jna.Library;
|
||||
import com.sun.jna.Native;
|
||||
|
||||
/**
|
||||
* @author hongawen
|
||||
* @version 1.0.0
|
||||
* @date 2021年07月14日 16:17
|
||||
*/
|
||||
public interface JnaLibrary extends Library {
|
||||
|
||||
JnaLibrary INSTANCE = (JnaLibrary)
|
||||
Native.loadLibrary(JnaLibrary.class.getResource("/harm_response.dll")
|
||||
.getPath()
|
||||
.substring(1),// substring(1)的原因是在Windows下获取到的路径前面会多一个斜杠,但在Linux下不会,
|
||||
JnaLibrary.class);
|
||||
|
||||
void harm_response(QvvrStruct outData);
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
package com.njcn.advance.service.responsibility.impl;
|
||||
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.text.StrPool;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.njcn.advance.mapper.responsibility.RespDataResultMapper;
|
||||
import com.njcn.advance.pojo.bo.responsibility.UserDataExcel;
|
||||
import com.njcn.advance.pojo.dto.responsibility.CustomerData;
|
||||
import com.njcn.advance.pojo.dto.responsibility.CustomerResponsibility;
|
||||
import com.njcn.advance.pojo.dto.responsibility.ResponsibilityResult;
|
||||
import com.njcn.advance.pojo.po.responsibility.RespData;
|
||||
import com.njcn.advance.pojo.po.responsibility.RespDataResult;
|
||||
import com.njcn.advance.service.responsibility.IRespDataResultService;
|
||||
import com.njcn.advance.service.responsibility.IRespDataService;
|
||||
import com.njcn.oss.utils.FileStorageUtil;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author hongawen
|
||||
* @since 2023-07-24
|
||||
*/
|
||||
@Service
|
||||
public class RespDataResultServiceImpl extends ServiceImpl<RespDataResultMapper, RespDataResult> implements IRespDataResultService {
|
||||
|
||||
@Resource
|
||||
private FileStorageUtil fileStorageUtil;
|
||||
|
||||
@Lazy
|
||||
@Resource
|
||||
private IRespDataService respDataService;
|
||||
|
||||
@Override
|
||||
public List<ResponsibilityResult> displayHistoryData(String id, Integer time) {
|
||||
List<ResponsibilityResult> responsibilityResults = new ArrayList<>();
|
||||
if (Objects.isNull(time)) {
|
||||
RespData respData = respDataService.getById(id);
|
||||
String[] split = respData.getDataTimes().split(StrPool.COMMA);
|
||||
time = Integer.parseInt(split[0]);
|
||||
}
|
||||
LambdaQueryWrapper<RespDataResult> respDataResultLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
respDataResultLambdaQueryWrapper.eq(RespDataResult::getResDataId, id)
|
||||
.eq(RespDataResult::getTime, time);
|
||||
List<RespDataResult> respDataResults = this.baseMapper.selectList(respDataResultLambdaQueryWrapper);
|
||||
if (CollectionUtil.isNotEmpty(respDataResults)) {
|
||||
ResponsibilityResult responsibilityResult;
|
||||
for (RespDataResult respDataResult : respDataResults) {
|
||||
responsibilityResult = new ResponsibilityResult();
|
||||
responsibilityResult.setLimitValue(String.valueOf(respDataResult.getLimitValue()));
|
||||
responsibilityResult.setLimitSTime(DateUtil.format(respDataResult.getStartTime(), DatePattern.NORM_DATETIME_PATTERN));
|
||||
responsibilityResult.setLimitETime(DateUtil.format(respDataResult.getEndTime(), DatePattern.NORM_DATETIME_PATTERN));
|
||||
responsibilityResult.setResponsibilityDataIndex(respDataResult.getResDataId());
|
||||
//处理时间轴数据
|
||||
InputStream timeDataStream = fileStorageUtil.getFileStream(respDataResult.getTimeData());
|
||||
String timeDataStr = IoUtil.read(timeDataStream, CharsetUtil.UTF_8);
|
||||
List<Long> timeData = JSONArray.parseArray(timeDataStr, Long.class);
|
||||
responsibilityResult.setTimeDatas(timeData);
|
||||
//处理用户详细数据
|
||||
InputStream userDetailStream = fileStorageUtil.getFileStream(respDataResult.getUserDetailData());
|
||||
String userDetailStr = IoUtil.read(userDetailStream, CharsetUtil.UTF_8);
|
||||
List<CustomerData> customerData = JSONArray.parseArray(userDetailStr, CustomerData.class);
|
||||
responsibilityResult.setDatas(customerData);
|
||||
//处理排名前10数据
|
||||
InputStream respStream = fileStorageUtil.getFileStream(respDataResult.getUserResponsibility());
|
||||
String respStr = IoUtil.read(respStream, CharsetUtil.UTF_8);
|
||||
List<CustomerResponsibility> respData = JSONArray.parseArray(respStr, CustomerResponsibility.class);
|
||||
responsibilityResult.setResponsibilities(respData);
|
||||
responsibilityResults.add(responsibilityResult);
|
||||
}
|
||||
}
|
||||
return responsibilityResults;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,876 @@
|
||||
package com.njcn.advance.service.responsibility.impl;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.text.StrPool;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.alibaba.fastjson.JSONObject;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.njcn.advance.enums.AdvanceResponseEnum;
|
||||
import com.njcn.advance.mapper.responsibility.RespDataMapper;
|
||||
import com.njcn.advance.pojo.bo.responsibility.*;
|
||||
import com.njcn.advance.pojo.dto.responsibility.CustomerData;
|
||||
import com.njcn.advance.pojo.dto.responsibility.CustomerResponsibility;
|
||||
import com.njcn.advance.pojo.dto.responsibility.RespDataDTO;
|
||||
import com.njcn.advance.pojo.dto.responsibility.ResponsibilityResult;
|
||||
import com.njcn.advance.pojo.param.ResponsibilityCalculateParam;
|
||||
import com.njcn.advance.pojo.param.ResponsibilitySecondCalParam;
|
||||
import com.njcn.advance.pojo.po.responsibility.RespData;
|
||||
import com.njcn.advance.pojo.po.responsibility.RespDataResult;
|
||||
import com.njcn.advance.pojo.po.responsibility.RespUserData;
|
||||
import com.njcn.advance.service.responsibility.IRespDataResultService;
|
||||
import com.njcn.advance.service.responsibility.IRespDataService;
|
||||
import com.njcn.advance.service.responsibility.IRespUserDataService;
|
||||
import com.njcn.advance.utils.JnaCallBalance;
|
||||
import com.njcn.advance.utils.JnaCallDllOrSo;
|
||||
import com.njcn.advance.utils.ResponsibilityCallDllOrSo;
|
||||
import com.njcn.common.pojo.enums.common.DataStateEnum;
|
||||
import com.njcn.common.pojo.exception.BusinessException;
|
||||
import com.njcn.common.pojo.response.HttpResult;
|
||||
import com.njcn.common.utils.FileUtil;
|
||||
import com.njcn.common.utils.PubUtils;
|
||||
import com.njcn.db.constant.DbConstant;
|
||||
import com.njcn.device.biz.pojo.po.Overlimit;
|
||||
import com.njcn.device.pq.api.LineFeignClient;
|
||||
import com.njcn.device.pq.pojo.vo.LineDetailDataVO;
|
||||
import com.njcn.device.pq.pojo.vo.LineDetailVO;
|
||||
import com.njcn.harmonic.api.HarmDataFeignClient;
|
||||
import com.njcn.harmonic.pojo.param.HistoryHarmParam;
|
||||
import com.njcn.influx.pojo.dto.HarmData;
|
||||
import com.njcn.influx.pojo.dto.HarmHistoryDataDTO;
|
||||
import com.njcn.oss.constant.OssPath;
|
||||
import com.njcn.oss.enums.OssResponseEnum;
|
||||
import com.njcn.oss.utils.FileStorageUtil;
|
||||
import com.njcn.system.pojo.vo.DictDataVO;
|
||||
import com.njcn.web.factory.PageFactory;
|
||||
import com.njcn.web.pojo.param.BaseParam;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.io.*;
|
||||
import java.math.BigDecimal;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author hongawen
|
||||
* @since 2023-07-21
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class RespDataServiceImpl extends ServiceImpl<RespDataMapper, RespData> implements IRespDataService {
|
||||
|
||||
private final IRespUserDataService iRespUserDataService;
|
||||
|
||||
private final FileStorageUtil fileStorageUtil;
|
||||
|
||||
private final LineFeignClient lineFeignClient;
|
||||
|
||||
private final HarmDataFeignClient harmDataFeignClient;
|
||||
|
||||
private final GetQvvrData getQvvrData;
|
||||
|
||||
private final IRespDataResultService respDataResultService;
|
||||
|
||||
@Override
|
||||
public Page<RespDataDTO> responsibilityList(BaseParam queryParam) {
|
||||
QueryWrapper<RespDataDTO> queryWrapper = new QueryWrapper<>();
|
||||
if (ObjectUtil.isNotNull(queryParam)) {
|
||||
//查询参数不为空,进行条件填充
|
||||
if (StrUtil.isNotBlank(queryParam.getSearchValue())) {
|
||||
//仅提供用采名称
|
||||
queryWrapper.and(param -> param.like("pqs_resp_user_data.name", queryParam.getSearchValue()));
|
||||
}
|
||||
//排序
|
||||
if (ObjectUtil.isAllNotEmpty(queryParam.getSortBy(), queryParam.getOrderBy())) {
|
||||
queryWrapper.orderBy(true, queryParam.getOrderBy().equals(DbConstant.ASC), StrUtil.toUnderlineCase(queryParam.getSortBy()));
|
||||
} else {
|
||||
//没有排序参数,默认根据sort字段排序,没有排序字段的,根据updateTime更新时间排序
|
||||
queryWrapper.orderBy(true, false, "pqs_resp_data.create_time");
|
||||
}
|
||||
queryWrapper.between("pqs_resp_data.create_time",queryParam.getSearchBeginTime(),queryParam.getSearchEndTime());
|
||||
}
|
||||
queryWrapper.eq("pqs_resp_data.state", DataStateEnum.ENABLE.getCode());
|
||||
Page<RespDataDTO> page = this.baseMapper.page(new Page<>(PageFactory.getPageNum(queryParam), PageFactory.getPageSize(queryParam)), queryWrapper);
|
||||
List<RespDataDTO> records = page.getRecords();
|
||||
if(CollectionUtil.isNotEmpty(records)){
|
||||
//获取该监测点的详细信息
|
||||
for (RespDataDTO respDataDTO : records) {
|
||||
LineDetailVO lineSubGdDetail = lineFeignClient.getLineSubGdDetail(respDataDTO.getLineId()).getData();
|
||||
BeanUtil.copyProperties(lineSubGdDetail,respDataDTO);
|
||||
}
|
||||
}
|
||||
return page.setRecords(records);
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
* 批量逻辑删除责任划分数据
|
||||
* @author hongawen
|
||||
* @date 2023/7/24 19:16
|
||||
*/
|
||||
@Override
|
||||
public void deleteByIds(List<String> ids) {
|
||||
this.baseMapper.deleteByIds(ids);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public ResponsibilityResult getDynamicData(ResponsibilityCalculateParam responsibilityCalculateParam) {
|
||||
ResponsibilityResult result = new ResponsibilityResult();
|
||||
//调用c++依赖需要待初始化的参数
|
||||
int pNode, pNum, win, harmNum;
|
||||
float harmMk;
|
||||
LambdaQueryWrapper<RespUserData> userDataLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
userDataLambdaQueryWrapper.eq(RespUserData::getId, responsibilityCalculateParam.getUserDataId()).eq(RespUserData::getState, DataStateEnum.ENABLE.getCode());
|
||||
RespUserData respUserData = iRespUserDataService.getOne(userDataLambdaQueryWrapper);
|
||||
if (Objects.isNull(respUserData)) {
|
||||
throw new BusinessException(AdvanceResponseEnum.USER_DATA_NOT_FOUND);
|
||||
}
|
||||
InputStream fileStream = fileStorageUtil.getFileStream(respUserData.getDataPath());
|
||||
String excelDataStr = IoUtil.read(fileStream, CharsetUtil.UTF_8);
|
||||
//将文件流转为list集合
|
||||
List<UserDataExcel> userDataExcels = JSONArray.parseArray(excelDataStr, UserDataExcel.class);
|
||||
if (CollectionUtils.isEmpty(userDataExcels)) {
|
||||
throw new BusinessException(AdvanceResponseEnum.USER_DATA_NOT_FOUND);
|
||||
}
|
||||
|
||||
//开始处理,根据接口参数需求,需要节点数(用户数,用户名+监测点号为一个用户),时间范围内功率数据
|
||||
DealDataResult dealDataResult = RespUserDataServiceImpl.getStanderData(userDataExcels, 1);
|
||||
Map<String/*户号@监测点号@户名*/, Map<String/*yyyy-MM-dd天日期*/, List<UserDataExcel>>> totalData = dealDataResult.getTotalListData();
|
||||
Map<String/*户号@监测点号@户名*/, Map<String/*yyyy-MM-dd天日期*/, List<UserDataExcel>>> finalData = new HashMap<>();
|
||||
/*第一个参数pNode 如果时间范围内完整性不足90%的节点,不参与责任量化统计,因为之前处理过用采数据,此时只需要判断是否满足100%就可以判断*/
|
||||
//根据时间天数,获取理论上多少次用采数据
|
||||
List<String> dateStr = PubUtils.getTimes(DateUtil.parse(responsibilityCalculateParam.getSearchBeginTime(), DatePattern.NORM_DATE_PATTERN), DateUtil.parse(responsibilityCalculateParam.getSearchEndTime(), DatePattern.NORM_DATE_PATTERN));
|
||||
int dueCounts = dateStr.size() * 96;
|
||||
Set<String> userNames = totalData.keySet();
|
||||
for (String userName : userNames) {
|
||||
int realCounts = 0;
|
||||
Map<String, List<UserDataExcel>> temp = totalData.get(userName);
|
||||
for (String date : dateStr) {
|
||||
if (CollectionUtil.isNotEmpty(temp.get(date))) {
|
||||
realCounts = realCounts + temp.get(date).size();
|
||||
}
|
||||
}
|
||||
if (realCounts == dueCounts) {
|
||||
//只有期望和实际数量一致的时候才作为计算用户
|
||||
finalData.put(userName, temp);
|
||||
}
|
||||
}
|
||||
//至此,finalData便是我们最终获得的用于计算责任数据,第一个参数节点数值pNode获取到
|
||||
pNode = finalData.size();
|
||||
if (pNode < 1) {
|
||||
//没有合理的用采数据直接返回
|
||||
throw new BusinessException(AdvanceResponseEnum.USER_DATA_P_NODE_PARAMETER_ERROR);
|
||||
}
|
||||
//第二个参数pNum,根据起始时间和截止时间以及监测点测量间隔计算数量
|
||||
LineDetailDataVO lineDetailData = lineFeignClient.getLineDetailData(responsibilityCalculateParam.getLineId()).getData();
|
||||
int lineInterval = lineDetailData.getTimeInterval();
|
||||
int userIntervalTime;
|
||||
if (lineInterval == 1 || lineInterval == 3 || lineInterval == 5) {
|
||||
userIntervalTime = 15;
|
||||
pNum = dateStr.size() * 96;
|
||||
} else {
|
||||
userIntervalTime = 30;
|
||||
pNum = dateStr.size() * 48;
|
||||
finalData = dealFinalDataByLineInterval(finalData);
|
||||
}
|
||||
//第三个参数win,根据起始时间和截止时间的间隔
|
||||
if (dateStr.size() > 1) {
|
||||
win = 96;
|
||||
} else {
|
||||
win = 4;
|
||||
}
|
||||
//第四个参数harmMk,默认为0f
|
||||
harmMk = 0f;
|
||||
//第五个参数harmNum,与功率数据保持一致
|
||||
harmNum = pNum;
|
||||
//至此基础数据组装完毕,开始组装功率数据和谐波数据
|
||||
//先做谐波数据,理论上到这步的时候,谐波数据是满足完整性并已经补充完整性到100%,此处需要将谐波数据与功率数据长度匹配上
|
||||
HarmHistoryDataDTO data = harmDataFeignClient.getHistoryHarmData(new HistoryHarmParam(responsibilityCalculateParam.getSearchBeginTime(), responsibilityCalculateParam.getSearchEndTime(), responsibilityCalculateParam.getLineId(), responsibilityCalculateParam.getType(), responsibilityCalculateParam.getTime())).getData();
|
||||
List<HarmData> historyData = data.getHistoryData();
|
||||
historyData = getDataWithLineInterval(historyData, lineInterval);
|
||||
//理论上此处的historyData的长度等于pNum,开始填充harm_data
|
||||
float[] harmData = new float[144000];
|
||||
//谐波波形的横轴时间集合
|
||||
List<Long> harmTime = new ArrayList<>();
|
||||
for (int i = 0; i < historyData.size(); i++) {
|
||||
Float value = historyData.get(i).getValue();
|
||||
if (value != null) {
|
||||
value = value * 1000;
|
||||
}
|
||||
harmData[i] = value;
|
||||
harmTime.add(PubUtils.instantToDate(historyData.get(i).getTime()).getTime());
|
||||
}
|
||||
//harmData填充完毕后,开始组装功率数据
|
||||
//首先获取当前时间内的各个用户的数据
|
||||
Map<String/*用户名*/, List<UserDataExcel>> originalPData = new HashMap<>();
|
||||
List<String> names = new ArrayList<>();
|
||||
Set<String> userNamesFinal = finalData.keySet();
|
||||
for (String userName : userNamesFinal) {
|
||||
List<UserDataExcel> tempData = new ArrayList<>();
|
||||
//根据日期将日期数据全部获取出来
|
||||
Map<String, List<UserDataExcel>> tempResult = finalData.get(userName);
|
||||
for (String date : dateStr) {
|
||||
tempData.addAll(tempResult.get(date));
|
||||
}
|
||||
//按日期排序
|
||||
Collections.sort(tempData);
|
||||
originalPData.put(userName, tempData);
|
||||
names.add(userName);
|
||||
}
|
||||
//然后开始组装数据
|
||||
PDataStruct[] pData = new PDataStruct[QvvrStruct.MAX_P_NUM];
|
||||
for (int i = 0; i < names.size(); i++) {
|
||||
//当前某用户测量节点的所有数据
|
||||
List<UserDataExcel> userDataExcelBodies1 = originalPData.get(names.get(i));
|
||||
for (int k = 0; k < userDataExcelBodies1.size(); k++) {
|
||||
PDataStruct pDataStruct = pData[k];
|
||||
if (pDataStruct == null) {
|
||||
pDataStruct = new PDataStruct();
|
||||
}
|
||||
float[] p = pDataStruct.getP();
|
||||
p[i] = userDataExcelBodies1.get(k).getWork().floatValue();
|
||||
pData[k] = pDataStruct;
|
||||
}
|
||||
}
|
||||
//至此功率数据也组装完毕,调用友谊提供的接口
|
||||
QvvrStruct qvvrStruct = new QvvrStruct();
|
||||
qvvrStruct.cal_flag = 0;
|
||||
qvvrStruct.p_node = pNode;
|
||||
qvvrStruct.p_num = pNum;
|
||||
qvvrStruct.win = win;
|
||||
qvvrStruct.harm_num = harmNum;
|
||||
qvvrStruct.harm_mk = harmMk;
|
||||
qvvrStruct.p_data = pData;
|
||||
qvvrStruct.harm_data = harmData;
|
||||
|
||||
ResponsibilityCallDllOrSo responsibilityCallDllOrSo = new ResponsibilityCallDllOrSo("harm_response.dll");
|
||||
responsibilityCallDllOrSo.setPath();
|
||||
ResponsibilityCallDllOrSo.ResponsibilityLibrary responsibilityLibrary = ResponsibilityCallDllOrSo.ResponsibilityLibrary.INSTANTCE;
|
||||
responsibilityLibrary.harm_response(qvvrStruct);
|
||||
//至此接口调用结束,开始组装动态责任数据和用户责任量化结果
|
||||
//首先判断cal_ok的标识位是否为1,为0表示程序没有计算出结果
|
||||
if (qvvrStruct.cal_ok == 0) {
|
||||
throw new BusinessException(AdvanceResponseEnum.RESPONSIBILITY_PARAMETER_ERROR);
|
||||
}
|
||||
//没问题后,先玩动态责任数据
|
||||
CustomerData[] customerDatas = new CustomerData[qvvrStruct.p_node];
|
||||
PDataStruct[] fKdata/*无背景的动态责任数据*/ = qvvrStruct.getFKdata();
|
||||
//第一个时间节点是起始时间+win窗口得到的时间
|
||||
Date sTime = DateUtil.parse(dateStr.get(0).concat(" 00:00:00"), DatePattern.NORM_DATETIME_PATTERN);
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(sTime);
|
||||
calendar.add(Calendar.MINUTE, (win - 1) * userIntervalTime);
|
||||
List<Long> timeDatas = new ArrayList<>();
|
||||
for (int i = 0; i < qvvrStruct.p_num - qvvrStruct.win; i++) {
|
||||
calendar.add(Calendar.MINUTE, userIntervalTime);
|
||||
//一个时间点所有的用户数据
|
||||
PDataStruct fKdatum = fKdata[i];
|
||||
for (int k = 0; k < qvvrStruct.p_node; k++) {
|
||||
CustomerData customerData = customerDatas[k];
|
||||
if (null == customerData) {
|
||||
customerData = new CustomerData();
|
||||
customerData.setCustomerName(names.get(k));
|
||||
}
|
||||
List<Float> valueDatas = customerData.getValueDatas();
|
||||
Float valueTemp = fKdatum.getP()[k];
|
||||
if (valueTemp.isNaN()) {
|
||||
valueTemp = 0.0f;
|
||||
}
|
||||
valueDatas.add(valueTemp);
|
||||
customerData.setValueDatas(valueDatas);
|
||||
customerDatas[k] = customerData;
|
||||
}
|
||||
timeDatas.add(calendar.getTimeInMillis());
|
||||
}
|
||||
//OK拿到所有测量点的数据了,现在就是看如何将相同户号的动态数据进行算术和求值,之前的用户name为:户号@测量点号@用户名
|
||||
Map<String/*用户名(户号)*/, List<CustomerData>> customerDataTemp = new HashMap<>();
|
||||
for (int i = 0; i < customerDatas.length; i++) {
|
||||
String customerName = customerDatas[i].getCustomerName();
|
||||
String[] customerInfo = customerName.split("@");
|
||||
String name = customerInfo[2] + "(" + customerInfo[0] + ")";
|
||||
List<CustomerData> customerData = customerDataTemp.get(name);
|
||||
CustomerData temp = customerDatas[i];
|
||||
temp.setCustomerName(name);
|
||||
if (CollectionUtils.isEmpty(customerData)) {
|
||||
customerData = new ArrayList<>();
|
||||
}
|
||||
customerData.add(temp);
|
||||
customerDataTemp.put(name, customerData);
|
||||
}
|
||||
//动态数据组装完成后,开始组装责任数据
|
||||
List<CustomerResponsibility> customerResponsibilities = getCustomerResponsibilityData(names, qvvrStruct.sumFKdata, qvvrStruct.p_node);
|
||||
//根据前十的用户数据,获取这些用户的动态责任数据
|
||||
List<CustomerData> customerData = new ArrayList<>();
|
||||
for (CustomerResponsibility customerResponsibility : customerResponsibilities) {
|
||||
String cusName = customerResponsibility.getCustomerName();
|
||||
List<CustomerData> customerData1 = customerDataTemp.get(cusName);
|
||||
if (CollectionUtils.isEmpty(customerData1)) {
|
||||
continue;
|
||||
}
|
||||
if (customerData1.size() == 1) {
|
||||
//表示用户唯一的
|
||||
customerData.add(customerData1.get(0));
|
||||
} else {
|
||||
//表示用户可能包含多个监测点号,需要进行数据累加
|
||||
CustomerData customerDataT = new CustomerData();
|
||||
customerDataT.setCustomerName(cusName);
|
||||
//进行数值累加
|
||||
List<Float> valueDatas = new ArrayList<>();
|
||||
for (int i = 0; i < customerData1.get(0).getValueDatas().size(); i++) {
|
||||
float original = 0.0f;
|
||||
for (int k = 0; k < customerData1.size(); k++) {
|
||||
original = original + customerData1.get(k).getValueDatas().get(i);
|
||||
}
|
||||
valueDatas.add(original);
|
||||
}
|
||||
customerDataT.setValueDatas(valueDatas);
|
||||
customerData.add(customerDataT);
|
||||
}
|
||||
}
|
||||
result.setDatas(customerData);
|
||||
result.setTimeDatas(timeDatas);
|
||||
result.setResponsibilities(customerResponsibilities);
|
||||
//此次的操作进行入库操作responsibilityData表数据
|
||||
//根据监测点名称+谐波框选的时间来查询,是否做过责任量化
|
||||
String timeWin = responsibilityCalculateParam.getSearchBeginTime().replaceAll(StrPool.DASHED, "").concat(StrPool.DASHED).concat(responsibilityCalculateParam.getSearchEndTime().replaceAll(StrPool.DASHED, ""));
|
||||
String type = responsibilityCalculateParam.getType() == 0 ? "谐波电流" : "谐波电压";
|
||||
//为了避免有监测点名称重复的,最终还是选择使用监测点索引来判断唯一性
|
||||
LambdaQueryWrapper<RespData> respDataLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
respDataLambdaQueryWrapper.eq(RespData::getLineId, responsibilityCalculateParam.getLineId())
|
||||
.eq(RespData::getUserDataId, responsibilityCalculateParam.getUserDataId())
|
||||
.eq(RespData::getTimeWindow, timeWin)
|
||||
.eq(RespData::getDataType, type)
|
||||
.eq(RespData::getState, DataStateEnum.ENABLE.getCode());
|
||||
List<RespData> responsibilityDataTemp = this.baseMapper.selectList(respDataLambdaQueryWrapper);
|
||||
RespData responsibilityData;
|
||||
if (CollectionUtils.isEmpty(responsibilityDataTemp)) {
|
||||
responsibilityData = new RespData();
|
||||
//库中没有记录则可以新建数据进行插入
|
||||
responsibilityData.setLineId(responsibilityCalculateParam.getLineId());
|
||||
responsibilityData.setUserDataId(responsibilityCalculateParam.getUserDataId());
|
||||
responsibilityData.setDataType(type);
|
||||
responsibilityData.setDataTimes(responsibilityCalculateParam.getTime().toString());
|
||||
responsibilityData.setTimeWindow(timeWin);
|
||||
responsibilityData.setState(DataStateEnum.ENABLE.getCode());
|
||||
//进行插入操作
|
||||
this.baseMapper.insert(responsibilityData);
|
||||
} else {
|
||||
//库中存在记录只需要判断次数进行数据更新
|
||||
responsibilityData = responsibilityDataTemp.get(0);
|
||||
String times = responsibilityData.getDataTimes();
|
||||
List<String> timesList = Stream.of(times.split(StrPool.COMMA)).collect(Collectors.toList());
|
||||
Integer time = responsibilityCalculateParam.getTime();
|
||||
if (!timesList.contains(time.toString())) {
|
||||
timesList.add(time.toString());
|
||||
timesList = timesList.stream().sorted().collect(Collectors.toList());
|
||||
responsibilityData.setDataTimes(String.join(StrPool.COMMA, timesList));
|
||||
}
|
||||
//执行更新操作
|
||||
this.baseMapper.updateById(responsibilityData);
|
||||
}
|
||||
//入库完毕之后,需要将必要数据进行序列化存储,方便后期的重复利用
|
||||
/**
|
||||
* 需要序列化三种数据结构 1 cal_flag置为1时需要的一些列参数的CacheQvvrData 2 cal_flag为0时的,动态结果。3 用户责任量化结果
|
||||
* 其中1/2都只需要一个文件即可
|
||||
* 3因为用户限值的变化调整,可能存在很多个文件,具体根据用户的选择而定
|
||||
*
|
||||
* 路径的结构为,temPath+userData+excelName+type+timeWin+lineIndex+time+文件名
|
||||
* 用户责任量化结果,需要再细化到限值
|
||||
*/
|
||||
//首先判断有没有存储记录,没有则存储,有就略过 指定测点、时间窗口、谐波类型、谐波次数判断唯一性
|
||||
LambdaQueryWrapper<RespDataResult> respDataResultLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
respDataResultLambdaQueryWrapper.eq(RespDataResult::getResDataId, responsibilityData.getId())
|
||||
.eq(RespDataResult::getTime, responsibilityCalculateParam.getTime())
|
||||
.eq(RespDataResult::getStartTime, DateUtil.parse(responsibilityCalculateParam.getSearchBeginTime()+" 00:00:00",DatePattern.NORM_DATETIME_PATTERN))
|
||||
.eq(RespDataResult::getEndTime, DateUtil.parse(responsibilityCalculateParam.getSearchEndTime()+" 23:59:59",DatePattern.NORM_DATETIME_PATTERN))
|
||||
.eq(RespDataResult::getLimitValue, data.getOverLimit());
|
||||
RespDataResult respDataResult = respDataResultService.getOne(respDataResultLambdaQueryWrapper);
|
||||
if (Objects.isNull(respDataResult)) {
|
||||
respDataResult = new RespDataResult();
|
||||
respDataResult.setResDataId(responsibilityData.getId());
|
||||
respDataResult.setTime(responsibilityCalculateParam.getTime());
|
||||
respDataResult.setStartTime(DateUtil.parse(responsibilityCalculateParam.getSearchBeginTime()+" 00:00:00",DatePattern.NORM_DATETIME_PATTERN));
|
||||
respDataResult.setEndTime(DateUtil.parse(responsibilityCalculateParam.getSearchEndTime()+" 23:59:59",DatePattern.NORM_DATETIME_PATTERN));
|
||||
respDataResult.setLimitValue(data.getOverLimit());
|
||||
//时间横轴数据 timeDatas
|
||||
JSONArray timeDataJson = JSONArray.parseArray(JSON.toJSONString(timeDatas));
|
||||
InputStream timeDataStream = IoUtil.toStream(timeDataJson.toString(), CharsetUtil.UTF_8);
|
||||
String timeDataPath = fileStorageUtil.uploadStream(timeDataStream, OssPath.RESPONSIBILITY_USER_RESULT_DATA, FileUtil.generateFileName("json"));
|
||||
respDataResult.setTimeData(timeDataPath);
|
||||
//用户每时刻对应的责任数据
|
||||
JSONArray customerDataJson = JSONArray.parseArray(JSON.toJSONString(customerData));
|
||||
InputStream customerStream = IoUtil.toStream(customerDataJson.toString(), CharsetUtil.UTF_8);
|
||||
String customerPath = fileStorageUtil.uploadStream(customerStream, OssPath.RESPONSIBILITY_USER_RESULT_DATA, FileUtil.generateFileName("json"));
|
||||
respDataResult.setUserDetailData(customerPath);
|
||||
//调用qvvr生成的中间数据
|
||||
CacheQvvrData cacheQvvrData = new CacheQvvrData(qvvrStruct.getP_node(), qvvrStruct.getHarm_num(), qvvrStruct.getHarm_data(), qvvrStruct.FKdata, qvvrStruct.HKdata, names, userIntervalTime, qvvrStruct.win, userIntervalTime, harmTime);
|
||||
JSONObject cacheQvvrDataDataJson = (JSONObject) JSONObject.toJSON(cacheQvvrData);
|
||||
InputStream cacheQvvrDataStream = IoUtil.toStream(cacheQvvrDataDataJson.toString(), CharsetUtil.UTF_8);
|
||||
String cacheQvvrDataPath = fileStorageUtil.uploadStream(cacheQvvrDataStream, OssPath.RESPONSIBILITY_USER_RESULT_DATA, FileUtil.generateFileName("json"));
|
||||
respDataResult.setQvvrData(cacheQvvrDataPath);
|
||||
//用户前10数据存储
|
||||
JSONArray customerResJson = JSONArray.parseArray(JSON.toJSONString(customerResponsibilities));
|
||||
InputStream customerResStream = IoUtil.toStream(customerResJson.toString(), CharsetUtil.UTF_8);
|
||||
String customerResPath = fileStorageUtil.uploadStream(customerResStream, OssPath.RESPONSIBILITY_USER_RESULT_DATA, FileUtil.generateFileName("json"));
|
||||
respDataResult.setUserResponsibility(customerResPath);
|
||||
respDataResultService.save(respDataResult);
|
||||
}
|
||||
//防止过程中创建了大量的对象,主动调用下GC处理
|
||||
System.gc();
|
||||
result.setResponsibilityDataIndex(responsibilityData.getId());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponsibilityResult getResponsibilityData(ResponsibilitySecondCalParam responsibilitySecondCalParam) {
|
||||
ResponsibilityResult result = new ResponsibilityResult();
|
||||
//根据时间天数,获取理论上多少次用采数据
|
||||
RespData responsibilityData = this.baseMapper.selectById(responsibilitySecondCalParam.getResDataId());
|
||||
if (Objects.isNull(responsibilityData)) {
|
||||
throw new BusinessException(AdvanceResponseEnum.RESP_DATA_NOT_FOUND);
|
||||
}
|
||||
Overlimit overlimit = lineFeignClient.getOverLimitData(responsibilityData.getLineId()).getData();
|
||||
//获取总数据
|
||||
LambdaQueryWrapper<RespDataResult> respDataResultLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
respDataResultLambdaQueryWrapper.eq(RespDataResult::getResDataId, responsibilityData.getId())
|
||||
.eq(RespDataResult::getTime, responsibilitySecondCalParam.getTime());
|
||||
if (responsibilitySecondCalParam.getType() == 0) {
|
||||
respDataResultLambdaQueryWrapper.eq(RespDataResult::getLimitValue, PubUtils.getValueByMethod(overlimit, "getIharm", responsibilitySecondCalParam.getTime()));
|
||||
} else {
|
||||
respDataResultLambdaQueryWrapper.eq(RespDataResult::getLimitValue, PubUtils.getValueByMethod(overlimit, "getUharm", responsibilitySecondCalParam.getTime()));
|
||||
}
|
||||
RespDataResult respDataResultTemp = respDataResultService.getOne(respDataResultLambdaQueryWrapper);
|
||||
if (Objects.isNull(respDataResultTemp)) {
|
||||
throw new BusinessException(AdvanceResponseEnum.RESP_DATA_NOT_FOUND);
|
||||
}
|
||||
CacheQvvrData cacheQvvrData;
|
||||
try {
|
||||
InputStream fileStream = fileStorageUtil.getFileStream(respDataResultTemp.getQvvrData());
|
||||
String qvvrDataStr = IoUtil.read(fileStream, CharsetUtil.UTF_8);
|
||||
cacheQvvrData = JSONObject.parseObject(qvvrDataStr, CacheQvvrData.class);
|
||||
} catch (Exception exception) {
|
||||
throw new BusinessException(AdvanceResponseEnum.RESP_RESULT_DATA_NOT_FOUND);
|
||||
}
|
||||
//获取成功后,延长该缓存的生命周期为初始生命时长
|
||||
int win = cacheQvvrData.getWin();
|
||||
//不管窗口为4或者96,都需要考虑最小公倍数
|
||||
//最小公倍数根据监测点测量间隔来获取,可以考虑也由第一步操作缓存起来
|
||||
int minMultiple = cacheQvvrData.getMinMultiple();
|
||||
//谐波横轴所有的时间
|
||||
List<Long> times = cacheQvvrData.getTimes();
|
||||
//首先根据窗口判断限值时间范围是否满足最小窗口
|
||||
Long limitSL = DateUtil.parse(responsibilitySecondCalParam.getLimitStartTime(),DatePattern.NORM_DATETIME_PATTERN).getTime();
|
||||
Long limitEL = DateUtil.parse(responsibilitySecondCalParam.getLimitEndTime(),DatePattern.NORM_DATETIME_PATTERN).getTime();
|
||||
List<Integer> temp = getTimes(times, limitSL, limitEL);
|
||||
//在动态责任数据中,时间的起始索引位置和截止索引位置
|
||||
Integer timeStartIndex = temp.get(0);
|
||||
Integer timeEndIndex = temp.get(1);
|
||||
//间隔中的时间长度
|
||||
int minus = timeEndIndex - timeStartIndex + 1;
|
||||
//组装参数
|
||||
QvvrStruct qvvrStruct = new QvvrStruct();
|
||||
qvvrStruct.cal_flag = 1;
|
||||
qvvrStruct.p_node = cacheQvvrData.getPNode();
|
||||
qvvrStruct.harm_mk = responsibilitySecondCalParam.getLimitValue();
|
||||
qvvrStruct.win = win;
|
||||
int resNum;
|
||||
PDataStruct[] FKdata = new PDataStruct[9600];
|
||||
HKDataStruct[] HKdata = new HKDataStruct[9600];
|
||||
float[] harmData = new float[1440 * 100];
|
||||
PDataStruct[] fKdataOriginal = cacheQvvrData.getFKdata();
|
||||
HKDataStruct[] hKdataOriginal = cacheQvvrData.getHKdata();
|
||||
float[] harmDataOriginal = cacheQvvrData.getHarmData();
|
||||
//如果起始索引与截止索引的差值等于时间轴的长度,则说明用户没有选择限值时间,直接带入全部的原始数据,参与计算即可
|
||||
if (minus == times.size()) {
|
||||
qvvrStruct.harm_num = cacheQvvrData.getHarmNum();
|
||||
qvvrStruct.res_num = cacheQvvrData.getHarmNum() - cacheQvvrData.getWin();
|
||||
qvvrStruct.setFKdata(cacheQvvrData.getFKdata());
|
||||
qvvrStruct.setHKdata(cacheQvvrData.getHKdata());
|
||||
qvvrStruct.harm_data = cacheQvvrData.getHarmData();
|
||||
} else {
|
||||
if (win == 4) {
|
||||
//当窗口为4时,两个时间限制范围在最小公倍数为15时,最起码有5个有效时间点,在最小公倍数为30时,最起码有3个有效时间点
|
||||
if (minMultiple == 15) {
|
||||
if (minus < 5) {
|
||||
throw new BusinessException(AdvanceResponseEnum.WIN_TIME_ERROR);
|
||||
}
|
||||
resNum = minus - 4;
|
||||
|
||||
} else if (minMultiple == 30) {
|
||||
if (minus < 3) {
|
||||
throw new BusinessException(AdvanceResponseEnum.WIN_TIME_ERROR);
|
||||
}
|
||||
resNum = minus - 2;
|
||||
} else {
|
||||
throw new BusinessException(AdvanceResponseEnum.CALCULATE_INTERVAL_ERROR);
|
||||
}
|
||||
} else if (win == 96) {
|
||||
//当窗口为96时,两个时间限值范围在最小公倍数为15时,最起码有97个有效时间点,在最小公倍数为30时,最起码有49个有效时间点
|
||||
if (minMultiple == 15) {
|
||||
if (minus < 97) {
|
||||
throw new BusinessException(AdvanceResponseEnum.WIN_TIME_ERROR);
|
||||
}
|
||||
resNum = minus - 96;
|
||||
} else if (minMultiple == 30) {
|
||||
if (minus < 49) {
|
||||
throw new BusinessException(AdvanceResponseEnum.WIN_TIME_ERROR);
|
||||
}
|
||||
resNum = minus - 48;
|
||||
} else {
|
||||
throw new BusinessException(AdvanceResponseEnum.CALCULATE_INTERVAL_ERROR);
|
||||
}
|
||||
} else {
|
||||
throw new BusinessException(AdvanceResponseEnum.CALCULATE_INTERVAL_ERROR);
|
||||
}
|
||||
qvvrStruct.res_num = resNum;
|
||||
qvvrStruct.harm_num = minus;
|
||||
//因为限值时间实际是含头含尾的,所以harmNum需要索引差值+1
|
||||
for (int i = timeStartIndex; i <= timeEndIndex; i++) {
|
||||
harmData[i - timeStartIndex] = harmDataOriginal[i];
|
||||
}
|
||||
qvvrStruct.harm_data = harmData;
|
||||
//FKData与HKData的值则等于resNum
|
||||
for (int i = timeStartIndex; i < timeStartIndex + resNum; i++) {
|
||||
FKdata[i - timeStartIndex] = fKdataOriginal[i];
|
||||
HKdata[i - timeStartIndex] = hKdataOriginal[i];
|
||||
}
|
||||
|
||||
qvvrStruct.setFKdata(FKdata);
|
||||
qvvrStruct.setHKdata(HKdata);
|
||||
}
|
||||
qvvrStruct = getQvvrData.getResponsibilityResult(qvvrStruct);
|
||||
if (qvvrStruct.cal_ok == 0) {
|
||||
throw new BusinessException(AdvanceResponseEnum.RESPONSIBILITY_PARAMETER_ERROR);
|
||||
}
|
||||
//没问题后,先玩动态责任数据
|
||||
List<String> names = cacheQvvrData.getNames();
|
||||
CustomerData[] customerDatas = new CustomerData[qvvrStruct.p_node];
|
||||
PDataStruct[] fKdata/*无背景的动态责任数据*/ = qvvrStruct.getFKdata();
|
||||
//第一个时间节点是起始时间+win窗口得到的时间
|
||||
Date sTime = new Date();
|
||||
sTime.setTime(times.get(timeStartIndex));
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(sTime);
|
||||
calendar.add(Calendar.MINUTE, (win - 1) * minMultiple);
|
||||
List<Long> timeDatas = new ArrayList<>();
|
||||
for (int i = 0; i < qvvrStruct.harm_num - qvvrStruct.win; i++) {
|
||||
calendar.add(Calendar.MINUTE, minMultiple);
|
||||
//一个时间点所有的用户数据
|
||||
PDataStruct fKdatum = fKdata[i];
|
||||
for (int k = 0; k < qvvrStruct.p_node; k++) {
|
||||
CustomerData customerData = customerDatas[k];
|
||||
if (null == customerData) {
|
||||
customerData = new CustomerData();
|
||||
customerData.setCustomerName(names.get(k));
|
||||
}
|
||||
List<Float> valueDatas = customerData.getValueDatas();
|
||||
Float valueTemp = fKdatum.getP()[k];
|
||||
if (valueTemp.isNaN()) {
|
||||
valueTemp = 0.0f;
|
||||
}
|
||||
valueDatas.add(valueTemp);
|
||||
customerData.setValueDatas(valueDatas);
|
||||
customerDatas[k] = customerData;
|
||||
}
|
||||
timeDatas.add(calendar.getTimeInMillis());
|
||||
}
|
||||
//OK拿到所有测量点的数据了,现在就是看如何将相同户号的动态数据进行算术和求值,之前的用户name为:户号@测量点号@用户名
|
||||
Map<String/*用户名(户号)*/, List<CustomerData>> customerDataTemp = new HashMap<>();
|
||||
for (int i = 0; i < customerDatas.length; i++) {
|
||||
String customerName = customerDatas[i].getCustomerName();
|
||||
String[] customerInfo = customerName.split("@");
|
||||
String name = customerInfo[2] + "(" + customerInfo[0] + ")";
|
||||
List<CustomerData> customerData = customerDataTemp.get(name);
|
||||
CustomerData customerTemp = customerDatas[i];
|
||||
customerTemp.setCustomerName(name);
|
||||
if (CollectionUtils.isEmpty(customerData)) {
|
||||
customerData = new ArrayList<>();
|
||||
}
|
||||
customerData.add(customerTemp);
|
||||
customerDataTemp.put(name, customerData);
|
||||
}
|
||||
//调用程序接口后,首先组装责任量化结果
|
||||
float[] sumFKdata = qvvrStruct.sumFKdata;
|
||||
List<CustomerResponsibility> customerResponsibilities = getCustomerResponsibilityData(names, sumFKdata, qvvrStruct.p_node);
|
||||
//根据前十的用户数据,获取这些用户的动态责任数据
|
||||
List<CustomerData> customerData = new ArrayList<>();
|
||||
|
||||
for (CustomerResponsibility customerResponsibility : customerResponsibilities) {
|
||||
String cusName = customerResponsibility.getCustomerName();
|
||||
List<CustomerData> customerData1 = customerDataTemp.get(cusName);
|
||||
if (CollectionUtils.isEmpty(customerData1)) {
|
||||
continue;
|
||||
}
|
||||
if (customerData1.size() == 1) {
|
||||
//表示用户唯一的
|
||||
customerData.add(customerData1.get(0));
|
||||
} else {
|
||||
//表示用户可能包含多个监测点号,需要进行数据累加
|
||||
CustomerData customerDataT = new CustomerData();
|
||||
customerDataT.setCustomerName(cusName);
|
||||
//进行数值累加
|
||||
List<Float> valueDatas = new ArrayList<>();
|
||||
for (int i = 0; i < customerData1.get(0).getValueDatas().size(); i++) {
|
||||
float original = 0.0f;
|
||||
for (int k = 0; k < customerData1.size(); k++) {
|
||||
original = original + customerData1.get(k).getValueDatas().get(i);
|
||||
}
|
||||
valueDatas.add(original);
|
||||
}
|
||||
customerDataT.setValueDatas(valueDatas);
|
||||
customerData.add(customerDataT);
|
||||
}
|
||||
}
|
||||
//接着组装动态数据结果
|
||||
result.setResponsibilities(customerResponsibilities);
|
||||
result.setDatas(customerData);
|
||||
result.setTimeDatas(timeDatas);
|
||||
|
||||
//首先判断有没有存储记录,没有则存储,有就略过 指定测点、时间窗口、谐波类型、谐波次数判断唯一性
|
||||
LambdaQueryWrapper<RespDataResult> respDataResultLambdaQueryWrapper1 = new LambdaQueryWrapper<>();
|
||||
respDataResultLambdaQueryWrapper1.eq(RespDataResult::getResDataId, responsibilityData.getId())
|
||||
.eq(RespDataResult::getTime, responsibilitySecondCalParam.getTime())
|
||||
.eq(RespDataResult::getStartTime, DateUtil.parse(responsibilitySecondCalParam.getLimitStartTime(),DatePattern.NORM_DATETIME_PATTERN))
|
||||
.eq(RespDataResult::getEndTime, DateUtil.parse(responsibilitySecondCalParam.getLimitEndTime(),DatePattern.NORM_DATETIME_PATTERN))
|
||||
.eq(RespDataResult::getLimitValue, responsibilitySecondCalParam.getLimitValue());
|
||||
RespDataResult respDataResult = respDataResultService.getOne(respDataResultLambdaQueryWrapper1);
|
||||
if (Objects.isNull(respDataResult)) {
|
||||
respDataResult = new RespDataResult();
|
||||
respDataResult.setResDataId(responsibilityData.getId());
|
||||
respDataResult.setTime(responsibilitySecondCalParam.getTime());
|
||||
respDataResult.setStartTime(DateUtil.parse(responsibilitySecondCalParam.getLimitStartTime(),DatePattern.NORM_DATETIME_PATTERN));
|
||||
respDataResult.setEndTime(DateUtil.parse(responsibilitySecondCalParam.getLimitEndTime(),DatePattern.NORM_DATETIME_PATTERN));
|
||||
respDataResult.setLimitValue(responsibilitySecondCalParam.getLimitValue());
|
||||
//时间横轴数据 timeDatas
|
||||
JSONArray timeDataJson = JSONArray.parseArray(JSON.toJSONString(timeDatas));
|
||||
InputStream timeDataStream = IoUtil.toStream(timeDataJson.toString(), CharsetUtil.UTF_8);
|
||||
String timeDataPath = fileStorageUtil.uploadStream(timeDataStream, OssPath.RESPONSIBILITY_USER_RESULT_DATA, FileUtil.generateFileName("json"));
|
||||
respDataResult.setTimeData(timeDataPath);
|
||||
//用户每时刻对应的责任数据
|
||||
JSONArray customerDataJson = JSONArray.parseArray(JSON.toJSONString(customerData));
|
||||
InputStream customerStream = IoUtil.toStream(customerDataJson.toString(), CharsetUtil.UTF_8);
|
||||
String customerPath = fileStorageUtil.uploadStream(customerStream, OssPath.RESPONSIBILITY_USER_RESULT_DATA, FileUtil.generateFileName("json"));
|
||||
respDataResult.setUserDetailData(customerPath);
|
||||
//用户前10数据存储
|
||||
JSONArray customerResJson = JSONArray.parseArray(JSON.toJSONString(customerResponsibilities));
|
||||
InputStream customerResStream = IoUtil.toStream(customerResJson.toString(), CharsetUtil.UTF_8);
|
||||
String customerResPath = fileStorageUtil.uploadStream(customerResStream, OssPath.RESPONSIBILITY_USER_RESULT_DATA, FileUtil.generateFileName("json"));
|
||||
respDataResult.setUserResponsibility(customerResPath);
|
||||
respDataResultService.save(respDataResult);
|
||||
}
|
||||
//防止过程中创建了大量的对象,主动调用下GC处理
|
||||
System.gc();
|
||||
result.setResponsibilityDataIndex(responsibilityData.getId());
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 监测点测量间隔获取最后用于计算的功率数据
|
||||
*
|
||||
* @param finalData 参数计算的功率数据
|
||||
*/
|
||||
private Map<String, Map<String, List<UserDataExcel>>> dealFinalDataByLineInterval(Map<String, Map<String, List<UserDataExcel>>> finalData) {
|
||||
DecimalFormat decimalFormat = new DecimalFormat("0.0000");
|
||||
Map<String, Map<String, List<UserDataExcel>>> result;
|
||||
//当监测点测量间隔为10分钟时,功率数据需要调整为30分钟数据
|
||||
result = new HashMap<>();
|
||||
Set<String> userNames = finalData.keySet();
|
||||
for (String userName : userNames) {
|
||||
Map<String, List<UserDataExcel>> temp = new HashMap<>();
|
||||
Map<String, List<UserDataExcel>> original = finalData.get(userName);
|
||||
Set<String> dates = original.keySet();
|
||||
for (String date : dates) {
|
||||
List<UserDataExcel> single = original.get(date);//某当天的数据
|
||||
//先根据事时间排序
|
||||
Collections.sort(single);
|
||||
//此时根据当天所有的数据,重新计算出所有时间点的数据,担心这个过程会消耗过长时间
|
||||
List<UserDataExcel> tempDatas = new ArrayList<>();
|
||||
for (int i = 0; i < 96; i = i + 2) {
|
||||
//30分钟内的2个15分钟功率数据相加作平均计算30分钟内的功率数据,最终的数据序列时间间隔30分钟。by 友谊文档
|
||||
UserDataExcel tempData = new UserDataExcel();
|
||||
tempData.setUserName(single.get(i).getUserName());
|
||||
tempData.setUserId(single.get(i).getUserId());
|
||||
tempData.setLine(single.get(i).getLine());
|
||||
tempData.setTime(single.get(i).getTime());
|
||||
//功率为 2个15分钟功率数据相加作平均
|
||||
double work = single.get(i).getWork().doubleValue() + single.get(i + 1).getWork().doubleValue();
|
||||
tempData.setWork(new BigDecimal(decimalFormat.format(work / 2.0)));
|
||||
tempDatas.add(tempData);
|
||||
}
|
||||
temp.put(date, tempDatas);
|
||||
}
|
||||
result.put(userName, temp);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过监测点测量间隔计算对齐后的谐波数据
|
||||
* 暂且认为最小公倍数就15、30两种可能
|
||||
*
|
||||
* @param historyData 原始的谐波数据
|
||||
* @param lineInterval 测量间隔
|
||||
*/
|
||||
private List<HarmData> getDataWithLineInterval(List<HarmData> historyData, int lineInterval) {
|
||||
List<HarmData> result = new ArrayList<>();
|
||||
switch (lineInterval) {
|
||||
case 1:
|
||||
result = getHarmResultByTimes(historyData, 15);
|
||||
break;
|
||||
case 3:
|
||||
result = getHarmResultByTimes(historyData, 5);
|
||||
break;
|
||||
case 5:
|
||||
case 10:
|
||||
result = getHarmResultByTimes(historyData, 3);
|
||||
break;
|
||||
}
|
||||
return result.stream().sorted(Comparator.comparing(HarmData::getTime)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过监测点测量间隔计算对齐后的谐波数据
|
||||
*
|
||||
* @param historyData 原始的谐波数据
|
||||
*/
|
||||
private List<HarmData> getHarmResultByTimes(List<HarmData> historyData, int times) {
|
||||
List<HarmData> result = new ArrayList<>();
|
||||
DecimalFormat decimalFormat = new DecimalFormat("0.0000");
|
||||
for (int i = 0; i < historyData.size(); i = i + times) {
|
||||
float temp = 0.0f;
|
||||
for (int j = 0; j < times; j++) {
|
||||
int index = i + j;
|
||||
temp = temp + historyData.get(index).getValue();
|
||||
}
|
||||
//求平均值
|
||||
temp = Float.parseFloat(decimalFormat.format(temp / (float) times));
|
||||
HarmData resTemp = new HarmData();
|
||||
resTemp.setTime(historyData.get(i).getTime());
|
||||
resTemp.setValue(temp);
|
||||
result.add(resTemp);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据接口返回值组装需要显示的责任量化数据
|
||||
*/
|
||||
private List<CustomerResponsibility> getCustomerResponsibilityData(List<String> names, float[] sumFKdata, int pNode) {
|
||||
Map<String/*用户名(户号)*/, CustomerResponsibility> customerResponsibilityMap = new HashMap<>();
|
||||
for (int i = 0; i < pNode; i++) {
|
||||
String[] customerInfo = names.get(i).split("@");/*用户ID 测量点ID 用户名*/
|
||||
String name = customerInfo[2] + "(" + customerInfo[0] + ")";
|
||||
CustomerResponsibility customerResponsibility;
|
||||
if (customerResponsibilityMap.containsKey(name)) {
|
||||
customerResponsibility = customerResponsibilityMap.get(name);
|
||||
customerResponsibility.setResponsibilityData(customerResponsibility.getResponsibilityData() + sumFKdata[i]);
|
||||
} else {
|
||||
customerResponsibility = new CustomerResponsibility();
|
||||
customerResponsibility.setCustomerName(name);
|
||||
customerResponsibility.setResponsibilityData(sumFKdata[i]);
|
||||
}
|
||||
customerResponsibilityMap.put(name, customerResponsibility);
|
||||
}
|
||||
//map转为list
|
||||
List<CustomerResponsibility> customerResponsibilities = new ArrayList<>();
|
||||
Set<String> cusNames = customerResponsibilityMap.keySet();
|
||||
for (String cusName : cusNames) {
|
||||
customerResponsibilities.add(customerResponsibilityMap.get(cusName));
|
||||
}
|
||||
//取出前十的用户责任数据
|
||||
customerResponsibilities = customerResponsibilities.stream().sorted(Comparator.comparing(CustomerResponsibility::getResponsibilityData).reversed()).collect(Collectors.toList());
|
||||
if (customerResponsibilities.size() > 10) {
|
||||
//当用户超出10,将前十用户保留,然后剩余归类为其他用户
|
||||
float tenTotal = 0.0f;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
float temp = PubUtils.floatRound(3, customerResponsibilities.get(i).getResponsibilityData());
|
||||
tenTotal = tenTotal + temp;
|
||||
}
|
||||
int size = customerResponsibilities.size() - 10;
|
||||
customerResponsibilities = customerResponsibilities.subList(0, 10);
|
||||
CustomerResponsibility others = new CustomerResponsibility();
|
||||
others.setCustomerName("其他用户(" + size + ")");
|
||||
others.setResponsibilityData(PubUtils.floatRound(3, 100.0f - tenTotal));
|
||||
customerResponsibilities.add(others);
|
||||
}
|
||||
return customerResponsibilities;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据起始时间获取在集合中最接近的起始和截止值
|
||||
*
|
||||
* @param times 时间集合
|
||||
* @param limitSL 起始值
|
||||
* @param limitEL 截止值
|
||||
*/
|
||||
private List<Integer> getTimes(List<Long> times, Long limitSL, Long limitEL) {
|
||||
List<Integer> result = new ArrayList<>();
|
||||
Integer temps = null;
|
||||
Integer tempe = null;
|
||||
//因为可以知道times是为4的倍数,所以长度肯定是偶数,不会出现索引越界的异常
|
||||
if (limitSL < times.get(0)) {
|
||||
temps = 0;
|
||||
}
|
||||
if (limitEL > times.get(times.size() - 1)) {
|
||||
tempe = times.size() - 1;
|
||||
}
|
||||
for (int i = 0; i < times.size() - 1; i++) {
|
||||
if (temps != null & tempe != null) {
|
||||
//判断都已经赋值后,跳出循环
|
||||
break;
|
||||
}
|
||||
//锁定前值
|
||||
if (times.get(i).equals(limitSL)) {
|
||||
//相等则给起始时间赋值
|
||||
temps = i;
|
||||
} else if (times.get(i + 1).equals(limitSL)) {
|
||||
temps = i + 1;
|
||||
} else if (times.get(i) < limitSL & times.get(i + 1) > limitSL) {
|
||||
//当起始时间处于中间时,将后值赋值给temps
|
||||
temps = i + 1;
|
||||
}
|
||||
//锁定后值
|
||||
if (times.get(i).equals(limitEL)) {
|
||||
//相等则给起始时间赋值
|
||||
tempe = i;
|
||||
} else if (times.get(i + 1).equals(limitEL)) {
|
||||
tempe = i + 1;
|
||||
} else if (times.get(i) < limitEL & times.get(i + 1) > limitEL) {//
|
||||
//当起始时间处于中间时,将前值赋值给temps
|
||||
tempe = i;
|
||||
}
|
||||
}
|
||||
if (temps == null) {
|
||||
temps = 0;
|
||||
}
|
||||
if (tempe == null) {
|
||||
tempe = times.size() - 1;
|
||||
}
|
||||
result.add(temps);
|
||||
result.add(tempe);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.njcn.advance.service.responsibility.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.njcn.advance.mapper.responsibility.RespUserDataIntegrityMapper;
|
||||
import com.njcn.advance.pojo.param.UserDataIntegrityParam;
|
||||
import com.njcn.advance.pojo.po.responsibility.RespUserDataIntegrity;
|
||||
import com.njcn.advance.service.responsibility.IRespUserDataIntegrityService;
|
||||
import com.njcn.web.factory.PageFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author hongawen
|
||||
* @since 2023-07-13
|
||||
*/
|
||||
@Service
|
||||
public class RespUserDataIntegrityServiceImpl extends ServiceImpl<RespUserDataIntegrityMapper, RespUserDataIntegrity> implements IRespUserDataIntegrityService {
|
||||
|
||||
@Override
|
||||
public Page<RespUserDataIntegrity> userDataIntegrityList(UserDataIntegrityParam userDataIntegrityParam) {
|
||||
QueryWrapper<RespUserDataIntegrity> lambdaQueryWrapper = new QueryWrapper<>();
|
||||
lambdaQueryWrapper.eq("pqs_resp_user_data_integrity.user_data_id", userDataIntegrityParam.getUserDataId())
|
||||
.orderByDesc("pqs_resp_user_data_integrity.create_time");
|
||||
return this.baseMapper.page(new Page<>(PageFactory.getPageNum(userDataIntegrityParam), PageFactory.getPageSize(userDataIntegrityParam)), lambdaQueryWrapper);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,465 @@
|
||||
package com.njcn.advance.service.responsibility.impl;
|
||||
|
||||
import cn.afterturn.easypoi.excel.ExcelImportUtil;
|
||||
import cn.afterturn.easypoi.excel.entity.ImportParams;
|
||||
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult;
|
||||
import cn.afterturn.easypoi.handler.inter.IReadHandler;
|
||||
import cn.hutool.core.collection.CollectionUtil;
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.text.StrPool;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.JSONArray;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.njcn.advance.enums.AdvanceResponseEnum;
|
||||
import com.njcn.advance.mapper.responsibility.RespUserDataMapper;
|
||||
import com.njcn.advance.pojo.bo.responsibility.DealDataResult;
|
||||
import com.njcn.advance.pojo.bo.responsibility.DealUserDataResult;
|
||||
import com.njcn.advance.pojo.bo.responsibility.UserDataExcel;
|
||||
import com.njcn.advance.pojo.po.responsibility.RespUserData;
|
||||
import com.njcn.advance.pojo.po.responsibility.RespUserDataIntegrity;
|
||||
import com.njcn.advance.service.responsibility.IRespUserDataIntegrityService;
|
||||
import com.njcn.advance.service.responsibility.IRespUserDataService;
|
||||
import com.njcn.common.pojo.dto.SelectOption;
|
||||
import com.njcn.common.pojo.enums.common.DataStateEnum;
|
||||
import com.njcn.common.pojo.exception.BusinessException;
|
||||
import com.njcn.common.utils.FileUtil;
|
||||
import com.njcn.common.utils.PubUtils;
|
||||
import com.njcn.db.constant.DbConstant;
|
||||
import com.njcn.oss.constant.OssPath;
|
||||
import com.njcn.oss.utils.FileStorageUtil;
|
||||
import com.njcn.poi.util.PoiUtil;
|
||||
import com.njcn.web.factory.PageFactory;
|
||||
import com.njcn.web.pojo.param.BaseParam;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author hongawen
|
||||
* @since 2023-07-13
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class RespUserDataServiceImpl extends ServiceImpl<RespUserDataMapper, RespUserData> implements IRespUserDataService {
|
||||
|
||||
private final FileStorageUtil fileStorageUtil;
|
||||
|
||||
private final IRespUserDataIntegrityService respUserDataIntegrityService;
|
||||
|
||||
@Override
|
||||
public void uploadUserData(MultipartFile file, HttpServletResponse response) {
|
||||
ImportParams params = new ImportParams();
|
||||
List<UserDataExcel> userDataExcels = new ArrayList<>();
|
||||
try {
|
||||
ExcelImportUtil.importExcelBySax(file.getInputStream(), UserDataExcel.class, params, new IReadHandler<UserDataExcel>() {
|
||||
@Override
|
||||
public void handler(UserDataExcel o) {
|
||||
userDataExcels.add(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doAfterAll() {
|
||||
|
||||
}
|
||||
});
|
||||
//处理用户上传的用采数据内容
|
||||
analysisUserData(userDataExcels, file.getOriginalFilename());
|
||||
} catch (Exception e) {
|
||||
throw new BusinessException(AdvanceResponseEnum.ANALYSIS_USER_DATA_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<RespUserData> userDataList(BaseParam queryParam) {
|
||||
QueryWrapper<RespUserData> respUserDataQueryWrapper = new QueryWrapper<>();
|
||||
if (ObjectUtil.isNotNull(queryParam)) {
|
||||
//查询参数不为空,进行条件填充
|
||||
if (StrUtil.isNotBlank(queryParam.getSearchValue())) {
|
||||
//仅提供用采名称
|
||||
respUserDataQueryWrapper.and(param -> param.like("pqs_resp_user_data.name", queryParam.getSearchValue()));
|
||||
}
|
||||
//排序
|
||||
if (ObjectUtil.isAllNotEmpty(queryParam.getSortBy(), queryParam.getOrderBy())) {
|
||||
respUserDataQueryWrapper.orderBy(true, queryParam.getOrderBy().equals(DbConstant.ASC), StrUtil.toUnderlineCase(queryParam.getSortBy()));
|
||||
} else {
|
||||
//没有排序参数,默认根据sort字段排序,没有排序字段的,根据updateTime更新时间排序
|
||||
respUserDataQueryWrapper.orderBy(true, false, "pqs_resp_user_data.update_time");
|
||||
}
|
||||
} else {
|
||||
respUserDataQueryWrapper.orderBy(true, false, "pqs_resp_user_data.update_time");
|
||||
}
|
||||
respUserDataQueryWrapper.eq("pqs_resp_user_data.state", DataStateEnum.ENABLE.getCode());
|
||||
return this.baseMapper.page(new Page<>(PageFactory.getPageNum(queryParam), PageFactory.getPageSize(queryParam)), respUserDataQueryWrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SelectOption> userDataSelect() {
|
||||
List<SelectOption> selectOptions = new ArrayList<>();
|
||||
LambdaQueryWrapper<RespUserData> respUserDataLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
respUserDataLambdaQueryWrapper.eq(RespUserData::getState, DataStateEnum.ENABLE.getCode())
|
||||
.orderByDesc(RespUserData::getUpdateTime);
|
||||
List<RespUserData> respUserData = this.baseMapper.selectList(respUserDataLambdaQueryWrapper);
|
||||
if (CollectionUtil.isNotEmpty(respUserData)) {
|
||||
selectOptions = respUserData.stream().map(temp -> new SelectOption(temp.getName(), temp.getId())).collect(Collectors.toList());
|
||||
}
|
||||
return selectOptions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteUserDataByIds(List<String> ids) {
|
||||
this.baseMapper.deleteUserDataByIds(ids);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据流获取出用采有功功率数据
|
||||
*/
|
||||
private void analysisUserData(List<UserDataExcel> userDataExcelList, String fileName) {
|
||||
List<UserDataExcel> exportExcelList = new ArrayList<>();
|
||||
RespUserData respUserData;
|
||||
//判断数据提取情况
|
||||
if (CollectionUtils.isEmpty(userDataExcelList)) {
|
||||
throw new BusinessException(AdvanceResponseEnum.USER_DATA_EMPTY);
|
||||
}
|
||||
DealDataResult dealDataResult = getStanderData(userDataExcelList, 0);
|
||||
Map<String/*户号@监测点号@户名*/, Map<String/*yyyy-MM-dd天日期*/, Map<Date/*yyyy-MM-dd HH:mm:ss日期格式*/, UserDataExcel>>> totalData = dealDataResult.getTotalData();
|
||||
//收集所有的日期,以便获取起始日期和截止日期
|
||||
List<String> dates = dealDataResult.getDates();
|
||||
//将前面获取出来的日期进行排序,提供入库
|
||||
List<LocalDate> resultDates = getSortDate(dates);
|
||||
LocalDate endTime = resultDates.get(resultDates.size() - 1);
|
||||
LocalDate startTime = resultDates.get(0);
|
||||
//针对每个用户的数据进行完整度的判断 todo 暂且认为所有用户的时间跨度是一样的,比如都是15天或者都是30天,不存在有的用户5天数据,有的用户10天数据
|
||||
Map<String, List<UserDataExcel>> tempResult = new HashMap<>();
|
||||
List<RespUserDataIntegrity> respUserDataIntegrities = new ArrayList<>();
|
||||
Set<String> userNames = totalData.keySet();
|
||||
for (String name : userNames) {
|
||||
Map<String, Map<Date, UserDataExcel>> userDataTemp = totalData.get(name);
|
||||
//现在数据拿到了,但是因为是hashkey,所以日期顺序是乱的-->怎么变成有序的呢
|
||||
Set<String> times = userDataTemp.keySet();
|
||||
//循环日期处理数据
|
||||
for (String time : times) {
|
||||
DealUserDataResult dealtData = dealUserData(name, userDataTemp.get(time), time, 15);
|
||||
List<UserDataExcel> UserDataExcelTemp = dealtData.getCompleted();
|
||||
List<UserDataExcel> UserDataExcel;
|
||||
if (CollectionUtils.isEmpty(UserDataExcelTemp) && Objects.nonNull(dealtData.getRespUserDataIntegrity())) {
|
||||
//为空,说明补齐操作没有进行,选择填充缺失数据即可
|
||||
respUserDataIntegrities.add(dealtData.getRespUserDataIntegrity());
|
||||
UserDataExcel = dealtData.getLack();
|
||||
} else {
|
||||
//填充补齐完整性后的数据
|
||||
UserDataExcel = UserDataExcelTemp;
|
||||
}
|
||||
List<UserDataExcel> userDatas = tempResult.get(name);
|
||||
if (CollectionUtil.isNotEmpty(UserDataExcel)) {
|
||||
if (CollectionUtils.isEmpty(userDatas)) {
|
||||
userDatas = new ArrayList<>(UserDataExcel);
|
||||
} else {
|
||||
userDatas.addAll(UserDataExcel);
|
||||
}
|
||||
}
|
||||
tempResult.put(name, userDatas);
|
||||
}
|
||||
}
|
||||
//完成后,开始将数据按公司排序,然后输出到指定表格中,方便下次使用
|
||||
for (String name : userNames) {
|
||||
List<UserDataExcel> tempUserData = tempResult.get(name);
|
||||
//按时间排序
|
||||
Collections.sort(tempUserData);
|
||||
exportExcelList.addAll(tempUserData);
|
||||
}
|
||||
//输出到报表中
|
||||
String fileNameWithOutSuffix = fileName.substring(0, fileName.indexOf('.'));
|
||||
fileNameWithOutSuffix = fileNameWithOutSuffix.concat(LocalDateTimeUtil.format(startTime, DatePattern.PURE_DATE_PATTERN)).concat(StrPool.DASHED).concat(LocalDateTimeUtil.format(endTime, DatePattern.PURE_DATE_PATTERN));
|
||||
//处理完后的用采数据,生成json文件流到oss服务器
|
||||
JSONArray finalUserData = JSONArray.parseArray(JSON.toJSONString(exportExcelList));
|
||||
InputStream reportStream = IoUtil.toStream(finalUserData.toString(), CharsetUtil.UTF_8);
|
||||
String ossPath = fileStorageUtil.uploadStream(reportStream, OssPath.RESPONSIBILITY_USER_DATA, FileUtil.generateFileName("json"));
|
||||
//入库前进行查询操作,存在则更新,不存在则插入
|
||||
LambdaQueryWrapper<RespUserData> respUserDataLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
respUserDataLambdaQueryWrapper.eq(RespUserData::getName, fileNameWithOutSuffix)
|
||||
.eq(RespUserData::getStartTime, startTime)
|
||||
.eq(RespUserData::getEndTime, endTime)
|
||||
.eq(RespUserData::getState, DataStateEnum.ENABLE.getCode());
|
||||
respUserData = this.baseMapper.selectOne(respUserDataLambdaQueryWrapper);
|
||||
//不存在则插入
|
||||
if (Objects.isNull(respUserData)) {
|
||||
respUserData = new RespUserData();
|
||||
respUserData.setEndTime(endTime);
|
||||
respUserData.setStartTime(startTime);
|
||||
respUserData.setName(fileNameWithOutSuffix);
|
||||
respUserData.setDataPath(ossPath);
|
||||
respUserData.setState(DataStateEnum.ENABLE.getCode());
|
||||
this.baseMapper.insert(respUserData);
|
||||
if (CollectionUtil.isNotEmpty(respUserDataIntegrities)) {
|
||||
//关联插入数据 户号,监测点号,户名,时间,完整性
|
||||
for (RespUserDataIntegrity respUserDataIntegrity : respUserDataIntegrities) {
|
||||
respUserDataIntegrity.setUserDataId(respUserData.getId());
|
||||
}
|
||||
//插入操作
|
||||
respUserDataIntegrityService.saveBatch(respUserDataIntegrities);
|
||||
respUserData.setIntegrity(1);
|
||||
} else {
|
||||
respUserData.setIntegrity(0);
|
||||
}
|
||||
this.baseMapper.updateById(respUserData);
|
||||
} else {
|
||||
//存在则更新,需要删除之前的oss文件
|
||||
fileStorageUtil.deleteFile(respUserData.getDataPath());
|
||||
if (CollectionUtil.isNotEmpty(respUserDataIntegrities)) {
|
||||
LambdaQueryWrapper<RespUserDataIntegrity> respUserDataIntegrityLambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||
respUserDataIntegrityLambdaQueryWrapper.eq(RespUserDataIntegrity::getUserDataId, respUserData.getId());
|
||||
respUserDataIntegrityService.remove(respUserDataIntegrityLambdaQueryWrapper);
|
||||
for (RespUserDataIntegrity respUserDataIntegrity : respUserDataIntegrities) {
|
||||
respUserDataIntegrity.setUserDataId(respUserData.getId());
|
||||
}
|
||||
//插入操作
|
||||
respUserDataIntegrityService.saveBatch(respUserDataIntegrities);
|
||||
respUserData.setIntegrity(1);
|
||||
} else {
|
||||
respUserData.setIntegrity(0);
|
||||
}
|
||||
respUserData.setDataPath(ossPath);
|
||||
this.baseMapper.updateById(respUserData);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析用采数据为一个标准格式
|
||||
*/
|
||||
public static DealDataResult getStanderData(List<UserDataExcel> userDataExcelBodies, int flag) {
|
||||
DealDataResult result = new DealDataResult();
|
||||
//收集所有的日期,以便获取起始日期和截止日期
|
||||
List<String> dates = new ArrayList<>();
|
||||
Map<String, Map<String, Map<Date, UserDataExcel>>> totalData = new HashMap<>();
|
||||
Map<String, Map<String, List<UserDataExcel>>> totalListData = new HashMap<>();
|
||||
for (UserDataExcel UserDataExcel : userDataExcelBodies) {
|
||||
//第一个key
|
||||
String key = UserDataExcel.getUserId() + "@" + UserDataExcel.getLine() + "@" + UserDataExcel.getUserName();
|
||||
String time = UserDataExcel.getTime().substring(0, 10);
|
||||
if (!dates.contains(time)) {
|
||||
dates.add(time);
|
||||
}
|
||||
if (!totalData.containsKey(key)) {
|
||||
if (flag == 0) {
|
||||
//Map形式,避免后面补齐数据嵌套循环
|
||||
Map<Date, UserDataExcel> userDatas = new HashMap<>();
|
||||
userDatas.put(PubUtils.getSecondsAsZero(DateUtil.parse(UserDataExcel.getTime(), DatePattern.NORM_DATETIME_PATTERN)), UserDataExcel);
|
||||
Map<String, Map<Date, UserDataExcel>> dataToUserDatas = new HashMap<>();
|
||||
dataToUserDatas.put(time, userDatas);
|
||||
totalData.put(key, dataToUserDatas);
|
||||
} else if (flag == 1) {
|
||||
//List形式,避免后面责任数据提取嵌套循环
|
||||
List<UserDataExcel> userListDatas = new ArrayList<>();
|
||||
userListDatas.add(UserDataExcel);
|
||||
Map<String, List<UserDataExcel>> dataToUserListDatas = new HashMap<>();
|
||||
dataToUserListDatas.put(time, userListDatas);
|
||||
totalData.put(key, new HashMap<>());
|
||||
totalListData.put(key, dataToUserListDatas);
|
||||
}
|
||||
} else {
|
||||
if (flag == 0) {
|
||||
//Map形式,避免后面补齐数据嵌套循环
|
||||
Map<String, Map<Date, UserDataExcel>> dataToUserDatas = totalData.get(key);
|
||||
Map<Date, UserDataExcel> userDatas = dataToUserDatas.get(time);
|
||||
//某日凌晨,还没存放该日的数据
|
||||
if (CollectionUtils.isEmpty(userDatas)) {
|
||||
userDatas = new HashMap<>();
|
||||
userDatas.put(PubUtils.getSecondsAsZero(DateUtil.parse(UserDataExcel.getTime(), DatePattern.NORM_DATETIME_PATTERN)), UserDataExcel);
|
||||
dataToUserDatas.put(time, userDatas);
|
||||
} else {
|
||||
//累加该日的数据
|
||||
userDatas.put(PubUtils.getSecondsAsZero(DateUtil.parse(UserDataExcel.getTime(), DatePattern.NORM_DATETIME_PATTERN)), UserDataExcel);
|
||||
dataToUserDatas.put(time, userDatas);
|
||||
}
|
||||
totalData.put(key, dataToUserDatas);
|
||||
} else if (flag == 1) {
|
||||
//List形式,避免后面责任数据提取嵌套循环
|
||||
Map<String, List<UserDataExcel>> dataToUserListDatas = totalListData.get(key);
|
||||
List<UserDataExcel> userListDatas = dataToUserListDatas.get(time);
|
||||
if (CollectionUtils.isEmpty(userListDatas)) {
|
||||
userListDatas = new ArrayList<>();
|
||||
userListDatas.add(UserDataExcel);
|
||||
dataToUserListDatas.put(time, userListDatas);
|
||||
} else {
|
||||
userListDatas.add(UserDataExcel);
|
||||
dataToUserListDatas.put(time, userListDatas);
|
||||
}
|
||||
totalListData.put(key, dataToUserListDatas);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
result.setDates(dates);
|
||||
result.setTotalData(totalData);
|
||||
result.setTotalListData(totalListData);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将日期排序后返回
|
||||
*/
|
||||
private List<LocalDate> getSortDate(List<String> dates) {
|
||||
List<LocalDate> result = new ArrayList<>();
|
||||
for (String date : dates) {
|
||||
LocalDate temp = LocalDateTimeUtil.parseDate(date, DatePattern.NORM_DATE_PATTERN);
|
||||
result.add(temp);
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(result)) {
|
||||
Collections.sort(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 处理用户每日数据
|
||||
*
|
||||
* @param name 用户名
|
||||
* @param beforeDeal 处理前的用户数据
|
||||
*/
|
||||
private DealUserDataResult dealUserData(String name, Map<Date, UserDataExcel> beforeDeal, String time, int step) {
|
||||
DealUserDataResult result = new DealUserDataResult();
|
||||
String[] userFlag = name.split("@");
|
||||
//每天的最开是的数据是从00:00:00开始的,所以起始时间为time + 00:00:00
|
||||
List<UserDataExcel> completed = new ArrayList<>();
|
||||
List<UserDataExcel> lack = new ArrayList<>();
|
||||
if (CollectionUtils.isEmpty(beforeDeal)) {
|
||||
return result;
|
||||
} else {
|
||||
String timeTemp = time + " 00:00:00";
|
||||
Date date = DateUtil.parse(timeTemp, DatePattern.NORM_DATETIME_PATTERN);
|
||||
int count = 24 * 60 / 15;
|
||||
if ((float) beforeDeal.size() / (float) count < 0.9) {
|
||||
Set<Date> dates = beforeDeal.keySet();
|
||||
for (Date tempDate : dates) {
|
||||
UserDataExcel UserDataExcel = beforeDeal.get(tempDate);
|
||||
if (UserDataExcel.getWork() != null) {
|
||||
lack.add(UserDataExcel);
|
||||
}
|
||||
}
|
||||
RespUserDataIntegrity respUserDataIntegrity = new RespUserDataIntegrity();
|
||||
respUserDataIntegrity.setIntegrity(BigDecimal.valueOf((double) lack.size() / 96.0));
|
||||
respUserDataIntegrity.setLackDate(LocalDateTimeUtil.parseDate(time, DatePattern.NORM_DATE_PATTERN));
|
||||
respUserDataIntegrity.setUserName(userFlag[2]);
|
||||
respUserDataIntegrity.setLineNo(userFlag[1]);
|
||||
respUserDataIntegrity.setUserNo(userFlag[0]);
|
||||
result.setLack(lack);
|
||||
result.setRespUserDataIntegrity(respUserDataIntegrity);
|
||||
return result;
|
||||
} else {
|
||||
for (int i = 0; i < count; i++) {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date);
|
||||
calendar.add(Calendar.MINUTE, step * i);
|
||||
UserDataExcel UserDataExcel = beforeDeal.get(calendar.getTime());
|
||||
if (UserDataExcel != null && UserDataExcel.getWork() != null) {
|
||||
completed.add(UserDataExcel);
|
||||
} else {
|
||||
//找到前一个时间点值
|
||||
Float perValue = getPreValue(date, calendar.getTime(), beforeDeal);
|
||||
//找到后一个时间点值
|
||||
Float appendValue = getAppendValue(date, count, step, calendar.getTime(), beforeDeal);
|
||||
UserDataExcel temp = new UserDataExcel();
|
||||
SimpleDateFormat sdf = new SimpleDateFormat(DatePattern.NORM_DATETIME_PATTERN);
|
||||
temp.setTime(sdf.format(calendar.getTime()));
|
||||
temp.setUserId(userFlag[0]);
|
||||
temp.setLine(userFlag[1]);
|
||||
temp.setUserName(userFlag[2]);
|
||||
//还需要判断前值和后值为空的情况
|
||||
if (null == perValue && null == appendValue) {
|
||||
temp.setWork(new BigDecimal("0.0"));
|
||||
} else if (null == perValue) {
|
||||
temp.setWork(new BigDecimal(appendValue));
|
||||
} else if (null == appendValue) {
|
||||
temp.setWork(new BigDecimal(perValue));
|
||||
} else {
|
||||
temp.setWork(BigDecimal.valueOf((perValue + appendValue) / 2));
|
||||
}
|
||||
completed.add(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
result.setCompleted(completed);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归找前值
|
||||
*
|
||||
* @param date 起始时间
|
||||
* @param time 当前时间
|
||||
* @param beforeDeal 处理前的数据
|
||||
*/
|
||||
private Float getPreValue(Date date, Date time, Map<Date, UserDataExcel> beforeDeal) {
|
||||
Float result;
|
||||
if (date.equals(time)) {
|
||||
return null;
|
||||
} else {
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(time);
|
||||
calendar.add(Calendar.MINUTE, -15);
|
||||
UserDataExcel temp = beforeDeal.get(calendar.getTime());
|
||||
if (temp == null || temp.getWork() == null) {
|
||||
result = getPreValue(date, calendar.getTime(), beforeDeal);
|
||||
} else {
|
||||
result = temp.getWork().floatValue();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归找后置
|
||||
*
|
||||
* @param date 起始时间
|
||||
* @param count 一天时间的总计数
|
||||
* @param step 间隔分钟
|
||||
* @param time 截止时间
|
||||
*/
|
||||
private Float getAppendValue(Date date, int count, int step, Date time, Map<Date, UserDataExcel> beforeDeal) {
|
||||
Float result;
|
||||
Calendar calendar = Calendar.getInstance();
|
||||
calendar.setTime(date);
|
||||
calendar.set(Calendar.MINUTE, (count - 1) * step);
|
||||
if (time.equals(calendar.getTime())) {
|
||||
return null;
|
||||
} else {
|
||||
Calendar calendar1 = Calendar.getInstance();
|
||||
calendar1.setTime(time);
|
||||
calendar1.add(Calendar.MINUTE, 15);
|
||||
UserDataExcel temp = beforeDeal.get(calendar1.getTime());
|
||||
if (temp == null || temp.getWork() == null) {
|
||||
result = getAppendValue(date, count, step, calendar1.getTime(), beforeDeal);
|
||||
} else {
|
||||
result = temp.getWork().floatValue();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.njcn.advance.utils;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.njcn.advance.enums.AdvanceResponseEnum;
|
||||
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
|
||||
import com.njcn.common.pojo.exception.BusinessException;
|
||||
import com.njcn.common.pojo.response.HttpResult;
|
||||
import com.njcn.common.utils.EnumUtils;
|
||||
import com.njcn.device.biz.enums.DeviceResponseEnum;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @author hongawen
|
||||
* @version 1.0.0
|
||||
* @date 2021年12月20日 10:03
|
||||
*/
|
||||
public class AdvanceEnumUtil {
|
||||
|
||||
|
||||
/**
|
||||
* 获取UserResponseEnum实例
|
||||
*/
|
||||
public static AdvanceResponseEnum getDeviceEnumResponseEnumByMessage(@NotNull Object value) {
|
||||
AdvanceResponseEnum advanceResponseEnum;
|
||||
try {
|
||||
String message = value.toString();
|
||||
if(message.indexOf(StrUtil.C_COMMA)>0){
|
||||
value = message.substring(message.indexOf(StrUtil.C_COMMA)+1);
|
||||
}
|
||||
advanceResponseEnum = EnumUtils.valueOf(AdvanceResponseEnum.class, value, AdvanceResponseEnum.class.getMethod(BusinessException.GET_MESSAGE_METHOD));
|
||||
return Objects.isNull(advanceResponseEnum) ? AdvanceResponseEnum.INTERNAL_ERROR : advanceResponseEnum;
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new BusinessException(CommonResponseEnum.INTERNAL_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
public static Enum<?> getExceptionEnum(HttpResult<Object> result){
|
||||
//如果返回错误,且为内部错误,则直接抛出异常
|
||||
CommonResponseEnum commonResponseEnum = EnumUtils.getCommonResponseEnumByCode(result.getCode());
|
||||
if (commonResponseEnum == CommonResponseEnum.ADVANCE_RESPONSE_ENUM) {
|
||||
return getDeviceEnumResponseEnumByMessage(result.getMessage());
|
||||
}
|
||||
return commonResponseEnum;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.njcn.advance.utils;
|
||||
|
||||
import com.njcn.advance.pojo.bo.responsibility.QvvrStruct;
|
||||
import com.sun.jna.Library;
|
||||
import com.sun.jna.Native;
|
||||
|
||||
/**
|
||||
* @author hongawen
|
||||
* @version 1.0.0
|
||||
* @date 2023年07月24日 14:12
|
||||
*/
|
||||
public class ResponsibilityCallDllOrSo extends JnaCallDllOrSo {
|
||||
|
||||
public static String strpath;
|
||||
|
||||
public ResponsibilityCallDllOrSo(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPath() {
|
||||
ResponsibilityCallDllOrSo.strpath = super.getStrpath();
|
||||
}
|
||||
|
||||
public interface ResponsibilityLibrary extends Library {
|
||||
// 加载Lib库
|
||||
ResponsibilityCallDllOrSo.ResponsibilityLibrary INSTANTCE = (ResponsibilityCallDllOrSo.ResponsibilityLibrary) Native.loadLibrary(ResponsibilityCallDllOrSo.strpath, ResponsibilityCallDllOrSo.ResponsibilityLibrary.class);
|
||||
// 定义方法--->与C方法相对应
|
||||
void harm_response(QvvrStruct outData);
|
||||
}
|
||||
}
|
||||
BIN
pqs-advance/advance-boot/src/main/resources/harm_response.dll
Normal file
BIN
pqs-advance/advance-boot/src/main/resources/harm_response.dll
Normal file
Binary file not shown.
Reference in New Issue
Block a user