Browse Source

退税服务协议签署

liangbo.huang 6 days ago
parent
commit
bb095f48e7

+ 49 - 0
trade-client/src/main/java/com/trade/client/config/CustomizeConfiguration.java

@@ -0,0 +1,49 @@
+package com.trade.client.config;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+
+import java.math.BigDecimal;
+import java.util.List;
+
+@Configuration
+@Getter
+@Setter
+public class CustomizeConfiguration {
+
+    // 系统网址
+    @Value("${trade.website:http://citp-finance.com}")
+    private String website;
+    // 退税服务费金额
+    @Value("${taxRebate.serviceFee.amount:2000}")
+    private BigDecimal taxRebateServiceFeeAmount;
+    // 退税服务费收款方名称
+    @Value("${taxRebate.serviceFee.payeeName:上海银颗科技服务有限公司}")
+    private String taxRebateServiceFeePayeeName;
+    // 退税服务费收款方证件类型
+    @Value("${taxRebate.serviceFee.payeeCertNo:91310000MA7M3DJM2P}")
+    private String taxRebateServiceFeePayeeCertNo;
+    // 退税服务费收款方账号
+    @Value("${taxRebate.serviceFee.payeeName:635973777}")
+    private String taxRebateServiceFeePayeeAccountNo;
+    // 退税服务费收款方开户行名称
+    @Value("${taxRebate.serviceFee.payeeName:中国民生银行股份有限公司上海曹杨支行}")
+    private String taxRebateServiceFeePayeeBankName;
+    // 退税服务联系人
+    @Value("${taxRebate.serviceFee.contactPerson:吴钧}")
+    private String taxRebateServiceFeeContactPerson;
+    // 退税服务联系电话
+    @Value("${taxRebate.serviceFee.contactPhone:021-61677022}")
+    private String taxRebateServiceFeeContactPhone;
+    // 退税服务联系邮箱
+    @Value("${taxRebate.serviceFee.contactEmail:jack.wu@changan-inkasso.com}")
+    private String taxRebateServiceFeeContactEmail;
+    // 退税服务联系地址
+    @Value("${taxRebate.serviceFee.contactAddress:上海市普陀区铜川路699弄2号中海中心A座1901室}")
+    private String taxRebateServiceFeeContactAddress;
+    // 自动签署的企业名单(企业社会统一信用代码,逗号分隔)
+    @Value("#{'${esign.autoSignList}'.split(',')}")
+    private List<String> autoSignEnterpriseCertNoList;
+}

+ 119 - 47
trade-client/src/main/java/com/trade/client/enterprise/customer/service/impl/EnterpriseServiceImpl.java

@@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.collection.CollectionUtil;
 import cn.hutool.core.date.LocalDateTimeUtil;
 import cn.hutool.core.util.StrUtil;
+import com.trade.client.config.CustomizeConfiguration;
 import com.trade.client.enterprise.customer.constant.CustConstant;
 import com.trade.client.enterprise.customer.domain.CustomerUser;
 import com.trade.client.enterprise.customer.domain.model.LoginUserInfo;
@@ -15,10 +16,7 @@ import com.trade.client.security.utils.UserUtils;
 import com.trade.common.constant.HttpStatus;
 import com.trade.common.exception.ServiceException;
 import com.trade.common.exception.ValidatorException;
-import com.trade.common.utils.ConstantUtil;
-import com.trade.common.utils.DateUtils;
-import com.trade.common.utils.LoggerUtil;
-import com.trade.common.utils.StringUtils;
+import com.trade.common.utils.*;
 import com.trade.common.utils.bean.Builder;
 import com.trade.common.validate.ValidatorGroup;
 import com.trade.common.validate.ValidatorUtil;
@@ -53,7 +51,6 @@ import com.trade.service.trade.salescontract.domain.ContractFile;
 import com.trade.service.trade.salescontract.service.ContractFileService;
 import org.jetbrains.annotations.NotNull;
 import org.slf4j.Logger;
-import org.springframework.beans.factory.annotation.Value;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -73,16 +70,8 @@ import java.util.stream.Collectors;
 public class EnterpriseServiceImpl implements EnterpriseService {
 
     private static final Logger log = LoggerUtil.logger(LoggerUtil.LogFileNameEnum.SERVICES_LOG);
-    @Value("${trade.website}")
-    private String website;
-    @Value("${taxRebate.serviceFee.amount:0.00}")
-    private BigDecimal taxRebateServiceFeeAmount;
-    @Value("${taxRebate.serviceFee.payeeName:上海银颗科技服务有限公司}")
-    private String taxRebateServiceFeePayeeName;
-    @Value("${taxRebate.serviceFee.payeeName:635973777}")
-    private String taxRebateServiceFeePayeeAccountNo;
-    @Value("${taxRebate.serviceFee.payeeName:中国民生银行股份有限公司上海曹杨支行}")
-    private String taxRebateServiceFeePayeeBankName;
+    @Resource
+    private CustomizeConfiguration customizeConfiguration;
     @Resource
     private CustomerMessageService customerMessageService;
     @Resource
@@ -122,7 +111,8 @@ public class EnterpriseServiceImpl implements EnterpriseService {
         EnterpriseStatusDto enterpriseStatusDto = new EnterpriseStatusDto();
         enterpriseStatusDto.setCertificationStatus(DictConstants.CERTIFICATION_STATUS_UNSUBMITTED);
         enterpriseStatusDto.setShowAllFunctions(Boolean.FALSE);
-        Long customerUserId = UserUtils.getCustomerUserId();
+        LoginUserInfo loginUser = UserUtils.getLoginUser();
+        Long customerUserId = loginUser.getCustomerUserId();
         EnterpriseChangeRecord record = enterpriseChangeRecordBaseService.getLatestRecord(customerUserId, null);
         if (record != null) {
             enterpriseStatusDto.setCertificationStatus(record.getCertificationStatus());
@@ -130,7 +120,8 @@ public class EnterpriseServiceImpl implements EnterpriseService {
         Enterprise enterprise = enterpriseBaseService.getEnterpriseByCustomerId(customerUserId);
         enterpriseStatusDto.setShowAllFunctions(enterprise != null
                 && DictConstants.CERTIFICATION_STATUS_PASSED.equals(enterprise.getCertificationStatus()));
-        boolean validityPeriod = judgeTaxRebateServiceValidityPeriod(enterprise);
+        boolean validityPeriod = judgeTaxRebateServiceValidityPeriod(enterprise,
+                loginUser.getCustomerUser().getXtUid());
         enterpriseStatusDto.setShowTaxRebateApplyMenu(enterprise != null && getShowTaxRebateApplyMenu(enterprise));
         enterpriseStatusDto.setShowApplyTaxRebateBtn(
                 enterprise != null && !validityPeriod && getShowApplyTaxRebateBtn(enterprise));
@@ -162,7 +153,7 @@ public class EnterpriseServiceImpl implements EnterpriseService {
                 && DictConstants.EXPORT_TYPE_SELF.equals(enterprise.getExportType());
     }
 
-    private boolean judgeTaxRebateServiceValidityPeriod(Enterprise enterprise) {
+    private boolean judgeTaxRebateServiceValidityPeriod(Enterprise enterprise, String xtUid) {
         if (enterprise == null) {
             return false;
         }
@@ -184,6 +175,17 @@ public class EnterpriseServiceImpl implements EnterpriseService {
             long recordId = saveEnterpriseChangeRecord(enterpriseDto);
             enterprise.setChangeRecordId(recordId);
             enterpriseBaseService.updateById(enterprise);
+            UpdateEnterpriseRequest updateEnterpriseRequest = new UpdateEnterpriseRequest();
+            updateEnterpriseRequest.setSbqyuuid(enterprise.getXtEid());
+            updateEnterpriseRequest.setHgqyDm(enterprise.getCustomsEnterpriseCode());
+            updateEnterpriseRequest.setNsrmc(enterprise.getName());
+            updateEnterpriseRequest.setNsrsbh(enterprise.getTaxNo());
+            updateEnterpriseRequest.setDqcode(enterprise.getTaxAuthorityArea());
+            updateEnterpriseRequest.setCktsqylxDm(enterprise.getEnterpriseType());
+            updateEnterpriseRequest.setYhuuid1(xtUid);
+            updateEnterpriseRequest.setHstqysqbz(DictConstants.SYS_YES);
+            updateEnterpriseRequest.setTsfwxybz(DictConstants.SYS_NO);
+            xiaotuRequestService.updateEnterprise(updateEnterpriseRequest);
             return false;
         }
     }
@@ -266,7 +268,7 @@ public class EnterpriseServiceImpl implements EnterpriseService {
     private void signAuthFile(EnterpriseDto enterpriseDto) {
         EnterpriseRelatedPersonDto authorizedPerson = enterpriseDto.getContactPerson();
         EnterpriseRelatedPersonDto legalPerson = enterpriseDto.getLegalPerson();
-        ContractGenInputItem item = getContractGenInputItem(enterpriseDto, legalPerson, authorizedPerson);
+        ContractGenInputItem item = getAuthFileGenInputItem(enterpriseDto, legalPerson, authorizedPerson);
         ContractGenOutputItem contractGenOutput = contractService.generateSingleContract(item,
                 enterpriseDto.getCustomerId());
         if (contractGenOutput == null) {
@@ -281,8 +283,8 @@ public class EnterpriseServiceImpl implements EnterpriseService {
                 .with(BusinessRelateFile::setFileId, unsignedAuthFile).build();
         businessRelateFileBaseService.addBusinessRelateFiles(Collections.singletonList(authFile));
         // 构建签署参数,并签署授权书
-        ContractSignInput signInput = getContractSignInput(enterpriseDto.getName(), enterpriseDto.getCertNo(),
-                "跨境通-授权委托书", ContractConstant.SIGN_BIZ_TYPE_AUTHORIZATION_LETTER, legalPerson, unsignedAuthFile);
+        ContractSignInput signInput = getAuthFileSignInput(enterpriseDto.getName(), enterpriseDto.getCertNo(),
+                legalPerson, unsignedAuthFile);
         ContractSignOutput contractSignOutput = contractService.signContract(signInput);
         if (contractSignOutput == null || CollUtil.isEmpty(contractSignOutput.getItems())) {
             throw new ValidatorException(HttpStatus.ERROR, "授权书签署处理失败!");
@@ -304,8 +306,8 @@ public class EnterpriseServiceImpl implements EnterpriseService {
     }
 
     @NotNull
-    private ContractGenInputItem getContractGenInputItem(EnterpriseDto enterpriseDto,
-            EnterpriseRelatedPersonDto legalPerson, EnterpriseRelatedPersonDto authorizedPerson) {
+    private ContractGenInputItem getAuthFileGenInputItem(EnterpriseDto enterpriseDto,
+                                                         EnterpriseRelatedPersonDto legalPerson, EnterpriseRelatedPersonDto authorizedPerson) {
         ContractGenInputItem inputItem = new ContractGenInputItem();
         inputItem.setTemplateCode(FileTypeEnum.AUTHORIZATION_FILE.getCode());
         inputItem.setContractName("授权委托书-跨境通");
@@ -315,17 +317,17 @@ public class EnterpriseServiceImpl implements EnterpriseService {
         dataMap.put("authorizedPerson", authorizedPerson.getName());
         dataMap.put("authorizedCertNo", authorizedPerson.getPersonalCertNo());
         dataMap.put("authorizedMobile", authorizedPerson.getMobile());
-        dataMap.put("website", website);
+        dataMap.put("website", customizeConfiguration.getWebsite());
         inputItem.setParams(dataMap);
         return inputItem;
     }
 
     @NotNull
-    private ContractSignInput getContractSignInput(String enterpriseName, String EnterpriseCertNo, String bizScene,
-            String bizType, EnterpriseRelatedPersonDto legalPerson, Long fileId) {
+    private ContractSignInput getAuthFileSignInput(String enterpriseName, String EnterpriseCertNo,
+                                                   EnterpriseRelatedPersonDto legalPerson, Long fileId) {
         ContractSignInput signInput = new ContractSignInput();
-        signInput.setBizScene(bizScene);
-        signInput.setBizType(bizType);
+        signInput.setBizScene("跨境通-授权委托书");
+        signInput.setBizType(ContractConstant.SIGN_BIZ_TYPE_AUTHORIZATION_LETTER);
         ContractSignInfo contractSignInfo = new ContractSignInfo();
         contractSignInfo.setFileId(fileId);
         contractSignInfo.setFileType(FileTypeEnum.AUTHORIZATION_FILE.getCode());
@@ -384,18 +386,22 @@ public class EnterpriseServiceImpl implements EnterpriseService {
         if (legalPerson == null) {
             throw new ServiceException("企业法人信息不存在", HttpStatus.BAD_REQUEST);
         }
+        EnterpriseRelatedPerson contactPerson = enterpriseRelatedPersonBaseService
+                .getContactByChangeRecordId(enterprise.getChangeRecordId());
+        if (contactPerson == null) {
+            throw new ServiceException("企业联系人信息不存在", HttpStatus.BAD_REQUEST);
+        }
+        String taxRebateAgreementNo = serialNumberGenerator.generateTaxRebateAgreementNo(enterprise.getName());
         EnterpriseRelatedPersonDto legalPersonDto = transStruct.transDto2EnterpriseRelatedPerson(legalPerson);
         ContractGenInputItem inputItem = new ContractGenInputItem();
         inputItem.setTemplateCode(FileTypeEnum.TAX_REBATE_AGREEMENT.getCode());
-        inputItem.setContractName("退税服务协议");
-        Map<String, Object> dataMap = new HashMap<>();
-        dataMap.put("enterpriseName", enterprise.getName());
-        dataMap.put("legalPerson", legalPerson.getName());
+        inputItem.setContractName("技术服务合同(退税服务)");
+        Map<String, Object> dataMap = getTaxRebateAgreementParams(enterprise, contactPerson, taxRebateAgreementNo);
         inputItem.setParams(dataMap);
         ContractGenOutputItem contractGenOutput = contractService.generateSingleContract(inputItem,
                 enterprise.getCustomerId());
         if (contractGenOutput == null) {
-            throw new ValidatorException(HttpStatus.ERROR, "退税服务协议生成失败!");
+            throw new ValidatorException(HttpStatus.ERROR, "《技术服务合同(退税服务)》生成失败!");
         }
         // 保存未签署的授权书文件
         Long unsignedAuthFile = contractGenOutput.getFileId();
@@ -406,8 +412,8 @@ public class EnterpriseServiceImpl implements EnterpriseService {
                 .with(BusinessRelateFile::setFileId, unsignedAuthFile).build();
         businessRelateFileBaseService.addBusinessRelateFiles(Collections.singletonList(authFile));
         // 构建签署参数,并签署授权书
-        ContractSignInput signInput = getContractSignInput(enterprise.getName(), enterprise.getCertNo(), "退税服务协议",
-                ContractConstant.SIGN_BIZ_TYPE_TAX_REBATE_AGREEMENT, legalPersonDto, unsignedAuthFile);
+        ContractSignInput signInput = getTaxRebateAgreementSignInput(enterprise.getName(), enterprise.getCertNo(),
+                legalPersonDto, unsignedAuthFile);
         ContractSignOutput contractSignOutput = contractService.signContract(signInput);
         if (contractSignOutput == null || CollUtil.isEmpty(contractSignOutput.getItems())) {
             throw new ValidatorException(HttpStatus.ERROR, "退税服务协议签署处理失败!");
@@ -423,7 +429,6 @@ public class EnterpriseServiceImpl implements EnterpriseService {
         contractFile.setSignFlowId(contractSignOutput.getFlowId());
         contractFileService.save(contractFile);
         // 更新退税服务协议签署状态:签署中
-        String taxRebateAgreementNo = serialNumberGenerator.generateTaxRebateAgreementNo(enterprise.getName());
         enterpriseBaseService.lambdaUpdate().eq(Enterprise::getId, enterprise.getId())
                 .set(Enterprise::getTaxRebateAgreementNo, taxRebateAgreementNo)
                 .set(Enterprise::getTaxRebateAgreementSignStatus, DictConstants.CONTRACT_STATUS_SIGNING).update();
@@ -434,6 +439,69 @@ public class EnterpriseServiceImpl implements EnterpriseService {
                 .update();
     }
 
+    private Map<String, Object> getTaxRebateAgreementParams(Enterprise enterprise,
+            EnterpriseRelatedPerson contactPerson, String taxRebateAgreementNo) {
+        Map<String, Object> dataMap = new HashMap<>();
+        dataMap.put("partyAName", enterprise.getName());
+        dataMap.put("partyAAddress", StrUtil.isBlank(enterprise.getBusinessAddress()) ? enterprise.getRegisterAddress()
+                : enterprise.getBusinessAddress());
+        dataMap.put("partyAPhone", contactPerson.getMobile());
+        dataMap.put("partyAEmail", contactPerson.getEmail());
+        dataMap.put("partyAContactPerson", contactPerson.getName());
+        dataMap.put("payeeBankName", customizeConfiguration.getTaxRebateServiceFeePayeeBankName());
+        dataMap.put("payeeAccountNo", customizeConfiguration.getTaxRebateServiceFeePayeeAccountNo());
+        dataMap.put("partyBName", customizeConfiguration.getTaxRebateServiceFeePayeeName());
+        dataMap.put("partyBAddress", customizeConfiguration.getTaxRebateServiceFeeContactAddress());
+        dataMap.put("partyBPhone", customizeConfiguration.getTaxRebateServiceFeeContactPhone());
+        dataMap.put("partyBEmail", customizeConfiguration.getTaxRebateServiceFeeContactEmail());
+        dataMap.put("partyBContactPerson", customizeConfiguration.getTaxRebateServiceFeeContactPerson());
+        dataMap.put("website", customizeConfiguration.getWebsite());
+        dataMap.put("taxRebateAgreementNo", taxRebateAgreementNo);
+        dataMap.put("contractNo", taxRebateAgreementNo + "-0001");
+        dataMap.put("feeAmount", customizeConfiguration.getTaxRebateServiceFeeAmount().toPlainString() + "/年");
+        dataMap.put("feeAmountCn",
+                MoneyToCNFormatUtil.formatToCN(customizeConfiguration.getTaxRebateServiceFeeAmount().doubleValue()));
+        return dataMap;
+    }
+
+    @NotNull
+    private ContractSignInput getTaxRebateAgreementSignInput(String enterpriseName, String EnterpriseCertNo,
+            EnterpriseRelatedPersonDto legalPerson, Long fileId) {
+        ContractSignInput signInput = new ContractSignInput();
+        signInput.setBizScene("技术服务合同(退税服务)");
+        signInput.setBizType(ContractConstant.SIGN_BIZ_TYPE_TAX_REBATE_AGREEMENT);
+        ContractSignInfo contractSignInfo = new ContractSignInfo();
+        contractSignInfo.setFileId(fileId);
+        contractSignInfo.setFileType(FileTypeEnum.TAX_REBATE_AGREEMENT.getCode());
+        // 甲方签署
+        List<ContractSeal> sealInfoList = new ArrayList<>();
+        ContractSigner partyAsigner = new ContractSigner();
+        partyAsigner.setSigner(legalPerson.getName());
+        partyAsigner.setSignerIdNo(legalPerson.getPersonalCertNo());
+        partyAsigner.setSignerIdType(ESignConstant.CRED_PSN_CH_IDCARD);
+        partyAsigner.setMobile(legalPerson.getMobile());
+        ContractSeal partyASeal = new ContractSeal();
+        partyASeal.setSigner(partyAsigner);
+        partyASeal.setKeyword(ESignConstant.KEYWORD_PARTY_A);
+        partyASeal.setSealIdType(ESignConstant.CRED_ORG_USCC);
+        partyASeal.setSealName(enterpriseName);
+        partyASeal.setSealIdNo(EnterpriseCertNo);
+        partyASeal.setWithTime(true);
+        sealInfoList.add(partyASeal);
+        // 乙方签字(上海银颗科技服务有限公司)
+        ContractSeal partyBSeal = new ContractSeal();
+        partyBSeal.setAutoSign(true);
+        partyBSeal.setKeyword(ESignConstant.KEYWORD_PARTY_B);
+        partyBSeal.setSealIdType(ESignConstant.CRED_ORG_USCC);
+        partyBSeal.setSealName(customizeConfiguration.getTaxRebateServiceFeePayeeName());
+        partyBSeal.setSealIdNo(customizeConfiguration.getTaxRebateServiceFeePayeeCertNo());
+        partyBSeal.setWithTime(true);
+        sealInfoList.add(partyBSeal);
+        contractSignInfo.setSealInfoList(sealInfoList);
+        signInput.setSigneInfoList(Collections.singletonList(contractSignInfo));
+        return signInput;
+    }
+
     /**
      * 电子签署回调处理
      * 
@@ -516,14 +584,7 @@ public class EnterpriseServiceImpl implements EnterpriseService {
             // 发送退税服务费支付通知邮件
             sendTaxRebateServiceFeePayNotifyEmail(enterprise);
             // 生成“待支付退税服务费”记录
-            ServiceFeeDto serviceFeeDto = new ServiceFeeDto();
-            serviceFeeDto.setCustomerUserId(customerUser.getId());
-            serviceFeeDto.setPaymentAmount(taxRebateServiceFeeAmount);
-            serviceFeeDto.setPaymentCurrency("CNY");
-            serviceFeeDto.setPaymentDeadline(bizData.getSignTime().plusHours(72));
-            serviceFeeDto.setPayeeName(taxRebateServiceFeePayeeName);
-            serviceFeeDto.setContactFileId(signedFile2Biz.getFileId());
-            payableAccountsService.saveTaxRefundServiceFee(serviceFeeDto);
+            saveTaxRefundServiceFee(bizData, customerUser, signedFile2Biz.getFileId());
         }
         // 更新授权书签署状态:status
         enterpriseBaseService.lambdaUpdate().eq(Enterprise::getId, enterprise.getId())
@@ -539,12 +600,23 @@ public class EnterpriseServiceImpl implements EnterpriseService {
                 .update();
     }
 
+    private void saveTaxRefundServiceFee(SignCallback2Biz bizData, CustomerUser customerUser, Long contactFileId) {
+        ServiceFeeDto serviceFeeDto = new ServiceFeeDto();
+        serviceFeeDto.setCustomerUserId(customerUser.getId());
+        serviceFeeDto.setPaymentAmount(customizeConfiguration.getTaxRebateServiceFeeAmount());
+        serviceFeeDto.setPaymentCurrency("CNY");
+        serviceFeeDto.setPaymentDeadline(bizData.getSignTime().plusHours(72));
+        serviceFeeDto.setPayeeName(customizeConfiguration.getTaxRebateServiceFeePayeeName());
+        serviceFeeDto.setContactFileId(contactFileId);
+        payableAccountsService.saveTaxRefundServiceFee(serviceFeeDto);
+    }
+
     void sendTaxRebateServiceFeePayNotifyEmail(Enterprise enterprise) {
         Map<String, Object> variables = new HashMap<>();
         variables.put("enterpriseName", enterprise.getName());
-        variables.put("payeeName", taxRebateServiceFeePayeeName);
-        variables.put("payeeAccountNo", taxRebateServiceFeePayeeAccountNo);
-        variables.put("payeeBankName", taxRebateServiceFeePayeeBankName);
+        variables.put("payeeName", customizeConfiguration.getTaxRebateServiceFeePayeeName());
+        variables.put("payeeAccountNo", customizeConfiguration.getTaxRebateServiceFeePayeeAccountNo());
+        variables.put("payeeBankName", customizeConfiguration.getTaxRebateServiceFeePayeeBankName());
         variables.put("taxRebateAgreementNo", enterprise.getTaxRebateAgreementNo());
         // 发送邮件
         EnterpriseRelatedPerson contactPerson = enterpriseRelatedPersonBaseService

+ 195 - 0
trade-common/src/main/java/com/trade/common/utils/MoneyToCNFormatUtil.java

@@ -0,0 +1,195 @@
+package com.trade.common.utils;
+
+import cn.hutool.core.util.StrUtil;
+
+import java.text.DecimalFormat;
+
+public class MoneyToCNFormatUtil {
+
+    public static String ToBig(int num) {
+        String str[] = {
+                "壹", "贰", "叁", "肆", "伍", "陆", "柒", "捌", "玖", "拾"
+        };
+        return str[num - 1];
+    }
+
+    public static String formatToCN(double x) {
+        DecimalFormat format = new DecimalFormat("##.##");
+        format.setMinimumFractionDigits(2);
+        String str = format.format(x);
+        String s[] = str.split("\\.");
+        String temp = "";
+        int ling = 0;
+        int shu = 0;
+        int pos = 0;
+        for (int j = 0; j < s[0].length(); ++j) {
+            int num = s[0].charAt(j) - '0';
+            if (num == 0) {
+                ling++;
+                if (ling == s[0].length()) {
+                    temp = "零";
+                } else if (s[0].length() - j - 1 == 4) {
+                    if (shu == 1 && (s[0].length() - pos - 1) >= 5 && (s[0].length() - pos - 1) <= 7) {
+                        temp += "万";
+                    }
+                } else if (s[0].length() - j - 1 == 8) {
+                    if (shu == 1 && (s[0].length() - pos - 1) >= 9 && (s[0].length() - pos - 1) <= 11) {
+                        temp += "亿";
+                    }
+                }
+            } else {
+                shu++;
+                int flag = 0;
+                if (shu == 1) {
+                    ling = 0;
+                    pos = j;
+                }
+                if (shu == 2) {
+                    flag = 1;
+                    if (ling > 0) {
+                        temp += "零";
+                    }
+                    shu = 1;
+                    pos = j;
+                    ling = 0;
+                }
+                if (s[0].length() - j - 1 == 11) {
+                    temp += ToBig(num) + "仟";
+                } else if (s[0].length() - j - 1 == 10) {
+                    temp += ToBig(num) + "佰";
+                } else if (s[0].length() - j - 1 == 9) {
+                    if (num == 1 && flag != 1)
+                        temp += "拾";
+                    else temp += ToBig(num) + "拾";
+                } else if (s[0].length() - j - 1 == 8) {
+                    temp += ToBig(num) + "亿";
+                } else if (s[0].length() - j - 1 == 7) {
+                    temp += ToBig(num) + "仟";
+                } else if (s[0].length() - j - 1 == 6) {
+                    temp += ToBig(num) + "佰";
+                } else if (s[0].length() - j - 1 == 5) {
+                    if (num == 1 && flag != 1)
+                        temp += "拾";
+                    else temp += ToBig(num) + "拾";
+                } else if (s[0].length() - j - 1 == 4) {
+                    temp += ToBig(num) + "万";
+                } else if (s[0].length() - j - 1 == 3) {
+                    temp += ToBig(num) + "仟";
+                } else if (s[0].length() - j - 1 == 2) {
+                    temp += ToBig(num) + "佰";
+                } else if (s[0].length() - j - 1 == 1) {
+                    if (num == 1 && flag != 1)
+                        temp += "拾";
+                    else temp += ToBig(num) + "拾";
+                } else {
+                    temp += ToBig(num);
+                }
+            }
+            // System.out.println(temp);
+        }
+        temp += "元";
+        for (int j = 0; j < s[1].length(); ++j) {
+            int num = s[1].charAt(j) - '0';
+            if (j == 0) {
+                if (num != 0)
+                    temp += ToBig(num) + "角";
+                else if (num == 0 && 1 < s[1].length() && s[1].charAt(1) != '0') {
+                    temp += "零";
+                }
+            } else if (j == 1) {
+                if (num != 0)
+                    temp += ToBig(num) + "分";
+            }
+        }
+        if (StrUtil.isNotEmpty(temp)) {
+            String endStr = temp.substring(temp.length() - 1);
+            if (endStr.equals("元")) {
+                temp += "整";
+            }
+        }
+        return temp;
+    }
+
+    /**
+     * 金额转大写(不带元和整,忽略小数)
+     * 
+     * @param x 金额
+     * @return 金额转大写
+     */
+    public static String formatToCN2(double x) {
+        DecimalFormat format = new DecimalFormat("##.##");
+        format.setMinimumFractionDigits(2);
+        String str = format.format(x);
+        String[] s = str.split("\\.");
+        StringBuilder temp = new StringBuilder();
+        int ling = 0;
+        int shu = 0;
+        int pos = 0;
+        for (int j = 0; j < s[0].length(); ++j) {
+            int num = s[0].charAt(j) - '0';
+            if (num == 0) {
+                ling++;
+                if (ling == s[0].length()) {
+                    temp = new StringBuilder("零");
+                } else if (s[0].length() - j - 1 == 4) {
+                    if (shu == 1 && (s[0].length() - pos - 1) >= 5 && (s[0].length() - pos - 1) <= 7) {
+                        temp.append("万");
+                    }
+                } else if (s[0].length() - j - 1 == 8) {
+                    if (shu == 1 && (s[0].length() - pos - 1) >= 9 && (s[0].length() - pos - 1) <= 11) {
+                        temp.append("亿");
+                    }
+                }
+            } else {
+                shu++;
+                int flag = 0;
+                if (shu == 1) {
+                    ling = 0;
+                    pos = j;
+                }
+                if (shu == 2) {
+                    flag = 1;
+                    if (ling > 0) {
+                        temp.append("零");
+                    }
+                    shu = 1;
+                    pos = j;
+                    ling = 0;
+                }
+                if (s[0].length() - j - 1 == 11) {
+                    temp.append(ToBig(num)).append("仟");
+                } else if (s[0].length() - j - 1 == 10) {
+                    temp.append(ToBig(num)).append("佰");
+                } else if (s[0].length() - j - 1 == 9) {
+                    if (num == 1 && flag != 1)
+                        temp.append("拾");
+                    else temp.append(ToBig(num)).append("拾");
+                } else if (s[0].length() - j - 1 == 8) {
+                    temp.append(ToBig(num)).append("亿");
+                } else if (s[0].length() - j - 1 == 7) {
+                    temp.append(ToBig(num)).append("仟");
+                } else if (s[0].length() - j - 1 == 6) {
+                    temp.append(ToBig(num)).append("佰");
+                } else if (s[0].length() - j - 1 == 5) {
+                    if (num == 1 && flag != 1)
+                        temp.append("拾");
+                    else temp.append(ToBig(num)).append("拾");
+                } else if (s[0].length() - j - 1 == 4) {
+                    temp.append(ToBig(num)).append("万");
+                } else if (s[0].length() - j - 1 == 3) {
+                    temp.append(ToBig(num)).append("仟");
+                } else if (s[0].length() - j - 1 == 2) {
+                    temp.append(ToBig(num)).append("佰");
+                } else if (s[0].length() - j - 1 == 1) {
+                    if (num == 1 && flag != 1)
+                        temp.append("拾");
+                    else temp.append(ToBig(num)).append("拾");
+                } else {
+                    temp.append(ToBig(num));
+                }
+            }
+            // System.out.println(temp);
+        }
+        return temp.toString();
+    }
+}

+ 4 - 0
trade-service/src/main/resources/data.init/v1.1/20241022.sql

@@ -196,3 +196,7 @@ CREATE TABLE `trading_platform_i18n`
   CHARACTER SET = utf8mb4
   COLLATE = utf8mb4_general_ci
   ROW_FORMAT = Dynamic;
+
+INSERT INTO `s_file_template` (`template_code`, `file_type`, `default_name`, `src_path`, `dest_dir`, `deleted`)
+VALUES ('taxRebateAgreement', 'taxRebateAgreement', '技术服务合同(退税服务)',
+        '/data/contract_template/技术服务合同(退税服务).docx', 'trade-user_document', 0);