迁移部分内联sql

This commit is contained in:
2026-07-15 09:07:38 +08:00
parent a8b2c05bd8
commit 752fba0582
5 changed files with 74 additions and 662 deletions
@@ -29,7 +29,6 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.ArrayList;
@@ -221,7 +220,7 @@ abstract class ContractLaunchSealPositionSupport {
}
boolean canManage = authManager().isUserCanAccessSys(currentUser.getId(), SysEnum.MANAGE);
boolean canBusiness = authManager().isUserCanAccessSys(currentUser.getId(), SysEnum.BUSINESS);
String currentOrgId = currentUser.getSysOrgEntity() == null ? null : trim(currentUser.getSysOrgEntity().getId());
String currentOrgId = trim(orgIdAsString(currentUser));
String currentAccount = trim(currentUser.getUsername());
String currentMobile = trim(currentUser.getMobilePhone());
Set<Long> partyIds = new LinkedHashSet<>();
@@ -369,6 +368,13 @@ abstract class ContractLaunchSealPositionSupport {
return isBlank(value) ? defaultValue : value;
}
protected String orgIdAsString(SysUserEntity user) {
if (user == null || user.getSysOrgEntity() == null || user.getSysOrgEntity().getId() == null) {
return null;
}
return String.valueOf(user.getSysOrgEntity().getId());
}
protected String trim(String value) {
return value == null ? null : value.trim();
}
@@ -489,60 +495,21 @@ abstract class ContractLaunchSealPositionSupport {
};
}
protected ContractLaunchMapper contractLaunchMapper() {
return readField("contractLaunchMapper", ContractLaunchMapper.class);
}
protected abstract ContractLaunchMapper contractLaunchMapper();
protected AdminSecurityManage adminSecurityManage() {
return readField("adminSecurityManage", AdminSecurityManage.class);
}
protected abstract AdminSecurityManage adminSecurityManage();
protected AuthManager authManager() {
return readField("authManager", AuthManager.class);
}
protected abstract AuthManager authManager();
protected SecurityManager securityManager() {
return readField("securityManager", SecurityManager.class);
}
protected abstract SecurityManager securityManager();
protected LocalFileService localFileService() {
return readField("localFileService", LocalFileService.class);
}
protected abstract LocalFileService localFileService();
protected SealTokenService sealTokenService() {
return readField("sealTokenService", SealTokenService.class);
}
protected abstract SealTokenService sealTokenService();
protected SealConfig sealConfig() {
return readField("sealConfig", SealConfig.class);
}
protected abstract SealConfig sealConfig();
protected PartnerManageService partnerManageService() {
return readField("partnerManageService", PartnerManageService.class);
}
protected <T> T readField(String fieldName, Class<T> type) {
try {
Field field = findField(getClass(), fieldName);
field.setAccessible(true);
Object value = field.get(this);
return type.cast(value);
} catch (Exception ex) {
throw new IllegalStateException("读取字段失败: " + fieldName, ex);
}
}
private Field findField(Class<?> clazz, String fieldName) throws NoSuchFieldException {
Class<?> current = clazz;
while (current != null) {
try {
return current.getDeclaredField(fieldName);
} catch (NoSuchFieldException ignored) {
current = current.getSuperclass();
}
}
throw new NoSuchFieldException(fieldName);
}
protected abstract PartnerManageService partnerManageService();
protected record SealPreviewData(String contractId, Integer imageWidth, Integer imageHeight, List<String> pdfToImageList) {
}
@@ -1,11 +1,5 @@
package com.nbport.zgwl.fiance.contractlaunch.service;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.nbport.zgwl.fiance.auth.AuthManager;
import com.nbport.zgwl.fiance.auth.SecurityManager;
import com.nbport.zgwl.fiance.auth.SysEnum;
import com.nbport.zgwl.fiance.common.PageResult;
import com.nbport.zgwl.fiance.contractlaunch.dto.ContractLaunchApproveDto;
import com.nbport.zgwl.fiance.contractlaunch.dto.ContractLaunchArchiveDto;
@@ -13,665 +7,71 @@ import com.nbport.zgwl.fiance.contractlaunch.dto.ContractLaunchCollectSaveDto;
import com.nbport.zgwl.fiance.contractlaunch.dto.ContractLaunchDto;
import com.nbport.zgwl.fiance.contractlaunch.dto.ContractLaunchLawCallbackDto;
import com.nbport.zgwl.fiance.contractlaunch.dto.ContractLaunchLawCallbackSampleDto;
import com.nbport.zgwl.fiance.contractlaunch.dto.ContractLaunchPartyDto;
import com.nbport.zgwl.fiance.contractlaunch.dto.ContractLaunchQueryDto;
import com.nbport.zgwl.fiance.contractlaunch.dto.ContractLaunchSealDto;
import com.nbport.zgwl.fiance.contractlaunch.dto.ContractLaunchSealPositionBatchStatusDto;
import com.nbport.zgwl.fiance.contractlaunch.dto.ContractLaunchSealPositionCheckResultDto;
import com.nbport.zgwl.fiance.contractlaunch.dto.ContractLaunchSealPositionDto;
import com.nbport.zgwl.fiance.contractlaunch.dto.ContractLaunchSealPositionPageDto;
import com.nbport.zgwl.fiance.contractlaunch.dto.ContractLaunchSealPositionSaveDto;
import com.nbport.zgwl.fiance.contractlaunch.mapper.ContractLaunchMapper;
import com.nbport.zgwl.fiance.contractlaunch.utils.ContractLaunchConstants;
import com.nbport.zgwl.fiance.entity.SysUserEntity;
import com.nbport.zgwl.fiance.exception.ServiceException;
import com.nbport.zgwl.fiance.partner.dto.PartnerManageDto;
import com.nbport.zgwl.fiance.partner.service.PartnerManageService;
import com.nbport.zgwl.fiance.seal.config.SealConfig;
import com.nbport.zgwl.fiance.seal.service.SealTokenService;
import com.nbport.zgwl.fiance.seal.utils.SealHttpClient;
import com.nbport.zgwl.fiance.service.LocalFileService;
import com.nbport.zgwl.fiance.utils.AdminSecurityManage;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
public interface ContractLaunchService {
/** 分页查询合同列表 */
PageResult<ContractLaunchDto> queryPage(ContractLaunchQueryDto queryDto);
/** 查询合同详情(含合同方/文件/履行计划/日志) */
ContractLaunchDto getDetail(Long id);
/** 创建合同草稿 */
ContractLaunchDto createDraft(ContractLaunchDto contract);
/** 编辑合同草稿 */
ContractLaunchDto updateDraft(ContractLaunchDto contract);
/** 复制合同并生成新的草稿 */
ContractLaunchDto copyDraft(Long id);
/** 基于现有合同发起变更/附加合同草稿 */
ContractLaunchDto createChangeDraft(Long id);
/** 提交法务审批(调用结算平台 pushContract 接口) */
ContractLaunchDto submitToLaw(Long id);
/** 模拟审批通过(测试按钮,TODO:替换为真实法务回调) */
ContractLaunchDto mockApprove(Long id, ContractLaunchApproveDto approveDto);
/** 模拟审批驳回(测试按钮,TODO:替换为真实法务回调) */
ContractLaunchDto mockReject(Long id, ContractLaunchApproveDto approveDto);
/** 获取法务审批回调样例(用于本地联调和前端展示) */
ContractLaunchLawCallbackSampleDto buildLawApproveCallbackSample(Long id);
/** 接收法务审批回调(处理审批结果,更新合同状态) */
ContractLaunchDto handleLawApproveCallback(ContractLaunchLawCallbackDto callbackData);
/** 回写签章信息(签署发起时调用,记录 sealContractId */
ContractLaunchDto saveSealInfo(Long id, ContractLaunchSealDto sealDto);
/** 签署完成回调(回写签署文件路径,状态变更为待采集) */
ContractLaunchDto markSealCompleted(Long id, ContractLaunchSealDto sealDto);
/** 保存采集信息(用印+签订信息),用于采集弹窗保存草稿 */
ContractLaunchDto saveCollectInfo(Long id, ContractLaunchCollectSaveDto collectDto);
/** 获取相对方签署确认状态 Map */
Map<String, Object> getCounterpartyConfirmMap(Long id);
/** 获取相对方签署确认状态(按权限过滤:manage 全量,business 只看自己) */
Map<String, Object> getCounterpartyConfirmFiltered(Long id);
/** 相对方确认已签署完成 */
Map<String, Object> confirmCounterparty(Long id, Long partyId);
/** 初始化合同签章位配置所需的签章平台预览 */
ContractLaunchSealPositionPageDto initSealPosition(Long id);
/** 查询合同签章位与预览信息 */
ContractLaunchSealPositionPageDto getSealPositionPage(Long id);
/** 保存合同签章位配置 */
ContractLaunchSealPositionPageDto saveSealPositions(Long id, ContractLaunchSealPositionSaveDto saveDto);
/** 批量更新签章位状态 */
ContractLaunchSealPositionPageDto batchUpdateSealPositionStatus(Long id, ContractLaunchSealPositionBatchStatusDto batchDto);
/** 校验签章位是否已全部签署 */
ContractLaunchSealPositionCheckResultDto checkSealPositions(Long id, Long partyId);
/** 处理签章平台预盖章回调 */
void handleSealPresignCallback(Map<String, Object> callbackData);
/** 上传法务水印合同文件(当审批回调未带回水印文件时,手动上传代替) */
ContractLaunchDto uploadWatermarkFile(Long id, MultipartFile file);
/** 模拟合同采集(调用数据采集 collectContract 接口,TODO:替换为真实调用) */
ContractLaunchDto mockCollect(Long id);
/** 合同归档(状态变更为已完成,TODO:同时推送归档到法务) */
ContractLaunchDto archive(Long id, ContractLaunchArchiveDto archiveDto);
/** 合同终止 */
ContractLaunchDto terminate(Long id, String terminateReason);
/** 删除草稿(仅 draft/rejected 状态允许) */
void deleteDraft(Long id);
default void assertSealPositionConfigAccess(ContractLaunchDto contract) {
if (contract == null || contract.getId() == null) {
throw new ServiceException("合同不存在");
}
if (!"1".equals(defaultIfBlank(contract.getIsElectron(), "1"))) {
throw new ServiceException("仅电子合同支持配置签章位");
}
SysUserEntity currentUser = adminSecurityManage().getUser();
if (currentUser == null) {
throw new ServiceException("当前用户未登录");
}
if (securityManager().isSuperAdmin()) {
return;
}
if (!authManager().isUserCanAccessSys(currentUser.getId(), SysEnum.MANAGE)) {
throw new ServiceException("仅管理端用户可配置签章位");
}
}
default void assertSealPositionViewAccess(ContractLaunchDto contract) {
if (contract == null || contract.getId() == null) {
throw new ServiceException("合同不存在");
}
if (!"1".equals(defaultIfBlank(contract.getIsElectron(), "1"))) {
throw new ServiceException("仅电子合同支持在线签署");
}
SysUserEntity currentUser = adminSecurityManage().getUser();
if (currentUser == null) {
throw new ServiceException("当前用户未登录");
}
if (securityManager().isSuperAdmin()) {
return;
}
boolean canManage = authManager().isUserCanAccessSys(currentUser.getId(), SysEnum.MANAGE);
boolean canBusiness = authManager().isUserCanAccessSys(currentUser.getId(), SysEnum.BUSINESS);
if (!canManage && !canBusiness) {
throw new ServiceException("当前用户无权访问在线签署");
}
}
default SealPreviewData startSealPreview(ContractLaunchDto contract) {
String filePath = trimText(contract == null ? null : contract.getContractTextFilePath());
if (isBlank(filePath)) {
throw new ServiceException("请先上传水印文件");
}
byte[] fileBytes = localFileService().readFileBytes(filePath);
String fileName = defaultIfBlank(trimText(contract.getContractTextFileName()), defaultIfBlank(trimText(contract.getContractName()), "合同正文") + ".pdf");
MultipartFile multipartFile = new SealPositionMultipartFile(fileBytes, fileName, resolveSealContentType(fileName, contract.getContractTextFileType()));
String response = SealHttpClient.postMultipart(
sealConfig().getBaseUrl() + "/saas/api/contract/start",
multipartFile,
buildSealPreviewContractName(contract, fileName),
"seal-position-init",
sealTokenService().getAccessToken()
);
JSONObject result = JSON.parseObject(response);
if (result == null || !result.getBooleanValue("isSuccess")) {
throw new ServiceException(result == null ? "初始化签署文件失败" : defaultIfBlank(result.getString("msg"), "初始化签署文件失败"));
}
SealPreviewData previewData = parseSealPreviewData(result.get("data"));
if (isBlank(previewData.contractId())) {
throw new ServiceException("签章平台未返回合同ID");
}
return previewData;
}
default SealPreviewData previewSealContract(String sealContractId, String cachedImageListJson) {
List<String> cachedImageList = parseSealImageListJson(cachedImageListJson);
if (isBlank(sealContractId)) {
return new SealPreviewData(null, 793, 1122, cachedImageList);
}
try {
JSONObject body = new JSONObject();
body.put("contractId", sealContractId);
String response = SealHttpClient.post(
sealConfig().getBaseUrl() + "/saas/api/contract/preview",
body.toJSONString(),
sealTokenService().getAccessToken(),
"application/json"
);
JSONObject result = JSON.parseObject(response);
if (result != null && result.getBooleanValue("isSuccess")) {
SealPreviewData previewData = parseSealPreviewData(result.get("data"));
if (!previewData.pdfToImageList().isEmpty()) {
return previewData;
}
}
} catch (Exception ex) {
if (cachedImageList.isEmpty()) {
throw new ServiceException("获取签章预览失败: " + ex.getMessage());
}
}
return new SealPreviewData(sealContractId, 793, 1122, cachedImageList);
}
default ContractLaunchSealPositionPageDto buildSealPositionPage(ContractLaunchDto contract, SealPreviewData previewData) {
ContractLaunchSealPositionPageDto pageDto = new ContractLaunchSealPositionPageDto();
pageDto.setContractId(contract.getId());
pageDto.setSealContractId(defaultIfBlank(contract.getSealContractId(), previewData == null ? null : previewData.contractId()));
pageDto.setSealPosConfigured(defaultIfBlank(contract.getSealPosConfigured(), ContractLaunchConstants.FLAG_NO));
pageDto.setImageWidth(previewData == null ? 793 : previewData.imageWidth());
pageDto.setImageHeight(previewData == null ? 1122 : previewData.imageHeight());
pageDto.setPdfToImageList(previewData == null ? new ArrayList<>() : previewData.pdfToImageList());
pageDto.setPositions(new ArrayList<>(contractLaunchMapper().selectSealPositionByContractId(contract.getId())));
List<Long> availablePartyIds = resolveAvailablePartyIds(contract, adminSecurityManage().getUser());
pageDto.setAvailablePartyIds(availablePartyIds);
pageDto.setPreferredPartyId(availablePartyIds.size() == 1 ? availablePartyIds.get(0) : null);
return pageDto;
}
default void validateSealPositionForSave(ContractLaunchSealPositionDto item, Map<Long, ContractLaunchPartyDto> partyMap) {
if (item == null) {
throw new ServiceException("签章位数据不能为空");
}
if (item.getPartyId() == null) {
throw new ServiceException("签章位必须绑定签署方");
}
if (partyMap == null || !partyMap.containsKey(item.getPartyId())) {
throw new ServiceException("签章位绑定的签署方不存在");
}
if (isBlank(item.getLabel())) {
throw new ServiceException("签章位标签不能为空");
}
if (item.getPageNum() == null || item.getPageNum() <= 0) {
throw new ServiceException("签章位页码必须大于0");
}
if (item.getX() == null || item.getY() == null || item.getWidth() == null || item.getHeight() == null) {
throw new ServiceException("签章位坐标不能为空");
}
if (item.getWidth() <= 0 || item.getHeight() <= 0) {
throw new ServiceException("签章位宽高必须大于0");
}
}
default String normalizeRequiredFlag(String required) {
String value = trimText(required);
if (value == null) {
return ContractLaunchConstants.FLAG_YES;
}
String normalized = value.toUpperCase(Locale.ROOT);
if ("N".equals(normalized) || "0".equals(normalized) || "FALSE".equals(normalized)) {
return ContractLaunchConstants.FLAG_NO;
}
return ContractLaunchConstants.FLAG_YES;
}
default Double roundCoordinate(Double value) {
if (value == null) {
return null;
}
return Math.round(value * 100D) / 100D;
}
default List<Long> resolveAvailablePartyIds(ContractLaunchDto contract, SysUserEntity currentUser) {
if (contract == null || contract.getPartyList() == null || contract.getPartyList().isEmpty() || currentUser == null) {
return new ArrayList<>();
}
if (securityManager().isSuperAdmin()) {
return contract.getPartyList().stream()
.map(ContractLaunchPartyDto::getId)
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
boolean canManage = authManager().isUserCanAccessSys(currentUser.getId(), SysEnum.MANAGE);
boolean canBusiness = authManager().isUserCanAccessSys(currentUser.getId(), SysEnum.BUSINESS);
String currentOrgId = currentUser.getSysOrgEntity() == null ? null : trimText(currentUser.getSysOrgEntity().getId());
String currentAccount = trimText(currentUser.getUsername());
String currentMobile = trimText(currentUser.getMobilePhone());
Set<Long> partyIds = new LinkedHashSet<>();
for (ContractLaunchPartyDto party : contract.getPartyList()) {
if (party == null || party.getId() == null) {
continue;
}
if (canManage && isOurParty(party) && Objects.equals(currentOrgId, trimText(party.getSubjectCode()))) {
partyIds.add(party.getId());
continue;
}
if (canBusiness && isOppositeParty(party) && isMatchedBusinessParty(party, currentOrgId, currentAccount, currentMobile)) {
partyIds.add(party.getId());
}
}
return new ArrayList<>(partyIds);
}
default Long resolveTargetPartyId(Long partyId, List<Long> availablePartyIds) {
if (partyId != null) {
if (availablePartyIds == null || availablePartyIds.isEmpty()) {
throw new ServiceException("当前用户未匹配到可签署方,请手动选择后重试");
}
if (!availablePartyIds.contains(partyId)) {
throw new ServiceException("当前用户不可操作该签署方");
}
return partyId;
}
if (availablePartyIds == null || availablePartyIds.isEmpty()) {
throw new ServiceException("当前用户未匹配到可签署方,请手动选择后重试");
}
if (availablePartyIds.size() > 1) {
throw new ServiceException("当前用户匹配到多个签署方,请手动选择后重试");
}
return availablePartyIds.get(0);
}
default void applySealPositionStatus(ContractLaunchSealPositionDto position,
ContractLaunchSealPositionBatchStatusDto batchDto,
ContractLaunchSealPositionBatchStatusDto.Item item,
SysUserEntity currentUser,
java.time.LocalDateTime now) {
Integer signedStatus = batchDto.getSignedStatus();
if (signedStatus == null) {
throw new ServiceException("签章位状态不能为空");
}
position.setUpdateBy(currentUser == null ? "system" : currentUser.getUsername());
position.setUpdateTime(now);
if (Objects.equals(signedStatus, ContractLaunchConstants.SEAL_POS_STATUS_EMPTY)) {
position.setSealId(null);
position.setSealName(null);
position.setRequestId(null);
position.setSignedByName(null);
position.setSignedById(null);
position.setSignedTime(null);
position.setSignedStatus(ContractLaunchConstants.SEAL_POS_STATUS_EMPTY);
return;
}
if (Objects.equals(signedStatus, ContractLaunchConstants.SEAL_POS_STATUS_SELECTED)) {
if (item == null || isBlank(item.getSealId())) {
throw new ServiceException("已选章状态必须传印章ID");
}
position.setSealId(item.getSealId());
position.setSealName(item.getSealName());
position.setRequestId(null);
position.setSignedByName(null);
position.setSignedById(null);
position.setSignedTime(null);
position.setSignedStatus(ContractLaunchConstants.SEAL_POS_STATUS_SELECTED);
return;
}
if (Objects.equals(signedStatus, ContractLaunchConstants.SEAL_POS_STATUS_SIGNING)) {
if (item != null && !isBlank(item.getSealId())) {
position.setSealId(item.getSealId());
}
if (item != null && !isBlank(item.getSealName())) {
position.setSealName(item.getSealName());
}
if (isBlank(position.getSealId())) {
throw new ServiceException("提交预盖章前请先选择印章");
}
if (isBlank(batchDto.getRequestId())) {
throw new ServiceException("二维码请求ID不能为空");
}
position.setRequestId(batchDto.getRequestId());
position.setSignedByName(null);
position.setSignedById(null);
position.setSignedTime(null);
position.setSignedStatus(ContractLaunchConstants.SEAL_POS_STATUS_SIGNING);
return;
}
if (Objects.equals(signedStatus, ContractLaunchConstants.SEAL_POS_STATUS_SIGNED)) {
if (item != null && !isBlank(item.getSealId())) {
position.setSealId(item.getSealId());
}
if (item != null && !isBlank(item.getSealName())) {
position.setSealName(item.getSealName());
}
if (!isBlank(batchDto.getRequestId())) {
position.setRequestId(batchDto.getRequestId());
}
position.setSignedByName(defaultIfBlank(batchDto.getSignedByName(), currentUser == null ? null : currentUser.getUsername()));
position.setSignedById(defaultIfBlank(batchDto.getSignedById(), currentUser == null ? null : String.valueOf(currentUser.getId())));
position.setSignedTime(now);
position.setSignedStatus(ContractLaunchConstants.SEAL_POS_STATUS_SIGNED);
return;
}
if (Objects.equals(signedStatus, ContractLaunchConstants.SEAL_POS_STATUS_FAILED)) {
position.setRequestId(null);
position.setSignedByName(null);
position.setSignedById(null);
position.setSignedTime(null);
position.setSignedStatus(ContractLaunchConstants.SEAL_POS_STATUS_FAILED);
return;
}
throw new ServiceException("不支持的签章位状态: " + signedStatus);
}
default boolean isSealPresignFailed(Map<String, Object> callbackData) {
String contractStatus = stringValue(callbackData == null ? null : callbackData.get("contractStatus"));
if (!isBlank(contractStatus)) {
if ("20".equals(contractStatus) || "2000".equals(contractStatus)) {
return false;
}
if ("0".equals(contractStatus) || contractStatus.startsWith("-")) {
return true;
}
}
Object successValue = callbackData == null ? null : (callbackData.containsKey("isSuccess") ? callbackData.get("isSuccess") : callbackData.get("success"));
if (successValue != null) {
return !Boolean.parseBoolean(String.valueOf(successValue));
}
String statusText = (defaultIfBlank(stringValue(callbackData == null ? null : callbackData.get("status")), "") + " "
+ defaultIfBlank(stringValue(callbackData == null ? null : callbackData.get("msg")), "")).toLowerCase(Locale.ROOT);
return statusText.contains("fail") || statusText.contains("cancel") || statusText.contains("timeout") || statusText.contains("reject");
}
default String stringValue(Object value) {
return value == null ? null : trimText(String.valueOf(value));
}
default boolean isBlank(String value) {
return value == null || value.isBlank();
}
default String defaultIfBlank(String value, String defaultValue) {
return isBlank(value) ? defaultValue : value;
}
private boolean isMatchedBusinessParty(ContractLaunchPartyDto party, String currentOrgId, String currentAccount, String currentMobile) {
if (Objects.equals(currentOrgId, trimText(party.getSubjectCode()))) {
return true;
}
if (party.getPartnerId() == null) {
return false;
}
try {
PartnerManageDto partner = partnerManageService().selectPartnerById(party.getPartnerId());
if (partner == null) {
return false;
}
if (partner.getLinkedOrgId() != null && Objects.equals(currentOrgId, String.valueOf(partner.getLinkedOrgId()))) {
return true;
}
String linkedUserAccount = trimText(partner.getLinkedUserAccount());
return !isBlank(linkedUserAccount) && (linkedUserAccount.equalsIgnoreCase(defaultIfBlank(currentAccount, ""))
|| linkedUserAccount.equalsIgnoreCase(defaultIfBlank(currentMobile, "")));
} catch (Exception ignored) {
return false;
}
}
private SealPreviewData parseSealPreviewData(Object dataObject) {
if (dataObject == null) {
return new SealPreviewData(null, 793, 1122, new ArrayList<>());
}
JSONObject data = dataObject instanceof JSONObject
? (JSONObject) dataObject
: JSON.parseObject(JSON.toJSONString(dataObject));
if (data == null) {
return new SealPreviewData(null, 793, 1122, new ArrayList<>());
}
List<String> imageList = new ArrayList<>();
Object imageObject = data.get("pdfToImageList");
if (imageObject instanceof JSONArray array) {
for (int i = 0; i < array.size(); i++) {
String item = stringValue(array.get(i));
if (!isBlank(item)) {
imageList.add(item);
}
}
} else if (imageObject instanceof List<?> list) {
for (Object item : list) {
String imageUrl = stringValue(item);
if (!isBlank(imageUrl)) {
imageList.add(imageUrl);
}
}
} else if (imageObject != null) {
imageList.addAll(parseSealImageListJson(String.valueOf(imageObject)));
}
Integer imageWidth = data.getInteger("imageWidth");
Integer imageHeight = data.getInteger("imageHeight");
return new SealPreviewData(
stringValue(data.get("contractId")),
imageWidth == null || imageWidth <= 0 ? 793 : imageWidth,
imageHeight == null || imageHeight <= 0 ? 1122 : imageHeight,
imageList
);
}
private List<String> parseSealImageListJson(String json) {
if (isBlank(json)) {
return new ArrayList<>();
}
try {
JSONArray array = JSON.parseArray(json);
List<String> imageList = new ArrayList<>();
for (int i = 0; i < array.size(); i++) {
String item = stringValue(array.get(i));
if (!isBlank(item)) {
imageList.add(item);
}
}
return imageList;
} catch (Exception ex) {
return new ArrayList<>();
}
}
private String buildSealPreviewContractName(ContractLaunchDto contract, String fileName) {
String value = defaultIfBlank(trimText(contract == null ? null : contract.getContractName()), trimText(fileName));
if (isBlank(value)) {
return "合同正文";
}
int index = value.lastIndexOf('.');
return index > 0 ? value.substring(0, index) : value;
}
private String resolveSealContentType(String fileName, String fileType) {
String suffix = trimText(fileType);
if (isBlank(suffix) && !isBlank(fileName) && fileName.contains(".")) {
suffix = fileName.substring(fileName.lastIndexOf('.') + 1);
}
suffix = defaultIfBlank(suffix, "pdf").toLowerCase(Locale.ROOT);
return switch (suffix) {
case "doc" -> "application/msword";
case "docx" -> "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
case "pdf" -> "application/pdf";
default -> "application/octet-stream";
};
}
private ContractLaunchMapper contractLaunchMapper() {
return readField("contractLaunchMapper", ContractLaunchMapper.class);
}
private AdminSecurityManage adminSecurityManage() {
return readField("adminSecurityManage", AdminSecurityManage.class);
}
private AuthManager authManager() {
return readField("authManager", AuthManager.class);
}
private SecurityManager securityManager() {
return readField("securityManager", SecurityManager.class);
}
private LocalFileService localFileService() {
return readField("localFileService", LocalFileService.class);
}
private SealTokenService sealTokenService() {
return readField("sealTokenService", SealTokenService.class);
}
private SealConfig sealConfig() {
return readField("sealConfig", SealConfig.class);
}
private PartnerManageService partnerManageService() {
return readField("partnerManageService", PartnerManageService.class);
}
private <T> T readField(String fieldName, Class<T> type) {
try {
Field field = findField(this.getClass(), fieldName);
field.setAccessible(true);
return type.cast(field.get(this));
} catch (Exception ex) {
throw new IllegalStateException("读取字段失败: " + fieldName, ex);
}
}
private Field findField(Class<?> type, String fieldName) throws NoSuchFieldException {
Class<?> current = type;
while (current != null) {
try {
return current.getDeclaredField(fieldName);
} catch (NoSuchFieldException ignored) {
current = current.getSuperclass();
}
}
throw new NoSuchFieldException(fieldName);
}
private boolean isOurParty(ContractLaunchPartyDto party) {
return party != null && "OUR".equalsIgnoreCase(trimText(party.getRoleCode()));
}
private boolean isOppositeParty(ContractLaunchPartyDto party) {
return party != null && "OPPOSITE".equalsIgnoreCase(trimText(party.getRoleCode()));
}
private String trimText(String value) {
return value == null ? null : value.trim();
}
class SealPositionMultipartFile implements MultipartFile {
private final byte[] content;
private final String originalFilename;
private final String contentType;
public SealPositionMultipartFile(byte[] content, String originalFilename, String contentType) {
this.content = content == null ? new byte[0] : content;
this.originalFilename = originalFilename;
this.contentType = contentType;
}
@Override
public String getName() {
return "file";
}
@Override
public String getOriginalFilename() {
return originalFilename;
}
@Override
public String getContentType() {
return contentType;
}
@Override
public boolean isEmpty() {
return content.length == 0;
}
@Override
public long getSize() {
return content.length;
}
@Override
public byte[] getBytes() {
return content;
}
@Override
public InputStream getInputStream() {
return new ByteArrayInputStream(content);
}
@Override
public void transferTo(File dest) throws IOException {
try (FileOutputStream outputStream = new FileOutputStream(dest)) {
outputStream.write(content);
}
}
}
}
@@ -82,7 +82,7 @@ import java.util.stream.Collectors;
@Slf4j
@Service
@RequiredArgsConstructor
public class ContractLaunchServiceImpl implements ContractLaunchService {
public class ContractLaunchServiceImpl extends ContractLaunchSealPositionSupport implements ContractLaunchService {
/** 法务接口要求的日期时间格式:yyyy-MM-dd HH:mm:ss */
private static final DateTimeFormatter LAW_DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
@@ -980,7 +980,7 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
? archiveDto.getArchiveTransferor()
: currentUser.getMobilePhone());
contract.setArchiveKeeperUnit(currentUser.getSysOrgEntity() == null ? contract.getArchiveKeeperUnit() : currentUser.getSysOrgEntity().getOrgName());
contract.setArchiveKeeperUnitCode(currentUser.getSysOrgEntity() == null ? contract.getArchiveKeeperUnitCode() : currentUser.getSysOrgEntity().getId());
contract.setArchiveKeeperUnitCode(currentUser.getSysOrgEntity() == null ? contract.getArchiveKeeperUnitCode() : orgIdAsString(currentUser));
contract.setStatus(ContractLaunchConstants.STATUS_COMPLETED);
contract.setUpdateBy(currentUser.getUsername());
contract.setUpdateTime(now);
@@ -1071,7 +1071,7 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
contract.setInitiator(currentUser.getUsername());
contract.setInitiatorDept(currentUser.getSysOrgEntity() == null ? "" : currentUser.getSysOrgEntity().getOrgName());
contract.setCompanyName(currentUser.getSysOrgEntity() == null ? "" : currentUser.getSysOrgEntity().getOrgName());
contract.setOrgId(currentUser.getSysOrgEntity() == null ? "" : currentUser.getSysOrgEntity().getId());
contract.setOrgId(defaultIfBlank(orgIdAsString(currentUser), ""));
contract.setCreatorPhone(currentUser.getMobilePhone());
contract.setCreateBy(currentUser.getUsername());
contract.setCreateTime(now);
@@ -1558,15 +1558,18 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
contract.setPartyList(normalized);
}
private boolean isOurParty(ContractLaunchPartyDto party) {
@Override
protected boolean isOurParty(ContractLaunchPartyDto party) {
return party != null && "OUR".equalsIgnoreCase(trim(party.getRoleCode()));
}
private boolean isOppositeParty(ContractLaunchPartyDto party) {
@Override
protected boolean isOppositeParty(ContractLaunchPartyDto party) {
return party != null && "OPPOSITE".equalsIgnoreCase(trim(party.getRoleCode()));
}
private boolean isSingleAgreement(ContractLaunchDto contract) {
@Override
protected boolean isSingleAgreement(ContractLaunchDto contract) {
String value = contract == null ? null : trim(contract.getIsSingleAgreement());
return "1".equals(value) || "Y".equalsIgnoreCase(value) || "true".equalsIgnoreCase(value);
}
@@ -1595,7 +1598,7 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
}
String currentOrgId = currentUser == null || currentUser.getSysOrgEntity() == null
? null
: trim(currentUser.getSysOrgEntity().getId());
: trim(orgIdAsString(currentUser));
return currentOrgId != null ? currentOrgId : trim(contract.getOrgId());
}
@@ -1605,7 +1608,7 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
}
String currentOrgId = currentUser == null || currentUser.getSysOrgEntity() == null
? null
: trim(currentUser.getSysOrgEntity().getId());
: trim(orgIdAsString(currentUser));
String currentOrgName = currentUser == null || currentUser.getSysOrgEntity() == null
? null
: trim(currentUser.getSysOrgEntity().getOrgName());
@@ -1695,7 +1698,7 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
}
String currentOrgId = trim(adminSecurityManage.getUser() == null || adminSecurityManage.getUser().getSysOrgEntity() == null
? null
: adminSecurityManage.getUser().getSysOrgEntity().getId());
: orgIdAsString(adminSecurityManage.getUser()));
if (currentOrgId != null && !currentOrgId.isBlank()) {
boolean containsCurrentOrg = contract.getPartyList().stream()
.filter(this::isOurParty)
@@ -2404,7 +2407,8 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
return null;
}
private String trim(String value) {
@Override
protected String trim(String value) {
return value == null ? null : value.trim();
}
@@ -2445,7 +2449,7 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
queryDto.setCurrentUserId(currentUser == null ? null : currentUser.getUsername());
queryDto.setCurrentOrgId(currentUser == null || currentUser.getSysOrgEntity() == null
? null
: currentUser.getSysOrgEntity().getId());
: orgIdAsString(currentUser));
queryDto.setCurrentDeptName(currentUser == null
? null
: (currentUser.getDeptName() == null || currentUser.getDeptName().isBlank()
@@ -2478,4 +2482,44 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
}
return null;
}
@Override
protected ContractLaunchMapper contractLaunchMapper() {
return contractLaunchMapper;
}
@Override
protected AdminSecurityManage adminSecurityManage() {
return adminSecurityManage;
}
@Override
protected AuthManager authManager() {
return authManager;
}
@Override
protected SecurityManager securityManager() {
return securityManager;
}
@Override
protected LocalFileService localFileService() {
return localFileService;
}
@Override
protected SealTokenService sealTokenService() {
return sealTokenService;
}
@Override
protected SealConfig sealConfig() {
return sealConfig;
}
@Override
protected PartnerManageService partnerManageService() {
return partnerManageService;
}
}
@@ -202,7 +202,7 @@ public class ContractTemplateServiceImpl implements ContractTemplateService {
SysUserEntity currentUser = adminSecurityManage.getUser();
String userOrgId = currentUser == null || currentUser.getSysOrgEntity() == null
? null
: currentUser.getSysOrgEntity().getId();
: String.valueOf(currentUser.getSysOrgEntity().getId());
if (userOrgId == null) {
return Collections.emptyList();
}
@@ -377,7 +377,8 @@ public class PartnerManageServiceImpl implements PartnerManageService {
if (currentUser == null || currentUser.getSysOrgEntity() == null) {
return null;
}
String orgId = currentUser.getSysOrgEntity().getId();
Object orgIdValue = currentUser.getSysOrgEntity().getId();
String orgId = orgIdValue == null ? null : String.valueOf(orgIdValue);
if (!StrUtilHelper.hasText(orgId)) {
return null;
}