动态成本

This commit is contained in:
pengjie 2024-08-30 10:33:21 +08:00
parent fa8f148743
commit 6398185761
23 changed files with 776 additions and 191 deletions

View File

@ -20,6 +20,7 @@ import com.zhgd.xmgl.modules.basicdata.service.ICompanyService;
import com.zhgd.xmgl.modules.basicdata.service.IOrganizationDeptService;
import com.zhgd.xmgl.modules.basicdata.service.IOrganizationJobService;
import com.zhgd.xmgl.modules.basicdata.service.ISystemUserService;
import com.zhgd.xmgl.util.JiuzhuUtil;
import com.zhgd.xmgl.util.MD5;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
@ -48,7 +49,7 @@ public class BaseDataController {
private final String ADDRESS = "http://218.95.151.122:18000";
@Autowired
private RedisRepository redisRepository;
private JiuzhuUtil jiuzhuUtil;
@Autowired
private IOrganizationJobService organizationJobService;
@ -70,7 +71,7 @@ public class BaseDataController {
params.put("pagesize", 1000);
params.put("curpage", 1);
jsonParams.put("params", params);
String result = testRestful(ADDRESS, "/api/hrm/resful/getHrmsubcompanyWithPage", JSONObject.toJSONString(jsonParams));
String result = jiuzhuUtil.testRestful(ADDRESS, "/api/hrm/resful/getHrmsubcompanyWithPage", JSONObject.toJSONString(jsonParams), APPID);
if (StringUtils.isNotBlank(result)) {
JSONObject obj = JSONObject.parseObject(result);
JSONArray jsonArray = obj.getJSONObject("data").getJSONArray("dataList");
@ -115,7 +116,7 @@ public class BaseDataController {
params.put("pagesize", 1000);
params.put("curpage", 1);
jsonParams.put("params", params);
String result = testRestful(ADDRESS, "/api/hrm/resful/getHrmdepartmentWithPage", JSONObject.toJSONString(jsonParams));
String result = jiuzhuUtil.testRestful(ADDRESS, "/api/hrm/resful/getHrmdepartmentWithPage", JSONObject.toJSONString(jsonParams), APPID);
if (StringUtils.isNotBlank(result)) {
JSONObject obj = JSONObject.parseObject(result);
JSONArray jsonArray = obj.getJSONObject("data").getJSONArray("dataList");
@ -159,7 +160,7 @@ public class BaseDataController {
params.put("pagesize", 1000);
params.put("curpage", 1);
jsonParams.put("params", params);
String result = testRestful(ADDRESS, "/api/hrm/resful/getJobtitleInfoWithPage", JSONObject.toJSONString(jsonParams));
String result = jiuzhuUtil.testRestful(ADDRESS, "/api/hrm/resful/getJobtitleInfoWithPage", JSONObject.toJSONString(jsonParams), APPID);
if (StringUtils.isNotBlank(result)) {
JSONObject obj = JSONObject.parseObject(result);
JSONArray jsonArray = obj.getJSONObject("data").getJSONArray("dataList");
@ -186,7 +187,7 @@ public class BaseDataController {
params.put("pagesize", 1000);
params.put("curpage", 1);
jsonParams.put("params", params);
String result = testRestful(ADDRESS, "/api/hrm/resful/getHrmUserInfoWithPage", JSONObject.toJSONString(jsonParams));
String result = jiuzhuUtil.testRestful(ADDRESS, "/api/hrm/resful/getHrmUserInfoWithPage", JSONObject.toJSONString(jsonParams), APPID);
if (StringUtils.isNotBlank(result)) {
JSONObject obj = JSONObject.parseObject(result);
JSONArray jsonArray = obj.getJSONObject("data").getJSONArray("dataList");
@ -227,106 +228,4 @@ public class BaseDataController {
}
return Result.success(null);
}
private String testRestful(String address,String api,String jsonParams){
//ECOLOGY返回的token
String token= (String) redisRepository.get("JIUZHU_SERVER_TOKEN");
if (StrUtil.isEmpty(token)){
token = (String) testGetoken(address).get("token");
}
String spk = (String) redisRepository.get("JIUZHU_SERVER_PUBLIC_KEY");
//封装请求头参数
RSA rsa = new RSA(null,spk);
//对用户信息进行加密传输,暂仅支持传输OA用户ID
String encryptUserid = rsa.encryptBase64("1",CharsetUtil.CHARSET_UTF_8,KeyType.PublicKey);
//调用ECOLOGY系统接口
String data = HttpRequest.post(address + api)
.header("appid",APPID)
.header("token",token)
.header("userid",encryptUserid)
.body(jsonParams)
.execute().body();
System.out.println("testRestful()"+data);
return data;
}
/**
* 第一步
*
* 调用ecology注册接口,根据appid进行注册,将返回服务端公钥和Secret信息
*/
private Map<String,Object> testRegist(String address){
//获取当前系统RSA加密的公钥
RSA rsa = new RSA();
String publicKey = rsa.getPublicKeyBase64();
String privateKey = rsa.getPrivateKeyBase64();
// 客户端RSA私钥
redisRepository.set("JIUZHU_LOCAL_PRIVATE_KEY",privateKey);
// 客户端RSA公钥
redisRepository.set("JIUZHU_LOCAL_PUBLIC_KEY",publicKey);
//调用ECOLOGY系统接口进行注册
String data = HttpRequest.post(address + "/api/ec/dev/auth/regist")
.header("appid",APPID)
.header("cpk",publicKey)
.timeout(2000)
.execute().body();
// 打印ECOLOGY响应信息
System.out.println("testRegist()"+data);
Map<String,Object> datas = JSONUtil.parseObj(data);
//ECOLOGY返回的系统公钥
redisRepository.set("JIUZHU_SERVER_PUBLIC_KEY", StrUtil.nullToEmpty((String)datas.get("spk")));
//ECOLOGY返回的系统密钥
redisRepository.set("JIUZHU_SERVER_SECRET",StrUtil.nullToEmpty((String)datas.get("secrit")));
return datas;
}
/**
* 第二步
*
* 通过第一步中注册系统返回信息进行获取token信息
*/
private Map<String,Object> testGetoken(String address){
// 从系统缓存或者数据库中获取ECOLOGY系统公钥和Secret信息
String secret = (String) redisRepository.get("JIUZHU_SERVER_SECRET");
String spk = (String) redisRepository.get("JIUZHU_SERVER_PUBLIC_KEY");
// 如果为空,说明还未进行注册,调用注册接口进行注册认证与数据更新
if (Objects.isNull(secret)||Objects.isNull(spk)){
testRegist(address);
// 重新获取最新ECOLOGY系统公钥和Secret信息
secret = (String) redisRepository.get("JIUZHU_SERVER_SECRET");
spk = (String) redisRepository.get("JIUZHU_SERVER_PUBLIC_KEY");
}
// 公钥加密,所以RSA对象私钥为null
RSA rsa = new RSA(null,spk);
//对秘钥进行加密传输防止篡改数据
String encryptSecret = rsa.encryptBase64(secret, CharsetUtil.CHARSET_UTF_8, KeyType.PublicKey);
//调用ECOLOGY系统接口进行注册
String data = HttpRequest.post(address+ "/api/ec/dev/auth/applytoken")
.header("appid",APPID)
.header("secret",encryptSecret)
.header("time","3600")
.execute().body();
System.out.println("testGetoken()"+data);
Map<String,Object> datas = JSONUtil.parseObj(data);
//ECOLOGY返回的token
// TODO 为Token缓存设置过期时间
redisRepository.setExpire("JIUZHU_SERVER_TOKEN",StrUtil.nullToEmpty((String)datas.get("token")), 60 * 30);
return datas;
}
}

View File

@ -7,6 +7,7 @@ import com.zhgd.xmgl.modules.basicdata.entity.Company;
import com.zhgd.xmgl.modules.basicdata.service.ICompanyService;
import com.zhgd.xmgl.modules.cost.dto.CostBudgetDto;
import com.zhgd.xmgl.modules.cost.dto.CostContractPlanDto;
import com.zhgd.xmgl.modules.cost.dto.DynamicCostDto;
import com.zhgd.xmgl.modules.cost.entity.CostSubject;
import com.zhgd.xmgl.modules.cost.vo.CostContractPlanVo;
import com.zhgd.xmgl.modules.project.entity.Project;
@ -315,4 +316,25 @@ public class CostContractPlanController {
return Result.ok("文件导入失败!");
}
/**
* 树形查询动态成本
*
* @param map
* @return
*/
@OperLog(operModul = "合约规划管理", operType = "列表查询", operDesc = "树形查询动态成本")
@ApiOperation(value = " 树形查询动态成本", notes = "树形查询动态成本", httpMethod = "POST")
@ApiImplicitParam(name = "projectSn", value = "项目SN", paramType = "body", dataType = "String")
@PostMapping(value = "/dynamicTree")
public Result<List<DynamicCostDto>> dynamicTree(@ApiIgnore @RequestBody Map<String, Object> map) {
String projectSn = MapUtils.getString(map, "projectSn");
ProjectInfoExtVo projectInfoBySn = projectService.getProjectInfoBySn(projectSn);
Company company = companyService.getOne(Wrappers.<Company>lambdaQuery().eq(Company::getCompanySn, projectInfoBySn.getCompanySn()));
map.put("companySn", company.getHeadquartersSn());
QueryWrapper<CostSubject> queryWrapper = QueryGenerator.initPageQueryWrapper(CostSubject.class, map);
queryWrapper.lambda().eq(CostSubject::getType, projectInfoBySn.getProjectLx());
List<DynamicCostDto> list = costContractPlanService.dynamicTree(queryWrapper, projectInfoBySn);
return Result.success(list);
}
}

View File

@ -5,9 +5,14 @@ import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zhgd.annotation.OperLog;
import com.zhgd.xmgl.modules.basicdata.entity.Company;
import com.zhgd.xmgl.modules.cost.dto.ContractPayOverviewDto;
import com.zhgd.xmgl.modules.cost.dto.DynamicCostDto;
import com.zhgd.xmgl.modules.cost.entity.CostQuantity;
import com.zhgd.xmgl.modules.cost.entity.CostSubject;
import com.zhgd.xmgl.modules.cost.service.ICostQuantityService;
import com.zhgd.xmgl.modules.project.entity.Project;
import com.zhgd.xmgl.modules.project.entity.vo.ProjectInfoExtVo;
import com.zhgd.xmgl.modules.project.service.IProjectService;
import com.zhgd.xmgl.util.PageUtil;
import io.swagger.annotations.Api;
@ -259,4 +264,19 @@ public class CostPayPlanController {
}
return result;
}
/**
* 支付总览
*
* @param map
* @return
*/
@OperLog(operModul = "资金计划管理", operType = "列表查询", operDesc = "支付总览")
@ApiOperation(value = " 支付总览", notes = "支付总览", httpMethod = "POST")
@ApiImplicitParam(name = "projectSn", value = "项目SN", paramType = "body", dataType = "String")
@PostMapping(value = "/payOverview")
public Result<List<ContractPayOverviewDto>> payOverview(@ApiIgnore @RequestBody Map<String, Object> map) {
List<ContractPayOverviewDto> list = costPayPlanService.payOverview(MapUtils.getString(map, "projectSn"));
return Result.success(list);
}
}

View File

@ -4,6 +4,7 @@ import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhgd.annotation.OperLog;
import com.zhgd.jeecg.common.api.vo.Result;
import com.zhgd.jeecg.common.system.query.QueryGenerator;
@ -14,6 +15,8 @@ import com.zhgd.xmgl.modules.cost.entity.CostSubject;
import com.zhgd.xmgl.modules.cost.service.ICostBudgetService;
import com.zhgd.xmgl.modules.cost.service.ICostContractService;
import com.zhgd.xmgl.modules.cost.service.ICostSubjectService;
import com.zhgd.xmgl.modules.jz.entity.*;
import com.zhgd.xmgl.modules.jz.service.*;
import com.zhgd.xmgl.modules.project.entity.ProgressPanoramaNodePlan;
import com.zhgd.xmgl.modules.project.entity.Project;
import com.zhgd.xmgl.modules.project.service.IProgressPanoramaNodePlanService;
@ -67,6 +70,21 @@ public class IndexController {
@Autowired
private IProgressPanoramaNodePlanService progressPanoramaNodePlanService;
@Autowired
private IJzCustomerService jzCustomerService;
@Autowired
private IJzProjectService jzProjectService;
@Autowired
private IJzBidService jzBidService;
@Autowired
private IJzProjectFollowService jzProjectFollowService;
@Autowired
private IJzBidResultService jzBidResultService;
/**
* 成本统计信息
* @return
@ -128,11 +146,37 @@ public class IndexController {
Map<String, Object> stateMap = new HashMap();
stateMap.put("total", list.size());
stateMap.put("unStart", list.stream().filter(l -> l.getStatus() == 1).count());
stateMap.put("inProgress", list.stream().filter(l -> l.getStatus() == 2 && DateUtil.parseDate(l.getFinishDate()).compareTo(new Date()) >= 0).count());
stateMap.put("delay", list.stream().filter(l -> l.getStatus() == 2 && DateUtil.parseDate(l.getFinishDate()).compareTo(new Date()) < 0).count());
stateMap.put("inProgress", list.stream().filter(l -> l.getStatus() == 2).count());
stateMap.put("delay", list.stream().filter(l -> l.getStatus() < 3 && DateUtil.parseDate(l.getPlanFinishDate()).compareTo(new Date()) < 0).count());
stateMap.put("delayCompletion", list.stream().filter(l -> l.getStatus() == 4).count());
stateMap.put("completion", list.stream().filter(l -> l.getStatus() == 3).count());
resultMap.put("stateMap", stateMap);
return Result.success(resultMap);
}
/**
* 项目招投标管理
* @return
*/
@OperLog(operModul = "门户信息管理", operType = "列表查询", operDesc = "项目招投标管理")
@ApiOperation(value = "项目招投标管理", notes = "项目招投标管理", httpMethod = "GET")
@GetMapping(value = "jzProjectStat")
public Result<Map<String, Object>> jzProjectStat() {
List<JzCustomer> jzCustomerList = jzCustomerService.list();
List<JzProject> jzProjectList = jzProjectService.pageList(new Page(-1, -1), null).getRecords();
List<JzBid> jzBidList = jzBidService.list();
List<JzProjectFollow> jzProjectFollowList = jzProjectFollowService.list();
List<JzBidResult> jzBidResults = jzBidResultService.list(Wrappers.<JzBidResult>lambdaQuery().eq(JzBidResult::getWinBid, 1));
Map<String, Object> stateMap = new HashMap();
stateMap.put("customer", jzCustomerList.size());
stateMap.put("project", jzProjectList.size());
stateMap.put("build", jzProjectList.stream().filter(l -> l.getStatus() == 1).count());
stateMap.put("result", jzBidResults.size());
stateMap.put("totalList", jzProjectList);
stateMap.put("buildList", jzProjectList.stream().filter(l -> l.getStatus() == 1).collect(Collectors.toList()));
stateMap.put("follow", jzProjectList.stream().filter(j -> jzProjectFollowList.stream().map(b -> b.getProjectId()).collect(Collectors.toList()).contains(j.getId().toString())).collect(Collectors.toList()));
stateMap.put("bidList", jzProjectList.stream().filter(j -> jzBidList.stream().map(b -> b.getProjectId()).collect(Collectors.toList()).contains(j.getId().toString())).collect(Collectors.toList()));
stateMap.put("resultList", jzProjectList.stream().filter(j -> jzBidResults.stream().map(b -> b.getProjectId()).collect(Collectors.toList()).contains(j.getId().toString())).collect(Collectors.toList()));
return Result.success(stateMap);
}
}

View File

@ -0,0 +1,30 @@
package com.zhgd.xmgl.modules.cost.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
@Data
@ApiModel(value = "支付总览(DTO)", description = "ContractPayOverviewDto")
public class ContractPayOverviewDto {
@ApiModelProperty(value = "项目ID")
private Long projectId;
@ApiModelProperty(value = "项目名称")
private String projectName;
@ApiModelProperty(value = "计划付款金额")
private BigDecimal planPayAmount = new BigDecimal(0);
@ApiModelProperty(value = "实际支付金额")
private BigDecimal payAmount = new BigDecimal(0);
@ApiModelProperty(value = "计划与实际支付差额")
private BigDecimal costDifference = new BigDecimal(0);
@ApiModelProperty(value = "计划与实际支付差额百分比")
private String costDifferenceRatio = "0";
}

View File

@ -0,0 +1,48 @@
package com.zhgd.xmgl.modules.cost.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.jeecgframework.poi.excel.annotation.Excel;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
@Data
@ApiModel(value = "动态成本(DTO)", description = "DynamicCostDto")
public class DynamicCostDto {
@ApiModelProperty(value = "科目名称")
private Long subjectId;
@ApiModelProperty(value = "科目名称")
private String subjectName;
@ApiModelProperty(value = "目标+调整")
private BigDecimal goal = new BigDecimal(0);
@ApiModelProperty(value = "动态成本")
private BigDecimal dynamicCost = new BigDecimal(0);
@ApiModelProperty(value = "差额比例")
private String costDifference = "0";
@ApiModelProperty(value = "合同金额")
private BigDecimal contractAmount = new BigDecimal(0);
@ApiModelProperty(value = "在途成本")
private BigDecimal underApproval = new BigDecimal(0);
@ApiModelProperty(value = "待发生合约")
private BigDecimal toOccur = new BigDecimal(0);
@ApiModelProperty(value = "预估变更")
private BigDecimal estimatedChange = new BigDecimal(0);
@ApiModelProperty(value = "规划余量")
private BigDecimal allowance = new BigDecimal(0);
@ApiModelProperty(value = "子级动态成本信息")
private List<DynamicCostDto> children = new ArrayList<>();
}

View File

@ -32,6 +32,12 @@ public class CostContract implements Serializable {
@TableId(type = IdType.INPUT)
@ApiModelProperty(value = "合同ID")
private Integer id;
/**
* 成本科目ID
*/
@Excel(name = "成本科目ID", width = 15)
@ApiModelProperty(value = "成本科目ID")
private Long subjectId;
/**
* 合同摘要
*/

View File

@ -3,6 +3,7 @@ package com.zhgd.xmgl.modules.cost.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zhgd.xmgl.modules.cost.dto.CostBudgetDto;
import com.zhgd.xmgl.modules.cost.dto.CostContractPlanDto;
import com.zhgd.xmgl.modules.cost.dto.DynamicCostDto;
import com.zhgd.xmgl.modules.cost.entity.CostContractPlan;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zhgd.xmgl.modules.cost.entity.CostSubject;
@ -21,6 +22,8 @@ public interface ICostContractPlanService extends IService<CostContractPlan> {
List<CostContractPlanDto> tree(QueryWrapper<CostSubject> wrapper, ProjectInfoExtVo projectInfoBySn);
List<DynamicCostDto> dynamicTree(QueryWrapper<CostSubject> wrapper, ProjectInfoExtVo projectInfoBySn);
boolean saveInfo(CostContractPlanVo costContractPlanVo);
boolean updateInfo(CostContractPlanVo costContractPlanVo);

View File

@ -1,8 +1,11 @@
package com.zhgd.xmgl.modules.cost.service;
import com.zhgd.xmgl.modules.cost.dto.ContractPayOverviewDto;
import com.zhgd.xmgl.modules.cost.entity.CostPayPlan;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* @Description: 资金计划
* @author pengj
@ -13,4 +16,6 @@ public interface ICostPayPlanService extends IService<CostPayPlan> {
CostPayPlan queryById(String id);
List<ContractPayOverviewDto> payOverview(String projectSn);
}

View File

@ -5,14 +5,13 @@ import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zhgd.xmgl.modules.cost.dto.CostBudgetDto;
import com.zhgd.xmgl.modules.cost.dto.CostContractPlanDto;
import com.zhgd.xmgl.modules.cost.entity.CostBudget;
import com.zhgd.xmgl.modules.cost.entity.CostContractPayPlan;
import com.zhgd.xmgl.modules.cost.entity.CostContractPlan;
import com.zhgd.xmgl.modules.cost.entity.CostSubject;
import com.zhgd.xmgl.modules.cost.dto.DynamicCostDto;
import com.zhgd.xmgl.modules.cost.entity.*;
import com.zhgd.xmgl.modules.cost.mapper.CostContractPayPlanMapper;
import com.zhgd.xmgl.modules.cost.mapper.CostContractPlanMapper;
import com.zhgd.xmgl.modules.cost.service.ICostContractPayPlanService;
import com.zhgd.xmgl.modules.cost.service.ICostContractPlanService;
import com.zhgd.xmgl.modules.cost.service.ICostContractService;
import com.zhgd.xmgl.modules.cost.service.ICostSubjectService;
import com.zhgd.xmgl.modules.cost.vo.CostContractPlanVo;
import com.zhgd.xmgl.modules.project.entity.vo.ProjectInfoExtVo;
@ -24,7 +23,9 @@ import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
@ -41,6 +42,9 @@ public class CostContractPlanServiceImpl extends ServiceImpl<CostContractPlanMap
@Autowired
private ICostSubjectService costSubjectService;
@Autowired
private ICostContractService costContractService;
@Autowired
private ICostContractPayPlanService costContractPayPlanService;
@ -59,6 +63,21 @@ public class CostContractPlanServiceImpl extends ServiceImpl<CostContractPlanMap
return parentPlanList;
}
@Override
public List<DynamicCostDto> dynamicTree(QueryWrapper<CostSubject> wrapper, ProjectInfoExtVo projectInfoBySn) {
List<CostSubject> allSubList = costSubjectService.list(wrapper);
List<CostSubject> parentSubList = allSubList.stream().filter(l -> l.getParentId().toString().equals("0") && StringUtils.isNotBlank(l.getName())).collect(Collectors.toList());
List<DynamicCostDto> resultList = new ArrayList<>();
if (allSubList.size() > 0) {
List<CostContractPlan> contractPlanList = this.list(Wrappers.<CostContractPlan>lambdaQuery()
.eq(CostContractPlan::getProjectSn, projectInfoBySn.getProjectSn()));
List<CostContract> contractList = costContractService.list(Wrappers.<CostContract>lambdaQuery()
.eq(CostContract::getProjectSn, projectInfoBySn.getProjectSn()));
resultList = getDynamicChildren(parentSubList, allSubList, contractPlanList, contractList);
}
return resultList;
}
@Override
public boolean saveInfo(CostContractPlanVo costContractPlanVo) {
List<CostContractPayPlan> costContractPayPlanList = costContractPlanVo.getCostContractPayPlanList();
@ -138,6 +157,37 @@ public class CostContractPlanServiceImpl extends ServiceImpl<CostContractPlanMap
}
}
private List<DynamicCostDto> getDynamicChildren(List<CostSubject> list, List<CostSubject> allList, List<CostContractPlan> contractPlanList, List<CostContract> contractList) {
List<DynamicCostDto> dynamicCostDtoList = new ArrayList<>();
for (CostSubject costSubject : list) {
DynamicCostDto dynamicCostDto = new DynamicCostDto();
dynamicCostDto.setSubjectId(costSubject.getId());
dynamicCostDto.setSubjectName(costSubject.getName());
// 查询合约
List<CostSubject> children = allList.stream().filter(a -> Arrays.asList(a.getAncestors().split(",")).contains(costSubject.getId().toString())).collect(Collectors.toList());
List<String> childrenSubIds = children.stream().map(c -> c.getId().toString()).collect(Collectors.toList());
List<CostContractPlan> contractPlans = new ArrayList<>();
List<CostContract> contracts = new ArrayList<>();
if (childrenSubIds.size() > 0) {
contractPlans = contractPlanList.stream().filter(c -> childrenSubIds.contains(c.getSubjectId().toString())).collect(Collectors.toList());
contracts = contractList.stream().filter(c -> childrenSubIds.contains(c.getSubjectId().toString())).collect(Collectors.toList());
} else {
contractPlans = contractPlanList.stream().filter(c -> c.getSubjectId().toString().equals(costSubject.getId().toString())).collect(Collectors.toList());
contracts = contractList.stream().filter(c -> c.getSubjectId().toString().equals(costSubject.getId().toString())).collect(Collectors.toList());
}
dynamicCostDto.setGoal(contractPlans.stream().map(c -> new BigDecimal(c.getGoal())).reduce(BigDecimal.ZERO, BigDecimal::add));
dynamicCostDto.setContractAmount(contracts.stream().filter(c -> c.getZt().equals("已生效")).map(c -> c.getHthszj()).reduce(BigDecimal.ZERO, BigDecimal::add));
dynamicCostDto.setUnderApproval(contracts.stream().filter(c -> c.getZt().equals("内审中")).map(c -> c.getHthszj()).reduce(BigDecimal.ZERO, BigDecimal::add));
dynamicCostDto.setDynamicCost(dynamicCostDto.getContractAmount().add(dynamicCostDto.getUnderApproval()).add(dynamicCostDto.getToOccur()).add(dynamicCostDto.getContractAmount()));
BigDecimal subtract = dynamicCostDto.getGoal().subtract(dynamicCostDto.getDynamicCost());
dynamicCostDto.setCostDifference(dynamicCostDto.getGoal().compareTo(new BigDecimal(0)) > 0 ? subtract.divide(dynamicCostDto.getGoal(), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)).toString() : "0");
dynamicCostDto.setAllowance(subtract);
dynamicCostDto.setChildren(getDynamicChildren(children, allList, contractPlanList, contractList));
dynamicCostDtoList.add(dynamicCostDto);
}
return dynamicCostDtoList;
}
private List<CostContractPlanDto> convert(List<CostSubject> list) {
List<CostContractPlanDto> dtoList = new ArrayList<>();
for (CostSubject costSubject : list) {

View File

@ -1,17 +1,22 @@
package com.zhgd.xmgl.modules.cost.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zhgd.xmgl.modules.cost.dto.ContractPayOverviewDto;
import com.zhgd.xmgl.modules.cost.entity.CostPayPlan;
import com.zhgd.xmgl.modules.cost.entity.CostQuantity;
import com.zhgd.xmgl.modules.cost.mapper.CostPayPlanMapper;
import com.zhgd.xmgl.modules.cost.mapper.CostQuantityMapper;
import com.zhgd.xmgl.modules.cost.service.ICostPayPlanService;
import com.zhgd.xmgl.modules.cost.service.ICostQuantityService;
import com.zhgd.xmgl.modules.project.entity.Project;
import com.zhgd.xmgl.modules.project.service.IProjectService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
/**
@ -26,6 +31,9 @@ public class CostPayPlanServiceImpl extends ServiceImpl<CostPayPlanMapper, CostP
@Autowired
private ICostQuantityService costQuantityService;
@Autowired
private IProjectService projectService;
@Override
public CostPayPlan queryById(String id) {
List<CostQuantity> list = costQuantityService.list(Wrappers.<CostQuantity>lambdaQuery().eq(CostQuantity::getPayPlanId, id));
@ -33,4 +41,25 @@ public class CostPayPlanServiceImpl extends ServiceImpl<CostPayPlanMapper, CostP
payPlan.setCostQuantityList(list);
return payPlan;
}
@Override
public List<ContractPayOverviewDto> payOverview(String projectSn) {
List<ContractPayOverviewDto> overviewDtos = new ArrayList<>();
List<Project> projects = projectService.list();
List<CostPayPlan> list = this.list();
for (Project project : projects) {
ContractPayOverviewDto contractPayOverviewDto = new ContractPayOverviewDto();
contractPayOverviewDto.setProjectId(project.getProjectId());
contractPayOverviewDto.setProjectName(project.getProjectName());
contractPayOverviewDto.setPlanPayAmount(list.stream().map(l -> new BigDecimal(l.getPayAmount())).reduce(BigDecimal.ZERO, BigDecimal::add));
contractPayOverviewDto.setPayAmount(new BigDecimal(0));
contractPayOverviewDto.setCostDifference(contractPayOverviewDto.getPlanPayAmount().subtract(contractPayOverviewDto.getPayAmount()));
if (contractPayOverviewDto.getPlanPayAmount().compareTo(new BigDecimal(0)) != 0) {
contractPayOverviewDto.setCostDifferenceRatio(contractPayOverviewDto.getCostDifference().divide(contractPayOverviewDto.getPlanPayAmount(), 2, BigDecimal.ROUND_HALF_UP)
.multiply(new BigDecimal(100)).toString());
}
overviewDtos.add(contractPayOverviewDto);
}
return overviewDtos;
}
}

View File

@ -89,13 +89,17 @@ public class JzProjectController {
Integer state = MapUtils.getInteger(map, "state");
if (state != null) {
List<Long> projectIds = new ArrayList<>();
if (state == 2) {
projectIds = jzProjectFollowService.list().stream().map(p -> p.getProjectId()).distinct().collect(Collectors.toList());
} else if (state == 3) {
projectIds = jzBidExamService.list().stream().map(p -> p.getProjectId()).distinct().collect(Collectors.toList());
if (state == 1) {
queryWrapper.lambda().eq(JzProject::getStatus, 1);
} else {
if (state == 2) {
projectIds = jzProjectFollowService.list().stream().map(p -> p.getProjectId()).distinct().collect(Collectors.toList());
} else if (state == 3) {
projectIds = jzBidExamService.list().stream().map(p -> p.getProjectId()).distinct().collect(Collectors.toList());
}
projectIds.add(0L);
queryWrapper.lambda().in(JzProject::getId, projectIds);
}
projectIds.add(0L);
queryWrapper.lambda().in(JzProject::getId, projectIds);
}
IPage<JzProject> pageList = jzProjectService.pageList(page, queryWrapper);
return Result.success(pageList);
@ -238,7 +242,7 @@ public class JzProjectController {
String [] type = {"工程类", "供货配合调试类", "售后服务类", "软件研发类", "维修类", "人员服务类", "纯销售类", "其他"};
List<JzProject> list = jzProjectService.list();
int follow = (int) jzProjectFollowService.list().stream().map(p -> p.getProjectId()).distinct().count();
int [] num = {list.size(), follow, 0};
int [] num = {(int) list.stream().filter(l -> l.getStatus() == 1).count(), follow, 0};
for (int i = 0; i < state.length; i++) {
TableDto tableDto = new TableDto();
tableDto.setTitle(state[i]);
@ -253,7 +257,7 @@ public class JzProjectController {
tableDto.setTitle(type[i]);
Integer value = i + 1;
tableDto.setValue("2-" + value);
tableDto.setNum((int) list.stream().filter(l -> l.getType().equals(value.toString())).count());
tableDto.setNum((int) list.stream().filter(l -> l.getStatus() == 1 && l.getType().equals(value.toString())).count());
tableDto.setFlag(2);
tableDtoList.add(tableDto);
}

View File

@ -210,6 +210,24 @@ public class JzProject implements Serializable {
@Excel(name = "附件", width = 15)
@ApiModelProperty(value = "附件")
private String fileUrl;
/**
* 状态(0未立项1已立项)
*/
@Excel(name = "状态(0未立项1已立项)", width = 15)
@ApiModelProperty(value = "状态(0未立项1已立项)")
private Integer status;
/**
* 项目负责人ID
*/
@Excel(name = "项目负责人ID", width = 15)
@ApiModelProperty(value = "项目负责人ID")
private String chargerId;
/**
* 项目负责人名称
*/
@Excel(name = "项目负责人名称", width = 15)
@ApiModelProperty(value = "项目负责人名称")
private String chargerName;
@TableField(exist = false)

View File

@ -3,6 +3,7 @@ package com.zhgd.xmgl.modules.project.controller;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
@ -17,13 +18,19 @@ import com.zhgd.jeecg.common.execption.OpenAlertException;
import com.zhgd.jeecg.common.mybatis.EntityMap;
import com.zhgd.jeecg.common.system.query.QueryGenerator;
import com.zhgd.xmgl.modules.basicdata.dto.ProjectKeyNode;
import com.zhgd.xmgl.modules.basicdata.entity.DictionaryItem;
import com.zhgd.xmgl.modules.basicdata.service.IDictionaryItemService;
import com.zhgd.xmgl.modules.basicdata.service.ISystemUserService;
import com.zhgd.xmgl.modules.project.entity.*;
import com.zhgd.xmgl.modules.project.entity.dto.ProgressPanoramaNodePlanDto;
import com.zhgd.xmgl.modules.project.entity.dto.ProgressPanoramaNodePlanExecDto;
import com.zhgd.xmgl.modules.project.entity.vo.ProjectInfoExtVo;
import com.zhgd.xmgl.modules.project.service.IProgressPanoramaNodePlanHistoryService;
import com.zhgd.xmgl.modules.project.service.IProgressPanoramaNodePlanService;
import com.zhgd.xmgl.modules.project.service.IProjectService;
import com.zhgd.xmgl.security.entity.UserInfo;
import com.zhgd.xmgl.security.util.SecurityUtils;
import com.zhgd.xmgl.util.JiuzhuUtil;
import com.zhgd.xmgl.util.MessageUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
@ -33,9 +40,11 @@ import jodd.util.StringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
@ -48,7 +57,7 @@ import java.util.stream.Collectors;
* @version V1.0
*/
@RestController
@RequestMapping("/xmgl/progressPanoramaNodePlan")
@RequestMapping("/xmgl/progressPanoramaNodePlan")
@Slf4j
@Api(tags="进度-全景节点计划")
public class ProgressPanoramaNodePlanController {
@ -58,6 +67,15 @@ public class ProgressPanoramaNodePlanController {
@Autowired
private IProjectService projectService;
@Autowired
private IDictionaryItemService dictionaryItemService;
@Autowired
private JiuzhuUtil jiuzhuUtil;
@Value("${jiuzhu.address}")
private final String ADDRESS = "http://218.95.151.122:18000";
// /**
// * 列表查询
// * @return
@ -103,6 +121,10 @@ public class ProgressPanoramaNodePlanController {
@PostMapping(value = "/filterList")
public Result<List<ProgressPanoramaNodePlan>> filterList(@RequestBody ProgressPanoramaNodePlan progressPanoramaNodePlan) {
QueryWrapper<ProgressPanoramaNodePlan> queryWrapper = QueryGenerator.initQueryWrapper(progressPanoramaNodePlan);
if (progressPanoramaNodePlan.getNature() != null) {
List<Project> projectList = projectService.list(Wrappers.<Project>lambdaQuery().eq(Project::getNature, progressPanoramaNodePlan.getNature()));
queryWrapper.lambda().in(ProgressPanoramaNodePlan::getProjectSn, projectList.stream().map(p -> p.getProjectSn()).collect(Collectors.toList()));
}
return Result.success(progressPanoramaNodePlanService.list(queryWrapper));
}
@ -120,9 +142,10 @@ public class ProgressPanoramaNodePlanController {
@PostMapping(value = "/keyNodeList")
public Result<List<ProjectKeyNode>> keyNodeList(@RequestBody Map<String, Object> map) {
String projectSn = MapUtils.getString(map, "projectSn");
String nature = MapUtils.getString(map, "nature");
Integer type = MapUtils.getInteger(map, "type");
LambdaQueryWrapper<Project> wrapper = Wrappers.<Project>lambdaQuery().eq(Project::getNature, 1);
if (StringUtil.isNotBlank(projectSn)) {
LambdaQueryWrapper<Project> wrapper = Wrappers.<Project>lambdaQuery().eq(Project::getNature, nature);
if (StringUtil.isNotBlank(projectSn)) {
wrapper.eq(Project::getProjectSn, projectSn);
}
List<Project> list = projectService.list(wrapper);
@ -360,4 +383,114 @@ public class ProgressPanoramaNodePlanController {
}
return Result.success(resultMap);
}
/**
* 计划达成统计
* @param
* @return
*/
@ApiOperation(value = "计划达成统计", notes = "计划达成统计", httpMethod = "POST")
@ApiImplicitParams({
@ApiImplicitParam(name = "projectSn", value = "项目sn", paramType = "body", required = true, dataType = "String"),
@ApiImplicitParam(name = "beginTime", value = "开始时间", paramType = "body", required = true, dataType = "String"),
@ApiImplicitParam(name = "endTime", value = "结束时间", paramType = "body", required = true, dataType = "String")
})
@PostMapping(value = "/planExec")
public Result<List<ProgressPanoramaNodePlanExecDto>> planExec(@RequestBody Map<String,Object> map) {
List<ProgressPanoramaNodePlanExecDto> execDtoList = new ArrayList<>();
String projectSn = MapUtils.getString(map, "projectSn");
String beginTime = MapUtils.getString(map, "beginTime");
String endTime = MapUtils.getString(map, "endTime");
List<ProgressPanoramaNodePlan> list = progressPanoramaNodePlanService.list(Wrappers.<ProgressPanoramaNodePlan>lambdaQuery()
.eq(ProgressPanoramaNodePlan::getProjectSn, projectSn)
.eq(ProgressPanoramaNodePlan::getApprovalStatue, 2)
.ge(ProgressPanoramaNodePlan::getPlanFinishDate, beginTime)
.le(ProgressPanoramaNodePlan::getPlanFinishDate, endTime)
.orderByAsc(ProgressPanoramaNodePlan::getPlanFinishDate));
String [] name = {"主项任务", "专项任务"};
for (int i = 0; i < name.length; i++) {
int finalI = i;
List<ProgressPanoramaNodePlan> panoramaNodePlans = list.stream().filter(l -> l.getLevelName().equals(name[finalI])).collect(Collectors.toList());
ProgressPanoramaNodePlanExecDto execDto = new ProgressPanoramaNodePlanExecDto();
execDto.setPlanName(name[i]);
execDto.setTotal(panoramaNodePlans.size());
List<ProgressPanoramaNodePlan> planCompalete = panoramaNodePlans.stream().filter(p -> DateUtil.parseDate(p.getPlanFinishDate()).compareTo(new Date()) < 0).collect(Collectors.toList());
execDto.setPlanCompleteNum(planCompalete.size());
int normalNum = (int) panoramaNodePlans.stream().filter(p -> p.getStatus() == 3).count();
execDto.setNormalNum(normalNum);
execDto.setNormalRatio(planCompalete.size() == 0 ? new BigDecimal(0) : new BigDecimal(normalNum).divide(new BigDecimal(planCompalete.size()), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)));
int delayNum = (int) panoramaNodePlans.stream().filter(p -> p.getStatus() == 4).count();
execDto.setDelayNum(delayNum);
int completeNum = normalNum + delayNum;
execDto.setCompleteNum(completeNum);
execDto.setCompleteRatio(planCompalete.size() == 0 ? new BigDecimal(0) : new BigDecimal(completeNum).divide(new BigDecimal(planCompalete.size()), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)));
execDto.setDelayUnComplete((int) panoramaNodePlans.stream().filter(p -> p.getStatus() < 3 && DateUtil.parseDate(p.getPlanFinishDate()).compareTo(new Date()) < 0).count());
execDtoList.add(execDto);
}
List<DictionaryItem> planType = dictionaryItemService.getDictList("plan_type", null);
for (DictionaryItem dictionaryItem : planType) {
List<ProgressPanoramaNodePlan> panoramaNodePlans = list.stream().filter(l -> StringUtils.isNotBlank(l.getType()) && l.getType().equals(dictionaryItem.getData())).collect(Collectors.toList());
ProgressPanoramaNodePlanExecDto execDto = new ProgressPanoramaNodePlanExecDto();
execDto.setPlanName(dictionaryItem.getName());
execDto.setTotal(panoramaNodePlans.size());
List<ProgressPanoramaNodePlan> planCompalete = panoramaNodePlans.stream().filter(p -> DateUtil.parseDate(p.getPlanFinishDate()).compareTo(new Date()) < 0).collect(Collectors.toList());
execDto.setPlanCompleteNum(planCompalete.size());
int normalNum = (int) panoramaNodePlans.stream().filter(p -> p.getStatus() == 3).count();
execDto.setNormalNum(normalNum);
execDto.setNormalRatio(planCompalete.size() == 0 ? new BigDecimal(0) : new BigDecimal(normalNum).divide(new BigDecimal(planCompalete.size()), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)));
int delayNum = (int) panoramaNodePlans.stream().filter(p -> p.getStatus() == 4).count();
execDto.setDelayNum(delayNum);
int completeNum = normalNum + delayNum;
execDto.setCompleteNum(completeNum);
execDto.setCompleteRatio(planCompalete.size() == 0 ? new BigDecimal(0) : new BigDecimal(completeNum).divide(new BigDecimal(planCompalete.size()), 2, BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(100)));
execDto.setDelayUnComplete((int) panoramaNodePlans.stream().filter(p -> p.getStatus() < 3 && DateUtil.parseDate(p.getPlanFinishDate()).compareTo(new Date()) < 0).count());
execDtoList.add(execDto);
}
return Result.success(execDtoList);
}
/**
* 任务催办
* @param
* @return
*/
@ApiOperation(value = "任务催办", notes = "任务催办", httpMethod = "POST")
@ApiImplicitParams({
@ApiImplicitParam(name = "id", value = "任务ID", paramType = "body", required = true, dataType = "String"),
@ApiImplicitParam(name = "content", value = "催办内容", paramType = "body", required = true, dataType = "String"),
@ApiImplicitParam(name = "requireDate", value = "要求完成日期", paramType = "body", required = true, dataType = "String")
})
@PostMapping(value = "/supervision")
public Result<Object> supervision(@RequestBody Map<String,Object> map) {
ProgressPanoramaNodePlan nodePlan = progressPanoramaNodePlanService.getById(MapUtils.getString(map, "id"));
UserInfo user = SecurityUtils.getUser();
Map<String, Object> params = new HashMap<>();
Map<String, Object> mainMap = new HashMap<>();
mainMap.put("sqr", user.getUserId());
mainMap.put("sqrg", DateUtil.formatDate(new Date()));
mainMap.put("zbr", nodePlan.getChargerId());
mainMap.put("jhksrq", nodePlan.getPlanStartDate());
mainMap.put("jhjsrq", nodePlan.getPlanFinishDate());
mainMap.put("rwmc", nodePlan.getNodeName());
mainMap.put("content", MapUtils.getString(map, "content"));
mainMap.put("requireDate", MapUtils.getString(map, "requireDate"));
JSONArray mainData = new JSONArray();
for (String s : mainMap.keySet()) {
JSONObject obj = new JSONObject();
obj.put("fieldName", s);
obj.put("fieldValue", mainMap.get(s));
mainData.add(obj);
}
params.put("requestName", "任务督办");
params.put("mainData", JSON.toJSONString(mainData));
params.put("detailData","[]");
params.put("workflowId", "422");
params.put("remark","restful接口创建流程测试");
Map<String, String> otherParams = new HashMap<>();
otherParams.put("isVerifyPer","0");
params.put("otherParams",JSONObject.toJSONString(otherParams));
System.out.println(JSON.toJSONString(params));
// String result = jiuzhuUtil.testRestful1(ADDRESS, "/api/workflow/paService/doCreateRequest", params, "5583bc0e-220e-4a44-8e14-d838d47ad9b9");
return Result.ok();
}
}

View File

@ -71,4 +71,7 @@ public class ProgressPanoramaNode implements Serializable {
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "最后操作时间")
private Date updateTime;
@ApiModelProperty(value = "项目性质")
private Integer nature;
}

View File

@ -1,6 +1,7 @@
package com.zhgd.xmgl.modules.project.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
@ -88,7 +89,7 @@ public class ProgressPanoramaNodePlan implements Serializable {
* 状态
*/
@Excel(name = "状态", width = 15)
@ApiModelProperty(value = "状态 2-已发布(进行中),3-节点汇报审批中,4-计划审批中,6-归档(完成)")
@ApiModelProperty(value = "状态(1:未开始[默认状态]2进行中3正常完成4延期完成)")
private Integer status;
/**
* 实际偏差
@ -194,4 +195,12 @@ public class ProgressPanoramaNodePlan implements Serializable {
*/
@ApiModelProperty(value = "完成标准")
private String completeStandard;
@TableField(exist = false)
@ApiModelProperty(value = "节点类别")
private String typeName;
@TableField(exist = false)
@ApiModelProperty(value = "项目性质")
private Integer nature;
}

View File

@ -76,35 +76,11 @@ public class ProgressPanoramaNodePlanChangeRecord implements Serializable {
@ApiModelProperty(value = "计划完成时间")
private String planFinishDate;
/**
* 实际开始时间
* 节点责任部门名称
*/
@Excel(name = "实际开始时间", width = 15)
@ApiModelProperty(value = "实际开始时间")
private String startDate;
/**
* 实际完成时间
*/
@Excel(name = "实际完成时间", width = 15)
@ApiModelProperty(value = "实际完成时间")
private String finishDate;
/**
* 状态
*/
@Excel(name = "状态", width = 15)
@ApiModelProperty(value = "状态")
private Integer status;
/**
* 实际偏差
*/
@Excel(name = "实际偏差", width = 15)
@ApiModelProperty(value = "实际偏差")
private String diffDate;
/**
* 节点责任人编号
*/
@Excel(name = "节点责任人编号", width = 15)
@ApiModelProperty(value = "节点责任人编号")
private String chargerId;
@Excel(name = "节点责任部门名称", width = 15)
@ApiModelProperty(value = "节点责任部门名称")
private String chargerDeptName;
/**
* 节点责任人名称
*/
@ -112,23 +88,11 @@ public class ProgressPanoramaNodePlanChangeRecord implements Serializable {
@ApiModelProperty(value = "节点责任人名称")
private String chargerName;
/**
* 成果物明细
* 协助人名称
*/
@Excel(name = "成果物明细", width = 15)
@ApiModelProperty(value = "成果物明细")
private String deliverable;
/**
* 父级ID
*/
@Excel(name = "父级ID", width = 15)
@ApiModelProperty(value = "父级ID")
private Integer parentId;
/**
* 祖级关系
*/
@Excel(name = "祖级关系", width = 15)
@ApiModelProperty(value = "祖级关系")
private String ancestors;
@Excel(name = "协助人名称", width = 15)
@ApiModelProperty(value = "协助人名称")
private String assistName;
/**
* 工期天数
*/
@ -136,21 +100,19 @@ public class ProgressPanoramaNodePlanChangeRecord implements Serializable {
@ApiModelProperty(value = "工期天数")
private String duration;
/**
* 是否为关键节点01(默认为0)
* 节点类别
*/
@Excel(name = "是否为关键节点01是(默认为0)", width = 15)
@ApiModelProperty(value = "是否为关键节点01是(默认为0)")
private Integer keyNode;
@Excel(name = "节点类别", width = 15)
@ApiModelProperty(value = "节点类别")
private String typeName;
/**
* 是否为里程碑01(默认为0)
* 完成标准
*/
@Excel(name = "是否为里程碑01是(默认为0)", width = 15)
@ApiModelProperty(value = "是否为里程碑01是(默认为0)")
private Integer milepostNode;
@ApiModelProperty(value = "完成标准")
private String completeStandard;
/**
* 是否为阶段性成果节点01(默认为0)
* 任务业务类型
*/
@Excel(name = "是否为阶段性成果节点01是(默认为0)", width = 15)
@ApiModelProperty(value = "是否为阶段性成果节点01是(默认为0)")
private Integer resultNode;
@ApiModelProperty(value = "任务业务类型")
private String businessType;
}

View File

@ -4,6 +4,7 @@ import java.io.Serializable;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@ -65,6 +66,12 @@ public class ProgressPanoramaNodePlanDraft implements Serializable {
@Excel(name = "节点类型", width = 15)
@ApiModelProperty(value = "节点类型")
private String levelName;
/**
* 节点类别
*/
@Excel(name = "节点类别", width = 15)
@ApiModelProperty(value = "节点类别")
private String type;
/**
* 计划开始时间
*/
@ -155,4 +162,51 @@ public class ProgressPanoramaNodePlanDraft implements Serializable {
@Excel(name = "是否为阶段性成果节点01是(默认为0)", width = 15)
@ApiModelProperty(value = "是否为阶段性成果节点01是(默认为0)")
private Boolean resultNode;
/**
* 阶段性成果类型ID
*/
@ApiModelProperty(value = "阶段性成果类型ID")
private Long resultId;
/**
* 节点责任部门编号
*/
@Excel(name = "节点责任部门编号", width = 15)
@ApiModelProperty(value = "节点责任部门编号")
private String chargerDeptId;
/**
* 节点责任部门名称
*/
@Excel(name = "节点责任部门名称", width = 15)
@ApiModelProperty(value = "节点责任部门名称")
private String chargerDeptName;
/**
* 协助人编号
*/
@Excel(name = "协助人编号", width = 15)
@ApiModelProperty(value = "协助人编号")
private String assistId;
/**
* 协助人名称
*/
@Excel(name = "协助人名称", width = 15)
@ApiModelProperty(value = "协助人名称")
private String assistName;
/**
* 任务业务类型
*/
@ApiModelProperty(value = "任务业务类型")
private String businessType;
/**
* 完成标准
*/
@ApiModelProperty(value = "完成标准")
private String completeStandard;
/**
* 里程碑类型ID
*/
@ApiModelProperty(value = "里程碑类型ID")
private Long milepostId;
@ApiModelProperty(value = "节点类别")
private String typeName;
}

View File

@ -97,6 +97,31 @@ public class ProgressPanoramaNodePlanTemplate implements Serializable {
*/
@ApiModelProperty(value = "最后操作时间")
private Date updateTime;
/**
* 是否为关键节点01(默认为0)
*/
@ApiModelProperty(value = "是否为关键节点01是(默认为0)")
private Boolean keyNode;
/**
* 是否为里程碑01(默认为0)
*/
@ApiModelProperty(value = "是否为里程碑01是(默认为0)")
private Boolean milepostNode;
/**
* 是否为阶段性成果节点01(默认为0)
*/
@ApiModelProperty(value = "是否为阶段性成果节点01是(默认为0)")
private Boolean resultNode;
/**
* 阶段性成果类型ID
*/
@ApiModelProperty(value = "阶段性成果类型ID")
private Long resultId;
/**
* 里程碑类型ID
*/
@ApiModelProperty(value = "里程碑类型ID")
private Long milepostId;
@TableField(exist = false)
@ApiModelProperty(value = "子级模版信息")

View File

@ -0,0 +1,41 @@
package com.zhgd.xmgl.modules.project.entity.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;
import java.util.List;
@Data
@ApiModel(value = "计划达成统计(DTO)", description = "ProgressPanoramaNodePlanExecDto")
public class ProgressPanoramaNodePlanExecDto {
@ApiModelProperty(value = "计划名称")
private String planName;
@ApiModelProperty(value = "计划总数")
private Integer total;
@ApiModelProperty(value = "计划应完成数")
private Integer planCompleteNum;
@ApiModelProperty(value = "按期完成数")
private Integer normalNum;
@ApiModelProperty(value = "按期达成率")
private BigDecimal normalRatio;
@ApiModelProperty(value = "延期完成数")
private Integer delayNum;
@ApiModelProperty(value = "已完成数")
private Integer completeNum;
@ApiModelProperty(value = "综合达成率")
private BigDecimal completeRatio;
@ApiModelProperty(value = "延期未完成")
private Integer delayUnComplete;
}

View File

@ -2,8 +2,9 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zhgd.xmgl.modules.project.mapper.ProgressPanoramaNodePlanMapper">
<select id="selectProgressPanoramaNodePlanPageList" resultType="com.zhgd.xmgl.modules.project.entity.dto.ProgressPanoramaNodePlanDto">
SELECT a.*
SELECT a.*, d.name as typeName
from progress_panorama_node_plan a
left join dictionary_item d on a.type = d.data and d.dictionary_encoding = 'plan_type'
where a.project_sn = #{param.projectSn}
<if test="param.nodeName != null and param.nodeName != ''">
and a.node_name like CONCAT(CONCAT('%', #{param.nodeName}), '%')
@ -14,7 +15,9 @@
<if test="param.approvalStatue != null and param.approvalStatue != ''">
and a.approval_statue = #{param.approvalStatue}
</if>
<if test="param.type != null and param.type != ''">
and a.type = #{param.type}
</if>
<if test="param.list != null">
and a.id in
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">

View File

@ -16,6 +16,8 @@ import com.zhgd.jeecg.common.api.vo.Result;
import com.zhgd.jeecg.common.execption.OpenAlertException;
import com.zhgd.jeecg.common.mybatis.EntityMap;
import com.zhgd.jeecg.common.system.query.QueryGenerator;
import com.zhgd.xmgl.modules.basicdata.entity.DictionaryItem;
import com.zhgd.xmgl.modules.basicdata.service.IDictionaryItemService;
import com.zhgd.xmgl.modules.cost.entity.CostSubject;
import com.zhgd.xmgl.modules.project.entity.*;
import com.zhgd.xmgl.modules.project.entity.dto.ProgressPanoramaNodePlanDto;
@ -61,6 +63,9 @@ public class ProgressPanoramaNodePlanServiceImpl extends ServiceImpl<ProgressPan
@Autowired
private IProjectService projectService;
@Autowired
private IDictionaryItemService dictionaryItemService;
@Autowired
private IProgressPanoramaNodePlanDraftService progressPanoramaNodePlanDraftService;
@ -119,6 +124,11 @@ public class ProgressPanoramaNodePlanServiceImpl extends ServiceImpl<ProgressPan
progressPanoramaNodePlan.setDuration(template.getDuration());
progressPanoramaNodePlan.setParentId(parentId);
progressPanoramaNodePlan.setApprovalStatue(0);
progressPanoramaNodePlan.setKeyNode(template.getKeyNode());
progressPanoramaNodePlan.setMilepostNode(template.getMilepostNode());
progressPanoramaNodePlan.setMilepostId(template.getMilepostId());
progressPanoramaNodePlan.setResultNode(template.getResultNode());
progressPanoramaNodePlan.setResultId(template.getResultId());
if (progressPanoramaNodePlan.getParentId() == 0) {
int count = this.count(Wrappers.<ProgressPanoramaNodePlan>lambdaQuery()
.eq(ProgressPanoramaNodePlan::getParentId, 0)
@ -317,6 +327,7 @@ public class ProgressPanoramaNodePlanServiceImpl extends ServiceImpl<ProgressPan
progressPanoramaNodePlan.setAncestors("0");
}
}
updateState(progressPanoramaNodePlan.getProjectSn());
progressPanoramaNodePlan.setApprovalStatue(0);
boolean flag = this.updateById(progressPanoramaNodePlan);
@ -426,6 +437,10 @@ public class ProgressPanoramaNodePlanServiceImpl extends ServiceImpl<ProgressPan
} else if (flag == 2) {
planDraft = progressPanoramaNodePlanDraftService.getOne(Wrappers.<ProgressPanoramaNodePlanDraft>lambdaQuery()
.eq(ProgressPanoramaNodePlanDraft::getId, nodePlan.getId()));
DictionaryItem planType1 = dictionaryItemService.getDict("plan_type", progressPanoramaNodePlan.getType(), null);
nodePlan.setTypeName(planType1.getName());
DictionaryItem planType = dictionaryItemService.getDict("plan_type", planDraft.getType(), null);
planDraft.setTypeName(planType.getName());
if (planDraft.getUpdateFlag() != null && planDraft.getUpdateFlag() == 1) {
BeanUtils.copyProperties(nodePlan, planDraft);
} else {
@ -447,7 +462,7 @@ public class ProgressPanoramaNodePlanServiceImpl extends ServiceImpl<ProgressPan
}
}
// 保存变更记录
ProgressPanoramaNodePlanDraft updateInfo = progressPanoramaNodePlanDraftService.getById(planDraft.getId());
ProgressPanoramaNodePlanDraft updateInfo = progressPanoramaNodePlanDraftService.getById(planDraft.getDraftId());
ProgressPanoramaNodePlanChangeRecord record = new ProgressPanoramaNodePlanChangeRecord();
BeanUtils.copyProperties(updateInfo, record);
progressPanoramaNodePlanChangeRecordService.save(record);
@ -461,24 +476,28 @@ public class ProgressPanoramaNodePlanServiceImpl extends ServiceImpl<ProgressPan
try {
for (Field field : fields) {
ReflectionUtils.makeAccessible(field);
if (field.getName().equals("approvalStatue")) {
if (field.getName().equals("approvalStatue") || field.getName().equals("serialVersionUID")) {
continue;
}
Field secondField = clazz2.getDeclaredField(field.getName());
ReflectionUtils.makeAccessible(secondField);
Object oldVal = field.get(oldObj);
Object newVal = secondField.get(newObj);
String value = String.valueOf(newVal);
if (value.contains("[")) {
value = value.substring(value.indexOf("[") + 1, value.indexOf("]"));
newVal = value;
}
if (!Objects.equals(oldVal, newVal)) {
// todo 差异
System.out.println("fiwName" + field.getName());
System.out.println("value" + oldVal + "[" + newVal + "]");
secondField.setAccessible(true);
String value = String.valueOf(newVal);
if (value.contains("[")) {
value = value.substring(value.indexOf("[") + 1, value.indexOf("]"));
newVal = value;
}
secondField.set(newObj, oldVal + "[" + newVal + "]");
Object o = newVal.equals("null") ? "" : newVal;
secondField.set(newObj, oldVal + "[" + o + "]");
} else {
secondField.setAccessible(true);
secondField.set(newObj, newVal);
}
}
} catch (Exception e) {

View File

@ -0,0 +1,158 @@
package com.zhgd.xmgl.util;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import com.zhgd.redis.lock.RedisRepository;
import com.zhgd.xmgl.modules.basicdata.service.ICompanyService;
import com.zhgd.xmgl.modules.basicdata.service.IOrganizationJobService;
import com.zhgd.xmgl.modules.basicdata.service.ISystemUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.Objects;
@Slf4j
@Component
public class JiuzhuUtil {
@Value("${jiuzhu.address}")
private final String ADDRESS = "http://218.95.151.122:18000";
@Autowired
private RedisRepository redisRepository;
public String testRestful(String address, String api, String jsonParams, String APPID){
//ECOLOGY返回的token
String token= (String) redisRepository.get("JIUZHU_SERVER_TOKEN" + APPID);
if (StrUtil.isEmpty(token)){
token = (String) testGetoken(address, APPID).get("token");
}
String spk = (String) redisRepository.get("JIUZHU_SERVER_PUBLIC_KEY" + APPID);
//封装请求头参数
RSA rsa = new RSA(null,spk);
//对用户信息进行加密传输,暂仅支持传输OA用户ID
String encryptUserid = rsa.encryptBase64("1", CharsetUtil.CHARSET_UTF_8, KeyType.PublicKey);
//调用ECOLOGY系统接口
String data = HttpRequest.post(address + api)
.header("appid",APPID)
.header("token",token)
.header("userid",encryptUserid)
.body(jsonParams)
.execute().body();
System.out.println("testRestful()"+data);
return data;
}
public String testRestful1(String address, String api, Map<String, Object> jsonParams, String APPID){
//ECOLOGY返回的token
String token= (String) redisRepository.get("JIUZHU_SERVER_TOKEN" + APPID);
if (StrUtil.isEmpty(token)){
token = (String) testGetoken(address, APPID).get("token");
}
String spk = (String) redisRepository.get("JIUZHU_SERVER_PUBLIC_KEY" + APPID);
//封装请求头参数
RSA rsa = new RSA(null,spk);
//对用户信息进行加密传输,暂仅支持传输OA用户ID
String encryptUserid = rsa.encryptBase64("648", CharsetUtil.CHARSET_UTF_8, KeyType.PublicKey);
//调用ECOLOGY系统接口
String data = HttpRequest.post(address + api)
.header("appid",APPID)
.header("token",token)
.header("userid",encryptUserid)
.contentType("application/x-www-form-urlencoded")
.form(jsonParams)
.execute().body();
System.out.println("testRestful()"+data);
return data;
}
/**
* 第一步
*
* 调用ecology注册接口,根据appid进行注册,将返回服务端公钥和Secret信息
*/
private Map<String,Object> testRegist(String address, String APPID){
//获取当前系统RSA加密的公钥
RSA rsa = new RSA();
String publicKey = rsa.getPublicKeyBase64();
String privateKey = rsa.getPrivateKeyBase64();
// 客户端RSA私钥
redisRepository.set("JIUZHU_LOCAL_PRIVATE_KEY" + APPID,privateKey);
// 客户端RSA公钥
redisRepository.set("JIUZHU_LOCAL_PUBLIC_KEY" + APPID,publicKey);
//调用ECOLOGY系统接口进行注册
String data = HttpRequest.post(address + "/api/ec/dev/auth/regist")
.header("appid",APPID)
.header("cpk",publicKey)
.timeout(2000)
.execute().body();
// 打印ECOLOGY响应信息
System.out.println("testRegist()"+data);
Map<String,Object> datas = JSONUtil.parseObj(data);
//ECOLOGY返回的系统公钥
redisRepository.set("JIUZHU_SERVER_PUBLIC_KEY" + APPID, StrUtil.nullToEmpty((String)datas.get("spk")));
//ECOLOGY返回的系统密钥
redisRepository.set("JIUZHU_SERVER_SECRET" + APPID,StrUtil.nullToEmpty((String)datas.get("secrit")));
return datas;
}
/**
* 第二步
*
* 通过第一步中注册系统返回信息进行获取token信息
*/
private Map<String,Object> testGetoken(String address, String APPID){
// 从系统缓存或者数据库中获取ECOLOGY系统公钥和Secret信息
String secret = (String) redisRepository.get("JIUZHU_SERVER_SECRET" + APPID);
String spk = (String) redisRepository.get("JIUZHU_SERVER_PUBLIC_KEY" + APPID);
// 如果为空,说明还未进行注册,调用注册接口进行注册认证与数据更新
if (Objects.isNull(secret)||Objects.isNull(spk)){
testRegist(address, APPID);
// 重新获取最新ECOLOGY系统公钥和Secret信息
secret = (String) redisRepository.get("JIUZHU_SERVER_SECRET" + APPID);
spk = (String) redisRepository.get("JIUZHU_SERVER_PUBLIC_KEY" + APPID);
}
// 公钥加密,所以RSA对象私钥为null
RSA rsa = new RSA(null,spk);
//对秘钥进行加密传输防止篡改数据
String encryptSecret = rsa.encryptBase64(secret, CharsetUtil.CHARSET_UTF_8, KeyType.PublicKey);
//调用ECOLOGY系统接口进行注册
String data = HttpRequest.post(address+ "/api/ec/dev/auth/applytoken")
.header("appid",APPID)
.header("secret",encryptSecret)
.header("time","3600")
.execute().body();
System.out.println("testGetoken()"+data);
Map<String,Object> datas = JSONUtil.parseObj(data);
//ECOLOGY返回的token
// TODO 为Token缓存设置过期时间
redisRepository.setExpire("JIUZHU_SERVER_TOKEN" + APPID,StrUtil.nullToEmpty((String)datas.get("token")), 60 * 30);
return datas;
}
}