@@ -56,7 +56,7 @@ public class GeneratorCodeKingbaseConfig { | |||||
} | } | ||||
public static void main(String[] args) { | public static void main(String[] args) { | ||||
generate("Lierbao", "organization", PATH_LXX, "ding_organization"); | |||||
generate("Lierbao", "signature", PATH_LXX, "nd_company_signature"); | |||||
} | } | ||||
} | } |
@@ -0,0 +1,13 @@ | |||||
package com.ningdatech.pmapi.api.tiangu; | |||||
import com.aliyuncs.http.IHttpClient; | |||||
import org.springframework.stereotype.Component; | |||||
/** | |||||
* @author liuxinxin | |||||
* @date 2023/2/10 上午11:15 | |||||
*/ | |||||
@Component | |||||
public class SealApi { | |||||
} |
@@ -0,0 +1,21 @@ | |||||
package com.ningdatech.pmapi.ding.task; | |||||
import com.ningdatech.zwdd.client.ZwddClient; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.transaction.annotation.Transactional; | |||||
/** | |||||
* @author liuxinxin | |||||
* @date 2023/2/10 上午9:52 | |||||
*/ | |||||
public class EmployeeBatchGetTask { | |||||
@Autowired | |||||
private ZwddClient zwddClient; | |||||
@Transactional(rollbackFor = Exception.class) | |||||
public void batchGetEmployeeTask() { | |||||
} | |||||
} |
@@ -1,171 +1,165 @@ | |||||
// | |||||
//package com.ningdatech.pmapi.ding.task; | |||||
// | |||||
//import cn.hutool.core.collection.CollUtil; | |||||
//import com.alibaba.fastjson.JSONObject; | |||||
//import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; | |||||
//import com.google.common.collect.Lists; | |||||
//import com.ningdatech.basic.model.GenericResult; | |||||
//import com.ningdatech.pmapi.ding.model.DingOrgInfoTreeDTO; | |||||
//import com.ningdatech.pmapi.organization.entity.DingOrganization; | |||||
//import com.ningdatech.pmapi.organization.service.IDingOrganizationService; | |||||
//import com.ningdatech.zwdd.client.ZwddAuthClient; | |||||
//import com.ningdatech.zwdd.client.ZwddClient; | |||||
//import com.ningdatech.zwdd.model.dto.DingOrgInfoDTO; | |||||
//import com.ningdatech.zwdd.model.dto.DingScopesV2DTO; | |||||
//import com.ningdatech.zwdd.model.dto.PageSubOrganizationCodeDTO; | |||||
//import lombok.extern.slf4j.Slf4j; | |||||
//import org.springframework.beans.factory.annotation.Autowired; | |||||
//import org.springframework.stereotype.Component; | |||||
//import org.springframework.transaction.annotation.Transactional; | |||||
// | |||||
//import java.util.ArrayList; | |||||
//import java.util.List; | |||||
//import java.util.Objects; | |||||
//import java.util.stream.Collectors; | |||||
// | |||||
///** | |||||
// * @author liuxinxin | |||||
// * @date 2023/2/7 上午10:15 | |||||
// */ | |||||
// | |||||
//@Slf4j | |||||
//@Component | |||||
//public class OrganizationBatchGetTask { | |||||
// | |||||
// @Autowired | |||||
// private ZwddClient zwddClient; | |||||
// | |||||
// @Autowired | |||||
// private ZwddAuthClient zwddAuthClient; | |||||
// | |||||
// private static final Integer GROUP_SIZE = 100; | |||||
// | |||||
// @Autowired | |||||
// private IDingOrganizationService iDingOrganizationService; | |||||
// | |||||
// /** | |||||
// * 获取浙政钉组织架构 | |||||
// */ | |||||
// @Transactional(rollbackFor = Exception.class) | |||||
// public void batchGetOrganizationTask() { | |||||
//// List<DingOrganization> allList = iDingOrganizationService.list(); | |||||
//// List<String> currentAllOrganizationCodeList = allList.stream().map(DingOrganization::getOrganizationCode).collect(Collectors.toList()); | |||||
// // 全量删除 | |||||
// // iDingOrganizationService.remove(Wrappers.lambdaQuery(DingOrganization.class).isNotNull(DingOrganization::getId)); | |||||
// // 获取顶级组织code | |||||
// GenericResult<DingScopesV2DTO> scopesV2Result = zwddClient.getScopesV2(); | |||||
// DingScopesV2DTO scopesV2 = scopesV2Result.getData(); | |||||
// | |||||
// if (Objects.nonNull(scopesV2)) { | |||||
// // 顶级组织code | |||||
// List<String> deptVisibleScopes = scopesV2.getDeptVisibleScopes(); | |||||
// log.info("顶级组织code: size = " + deptVisibleScopes.size() + "列表:" + JSONObject.toJSONString(deptVisibleScopes)); | |||||
// // 获取顶级节点信息 | |||||
// GenericResult<List<DingOrgInfoDTO>> listGenericResult = zwddClient.listOrganizationsByCodes(deptVisibleScopes); | |||||
// List<DingOrgInfoDTO> dingOrgInfoDtos = listGenericResult.getData(); | |||||
// for (String orgCode : deptVisibleScopes) { | |||||
//// if (currentAllOrganizationCodeList.contains(orgCode)) { | |||||
//// log.info("已存在组织架构---{}", orgCode); | |||||
//// continue; | |||||
//// } | |||||
// List<DingOrgInfoTreeDTO> treeDTOList = new ArrayList<>(); | |||||
// | |||||
// DingOrgInfoTreeDTO childDingOrgInfoTreeDTO = new DingOrgInfoTreeDTO(); | |||||
// //设置节点详情 | |||||
// if (dingOrgInfoDtos != null && !dingOrgInfoDtos.isEmpty()) { | |||||
// for (DingOrgInfoDTO orgInfo : dingOrgInfoDtos) { | |||||
// if (orgInfo.getOrganizationCode().equals(orgCode)) { | |||||
// childDingOrgInfoTreeDTO.setDingOrgInfoDTO(orgInfo); | |||||
// } | |||||
// } | |||||
package com.ningdatech.pmapi.ding.task; | |||||
import cn.hutool.core.collection.CollUtil; | |||||
import com.alibaba.fastjson.JSONObject; | |||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; | |||||
import com.google.common.collect.Lists; | |||||
import com.ningdatech.basic.model.GenericResult; | |||||
import com.ningdatech.pmapi.ding.model.DingOrgInfoTreeDTO; | |||||
import com.ningdatech.pmapi.organization.entity.DingOrganization; | |||||
import com.ningdatech.pmapi.organization.service.IDingOrganizationService; | |||||
import com.ningdatech.zwdd.client.ZwddClient; | |||||
import com.ningdatech.zwdd.model.dto.DingOrgInfoDTO; | |||||
import com.ningdatech.zwdd.model.dto.DingScopesV2DTO; | |||||
import com.ningdatech.zwdd.model.dto.PageSubOrganizationCodeDTO; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.stereotype.Component; | |||||
import org.springframework.transaction.annotation.Transactional; | |||||
import java.util.ArrayList; | |||||
import java.util.List; | |||||
import java.util.Objects; | |||||
import java.util.stream.Collectors; | |||||
/** | |||||
* @author liuxinxin | |||||
* @date 2023/2/7 上午10:15 | |||||
*/ | |||||
@Slf4j | |||||
@Component | |||||
public class OrganizationBatchGetTask { | |||||
@Autowired | |||||
private ZwddClient zwddClient; | |||||
private static final Integer GROUP_SIZE = 100; | |||||
@Autowired | |||||
private IDingOrganizationService iDingOrganizationService; | |||||
/** | |||||
* 获取浙政钉组织架构 | |||||
*/ | |||||
@Transactional(rollbackFor = Exception.class) | |||||
public void batchGetOrganizationTask() { | |||||
// List<DingOrganization> allList = iDingOrganizationService.list(); | |||||
// List<String> currentAllOrganizationCodeList = allList.stream().map(DingOrganization::getOrganizationCode).collect(Collectors.toList()); | |||||
// 全量删除 | |||||
// iDingOrganizationService.remove(Wrappers.lambdaQuery(DingOrganization.class).isNotNull(DingOrganization::getId)); | |||||
// 获取顶级组织code | |||||
GenericResult<DingScopesV2DTO> scopesV2Result = zwddClient.getScopesV2(); | |||||
DingScopesV2DTO scopesV2 = scopesV2Result.getData(); | |||||
if (Objects.nonNull(scopesV2)) { | |||||
// 顶级组织code | |||||
List<String> deptVisibleScopes = scopesV2.getDeptVisibleScopes(); | |||||
log.info("顶级组织code: size = " + deptVisibleScopes.size() + "列表:" + JSONObject.toJSONString(deptVisibleScopes)); | |||||
// 获取顶级节点信息 | |||||
GenericResult<List<DingOrgInfoDTO>> listGenericResult = zwddClient.listOrganizationsByCodes(deptVisibleScopes); | |||||
List<DingOrgInfoDTO> dingOrgInfoDtos = listGenericResult.getData(); | |||||
for (String orgCode : deptVisibleScopes) { | |||||
// if (currentAllOrganizationCodeList.contains(orgCode)) { | |||||
// log.info("已存在组织架构---{}", orgCode); | |||||
// continue; | |||||
// } | // } | ||||
// childDingOrgInfoTreeDTO.setCode(orgCode); | |||||
// childDingOrgInfoTreeDTO.setChildCodes(new ArrayList<>()); | |||||
// getDingOrgChild(childDingOrgInfoTreeDTO); | |||||
// treeDTOList.add(childDingOrgInfoTreeDTO); | |||||
// | |||||
// if (CollectionUtils.isNotEmpty(treeDTOList)) { | |||||
// List<DingOrganization> saveRecordList = new ArrayList<>(); | |||||
// buildSaveRecordList(treeDTOList, saveRecordList); | |||||
// | |||||
// // 批量保存 | |||||
// if (saveRecordList.size() <= GROUP_SIZE) { | |||||
// iDingOrganizationService.saveBatch(saveRecordList); | |||||
// } else { | |||||
// List<List<DingOrganization>> split = Lists.partition(saveRecordList, GROUP_SIZE); | |||||
// for (List<DingOrganization> segment : split) { | |||||
// iDingOrganizationService.saveBatch(segment); | |||||
// } | |||||
// } | |||||
// } | |||||
// log.info("----拉取浙政钉组织结构结束---,顶级code:" + orgCode); | |||||
// } | |||||
// } | |||||
// } | |||||
// | |||||
// private void buildSaveRecordList(List<DingOrgInfoTreeDTO> treeDTOList, List<DingOrganization> saveRecordList) { | |||||
// if (CollectionUtils.isEmpty(treeDTOList)) { | |||||
// return; | |||||
// } | |||||
// for (DingOrgInfoTreeDTO dingOrgInfoTreeDTO : treeDTOList) { | |||||
// DingOrganization saveRecord = new DingOrganization(); | |||||
// DingOrgInfoDTO dingOrgInfoDTO = dingOrgInfoTreeDTO.getDingOrgInfoDTO(); | |||||
// List<DingOrgInfoTreeDTO> childCodes = dingOrgInfoTreeDTO.getChildCodes(); | |||||
// saveRecord.setDisplayOrder(dingOrgInfoDTO.getDisplayOrder()); | |||||
//// saveRecord.setEnabled("1"); | |||||
// saveRecord.setParentCode(dingOrgInfoDTO.getParentCode()); | |||||
// saveRecord.setOrganizationCode(dingOrgInfoDTO.getOrganizationCode()); | |||||
//// saveRecord.setSubCount((long) dingOrgInfoTreeDTO.getChildCodes().size()); | |||||
// saveRecord.setOrganizationName(dingOrgInfoDTO.getOrganizationName()); | |||||
// saveRecordList.add(saveRecord); | |||||
// if (CollectionUtils.isNotEmpty(childCodes)) { | |||||
// buildSaveRecordList(childCodes, saveRecordList); | |||||
// } | |||||
// } | |||||
// | |||||
// } | |||||
// | |||||
// private void getDingOrgChild(DingOrgInfoTreeDTO parentDingOrgInfoTreeDTO) { | |||||
// String parentOrgCode = parentDingOrgInfoTreeDTO.getCode(); | |||||
// DingOrgInfoDTO orgInfoDTO = parentDingOrgInfoTreeDTO.getDingOrgInfoDTO(); | |||||
// boolean leaf = orgInfoDTO.getLeaf(); | |||||
// if (!leaf) { | |||||
// int currentPage = 1; | |||||
// int pageSize = 100; | |||||
// GenericResult<PageSubOrganizationCodeDTO> pageSubOrganizationCodeDTOGenericResult = zwddClient.pageSubOrganizationCodes(currentPage++, pageSize, parentOrgCode); | |||||
// PageSubOrganizationCodeDTO pageSubOrganizationCodeDTO = pageSubOrganizationCodeDTOGenericResult.getData(); | |||||
// | |||||
// if (CollUtil.isNotEmpty(pageSubOrganizationCodeDTO.getSubOrganizationCodeList())) { | |||||
// List<String> subOrganizationCodeList = new ArrayList<>(pageSubOrganizationCodeDTO.getSubOrganizationCodeList()); | |||||
// Long totalSize = pageSubOrganizationCodeDTO.getTotalSize(); | |||||
// | |||||
// while (totalSize > (long) currentPage * pageSize) { | |||||
// GenericResult<PageSubOrganizationCodeDTO> subPageSubOrganizationCodeDTOGenericResult = zwddClient | |||||
// .pageSubOrganizationCodes(currentPage++, pageSize, parentOrgCode); | |||||
// PageSubOrganizationCodeDTO subOrganizationCodeDTO = subPageSubOrganizationCodeDTOGenericResult.getData(); | |||||
// if (CollectionUtils.isNotEmpty(subOrganizationCodeDTO.getSubOrganizationCodeList())) { | |||||
// subOrganizationCodeList.addAll(subOrganizationCodeDTO.getSubOrganizationCodeList()); | |||||
// } | |||||
// } | |||||
// | |||||
// if (CollectionUtils.isNotEmpty(subOrganizationCodeList)) { | |||||
// GenericResult<List<DingOrgInfoDTO>> listGenericResult = zwddClient | |||||
// .listOrganizationsByCodes(subOrganizationCodeList); | |||||
// List<DingOrgInfoDTO> dingOrgInfoDtos = listGenericResult.getData(); | |||||
// List<DingOrgInfoTreeDTO> dingOrgInfoTreeDTOList = dingOrgInfoDtos.stream().map(r -> { | |||||
// DingOrgInfoTreeDTO dingOrgInfoTreeDTO = new DingOrgInfoTreeDTO(); | |||||
// dingOrgInfoTreeDTO.setCode(r.getOrganizationCode()); | |||||
// dingOrgInfoTreeDTO.setDingOrgInfoDTO(r); | |||||
// dingOrgInfoTreeDTO.setChildCodes(new ArrayList<>()); | |||||
// getDingOrgChild(dingOrgInfoTreeDTO); | |||||
// return dingOrgInfoTreeDTO; | |||||
// }).collect(Collectors.toList()); | |||||
// parentDingOrgInfoTreeDTO.setChildCodes(dingOrgInfoTreeDTOList); | |||||
// } | |||||
// } | |||||
// } | |||||
// } | |||||
// | |||||
//} | |||||
// | |||||
List<DingOrgInfoTreeDTO> treeDTOList = new ArrayList<>(); | |||||
DingOrgInfoTreeDTO childDingOrgInfoTreeDTO = new DingOrgInfoTreeDTO(); | |||||
//设置节点详情 | |||||
if (dingOrgInfoDtos != null && !dingOrgInfoDtos.isEmpty()) { | |||||
for (DingOrgInfoDTO orgInfo : dingOrgInfoDtos) { | |||||
if (orgInfo.getOrganizationCode().equals(orgCode)) { | |||||
childDingOrgInfoTreeDTO.setDingOrgInfoDTO(orgInfo); | |||||
} | |||||
} | |||||
} | |||||
childDingOrgInfoTreeDTO.setCode(orgCode); | |||||
childDingOrgInfoTreeDTO.setChildCodes(new ArrayList<>()); | |||||
getDingOrgChild(childDingOrgInfoTreeDTO); | |||||
treeDTOList.add(childDingOrgInfoTreeDTO); | |||||
if (CollectionUtils.isNotEmpty(treeDTOList)) { | |||||
List<DingOrganization> saveRecordList = new ArrayList<>(); | |||||
buildSaveRecordList(treeDTOList, saveRecordList); | |||||
// 批量保存 | |||||
if (saveRecordList.size() <= GROUP_SIZE) { | |||||
iDingOrganizationService.saveBatch(saveRecordList); | |||||
} else { | |||||
List<List<DingOrganization>> split = Lists.partition(saveRecordList, GROUP_SIZE); | |||||
for (List<DingOrganization> segment : split) { | |||||
iDingOrganizationService.saveBatch(segment); | |||||
} | |||||
} | |||||
} | |||||
log.info("----拉取浙政钉组织结构结束---,顶级code:" + orgCode); | |||||
} | |||||
} | |||||
} | |||||
private void buildSaveRecordList(List<DingOrgInfoTreeDTO> treeDTOList, List<DingOrganization> saveRecordList) { | |||||
if (CollectionUtils.isEmpty(treeDTOList)) { | |||||
return; | |||||
} | |||||
for (DingOrgInfoTreeDTO dingOrgInfoTreeDTO : treeDTOList) { | |||||
DingOrganization saveRecord = new DingOrganization(); | |||||
DingOrgInfoDTO dingOrgInfoDTO = dingOrgInfoTreeDTO.getDingOrgInfoDTO(); | |||||
List<DingOrgInfoTreeDTO> childCodes = dingOrgInfoTreeDTO.getChildCodes(); | |||||
saveRecord.setDisplayOrder(dingOrgInfoDTO.getDisplayOrder()); | |||||
// saveRecord.setEnabled("1"); | |||||
saveRecord.setParentCode(dingOrgInfoDTO.getParentCode()); | |||||
saveRecord.setOrganizationCode(dingOrgInfoDTO.getOrganizationCode()); | |||||
// saveRecord.setSubCount((long) dingOrgInfoTreeDTO.getChildCodes().size()); | |||||
saveRecord.setOrganizationName(dingOrgInfoDTO.getOrganizationName()); | |||||
saveRecordList.add(saveRecord); | |||||
if (CollectionUtils.isNotEmpty(childCodes)) { | |||||
buildSaveRecordList(childCodes, saveRecordList); | |||||
} | |||||
} | |||||
} | |||||
private void getDingOrgChild(DingOrgInfoTreeDTO parentDingOrgInfoTreeDTO) { | |||||
String parentOrgCode = parentDingOrgInfoTreeDTO.getCode(); | |||||
DingOrgInfoDTO orgInfoDTO = parentDingOrgInfoTreeDTO.getDingOrgInfoDTO(); | |||||
boolean leaf = orgInfoDTO.getLeaf(); | |||||
if (!leaf) { | |||||
int currentPage = 1; | |||||
int pageSize = 100; | |||||
GenericResult<PageSubOrganizationCodeDTO> pageSubOrganizationCodeDTOGenericResult = zwddClient.pageSubOrganizationCodes(currentPage++, pageSize, parentOrgCode); | |||||
PageSubOrganizationCodeDTO pageSubOrganizationCodeDTO = pageSubOrganizationCodeDTOGenericResult.getData(); | |||||
if (CollUtil.isNotEmpty(pageSubOrganizationCodeDTO.getSubOrganizationCodeList())) { | |||||
List<String> subOrganizationCodeList = new ArrayList<>(pageSubOrganizationCodeDTO.getSubOrganizationCodeList()); | |||||
Long totalSize = pageSubOrganizationCodeDTO.getTotalSize(); | |||||
while (totalSize > (long) currentPage * pageSize) { | |||||
GenericResult<PageSubOrganizationCodeDTO> subPageSubOrganizationCodeDTOGenericResult = zwddClient | |||||
.pageSubOrganizationCodes(currentPage++, pageSize, parentOrgCode); | |||||
PageSubOrganizationCodeDTO subOrganizationCodeDTO = subPageSubOrganizationCodeDTOGenericResult.getData(); | |||||
if (CollectionUtils.isNotEmpty(subOrganizationCodeDTO.getSubOrganizationCodeList())) { | |||||
subOrganizationCodeList.addAll(subOrganizationCodeDTO.getSubOrganizationCodeList()); | |||||
} | |||||
} | |||||
if (CollectionUtils.isNotEmpty(subOrganizationCodeList)) { | |||||
GenericResult<List<DingOrgInfoDTO>> listGenericResult = zwddClient | |||||
.listOrganizationsByCodes(subOrganizationCodeList); | |||||
List<DingOrgInfoDTO> dingOrgInfoDtos = listGenericResult.getData(); | |||||
List<DingOrgInfoTreeDTO> dingOrgInfoTreeDTOList = dingOrgInfoDtos.stream().map(r -> { | |||||
DingOrgInfoTreeDTO dingOrgInfoTreeDTO = new DingOrgInfoTreeDTO(); | |||||
dingOrgInfoTreeDTO.setCode(r.getOrganizationCode()); | |||||
dingOrgInfoTreeDTO.setDingOrgInfoDTO(r); | |||||
dingOrgInfoTreeDTO.setChildCodes(new ArrayList<>()); | |||||
getDingOrgChild(dingOrgInfoTreeDTO); | |||||
return dingOrgInfoTreeDTO; | |||||
}).collect(Collectors.toList()); | |||||
parentDingOrgInfoTreeDTO.setChildCodes(dingOrgInfoTreeDTOList); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
} | |||||
@@ -0,0 +1,20 @@ | |||||
package com.ningdatech.pmapi.fiscal.controller; | |||||
import org.springframework.web.bind.annotation.RequestMapping; | |||||
import org.springframework.stereotype.Controller; | |||||
/** | |||||
* <p> | |||||
* 前端控制器 | |||||
* </p> | |||||
* | |||||
* @author Lierbao | |||||
* @since 2023-02-10 | |||||
*/ | |||||
@Controller | |||||
@RequestMapping("/pmapi.fiscal/nd-company-fiscal-code") | |||||
public class NdCompanyFiscalCodeController { | |||||
} |
@@ -0,0 +1,39 @@ | |||||
package com.ningdatech.pmapi.fiscal.entity; | |||||
import com.baomidou.mybatisplus.annotation.TableName; | |||||
import io.swagger.annotations.ApiModel; | |||||
import lombok.Data; | |||||
import java.io.Serializable; | |||||
import java.time.LocalDateTime; | |||||
/** | |||||
* <p> | |||||
* | |||||
* </p> | |||||
* | |||||
* @author Lierbao | |||||
* @since 2023-02-10 | |||||
*/ | |||||
@Data | |||||
@TableName("nd_company_fiscal_code") | |||||
@ApiModel(value = "NdCompanyFiscalCode对象", description = "") | |||||
public class NdCompanyFiscalCode implements Serializable { | |||||
private static final long serialVersionUID = 1L; | |||||
private Long id; | |||||
private String fiscalCode; | |||||
private Long companyId; | |||||
private LocalDateTime createOn; | |||||
private LocalDateTime updateOn; | |||||
private Long createBy; | |||||
private Long updateBy; | |||||
} |
@@ -0,0 +1,16 @@ | |||||
package com.ningdatech.pmapi.fiscal.mapper; | |||||
import com.ningdatech.pmapi.fiscal.entity.NdCompanyFiscalCode; | |||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; | |||||
/** | |||||
* <p> | |||||
* Mapper 接口 | |||||
* </p> | |||||
* | |||||
* @author Lierbao | |||||
* @since 2023-02-10 | |||||
*/ | |||||
public interface NdCompanyFiscalCodeMapper extends BaseMapper<NdCompanyFiscalCode> { | |||||
} |
@@ -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.ningdatech.pmapi.fiscal.mapper.NdCompanyFiscalCodeMapper"> | |||||
</mapper> |
@@ -0,0 +1,16 @@ | |||||
package com.ningdatech.pmapi.fiscal.service; | |||||
import com.ningdatech.pmapi.fiscal.entity.NdCompanyFiscalCode; | |||||
import com.baomidou.mybatisplus.extension.service.IService; | |||||
/** | |||||
* <p> | |||||
* 服务类 | |||||
* </p> | |||||
* | |||||
* @author Lierbao | |||||
* @since 2023-02-10 | |||||
*/ | |||||
public interface INdCompanyFiscalCodeService extends IService<NdCompanyFiscalCode> { | |||||
} |
@@ -0,0 +1,20 @@ | |||||
package com.ningdatech.pmapi.fiscal.service.impl; | |||||
import com.ningdatech.pmapi.fiscal.entity.NdCompanyFiscalCode; | |||||
import com.ningdatech.pmapi.fiscal.mapper.NdCompanyFiscalCodeMapper; | |||||
import com.ningdatech.pmapi.fiscal.service.INdCompanyFiscalCodeService; | |||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | |||||
import org.springframework.stereotype.Service; | |||||
/** | |||||
* <p> | |||||
* 服务实现类 | |||||
* </p> | |||||
* | |||||
* @author Lierbao | |||||
* @since 2023-02-10 | |||||
*/ | |||||
@Service | |||||
public class NdCompanyFiscalCodeServiceImpl extends ServiceImpl<NdCompanyFiscalCodeMapper, NdCompanyFiscalCode> implements INdCompanyFiscalCodeService { | |||||
} |
@@ -0,0 +1,355 @@ | |||||
package com.ningdatech.pmapi.irs.sign; | |||||
import com.alibaba.fastjson.JSON; | |||||
import com.alibaba.fastjson.JSONObject; | |||||
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64; | |||||
import javafx.util.Pair; | |||||
import org.apache.http.HttpEntity; | |||||
import org.apache.http.HttpResponse; | |||||
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; | |||||
import org.apache.http.client.methods.HttpPost; | |||||
import org.apache.http.entity.ByteArrayEntity; | |||||
import org.apache.http.entity.ContentType; | |||||
import org.apache.http.impl.client.CloseableHttpClient; | |||||
import org.apache.http.impl.client.HttpClientBuilder; | |||||
import sun.misc.BASE64Decoder; | |||||
import sun.misc.BASE64Encoder; | |||||
import javax.crypto.Mac; | |||||
import javax.crypto.spec.SecretKeySpec; | |||||
import javax.xml.bind.DatatypeConverter; | |||||
import java.io.*; | |||||
import java.net.URI; | |||||
import java.net.URL; | |||||
import java.net.URLEncoder; | |||||
import java.security.Key; | |||||
import java.text.DateFormat; | |||||
import java.text.SimpleDateFormat; | |||||
import java.util.*; | |||||
import java.util.stream.Collectors; | |||||
public class IRSAPIRequest { | |||||
//天印服务器接口信息 | |||||
// private static String ProjectID = "XXX"; | |||||
// private static String ProjectSecret = "XXXX"; | |||||
// private static String accessKey = "XXXX"; | |||||
// private static String secretKey = "XXXX"; | |||||
// private static String apiUrl = "https://ibcdsg.zj.gov.cn:8443/restapi/prod/IC33000020220309000004/seal-platform/seal/v1/rest/sign/signPdf"; | |||||
private static String ProjectID = "XXX"; | |||||
private static String ProjectSecret = "XXXX"; | |||||
private static String accessKey = "XXXX"; | |||||
private static String secretKey = "XXXX"; | |||||
private static String apiUrl = "https://ibcdsg.zj.gov.cn:8443/restapi/prod/IC33000020220309000004/seal-platform/seal/v1/rest/sign/signPdf"; | |||||
public static void main(String[] args) throws Exception { | |||||
createSignPdf(); | |||||
} | |||||
/** | |||||
* pdf文件盖章 | |||||
* 接口地址:/V1/accounts/outerAccounts/create | |||||
* | |||||
* @return | |||||
*/ | |||||
public static JSONObject createSignPdf() { | |||||
JSONObject obj = null; | |||||
String resp = null; | |||||
try { | |||||
JSONObject ReqData = new JSONObject(); | |||||
String pathname = "D://001.pdf"; | |||||
File file = new File(pathname); | |||||
String fileByte1 = IRSAPIRequest.PDFToBase64(file); | |||||
ReqData.put("fileBase64", fileByte1); | |||||
ReqData.put("sealSn", "33012108041829053952"); | |||||
ReqData.put("posX", "200"); | |||||
ReqData.put("posY", "200"); | |||||
ReqData.put("signType", "1"); | |||||
// ReqData.put("key", "单位"); | |||||
ReqData.put("posPage", "1"); | |||||
ReqData.put("fileName", "01.pdf"); | |||||
resp = post(ReqData, "post"); | |||||
JSONObject jsonObject = JSON.parseObject(resp); | |||||
String data = jsonObject.getString("data"); | |||||
JSONObject jsondata = JSON.parseObject(data); | |||||
String signFileB64 = jsondata.getString("signFileB64"); | |||||
IRSAPIRequest.base64StringToPdf(signFileB64, "D:\\test21.pdf"); | |||||
} catch (Exception e) { | |||||
e.printStackTrace(); | |||||
} | |||||
return obj; | |||||
} | |||||
public static String post(JSONObject data, String requestMethod) throws Exception { | |||||
//计算irs请求头里面参数信息 | |||||
DateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US); | |||||
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT")); | |||||
String date = dateFormat.format(new Date()); | |||||
URL url = new URL(apiUrl); | |||||
URI uri = new URI(url.getProtocol(), url.getHost(), url.getPath(), url.getQuery(), null); | |||||
String canonicalQueryString = getCanonicalQueryString(uri.getQuery()); | |||||
String message = requestMethod.toUpperCase() + "\n" + uri.getPath() + "\n" + canonicalQueryString + "\n" + accessKey + "\n" + date + "\n"; | |||||
Mac hasher = Mac.getInstance("HmacSHA256"); | |||||
hasher.init(new SecretKeySpec(secretKey.getBytes(), "HmacSHA256")); | |||||
byte[] hash = hasher.doFinal(message.getBytes()); | |||||
DatatypeConverter.printHexBinary(hash); | |||||
String sign = DatatypeConverter.printBase64Binary(hash); | |||||
/*byte[] stream1 = message.toString().getBytes("UTF-8"); | |||||
String sign = sign1(stream1);*/ | |||||
// 计算电子印章组件signature值 | |||||
String myData = data.toString(); | |||||
System.out.println(myData); | |||||
byte[] stream = data.toString().getBytes("UTF-8"); | |||||
// 签名数据,根据签名算法,对请求数据进行签名 | |||||
String signature = sign(stream); | |||||
//System.out.println(signature); | |||||
// 设置HTTP请求头 | |||||
HttpEntityEnclosingRequestBase req = new HttpPost(apiUrl); | |||||
// project-id为用户的projectId | |||||
req.addHeader("appId", ProjectID); | |||||
// signature为之前生成的签名 | |||||
req.addHeader("signature", signature); | |||||
req.addHeader("X-BG-HMAC-SIGNATURE", sign); | |||||
req.addHeader("X-BG-HMAC-ALGORITHM", "hmac-sha256"); | |||||
req.addHeader("X-BG-HMAC-ACCESS-KEY", accessKey); | |||||
req.addHeader("X-BG-DATE-TIME", date); | |||||
req.addHeader("Content-Type", "application/json"); | |||||
// 设置HTTP请求体 | |||||
HttpEntity entity = new ByteArrayEntity(stream, ContentType | |||||
.create(ContentType.APPLICATION_JSON.getMimeType(), "UTF-8")); | |||||
req.setEntity(entity); | |||||
// 执行请求 | |||||
HttpClientBuilder httpClientBuilder = HttpClientBuilder.create(); | |||||
CloseableHttpClient cli = httpClientBuilder.build(); | |||||
HttpResponse res = cli.execute(req); | |||||
int statusCode = res.getStatusLine().getStatusCode(); | |||||
System.out.println(statusCode); | |||||
if (200 != statusCode) { | |||||
System.out.println(statusCode); | |||||
} | |||||
// 获取响应 | |||||
InputStream in = res.getEntity().getContent(); | |||||
byte[] resp = readStream(in); | |||||
String strRes = new String(resp, "UTF-8"); | |||||
System.out.println(strRes); | |||||
cli.close(); | |||||
return strRes; | |||||
} | |||||
private static String sign(byte[] stream) | |||||
throws Exception { | |||||
// 获取消息验证码类的实例,算法选择"HmacSHA256" | |||||
Mac mac = Mac.getInstance("HmacSHA256"); | |||||
// 获取安全密钥 | |||||
Key secKey = new SecretKeySpec( | |||||
ProjectSecret.getBytes("UTF-8"), | |||||
mac.getAlgorithm()); | |||||
// 初始化 | |||||
mac.init(secKey); | |||||
// 获得签名 | |||||
byte[] sign = mac.doFinal(stream); | |||||
// 将byte[]格式的签名用binary编码转化为字符串返回 | |||||
return binaryEncode(sign); | |||||
} | |||||
private static String sign1(byte[] stream) | |||||
throws Exception { | |||||
// 获取消息验证码类的实例,算法选择"HmacSHA256" | |||||
Mac mac = Mac.getInstance("HmacSHA256"); | |||||
// 获取安全密钥 | |||||
Key secKey = new SecretKeySpec( | |||||
secretKey.getBytes("UTF-8"), | |||||
mac.getAlgorithm()); | |||||
// 初始化 | |||||
mac.init(secKey); | |||||
// 获得签名 | |||||
byte[] sign = mac.doFinal(stream); | |||||
// 将byte[]格式的签名用binary编码转化为字符串返回 | |||||
return binaryEncode(sign); | |||||
} | |||||
public static String binaryEncode(byte[] data) { | |||||
final char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', | |||||
'9', 'a', 'b', 'c', 'd', 'e', 'f'}; | |||||
StringBuilder builder = new StringBuilder(); | |||||
for (byte i : data) { | |||||
builder.append(hexDigits[i >>> 4 & 0xf]); | |||||
builder.append(hexDigits[i & 0xf]); | |||||
} | |||||
return builder.toString(); | |||||
} | |||||
public static byte[] readStream(InputStream in) throws IOException { | |||||
ByteArrayOutputStream output = new ByteArrayOutputStream(); | |||||
byte[] buffer = new byte[1024 * 10]; | |||||
try { | |||||
int n = 0; | |||||
while ((n = in.read(buffer)) != -1) { | |||||
output.write(buffer, 0, n); | |||||
} | |||||
return output.toByteArray(); | |||||
} finally { | |||||
in.close(); | |||||
output.close(); | |||||
} | |||||
} | |||||
/** | |||||
* Description: 将pdf文件转换为Base64编码 | |||||
* <p> | |||||
* // * @param 要转的的pdf文件 | |||||
* | |||||
* @Author fuyuwei | |||||
* Create Date: 2015年8月3日 下午9:52:30 | |||||
*/ | |||||
public static String PDFToBase64(File file) { | |||||
BASE64Encoder encoder = new BASE64Encoder(); | |||||
FileInputStream fin = null; | |||||
BufferedInputStream bin = null; | |||||
ByteArrayOutputStream baos = null; | |||||
BufferedOutputStream bout = null; | |||||
try { | |||||
fin = new FileInputStream(file); | |||||
bin = new BufferedInputStream(fin); | |||||
baos = new ByteArrayOutputStream(); | |||||
bout = new BufferedOutputStream(baos); | |||||
byte[] buffer = new byte[1024]; | |||||
int len = bin.read(buffer); | |||||
while (len != -1) { | |||||
bout.write(buffer, 0, len); | |||||
len = bin.read(buffer); | |||||
} | |||||
//刷新此输出流并强制写出所有缓冲的输出字节 | |||||
bout.flush(); | |||||
byte[] bytes = baos.toByteArray(); | |||||
return Base64.encode(bytes); | |||||
//return encoder.encodeBuffer(bytes); | |||||
} catch (FileNotFoundException e) { | |||||
e.printStackTrace(); | |||||
} catch (IOException e) { | |||||
e.printStackTrace(); | |||||
} finally { | |||||
try { | |||||
fin.close(); | |||||
bin.close(); | |||||
bout.close(); | |||||
} catch (IOException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
} | |||||
return null; | |||||
} | |||||
/** | |||||
* Description: 将base64编码内容转换为Pdf | |||||
* <p> | |||||
* // * @param base64编码内容,文件的存储路径(含文件名) | |||||
* | |||||
* @Author fuyuwei | |||||
* Create Date: 2015年7月30日 上午9:40:23 | |||||
*/ | |||||
public static void base64StringToPdf(String base64Content, String filePath) { | |||||
BASE64Decoder decoder = new BASE64Decoder(); | |||||
BufferedInputStream bis = null; | |||||
FileOutputStream fos = null; | |||||
BufferedOutputStream bos = null; | |||||
try { | |||||
byte[] bytes = decoder.decodeBuffer(base64Content);//base64编码内容转换为字节数组 | |||||
ByteArrayInputStream byteInputStream = new ByteArrayInputStream(bytes); | |||||
bis = new BufferedInputStream(byteInputStream); | |||||
File file = new File(filePath); | |||||
File path = file.getParentFile(); | |||||
if (!path.exists()) { | |||||
path.mkdirs(); | |||||
} | |||||
fos = new FileOutputStream(file); | |||||
bos = new BufferedOutputStream(fos); | |||||
byte[] buffer = new byte[1024]; | |||||
int length = bis.read(buffer); | |||||
while (length != -1) { | |||||
bos.write(buffer, 0, length); | |||||
length = bis.read(buffer); | |||||
} | |||||
bos.flush(); | |||||
} catch (Exception e) { | |||||
e.printStackTrace(); | |||||
} finally { | |||||
//closeStream(bis, fos, bos); | |||||
} | |||||
} | |||||
private static String getCanonicalQueryString(String query) { | |||||
if (query == null || query.trim().length() == 0) { | |||||
return ""; | |||||
} | |||||
List<Pair<String, String>> queryParamList = new ArrayList<>(); | |||||
String[] params = query.split("&"); | |||||
for (String param : params) { | |||||
int eqIndex = param.indexOf("="); | |||||
String key = param.substring(0, eqIndex); | |||||
String value = param.substring(eqIndex + 1); | |||||
Pair<String, String> pair = new Pair<String, String>(key, value); | |||||
queryParamList.add(pair); | |||||
} | |||||
List<Pair<String, String>> sortedParamList = queryParamList.stream().sorted(Comparator.comparing(param -> param.getKey() + "=" + Optional.ofNullable(param.getValue()).orElse(""))).collect(Collectors.toList()); | |||||
List<Pair<String, String>> encodeParamList = new ArrayList<>(); | |||||
sortedParamList.stream().forEach(param -> { | |||||
try { | |||||
String key = URLEncoder.encode(param.getKey(), "utf-8"); | |||||
String value = URLEncoder.encode(Optional.ofNullable(param.getValue()).orElse(""), "utf-8") | |||||
.replaceAll("\\%2B", "%20") | |||||
.replaceAll("\\+", "%20") | |||||
.replaceAll("\\%21", "!") | |||||
.replaceAll("\\%27", "'") | |||||
.replaceAll("\\%28", "(") | |||||
.replaceAll("\\%29", ")") | |||||
.replaceAll("\\%7E", "~") | |||||
.replaceAll("\\%25", "%"); | |||||
encodeParamList.add(new Pair<>(key, value)); | |||||
} catch (UnsupportedEncodingException e) { | |||||
throw new RuntimeException("encoding error"); | |||||
} | |||||
}); | |||||
StringBuilder queryParamString = new StringBuilder(64); | |||||
for (Pair<String, String> encodeParam : encodeParamList) { | |||||
queryParamString.append(encodeParam.getKey()).append("=").append(Optional.ofNullable(encodeParam.getValue()).orElse("")); | |||||
queryParamString.append("&"); | |||||
} | |||||
return queryParamString.substring(0, queryParamString.length() - 1); | |||||
} | |||||
} |
@@ -0,0 +1,20 @@ | |||||
package com.ningdatech.pmapi.signature.controller; | |||||
import org.springframework.web.bind.annotation.RequestMapping; | |||||
import org.springframework.stereotype.Controller; | |||||
/** | |||||
* <p> | |||||
* 前端控制器 | |||||
* </p> | |||||
* | |||||
* @author Lierbao | |||||
* @since 2023-02-10 | |||||
*/ | |||||
@Controller | |||||
@RequestMapping("/pmapi.signature/nd-company-signature") | |||||
public class NdCompanySignatureController { | |||||
} |
@@ -0,0 +1,38 @@ | |||||
package com.ningdatech.pmapi.signature.entity; | |||||
import com.baomidou.mybatisplus.annotation.TableName; | |||||
import io.swagger.annotations.ApiModel; | |||||
import lombok.Data; | |||||
import java.io.Serializable; | |||||
import java.time.LocalDateTime; | |||||
/** | |||||
* <p> | |||||
* | |||||
* </p> | |||||
* | |||||
* @author Lierbao | |||||
* @since 2023-02-10 | |||||
*/ | |||||
@TableName("nd_company_signature") | |||||
@Data | |||||
@ApiModel(value = "NdCompanySignature对象", description = "") | |||||
public class NdCompanySignature implements Serializable { | |||||
private static final long serialVersionUID = 1L; | |||||
private Long id; | |||||
private String sealSn; | |||||
private Long companyId; | |||||
private LocalDateTime createOn; | |||||
private Long createBy; | |||||
private LocalDateTime updateOn; | |||||
private Long updateBy; | |||||
} |
@@ -0,0 +1,16 @@ | |||||
package com.ningdatech.pmapi.signature.mapper; | |||||
import com.ningdatech.pmapi.signature.entity.NdCompanySignature; | |||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; | |||||
/** | |||||
* <p> | |||||
* Mapper 接口 | |||||
* </p> | |||||
* | |||||
* @author Lierbao | |||||
* @since 2023-02-10 | |||||
*/ | |||||
public interface NdCompanySignatureMapper extends BaseMapper<NdCompanySignature> { | |||||
} |
@@ -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.ningdatech.pmapi.signature.mapper.NdCompanySignatureMapper"> | |||||
</mapper> |
@@ -0,0 +1,16 @@ | |||||
package com.ningdatech.pmapi.signature.service; | |||||
import com.ningdatech.pmapi.signature.entity.NdCompanySignature; | |||||
import com.baomidou.mybatisplus.extension.service.IService; | |||||
/** | |||||
* <p> | |||||
* 服务类 | |||||
* </p> | |||||
* | |||||
* @author Lierbao | |||||
* @since 2023-02-10 | |||||
*/ | |||||
public interface INdCompanySignatureService extends IService<NdCompanySignature> { | |||||
} |
@@ -0,0 +1,20 @@ | |||||
package com.ningdatech.pmapi.signature.service.impl; | |||||
import com.ningdatech.pmapi.signature.entity.NdCompanySignature; | |||||
import com.ningdatech.pmapi.signature.mapper.NdCompanySignatureMapper; | |||||
import com.ningdatech.pmapi.signature.service.INdCompanySignatureService; | |||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | |||||
import org.springframework.stereotype.Service; | |||||
/** | |||||
* <p> | |||||
* 服务实现类 | |||||
* </p> | |||||
* | |||||
* @author Lierbao | |||||
* @since 2023-02-10 | |||||
*/ | |||||
@Service | |||||
public class NdCompanySignatureServiceImpl extends ServiceImpl<NdCompanySignatureMapper, NdCompanySignature> implements INdCompanySignatureService { | |||||
} |