杜洪波
2026-03-20 107e63ea3d1dd252841e934d6f483b0032e68493
系统租户申请代码提交
已添加1个文件
已修改4个文件
375 ■■■■ 文件已修改
src/main/java/com/product/saas/config/SaasCode.java 64 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/product/saas/config/SaasConst.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/product/saas/controller/TenantApplyController.java 23 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/product/saas/service/TenantApplyService.java 273 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/product/saas/service/idel/ITenantApplyService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/product/saas/config/SaasCode.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,64 @@
package com.product.saas.config;
import java.text.DecimalFormat;
import java.text.Format;
import com.product.common.enums.IEnum;
import com.product.common.enums.ModuleEnum;
import com.product.core.config.Global;
import com.product.util.BaseUtil;
public enum SaasCode implements IEnum{
    // ç§Ÿæˆ·ç”³è¯·
    TENANT_APPLY_VALID_UNIT_HAS_APPLY("租户单位已经用于申请", 1),
    TENANT_APPLY_VALID_PHONE_HAS_APPLY("租户手机号已经用于申请", 2),
    TENANT_APPLY_VALID_UNIT_AND_PHONE_HAS_APPLY("租户单位和手机号已经用于申请", 3),
    TENANT_APPLY_VALID_INFO_FAIL("租户申请信息验证失败:", 4),
    TENANT_AAPLY_INFO_GET_FAIL("租户申请信息请求失败:", 5),
    TENANT_AAPLY_INFO_SUBMIT_FAIL("租户申请信息提交失败:", 6),
    TENANT_AAPLY_INFO_FLOW_TASK_ERROR("租户申请信息流程数据不存在", 7),
    TENANT_AAPLY_INFO_CANCEL_FAIL("租户申请信息撤消失败:", 8),
    TENANT_APPLY_LICENSE_DATA_NO_EXIST("租户申请License数据不存在", 9),
    TENANT_APPLY_LICENSE_FILE_NO_EXIST("租户申请License文件不存在", 10),
    TENANT_APPLY_LICENSE_FILE_COPY_FAIL("租户申请License文件COPY失败", 11),
    // ç§Ÿæˆ·ä¿¡æ¯
    TENANT_INFO_GET_LIST_FAIL("租户信息列表查询失败", 12),
    ;
    private String text;
    private int value;
    private SaasCode(String text, int value) {
        this.text = text;
        this.value = value;
    }
    public String getText() {
        try {
            //使用正则匹配text中的特殊表达式以{&开头,&}结尾,获取到其中的内容
            String regex = "\\{&(.+?)&\\}";
            String result = this.text;
            if (this.text.matches(regex)) {
                result = this.text.replaceAll(regex, "$1");
            }
            String defaultValue = null;
            //截取result中以(开头,)结尾的内容
            if (result.contains("(") && result.contains(")")) {
                defaultValue = result.substring(0, result.indexOf("("));
            }
            //去掉result中 (开头,)结尾的内容 åŒ…含括号
            result = result.replaceAll("\\(.*?\\)", "");
            //获取系统配置中的值
            return BaseUtil.ifNull(Global.getSystemConfig(result, defaultValue), text);
        } catch (Exception e) {
            return text;
        }
    }
    public String getValue() {
        Format format = new DecimalFormat("000");
        return ModuleEnum.SAAS.getValue() + format.format(this.value);
    }
}
src/main/java/com/product/saas/config/SaasConst.java
@@ -1,6 +1,8 @@
package com.product.saas.config;
public class SaasConst {
import com.product.admin.config.CmnConst;
public class SaasConst extends CmnConst{
    // ç‰¹æ®Šå¸¸é‡
    public static final String FLOW_TENANT_APPLY = "77af46c9-91cf-44ee-924c-1d0df8c324f2";    //租户申请流程唯一值
src/main/java/com/product/saas/controller/TenantApplyController.java
@@ -7,7 +7,7 @@
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.product.admin.config.SystemCode;
import com.product.saas.config.SaasCode;
import com.product.saas.service.TenantApplyService;
import com.product.saas.service.idel.ITenantApplyService;
import com.product.core.config.CoreConst;
@@ -15,7 +15,6 @@
import com.product.core.entity.FieldSetEntity;
import com.product.core.entity.RequestParameterEntity;
import com.product.core.exception.BaseException;
import com.product.core.spring.context.SpringMVCContextHolder;
import com.product.file.service.FileManagerService;
import com.product.module.sys.version.ApiVersion;
import com.product.util.BaseUtil;
@@ -47,13 +46,10 @@
            return OK();
        } catch (BaseException e) {
            e.printStackTrace();
            SpringMVCContextHolder.getSystemLogger().error(e);
            return this.error(e.getCode(), e.getMessageInfo());
        } catch (Exception e) {
            e.printStackTrace();
            SpringMVCContextHolder.getSystemLogger().error(e);
            e.printStackTrace();
            return error(SystemCode.DELETE_ADMINISTRATIVE_DIVISION_FAIL);
            return error(SaasCode.TENANT_APPLY_VALID_INFO_FAIL.getValue(), SaasCode.TENANT_APPLY_VALID_INFO_FAIL.getText() + e.getMessage());
        }
    }
    
@@ -70,13 +66,10 @@
            return OK_List(tenantApplyService.getTenantApplyByPhone(fse.getString("applicant_phone")));
        } catch (BaseException e) {
            e.printStackTrace();
            SpringMVCContextHolder.getSystemLogger().error(e);
            return this.error(e.getCode(), e.getMessageInfo());
        } catch (Exception e) {
            e.printStackTrace();
            SpringMVCContextHolder.getSystemLogger().error(e);
            e.printStackTrace();
            return error(SystemCode.DELETE_ADMINISTRATIVE_DIVISION_FAIL);
            return error(SaasCode.TENANT_AAPLY_INFO_GET_FAIL.getValue(), SaasCode.TENANT_AAPLY_INFO_GET_FAIL.getText() + e.getMessage());
        }
    }
    
@@ -107,13 +100,10 @@
            return OK();
        } catch (BaseException e) {
            e.printStackTrace();
            SpringMVCContextHolder.getSystemLogger().error(e);
            return this.error(e.getCode(), e.getMessageInfo());
        } catch (Exception e) {
            e.printStackTrace();
            SpringMVCContextHolder.getSystemLogger().error(e);
            e.printStackTrace();
            return error(SystemCode.DELETE_ADMINISTRATIVE_DIVISION_FAIL);
            return error(SaasCode.TENANT_AAPLY_INFO_SUBMIT_FAIL.getValue(), SaasCode.TENANT_AAPLY_INFO_SUBMIT_FAIL.getText() + e.getMessage());
        }
    }
    
@@ -133,13 +123,10 @@
            return OK();
        } catch (BaseException e) {
            e.printStackTrace();
            SpringMVCContextHolder.getSystemLogger().error(e);
            return this.error(e.getCode(), e.getMessageInfo());
        } catch (Exception e) {
            e.printStackTrace();
            SpringMVCContextHolder.getSystemLogger().error(e);
            e.printStackTrace();
            return error(SystemCode.DELETE_ADMINISTRATIVE_DIVISION_FAIL);
            return error(SaasCode.TENANT_AAPLY_INFO_CANCEL_FAIL.getValue(), SaasCode.TENANT_AAPLY_INFO_CANCEL_FAIL.getText() + e.getMessage());
        }
    }
}
src/main/java/com/product/saas/service/TenantApplyService.java
@@ -1,25 +1,45 @@
package com.product.saas.service;
import java.io.File;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.product.admin.config.CmnConst;
import com.product.admin.service.CodeService;
import com.product.admin.service.LoginAuthService;
import com.product.core.config.Global;
import com.product.core.dao.BaseDao;
import com.product.core.entity.FieldSetEntity;
import com.product.core.exception.BaseException;
import com.product.core.service.support.AbstractBaseService;
import com.product.core.transfer.Transactional;
import com.product.file.service.FileManagerService;
import com.product.module.sys.service.UserService;
import com.product.saas.config.SaasCode;
import com.product.saas.config.SaasConst;
import com.product.saas.service.idel.ITenantApplyService;
import com.product.tool.flow.service.FlowService;
import com.product.util.BaseUtil;
import cn.hutool.core.io.FileUtil;
/**
 *    ç§Ÿæˆ·ç”³è¯·
 *
 */
@Component
public class TenantApplyService extends AbstractBaseService implements ITenantApplyService{
    @Autowired
    BaseDao baseDao;
    @Autowired
    CodeService codeService;
    @Autowired
    UserService userService;
    
    @Autowired
    FlowService flowService;
@@ -45,25 +65,24 @@
        // éªŒè¯ä¿¡æ¯æ˜¯å¦åŒ¹é…
        FieldSetEntity fseTenantByPhone = baseDao.getFieldSetEntityByFilter(SaasConst.PRODUCT_SYS_TENANT_APPLY, "applicant_phone = ?", new Object[] {phone}, false);
        FieldSetEntity fseTenantByName = baseDao.getFieldSetEntityByFilter(SaasConst.PRODUCT_SYS_TENANT_APPLY, "unit_name = ?", new Object[] {unitName}, false);
        if (fseTenantByPhone == null) {
            if(fseTenantByName == null) {
                // éƒ½ä¸å­˜åœ¨ï¼ŒéªŒè¯é€šè¿‡
                return true;
            } else {
                throw new BaseException("单位已经被使用", "单位已经被使用");
            }
        } else {
            if(fseTenantByName == null) {
                throw new BaseException("手机号已经被使用", "手机号已经被使用");
            } else {
                if (fseTenantByName.getUUID().equals(fseTenantByPhone.getUUID())) {
                    // éƒ½å­˜åœ¨äºŽåŒä¸€æ¡æ•°æ®ï¼ŒéªŒè¯é€šè¿‡
                    return true;
                } else {
                    throw new BaseException("手机号和单位已经被使用", "手机号和单位已经被使用");
                }
            }
        }
        // æƒ…况1:手机号和单位名都不存在 -> é€šè¿‡
        if (fseTenantByPhone == null && fseTenantByName == null) {
            return true;
        }
        // æƒ…况2:只存在手机号 -> æ‰‹æœºå·å·²ç”³è¯·
        if (fseTenantByPhone != null && fseTenantByName == null) {
            throw new BaseException(SaasCode.TENANT_APPLY_VALID_UNIT_HAS_APPLY.getValue(), SaasCode.TENANT_APPLY_VALID_UNIT_HAS_APPLY.getText());
        }
        // æƒ…况3:只存在单位名 -> å•位已申请
        if (fseTenantByPhone == null && fseTenantByName != null) {
            throw new BaseException(SaasCode.TENANT_APPLY_VALID_PHONE_HAS_APPLY.getValue(), SaasCode.TENANT_APPLY_VALID_PHONE_HAS_APPLY.getText());
        }
        // æƒ…况4:都存在 -> æ£€æŸ¥æ˜¯å¦æ˜¯åŒä¸€æ¡è®°å½•
        if (fseTenantByPhone.getUUID().equals(fseTenantByName.getUUID())) {
            return true;
        }
        // æƒ…况5:都存在但不是同一条记录 -> æ‰‹æœºå·å’Œå•位名都已申请
        throw new BaseException(SaasCode.TENANT_APPLY_VALID_UNIT_AND_PHONE_HAS_APPLY.getValue(), SaasCode.TENANT_APPLY_VALID_UNIT_AND_PHONE_HAS_APPLY.getText());
    }
    
    /**
@@ -83,6 +102,7 @@
    
    /**
     *     ä¿å­˜ç§Ÿæˆ·ç”³è¯·
     *     approval_sign:送审标识(0:保存;1:送审或激活)
     * @param fse
     * @return
     */
@@ -92,42 +112,203 @@
        // èŽ·å–é€å®¡æ ‡å¿—
        String flowSign = fse.getString("approval_sign");
        if (!BaseUtil.strIsNull(flowSign) || "1".equals(flowSign)) {
            // ä¿å­˜ç§Ÿæˆ·ä¿¡æ¯
            fse.setValue("apply_status", 2);
            fse.setValue("is_passed", 0);
            baseDao.saveFieldSetEntity(fse);
            // èŽ·å–é€å®¡å¼€å§‹çš„åŽä¸€ä¸ªèŠ‚ç‚¹ä¿¡æ¯
            StringBuilder sql = new StringBuilder();
            sql.append("SELECT * FROM product_sys_flow_node \n");
            sql.append("WHERE uuid IN ( \n");
            sql.append("    SELECT target_uuid FROM product_sys_flow_link \n");
            sql.append("    WHERE source_uuid IN ( \n");
            sql.append("        SELECT uuid FROM product_sys_flow_node \n");
            sql.append("        WHERE module_type = 1 AND flow_uuid IN ( \n");
            sql.append("            SELECT uuid FROM product_sys_flow_model \n");
            sql.append("            WHERE type_code = ? \n");
            sql.append("        ) \n");
            sql.append("    ) \n");
            sql.append(") \n");
            FieldSetEntity fseFlowNode = baseDao.getFieldSetEntityBySQL(sql.toString(), new Object[] {SaasConst.FLOW_TENANT_APPLY}, false);
            if (fseFlowNode == null || BaseUtil.strIsNull(fseFlowNode.getString("default_users"))) {
                throw new BaseException("租户申请流程有误", "租户申请流程有误");
            // æŸ¥è¯¢é€å®¡è®°å½•
            FieldSetEntity fseTask = baseDao.getFieldSetEntityByFilter("product_sys_flow_task", "table_name = 'product_sys_tenant_apply' AND record_uuid = ?", new Object[] {fse.getUUID()}, false);
            if (fseTask == null) {
                // èŽ·å–é€å®¡å¼€å§‹çš„åŽä¸€ä¸ªèŠ‚ç‚¹ä¿¡æ¯
                StringBuilder sql = new StringBuilder();
                sql.append("SELECT * FROM product_sys_flow_node \n");
                sql.append("WHERE uuid IN ( \n");
                sql.append("    SELECT target_uuid FROM product_sys_flow_link \n");
                sql.append("    WHERE source_uuid IN ( \n");
                sql.append("        SELECT uuid FROM product_sys_flow_node \n");
                sql.append("        WHERE module_type = 1 AND flow_uuid IN ( \n");
                sql.append("            SELECT uuid FROM product_sys_flow_model \n");
                sql.append("            WHERE type_code = ? \n");
                sql.append("        ) \n");
                sql.append("    ) \n");
                sql.append(") \n");
                FieldSetEntity fseFlowNode = baseDao.getFieldSetEntityBySQL(sql.toString(), new Object[] {SaasConst.FLOW_TENANT_APPLY}, false);
                if (fseFlowNode == null || BaseUtil.strIsNull(fseFlowNode.getString("default_users"))) {
                    throw new BaseException("租户申请流程有误", "租户申请流程有误");
                }
                // å°è£…送审参数
                FieldSetEntity fseFlowTask = new FieldSetEntity(SaasConst.PRODUCT_SYS_TENANT_APPLY);
                fseFlowTask.setValue("uuid", fse.getUUID());
                fseFlowTask.setValue("type_code", SaasConst.FLOW_TENANT_APPLY);
                fseFlowTask.setValue("accepters", fseFlowNode.getString("default_users"));
                fseFlowTask.setValue("flow_title", "租户申请-" + fse.getString("unit_name"));
                // æ‰§è¡Œé€å®¡
                flowService.autoSendFlow(fseFlowTask);
            } else {
                // æ¿€æ´»é€å®¡ä»»åŠ¡
                FieldSetEntity fseTaskDetail = new FieldSetEntity("product_sys_flow_detail");
                fseTaskDetail.setValue("task_uuid", fseTask.getUUID());
                fseTaskDetail.setValue("is_sub_flow", "0");
                fseTaskDetail.setValue("opinion", "租户撤回后重新提交");
                flowService.activate(fseTaskDetail);
            }
            // å°è£…送审参数
            FieldSetEntity fseFlowTask = new FieldSetEntity(SaasConst.PRODUCT_SYS_TENANT_APPLY);
            fseFlowTask.setValue("uuid", fse.getUUID());
            fseFlowTask.setValue("type_code", SaasConst.FLOW_TENANT_APPLY);
            fseFlowTask.setValue("accepters", fseFlowNode.getString("default_users"));
            fseFlowTask.setValue("flow_title", "租户申请-" + fse.getString("unit_name"));
            // æ‰§è¡Œé€å®¡
            flowService.autoSendFlow(fseFlowTask);
            return true;
        } else {
            fse.setValue("apply_status", 1);
            // ä¿å­˜è®°å½•
            fse.setValue("is_passed", 0);
            // ä¿å­˜ç§Ÿæˆ·ä¿¡æ¯
            return baseDao.saveFieldSetEntity(fse);
        }
    }
    /**
     *     æ’¤é”€ç§Ÿæˆ·ç”³è¯·
     * @param fse
     * @return
     */
    @Override
    @Transactional
    public boolean cancelTenantApply(FieldSetEntity fse){
        return true;
        // èŽ·å–å¯¹åº”æµç¨‹ä»»åŠ¡
        FieldSetEntity fseTask = baseDao.getFieldSetEntityByFilter("product_sys_flow_task", "table_name = 'product_sys_tenant_apply' AND record_uuid = ?", new Object[] {fse.getUUID()}, false);
        if (fseTask == null) {
            throw new BaseException(SaasCode.TENANT_AAPLY_INFO_FLOW_TASK_ERROR.getValue(), SaasCode.TENANT_AAPLY_INFO_FLOW_TASK_ERROR.getText());
        }
        // ç»ˆæ­¢æµç¨‹
        flowService.stop(fseTask);
        // æ ‡è®°ç”³è¯·æ•°æ®ä¸ºæœªé€å®¡
        return baseDao.executeUpdate("UPDATE product_sys_tenant_apply SET apply_status = 1 WHERE applicant_phone = ? AND unit_name = ? ",
                new Object[] {fse.getString("applicant_phone"), fse.getString("unit_name")});
    }
    /**
     *     åˆ·æ–°ç”³è¯·å•状态(流程处理器调用)
     * @param fseApply
     */
    public void refreshApplyStatus(FieldSetEntity fseApply) {
        if ("1".equals(fseApply.getString("is_passed"))) {
            // å®¡æ ¸é€šè¿‡
            baseDao.executeUpdate("UPDATE product_sys_tenant_apply SET apply_status = 3 WHERE uuid = ?", new Object[] {fseApply.getUUID()});
        } else {
            // å®¡æ ¸å¤±è´¥
            baseDao.executeUpdate("UPDATE product_sys_tenant_apply SET apply_status = 4 WHERE uuid = ?", new Object[] {fseApply.getUUID()});
        }
    }
    /**
     * ç”³è¯·å®Œæˆ
     * @param fseApply
     */
    @Transactional
    public void applyFinish(FieldSetEntity fseApply) {
        // åˆ›å»ºå®¢æˆ·ä¿¡æ¯
        FieldSetEntity fseClient = new FieldSetEntity(SaasConst.PRODUCT_SYS_CLIENTS);
        fseClient.setValue("client_name", fseApply.getString("unit_name"));
        fseClient.setValue("client_tel", fseApply.getString("applicant_phone"));
        fseClient.setValue("client_code", codeService.createCode(SaasConst.PRODUCT_SYS_CLIENTS, "client_code", ""));
        fseClient.setValue("attachment_capacity", "2130000000");
        fseClient.setValue("platform_admin", fseApply.getString("platform_admin"));
        fseClient.setValue("expiration_date", fseApply.getString("expiration_date"));
        fseClient.setValue("client_unit_type", fseApply.getString("unit_type"));
        fseClient.setValue("client_address_province_id", fseApply.getString("area_province"));
        fseClient.setValue("client_address_city_id", fseApply.getString("area_city"));
        fseClient.setValue("client_address_county_id", fseApply.getString("area_county"));
        fseClient.setValue("client_address_line_one", fseApply.getString("address"));
        fseClient.setValue(CmnConst.CREATED_BY, "1");
        fseClient.setValue(CmnConst.CREATED_UTC_DATETIME, new Date());
        baseDao.add(fseClient);
        // å¤åˆ¶license到web模块
        copyLicense(fseApply.getString("license"), fseClient.getString("client_code"));
        // åˆ›å»ºç»„织机构单位
        FieldSetEntity fseOrgUnit = new FieldSetEntity(CmnConst.PRODUCT_SYS_ORG_LEVELS);
        fseOrgUnit.setValue("client_uuid", fseClient.getUUID());
        fseOrgUnit.setValue("org_level_name", fseApply.getString("unit_name"));
        fseOrgUnit.setValue("org_level_all", fseApply.getString("unit_name"));
        fseOrgUnit.setValue("org_level_code", codeService.createCode("product_sys_org_levels", "org_level_code", null));
        fseOrgUnit.setValue("org_level_type", 0);
        fseOrgUnit.setValue("sequence", 1);
        fseOrgUnit.setValue(CmnConst.CREATED_BY, "1");
        fseOrgUnit.setValue(CmnConst.CREATED_UTC_DATETIME, new Date());
        baseDao.add(fseOrgUnit);
        // åˆ›å»ºç§Ÿæˆ·ç®¡ç†å‘˜ç”¨æˆ·ä¿¡æ¯
        FieldSetEntity fseUser = new FieldSetEntity(CmnConst.PRODUCT_SYS_USERS);
        fseUser.setValue(CmnConst.USER_NAME, fseApply.getString("applicant_name"));
        fseUser.setValue(CmnConst.USER_ACCOUNT, fseApply.getString("applicant_phone"));
        fseUser.setValue(CmnConst.USER_PRIMARY_EMAIL, fseApply.getString("applicant_email"));
        fseUser.setValue(CmnConst.USER_MOBILE_NUMBER, fseApply.getString("applicant_phone"));
        fseUser.setValue(CmnConst.USER_PWD, userService.createPassWord(fseApply.getString("applicant_phone"), fseApply.getString("applicant_pwd")));
        fseUser.setValue(CmnConst.IS_MANAGER, 1);
        fseUser.setValue(CmnConst.STATUS, 1);
        fseUser.setValue(CmnConst.CREATED_BY, "1");
        fseUser.setValue(CmnConst.CREATED_UTC_DATETIME, new Date());
        baseDao.add(fseUser);
        FieldSetEntity fseUserInfo = baseDao.getFieldSetEntity(CmnConst.PRODUCT_SYS_USERS, fseUser.getUUID(), false);
        // åˆ›å»ºç§Ÿæˆ·ç®¡ç†å‘˜ä¿¡æ¯
        FieldSetEntity fseManager = new FieldSetEntity(CmnConst.PRODUCT_SYS_ORG_MANAGER);
        fseManager.setValue(CmnConst.USER_ID, fseUserInfo.getString(CmnConst.USER_ID));
        fseManager.setValue(CmnConst.ORG_LEVEL_UUID, fseOrgUnit.getUUID());
        fseManager.setValue(CmnConst.MANAGER_TYPE, 2);
        fseManager.setValue(CmnConst.ROLE_UUIDS, "eabb00f3-2118-4165-967b-a7d88f472f67-notchange");
        fseManager.setValue(CmnConst.IS_USED, 1);
        fseManager.setValue(CmnConst.CLIENT_UUID, fseClient.getUUID());
        fseManager.setValue(CmnConst.CREATED_BY, "1");
        fseManager.setValue(CmnConst.CREATED_UTC_DATETIME, new Date());
        baseDao.add(fseManager);
    }
    /**
     *     å¤åˆ¶license到指定目录
     * @param fileUUID        é™„ä»¶UUID
     * @param clientCode    å®¢æˆ·ç¼–码
     */
    public void copyLicense(String fileUUID, String clientCode) {
        // èŽ·å–æ–‡ä»¶ä¿¡æ¯
        FieldSetEntity fse = baseDao.getFieldSetEntity(SaasConst.PRODUCT_SYS_ATTACHMENTS, fileUUID, false);
        if (fse == null) {
            throw new BaseException(SaasCode.TENANT_APPLY_LICENSE_DATA_NO_EXIST.getValue(), SaasCode.TENANT_APPLY_LICENSE_DATA_NO_EXIST.getText());
        }
        // æž„建源文件路径
        String baseDir = System.getProperty("user.dir");
        String localDir = Global.getSystemConfig("local.dir", "");
        String attachmentUrl = fse.getString("attachment_url");
        String attachmentTitle = fse.getString("attachment_title");
        String filePath = baseDir + File.separator + localDir + File.separator + attachmentUrl + File.separator + attachmentTitle;
        // æ£€æŸ¥æºæ–‡ä»¶æ˜¯å¦å­˜åœ¨
        if (!FileUtil.exist(filePath)) {
            throw new BaseException(SaasCode.TENANT_APPLY_LICENSE_FILE_NO_EXIST.getValue(), SaasCode.TENANT_APPLY_LICENSE_FILE_NO_EXIST.getText());
        }
        // æž„建目标目录
        String targetDir = baseDir + File.separator + "resources" + File.separator;
        FileUtil.mkdir(targetDir);
        // æž„建目标文件名:license + clientCode + .dat
        // æ— è®ºåŽŸæ–‡ä»¶æ˜¯å¦æœ‰æ‰©å±•åï¼Œéƒ½ä½¿ç”¨.dat扩展名
        String targetFileName = "license" + clientCode + ".dat";
        String targetPath = targetDir + targetFileName;
        // å¤åˆ¶æ–‡ä»¶
        try {
            // ä½¿ç”¨Hutool复制,第三个参数true表示覆盖已存在的文件
            FileUtil.copy(filePath, targetPath, true);
            // éªŒè¯å¤åˆ¶ç»“æžœ
            if (FileUtil.exist(targetPath)) {
                long sourceSize = FileUtil.size(new File(filePath));
                long targetSize = FileUtil.size(new File(targetPath));
                if (sourceSize != targetSize) {
                    throw new BaseException(SaasCode.TENANT_APPLY_LICENSE_FILE_COPY_FAIL.getValue(),  SaasCode.TENANT_APPLY_LICENSE_FILE_COPY_FAIL.getValue() + "目标文件不完整");
                }
            } else {
                throw new BaseException(SaasCode.TENANT_APPLY_LICENSE_FILE_COPY_FAIL.getValue(),  SaasCode.TENANT_APPLY_LICENSE_FILE_COPY_FAIL.getValue() + "目标文件不存在");
            }
        } catch (Exception e) {
            throw new BaseException(SaasCode.TENANT_APPLY_LICENSE_FILE_COPY_FAIL.getValue(),  SaasCode.TENANT_APPLY_LICENSE_FILE_COPY_FAIL.getValue() + e.getMessage());
        }
    }
}
src/main/java/com/product/saas/service/idel/ITenantApplyService.java
@@ -11,5 +11,16 @@
     */
    boolean saveTenantApply(FieldSetEntity fse);
    
    /**
     *     ç§Ÿæˆ·æ³¨å†Œæ’¤é”€
     * @param fse
     * @return
     */
    boolean cancelTenantApply(FieldSetEntity fse);
    /**
     *     ç§Ÿæˆ·æ³¨å†Œå®Œæ•´
     * @param fse
     */
    void applyFinish(FieldSetEntity fse);
}