@@ -0,0 +1,109 @@ | |||||
package com.ningdatech.pmapi.common.config; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.apache.http.Header; | |||||
import org.apache.http.client.HttpClient; | |||||
import org.apache.http.client.config.RequestConfig; | |||||
import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy; | |||||
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler; | |||||
import org.apache.http.impl.client.HttpClientBuilder; | |||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; | |||||
import org.apache.http.message.BasicHeader; | |||||
import org.springframework.context.annotation.Bean; | |||||
import org.springframework.context.annotation.Configuration; | |||||
import org.springframework.http.MediaType; | |||||
import org.springframework.http.client.ClientHttpRequestFactory; | |||||
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; | |||||
import org.springframework.http.converter.HttpMessageConverter; | |||||
import org.springframework.http.converter.StringHttpMessageConverter; | |||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; | |||||
import org.springframework.web.client.RestTemplate; | |||||
import java.nio.charset.StandardCharsets; | |||||
import java.util.ArrayList; | |||||
import java.util.Arrays; | |||||
import java.util.List; | |||||
import java.util.concurrent.TimeUnit; | |||||
/** | |||||
* @Classname BeanConfig | |||||
* @Description | |||||
* @Date 2023/3/2 9:42 | |||||
* @Created by PoffyZhang | |||||
*/ | |||||
@Configuration | |||||
@Slf4j | |||||
public class BeanConfig { | |||||
@Bean | |||||
public RestTemplate restTemplate() { | |||||
// 添加内容转换器,使用默认的内容转换器 | |||||
RestTemplate restTemplate = new RestTemplate(httpRequestFactory()); | |||||
// 设置编码格式为UTF-8,解决中文乱码问题 | |||||
List<HttpMessageConverter<?>> converterList = restTemplate.getMessageConverters(); | |||||
HttpMessageConverter<?> converterTarget = null; | |||||
for (HttpMessageConverter<?> item : converterList) { | |||||
if (item.getClass() == StringHttpMessageConverter.class) { | |||||
converterTarget = item; | |||||
break; | |||||
} | |||||
} | |||||
if (converterTarget != null) { | |||||
converterList.remove(converterTarget); | |||||
} | |||||
HttpMessageConverter<?> converter = new StringHttpMessageConverter(StandardCharsets.UTF_8); | |||||
converterList.add(1,converter); | |||||
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter(); | |||||
mappingJackson2HttpMessageConverter.setSupportedMediaTypes(Arrays.asList( | |||||
MediaType.TEXT_HTML, | |||||
MediaType.TEXT_PLAIN)); | |||||
restTemplate.getMessageConverters().add(mappingJackson2HttpMessageConverter); | |||||
log.info("-----restTemplate-----初始化完成"); | |||||
return restTemplate; | |||||
} | |||||
@Bean | |||||
public ClientHttpRequestFactory httpRequestFactory() { | |||||
return new HttpComponentsClientHttpRequestFactory(httpClient()); | |||||
} | |||||
@Bean | |||||
public HttpClient httpClient() { | |||||
// 长连接保持30秒 | |||||
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(30, TimeUnit.SECONDS); | |||||
//设置整个连接池最大连接数 根据自己的场景决定 | |||||
connectionManager.setMaxTotal(500); | |||||
//同路由的并发数,路由是对maxTotal的细分 | |||||
connectionManager.setDefaultMaxPerRoute(500); | |||||
//requestConfig | |||||
RequestConfig requestConfig = RequestConfig.custom() | |||||
//服务器返回数据(response)的时间,超过该时间抛出read timeout | |||||
.setSocketTimeout(10000) | |||||
//连接上服务器(握手成功)的时间,超出该时间抛出connect timeout | |||||
.setConnectTimeout(5000) | |||||
//从连接池中获取连接的超时时间,超过该时间未拿到可用连接,会抛出org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool | |||||
.setConnectionRequestTimeout(500) | |||||
.build(); | |||||
//headers | |||||
List<Header> headers = new ArrayList<>(); | |||||
headers.add(new BasicHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.16 Safari/537.36")); | |||||
headers.add(new BasicHeader("Accept-Encoding", "gzip,deflate")); | |||||
headers.add(new BasicHeader("Accept-Language", "zh-CN")); | |||||
headers.add(new BasicHeader("Connection", "Keep-Alive")); | |||||
headers.add(new BasicHeader("Content-type", "application/json;charset=UTF-8")); | |||||
return HttpClientBuilder.create() | |||||
.setDefaultRequestConfig(requestConfig) | |||||
.setConnectionManager(connectionManager) | |||||
.setDefaultHeaders(headers) | |||||
// 保持长连接配置,需要在头添加Keep-Alive | |||||
.setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy()) | |||||
//重试次数,默认是3次,没有开启 | |||||
.setRetryHandler(new DefaultHttpRequestRetryHandler(2, true)) | |||||
.build(); | |||||
} | |||||
} |
@@ -0,0 +1,27 @@ | |||||
package com.ningdatech.pmapi.common.config; | |||||
import lombok.Data; | |||||
import org.springframework.boot.context.properties.ConfigurationProperties; | |||||
import org.springframework.context.annotation.Configuration; | |||||
import java.util.ArrayList; | |||||
import java.util.List; | |||||
/** | |||||
* @author zpf | |||||
* @date 2023/3/2 下午5:37 | |||||
*/ | |||||
@Data | |||||
@Configuration | |||||
@ConfigurationProperties(prefix = "provincial") | |||||
public class ProvincialProperties { | |||||
private String host; | |||||
private String pushUrl; | |||||
private String detailUrl; | |||||
private String key; | |||||
private String secret; | |||||
} |
@@ -6,10 +6,8 @@ import com.ningdatech.pmapi.projectdeclared.manage.DeclaredProjectManage; | |||||
import com.ningdatech.pmapi.projectdeclared.manage.PrequalificationDeclaredProjectManage; | import com.ningdatech.pmapi.projectdeclared.manage.PrequalificationDeclaredProjectManage; | ||||
import com.ningdatech.pmapi.projectdeclared.model.dto.DefaultDeclaredDTO; | import com.ningdatech.pmapi.projectdeclared.model.dto.DefaultDeclaredDTO; | ||||
import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | ||||
import lombok.RequiredArgsConstructor; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||
import javax.annotation.PostConstruct; | |||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.function.Function; | import java.util.function.Function; | ||||
@@ -20,21 +18,22 @@ import java.util.function.Function; | |||||
* @Author PoffyZhang | * @Author PoffyZhang | ||||
*/ | */ | ||||
@Component | @Component | ||||
@RequiredArgsConstructor | |||||
public class ReStartProcessMapUtil { | public class ReStartProcessMapUtil { | ||||
private final DeclaredProjectManage declaredProjectManage; | |||||
@Autowired | |||||
private DeclaredProjectManage declaredProjectManage; | |||||
private final ConstructionPlanManage constructionPlanManage; | |||||
@Autowired | |||||
private ConstructionPlanManage constructionPlanManage; | |||||
private final PrequalificationDeclaredProjectManage prequalificationDeclaredProjectManage; | |||||
@Autowired | |||||
private PrequalificationDeclaredProjectManage prequalificationDeclaredProjectManage; | |||||
public Map<Integer, Function<DefaultDeclaredDTO,String>> reStartProcessMap = Maps.newHashMap(); | public Map<Integer, Function<DefaultDeclaredDTO,String>> reStartProcessMap = Maps.newHashMap(); | ||||
/** | /** | ||||
* 初始化业务分派逻辑,代替了if-else部分 | * 初始化业务分派逻辑,代替了if-else部分 | ||||
* key: 枚举 状态值 | * key: 枚举 状态值 | ||||
* value: lambda表达式,最终会获取发起实例的函数 | * value: lambda表达式,最终会获取发起实例的函数 | ||||
*/ | */ | ||||
@PostConstruct | |||||
public void reStartProcessInit(){ | |||||
public ReStartProcessMapUtil(){ | |||||
//重新项目申报 | //重新项目申报 | ||||
reStartProcessMap.put(ProjectStatusEnum.UNDER_INTERNAL_AUDIT_NOT_PASS.getCode(), | reStartProcessMap.put(ProjectStatusEnum.UNDER_INTERNAL_AUDIT_NOT_PASS.getCode(), | ||||
dto->declaredProjectManage.reStartTheProcess(dto)); | dto->declaredProjectManage.reStartTheProcess(dto)); | ||||
@@ -0,0 +1,38 @@ | |||||
package com.ningdatech.pmapi.provincial.controller; | |||||
import com.ningdatech.pmapi.provincial.model.dto.ProvincialProjectDTO; | |||||
import com.ningdatech.pmapi.provincial.service.IJoinReviewProvincialBureauService; | |||||
import io.swagger.annotations.Api; | |||||
import io.swagger.annotations.ApiOperation; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.validation.annotation.Validated; | |||||
import org.springframework.web.bind.annotation.*; | |||||
import javax.validation.Valid; | |||||
/** | |||||
* @Classname TestController | |||||
* @Description | |||||
* @Date 2023/3/2 15:08 | |||||
* @Author PoffyZhang | |||||
*/ | |||||
@RestController | |||||
@RequestMapping("/api/v1/test") | |||||
@Api(tags = "测试省局接口") | |||||
public class TestController { | |||||
@Autowired | |||||
private IJoinReviewProvincialBureauService joinReviewProvincialBureauService; | |||||
@PostMapping("/push") | |||||
@ApiOperation("测试推送") | |||||
private String push(@Valid @RequestBody ProvincialProjectDTO project){ | |||||
return joinReviewProvincialBureauService.pushImportProject(project); | |||||
} | |||||
@GetMapping("/detail") | |||||
@ApiOperation("测试推送") | |||||
private String detail(@RequestParam String projectId){ | |||||
return joinReviewProvincialBureauService.processInfo(projectId); | |||||
} | |||||
} |
@@ -0,0 +1,36 @@ | |||||
package com.ningdatech.pmapi.provincial.model.dto; | |||||
import io.swagger.annotations.ApiModel; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.Builder; | |||||
import lombok.Data; | |||||
/** | |||||
* @Classname ProcessCommentDTO | |||||
* @Description | |||||
* @Date 2023/3/2 15:25 | |||||
* @Author PoffyZhang | |||||
*/ | |||||
@Data | |||||
@Builder | |||||
@ApiModel(value = "ProcessCommentDTO", description = "省局返回流程审核详情") | |||||
public class ProcessCommentDTO { | |||||
@ApiModelProperty("任务id") | |||||
private String taskId; | |||||
@ApiModelProperty("comment") | |||||
private String comment; | |||||
@ApiModelProperty("流程步骤") | |||||
private String stepName; | |||||
@ApiModelProperty("审批状态") | |||||
private String status; | |||||
@ApiModelProperty("审批人") | |||||
private String label; | |||||
@ApiModelProperty("时间") | |||||
private String approverTime; | |||||
} |
@@ -0,0 +1,98 @@ | |||||
package com.ningdatech.pmapi.provincial.model.dto; | |||||
import io.swagger.annotations.ApiModel; | |||||
import lombok.AllArgsConstructor; | |||||
import lombok.Builder; | |||||
import lombok.Data; | |||||
import lombok.NoArgsConstructor; | |||||
import java.util.List; | |||||
/** | |||||
* @Classname ProvincialApplicationDTO | |||||
* @Description | |||||
* @Date 2023/3/2 10:06 | |||||
* @Author PoffyZhang | |||||
*/ | |||||
@Data | |||||
@Builder | |||||
@ApiModel(value = "ProvincialApplicationDTO", description = "") | |||||
public class ProvincialApplicationDTO { | |||||
//云 信息 | |||||
private List<Cloud> clouds; | |||||
//是否初次建设 1是 2不是 | |||||
private Integer isFirst; | |||||
//应用名称 | |||||
private String applicationName; | |||||
//关联 关联的IRS应用code | |||||
private String applicationCode; | |||||
//关联的IRS应用name | |||||
private String relatedExistsApplication; | |||||
//1: '办公类系统',2: '业务应用类系统',3: '门户网站',4: '宣传微博/微信公众号',5: '硬件类系统',6: '工具类系统',99: '其他' | |||||
private Integer applicationType; | |||||
//建设层级 1:国家 2:省级 3:市级 4:县(市、区) | |||||
private Integer buildLevel; | |||||
//是否统建 0:否 1:是 | |||||
private Integer isUniteBuild; | |||||
//统建类型 1:全省统建 2:全市统建 | |||||
private Integer unionBuildKind; | |||||
//应用简介 | |||||
private String applicationSummary; | |||||
//应用备注 | |||||
private String applicationRemark; | |||||
//应用总投资测算明细 | |||||
private String applicationEstimateFile; | |||||
//是否数改系统 0:否 1:是 | |||||
private Integer isFiveDomain; | |||||
//1: '党政机关整体智治',2: '数字政府',3: '数字经济',4: '数字社会',7: '数字文化',5: '数字法治',6: '一体化智能化公共数据平台', 8: '基层智治' 多个用英文,分隔 | |||||
private String fiveDomain; | |||||
//业务领域 | |||||
private String bizDomain; | |||||
//否涉及业务协同 0:否 1:是 | |||||
private Integer isBizCooperate; | |||||
//协同单位111111 | |||||
private String cooperativeUnit; | |||||
//用户范围 0: '机关事业单位人员','0-1': '跨部门跨系统','0-2': '系统内地方各级','0-3': '本部门本级','0-4': '处室内部','0-6': '主管处室内部','0-5': '其他',1: '企业', 2: '社会公众',3: '其他' 多个用英文,分隔 | |||||
private String userRange; | |||||
//是否使用政务云资源 1使用 | |||||
private Integer useGovCloud; | |||||
//是否符合国家信息技术应用创新相关规范 0:否 1:是 | |||||
private Integer nationalITSpec; | |||||
//网络环境 1:政务内网 2:政务外网 3:互联网 4:业务专网 5:单机 | |||||
private String netEnv; | |||||
//等保级别 1:一级 2:二级 3:三级 4:四级 5:五级 | |||||
private Integer secrecyGrade; | |||||
//密码测评级别 1:一级 2:二级 3:三级 4:四级 5:五级 | |||||
private Integer passwordGrade; | |||||
//是否是S2 0:否 1:是 | |||||
private Integer isS2; | |||||
//一本账应用名称 | |||||
private String accountAppName; | |||||
//领域”大脑”一本帐名称 | |||||
private String brainAccountAppName; | |||||
//是否使用公共数据 | |||||
private Integer useCommonData; | |||||
//使用的公共数据名称 | |||||
private String dataName; | |||||
//使用公共组件的名称 | |||||
private String commonComponents; | |||||
//是否使用公共组件 | |||||
private Integer useCommonComponent; | |||||
//是否产生公共组件 | |||||
private Integer isProduceCommonComponent; | |||||
//产生的组件名称 | |||||
private String produceCommonComponent; | |||||
//发布端 '浙里办','浙政钉','数字化改革门户','支付宝','微信','网页','PC客户端','APP端' | |||||
private String publishSide; | |||||
public static class Cloud { | |||||
//云资源台数 11 | |||||
private Integer cloudNums; | |||||
//云资源类型 云服务器(ECS) | |||||
private String cloudType; | |||||
//云资源规格 1核8G | |||||
private String cloudBasicSpec; | |||||
//云资源描述 | |||||
private String cloudUseDescription; | |||||
} | |||||
} |
@@ -0,0 +1,125 @@ | |||||
package com.ningdatech.pmapi.provincial.model.dto; | |||||
import io.swagger.annotations.ApiModel; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.AllArgsConstructor; | |||||
import lombok.Builder; | |||||
import lombok.Data; | |||||
import lombok.NoArgsConstructor; | |||||
import java.math.BigDecimal; | |||||
import java.util.List; | |||||
/** | |||||
* @Classname ProvincialProjectDTO | |||||
* @Description | |||||
* @Date 2023/3/2 10:06 | |||||
* @Author PoffyZhang | |||||
*/ | |||||
@Data | |||||
@Builder | |||||
@AllArgsConstructor | |||||
@NoArgsConstructor | |||||
@ApiModel(value = "ProvincialProjectDTO", description = "") | |||||
public class ProvincialProjectDTO { | |||||
@ApiModelProperty("区域code") | |||||
private String regionCode; | |||||
@ApiModelProperty("区域名称") | |||||
private String regionName; | |||||
@ApiModelProperty("重大项目名称") | |||||
private String projectName; | |||||
@ApiModelProperty("重大项目code 21位") | |||||
private String projectId; | |||||
@ApiModelProperty("项目类型 1新建 2续建") | |||||
private Integer projectType; | |||||
@ApiModelProperty("项目总投资(万元)") | |||||
private BigDecimal totalMoney; | |||||
@ApiModelProperty("项目年度预算(万元)") | |||||
private BigDecimal yearBudget; | |||||
@ApiModelProperty("自有资金,政府投资-本级财政资金,政府投资-上级补助资金") | |||||
private String budgetFrom; | |||||
@ApiModelProperty("预算年度 2023") | |||||
private String year; | |||||
@ApiModelProperty("财政code 32") | |||||
private String financialCode; | |||||
@ApiModelProperty("发改code 23") | |||||
private String developCode; | |||||
@ApiModelProperty("开始时间 比如2022-11-18") | |||||
private String beginTime; | |||||
@ApiModelProperty("结束时间 比如2022-12-13") | |||||
private String endTime; | |||||
@ApiModelProperty("立项依据1111") | |||||
private String buildBasis; | |||||
@ApiModelProperty("立项依据材料 [{\"fileId\":\"\"}]") | |||||
private String buildBasisFile; | |||||
@ApiModelProperty("项目概述") | |||||
private String projectSummary; | |||||
@ApiModelProperty("负责人") | |||||
private String responsibleMan; | |||||
@ApiModelProperty("联系人联系方式") | |||||
private String responsibleManPhone; | |||||
@ApiModelProperty("联系人") | |||||
private String contactName; | |||||
@ApiModelProperty("联系人联系方式") | |||||
private String contactPhone; | |||||
@ApiModelProperty("建设单位 比如财政局") | |||||
private String buildUnit; | |||||
@ApiModelProperty("建设单位浙政钉code") | |||||
private String buildUnitCode; | |||||
@ApiModelProperty("主管单位") | |||||
private String superUnit; | |||||
@ApiModelProperty("主管单位浙政钉code") | |||||
private String superUnitCode; | |||||
@ApiModelProperty("可研报告文件") | |||||
private String researchReport; | |||||
@ApiModelProperty("项目申报书") | |||||
private String projectApplyFile; | |||||
@ApiModelProperty("项目总投资测算明细") | |||||
private String projectEstimateFile; | |||||
@ApiModelProperty("申报单位主要职责") | |||||
private String unitThreePlan; | |||||
@ApiModelProperty("其他附件") | |||||
private String otherFile; | |||||
@ApiModelProperty("项目备注111") | |||||
private String projectRemark; | |||||
@ApiModelProperty("是否有效 1有效 2无效 3撤回") | |||||
private String isEffective; | |||||
@ApiModelProperty("是否包含应用 1包含") | |||||
private String includeApplication; | |||||
@ApiModelProperty("app信息") | |||||
private List<ProvincialApplicationDTO> applicationInfo; | |||||
} |
@@ -0,0 +1,25 @@ | |||||
package com.ningdatech.pmapi.provincial.service; | |||||
import com.ningdatech.pmapi.provincial.model.dto.ProvincialProjectDTO; | |||||
/** | |||||
* @Classname JointReviewProvincialBureauService | |||||
* @Description 省局联审接口 | |||||
* @Date 2023/3/2 9:29 | |||||
* @Author PoffyZhang | |||||
*/ | |||||
public interface IJoinReviewProvincialBureauService { | |||||
/** | |||||
* 推送/保存 重大接口到 省局联审 | |||||
* @return | |||||
*/ | |||||
String pushImportProject(ProvincialProjectDTO project); | |||||
/** | |||||
* 查看 本区域 省局联审 的项目审核详情 | |||||
* @return | |||||
*/ | |||||
String processInfo(String projectId); | |||||
} |
@@ -0,0 +1,114 @@ | |||||
package com.ningdatech.pmapi.provincial.service.impl; | |||||
import cn.hutool.core.util.StrUtil; | |||||
import cn.hutool.crypto.SecureUtil; | |||||
import com.ningdatech.pmapi.common.config.ProvincialProperties; | |||||
import com.ningdatech.pmapi.provincial.model.dto.ProvincialProjectDTO; | |||||
import com.ningdatech.pmapi.provincial.service.IJoinReviewProvincialBureauService; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.http.HttpMethod; | |||||
import org.springframework.http.MediaType; | |||||
import org.springframework.http.RequestEntity; | |||||
import org.springframework.http.ResponseEntity; | |||||
import org.springframework.stereotype.Service; | |||||
import org.springframework.web.client.RestTemplate; | |||||
/** | |||||
* @Classname JointReviewProvincialBureauService | |||||
* @Description 省局联审接口 | |||||
* @Date 2023/3/2 9:29 | |||||
* @Author PoffyZhang | |||||
*/ | |||||
@Service | |||||
@Slf4j | |||||
public class JoinReviewProvincialBureauServiceImpl implements IJoinReviewProvincialBureauService { | |||||
@Autowired | |||||
private ProvincialProperties provincialProperties; | |||||
@Autowired | |||||
private RestTemplate restTemplate; | |||||
/** | |||||
* 推送/保存 重大接口到 省局联审 | |||||
* @return | |||||
*/ | |||||
@Override | |||||
public String pushImportProject(ProvincialProjectDTO project){ | |||||
Long timeStamp = System.currentTimeMillis()/1000; | |||||
String url = provincialProperties.getHost() + provincialProperties.getPushUrl() | |||||
+ "?timestamp=" + timeStamp; | |||||
log.info("省局推送联审url {}",url); | |||||
ResponseEntity<String> responseEntity = null; | |||||
String signature = getSha256(timeStamp,provincialProperties.getPushUrl(), | |||||
HttpMethod.POST.name()); | |||||
//发送post请求 | |||||
RequestEntity<ProvincialProjectDTO> requestEntity = RequestEntity | |||||
.post(url) | |||||
.header("Accept", MediaType.APPLICATION_JSON.toString()) | |||||
.header("X-Hmac-Auth-Key",provincialProperties.getKey()) | |||||
.header("X-Hmac-Auth-Signature",signature) | |||||
.contentType(MediaType.APPLICATION_JSON) | |||||
.accept(MediaType.APPLICATION_JSON) | |||||
.body(project); | |||||
try { | |||||
responseEntity = restTemplate.exchange(requestEntity,String.class); | |||||
log.info("省局联审 响应 :{}",responseEntity); | |||||
} catch (Exception e) { | |||||
log.error("[省局联审] http request error", e); | |||||
} | |||||
return responseEntity.getBody(); | |||||
} | |||||
/** | |||||
* 获取流程审批详情 | |||||
* @param projectId | |||||
* @return | |||||
*/ | |||||
@Override | |||||
public String processInfo(String projectId) { | |||||
Long timeStamp = System.currentTimeMillis()/1000; | |||||
String url = provincialProperties.getHost() + provincialProperties.getDetailUrl() | |||||
+ "?timestamp=" + timeStamp; | |||||
log.info("省局获取审核详情 url {}",url); | |||||
ResponseEntity<String> responseEntity = null; | |||||
String signature = getSha256(timeStamp,provincialProperties.getDetailUrl(), | |||||
HttpMethod.POST.name()); | |||||
//发送post请求 | |||||
RequestEntity<String> requestEntity = RequestEntity | |||||
.post(url) | |||||
.header("Accept", MediaType.APPLICATION_JSON.toString()) | |||||
.header("X-Hmac-Auth-Key",provincialProperties.getKey()) | |||||
.header("X-Hmac-Auth-Signature",signature) | |||||
.contentType(MediaType.APPLICATION_JSON) | |||||
.accept(MediaType.APPLICATION_JSON) | |||||
.body(projectId); //也可以是DTO | |||||
try { | |||||
responseEntity = restTemplate.exchange(requestEntity,String.class); | |||||
log.info("获取审批详情 响应 :{}",responseEntity); | |||||
} catch (Exception e) { | |||||
log.error("[省局获取审核详情] http request error", e); | |||||
} | |||||
return responseEntity.getBody(); | |||||
} | |||||
private String getSha256(Long timeStamp,String url,String method){ | |||||
String secret = provincialProperties.getSecret(); | |||||
String key = provincialProperties.getKey(); | |||||
String bytesToSign = method + StrUtil.LF + url + StrUtil.LF + timeStamp + StrUtil.LF + key; | |||||
log.info("加密message :{}",bytesToSign); | |||||
String res = SecureUtil.hmacSha256(secret).digestBase64(bytesToSign,false); | |||||
log.info("加密结果 :{}",res); | |||||
return res; | |||||
} | |||||
} |
@@ -7,6 +7,7 @@ import com.ningdatech.pmapi.projectlib.enumeration.ProjectStatusEnum; | |||||
import com.ningdatech.pmapi.projectlib.model.entity.Project; | import com.ningdatech.pmapi.projectlib.model.entity.Project; | ||||
import com.ningdatech.pmapi.staging.model.entity.ProjectStaging; | import com.ningdatech.pmapi.staging.model.entity.ProjectStaging; | ||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||
import javax.annotation.PostConstruct; | import javax.annotation.PostConstruct; | ||||
@@ -20,11 +21,12 @@ import java.util.function.Function; | |||||
* @Author PoffyZhang | * @Author PoffyZhang | ||||
*/ | */ | ||||
@Component | @Component | ||||
@RequiredArgsConstructor | |||||
public class ProjectStatusFlowMapUtil { | public class ProjectStatusFlowMapUtil { | ||||
private final ReviewByProvincialDeptManage provincialDeptManage; | |||||
@Autowired | |||||
private ReviewByProvincialDeptManage provincialDeptManage; | |||||
private final ReviewByDeptJointManage reviewByDeptJointManage; | |||||
@Autowired | |||||
private ReviewByDeptJointManage reviewByDeptJointManage; | |||||
public Map<Integer, Function<Project,Boolean>> statusFlowFunctionMap = Maps.newHashMap(); | public Map<Integer, Function<Project,Boolean>> statusFlowFunctionMap = Maps.newHashMap(); | ||||
/** | /** | ||||
@@ -37,8 +39,7 @@ public class ProjectStatusFlowMapUtil { | |||||
* key: 枚举 状态值 | * key: 枚举 状态值 | ||||
* value: lambda表达式,最终会获取发起实例的函数 | * value: lambda表达式,最终会获取发起实例的函数 | ||||
*/ | */ | ||||
@PostConstruct | |||||
public void statusFlowFunctionInit(){ | |||||
public ProjectStatusFlowMapUtil(){ | |||||
//省级部门联审 | //省级部门联审 | ||||
statusFlowFunctionMap.put(ProjectStatusEnum.JOINT_REVIEW_BY_PROVINCIAL_DEPARTMENTS.getCode(), | statusFlowFunctionMap.put(ProjectStatusEnum.JOINT_REVIEW_BY_PROVINCIAL_DEPARTMENTS.getCode(), | ||||
project->provincialDeptManage.startTheProcess(project)); | project->provincialDeptManage.startTheProcess(project)); | ||||
@@ -47,6 +48,7 @@ public class ProjectStatusFlowMapUtil { | |||||
project->reviewByDeptJointManage.startTheProcess(project)); | project->reviewByDeptJointManage.startTheProcess(project)); | ||||
} | } | ||||
/** | /** | ||||
* 扫描的间隔越来越长 秒数 | * 扫描的间隔越来越长 秒数 | ||||
*/ | */ | ||||
@@ -184,4 +184,12 @@ yxt: | |||||
password: hzndkj@2021 | password: hzndkj@2021 | ||||
#音信通开关 | #音信通开关 | ||||
sms-enable: true | sms-enable: true | ||||
tel-enable: true | |||||
tel-enable: true | |||||
#省局联审 请求信息 | |||||
provincial: | |||||
host: http://zj.ningdatech.com/prometheus-zhejiang_foreign | |||||
pushUrl: /api/v1/foreign/importantPro | |||||
detailUrl: /api/v1/foreign/importantProView | |||||
key: 7196317343a64e67895dc0375c098fe7 | |||||
secret: 75152a97f20e4c4c854dc6301cf72ad4 |
@@ -0,0 +1,37 @@ | |||||
package com.ningdatech.pmapi.provincial; | |||||
import cn.hutool.crypto.SecureUtil; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.apache.commons.codec.binary.Base64; | |||||
import javax.crypto.Mac; | |||||
import javax.crypto.spec.SecretKeySpec; | |||||
import java.io.UnsupportedEncodingException; | |||||
import java.security.InvalidKeyException; | |||||
import java.security.NoSuchAlgorithmException; | |||||
/** | |||||
* @Classname Test | |||||
* @Description | |||||
* @Date 2023/3/2 16:14 | |||||
* @Author PoffyZhang | |||||
*/ | |||||
@Slf4j | |||||
public class Test { | |||||
@org.junit.Test | |||||
public void test() throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException { | |||||
// Long timeStamp = System.currentTimeMillis()/1000; | |||||
Long timeStamp = 1677750055L; | |||||
String key = "7196317343a64e67895dc0375c098fe7"; | |||||
String url = "/api/v1/foreign/importantProView"; | |||||
String methed = "POST"; | |||||
String bytesToSign = methed + "\n" + url + "\n" + timeStamp + "\n" + key; | |||||
log.info("" + bytesToSign); | |||||
String secret = "75152a97f20e4c4c854dc6301cf72ad4"; | |||||
String str = SecureUtil.hmacSha256(secret).digestBase64(bytesToSign,false); | |||||
log.info("" + str); | |||||
} | |||||
} |