杜洪波
2026-03-20 107e63ea3d1dd252841e934d6f483b0032e68493
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) {
            // 都不存在,验证通过
      // 情况1:手机号和单位名都不存在 -> 通过
       if (fseTenantByPhone == null && fseTenantByName == null) {
            return true;
         } else {
            throw new BaseException("单位已经被使用", "单位已经被使用");
         }
      } else {
         if(fseTenantByName == null) {
            throw new BaseException("手机号已经被使用", "手机号已经被使用");
         } else {
            if (fseTenantByName.getUUID().equals(fseTenantByPhone.getUUID())) {
               // 都存在于同一条数据,验证通过
       // 情况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;
            } else {
               throw new BaseException("手机号和单位已经被使用", "手机号和单位已经被使用");
            }
         }
      }
       // 情况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,8 +112,14 @@
      // 获取送审标志
      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);
         // 查询送审记录
         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");
@@ -119,15 +145,170 @@
         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);
         }
         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());
       }
   }
}