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; @Autowired LoginAuthService loginAuthService; @Autowired FileManagerService fileManagerService; /** * 租户信息读取和验证 * @param fse * @return */ public boolean validTenantInfo(FieldSetEntity fse) { // 获取手机号和验证码 String phone = fse.getString("phone"); String code = fse.getString("code"); // 验证验证码是否正确 loginAuthService.verifyPhoneCaptcha(phone, code); String unitName = fse.getString("unitName"); // 验证信息是否匹配 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); // 情况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()); } /** * 获取指定租户申请,根据申请人手机号 * @param applicantPhone 申请人手机号 * @return */ public FieldSetEntity getTenantApplyByPhone(String applicantPhone) { StringBuilder sql = new StringBuilder(); sql.append("SELECT A.*, B.file_name AS business_license_name, B.attachment_size AS business_license_size, C.dict_label AS apply_status_label \n"); sql.append("FROM product_sys_tenant_apply A \n"); sql.append("LEFT JOIN product_sys_attachments B ON B.uuid = A.business_license \n"); sql.append("LEFT JOIN product_sys_dict C ON C.dict_value = A.apply_status AND C.dict_name = 'SYSTEM_TENANT_APPLY_STATUS' \n"); sql.append("WHERE A.applicant_phone = ?"); return baseDao.getFieldSetEntityBySQL(sql.toString(), new Object[] {applicantPhone}, false); } /** * 保存租户申请 * approval_sign:送审标识(0:保存;1:送审或激活) * @param fse * @return */ @Override @Transactional public boolean saveTenantApply(FieldSetEntity fse) { // 获取送审标志 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"); 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); } 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){ // 获取对应流程任务 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", "成都XXXX软件有限公司>" + fseApply.getString("unit_name")); fseOrgUnit.setValue("org_level_code", codeService.createCode("product_sys_org_levels", "org_level_code", "001")); fseOrgUnit.setValue("org_level_code_parent", "001"); 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); baseDao.executeUpdate("UPDATE product_sys_tenant_apply SET client_uuid = ? WHERE uuid = ?", new Object[] {fseClient.getUUID(), fseApply.getUUID()}); } /** * 复制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()); } } }