| | |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.vincent.rsf.framework.exception.CoolException; |
| | | import com.vincent.rsf.server.ai.config.AiDefaults; |
| | | import com.vincent.rsf.server.ai.dto.AiParamValidateResultDto; |
| | | import com.vincent.rsf.server.ai.entity.AiParam; |
| | | import com.vincent.rsf.server.ai.mapper.AiParamMapper; |
| | | import com.vincent.rsf.server.ai.service.AiParamService; |
| | | import com.vincent.rsf.server.system.enums.StatusType; |
| | | import lombok.RequiredArgsConstructor; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.util.StringUtils; |
| | | |
| | | import java.text.SimpleDateFormat; |
| | | import java.util.Date; |
| | | |
| | | @Service("aiParamService") |
| | | @RequiredArgsConstructor |
| | | public class AiParamServiceImpl extends ServiceImpl<AiParamMapper, AiParam> implements AiParamService { |
| | | |
| | | private final AiParamValidationSupport aiParamValidationSupport; |
| | | |
| | | @Override |
| | | public AiParam getActiveParam() { |
| | | public AiParam getActiveParam(Long tenantId) { |
| | | ensureTenantId(tenantId); |
| | | AiParam aiParam = this.getOne(new LambdaQueryWrapper<AiParam>() |
| | | .eq(AiParam::getTenantId, tenantId) |
| | | .eq(AiParam::getStatus, StatusType.ENABLE.val) |
| | | .eq(AiParam::getDeleted, 0) |
| | | .last("limit 1")); |
| | | if (aiParam == null) { |
| | | throw new CoolException("未找到启用中的 AI 参数配置"); |
| | |
| | | } |
| | | |
| | | @Override |
| | | public void validateBeforeSave(AiParam aiParam) { |
| | | public void validateBeforeSave(AiParam aiParam, Long tenantId) { |
| | | ensureTenantId(tenantId); |
| | | aiParam.setTenantId(tenantId); |
| | | fillDefaults(aiParam); |
| | | ensureBaseFields(aiParam); |
| | | ensureSingleActive(aiParam, null); |
| | | ensureSingleActive(tenantId, null, aiParam.getStatus()); |
| | | applyValidation(aiParam); |
| | | } |
| | | |
| | | @Override |
| | | public void validateBeforeUpdate(AiParam aiParam) { |
| | | public void validateBeforeUpdate(AiParam aiParam, Long tenantId) { |
| | | ensureTenantId(tenantId); |
| | | fillDefaults(aiParam); |
| | | if (aiParam.getId() == null) { |
| | | throw new CoolException("AI 参数 ID 不能为空"); |
| | | } |
| | | AiParam current = requireOwnedRecord(aiParam.getId(), tenantId); |
| | | aiParam.setTenantId(current.getTenantId()); |
| | | ensureBaseFields(aiParam); |
| | | ensureSingleActive(aiParam, aiParam.getId()); |
| | | ensureSingleActive(tenantId, aiParam.getId(), aiParam.getStatus()); |
| | | applyValidation(aiParam); |
| | | } |
| | | |
| | | @Override |
| | | public AiParamValidateResultDto validateDraft(AiParam aiParam, Long tenantId) { |
| | | ensureTenantId(tenantId); |
| | | fillDefaults(aiParam); |
| | | ensureBaseFields(aiParam); |
| | | return aiParamValidationSupport.validate(aiParam); |
| | | } |
| | | |
| | | private void ensureBaseFields(AiParam aiParam) { |
| | |
| | | } |
| | | } |
| | | |
| | | private void ensureSingleActive(AiParam aiParam, Long selfId) { |
| | | if (aiParam.getStatus() == null || aiParam.getStatus() != StatusType.ENABLE.val) { |
| | | private void ensureSingleActive(Long tenantId, Long selfId, Integer status) { |
| | | if (status == null || status != StatusType.ENABLE.val) { |
| | | return; |
| | | } |
| | | LambdaQueryWrapper<AiParam> wrapper = new LambdaQueryWrapper<AiParam>() |
| | | .eq(AiParam::getStatus, StatusType.ENABLE.val); |
| | | .eq(AiParam::getTenantId, tenantId) |
| | | .eq(AiParam::getStatus, StatusType.ENABLE.val) |
| | | .eq(AiParam::getDeleted, 0); |
| | | if (selfId != null) { |
| | | wrapper.ne(AiParam::getId, selfId); |
| | | } |
| | | if (this.count(wrapper) > 0) { |
| | | throw new CoolException("同一租户仅允许一条启用中的 AI 参数配置"); |
| | | } |
| | | } |
| | | |
| | | private AiParam requireOwnedRecord(Long id, Long tenantId) { |
| | | AiParam aiParam = this.getOne(new LambdaQueryWrapper<AiParam>() |
| | | .eq(AiParam::getId, id) |
| | | .eq(AiParam::getTenantId, tenantId) |
| | | .eq(AiParam::getDeleted, 0) |
| | | .last("limit 1")); |
| | | if (aiParam == null) { |
| | | throw new CoolException("AI 参数不存在或无权访问"); |
| | | } |
| | | return aiParam; |
| | | } |
| | | |
| | | private void ensureTenantId(Long tenantId) { |
| | | if (tenantId == null) { |
| | | throw new CoolException("当前租户不存在"); |
| | | } |
| | | } |
| | | |
| | |
| | | if (aiParam.getStreamingEnabled() == null) { |
| | | aiParam.setStreamingEnabled(Boolean.TRUE); |
| | | } |
| | | if (!StringUtils.hasText(aiParam.getValidateStatus())) { |
| | | aiParam.setValidateStatus(AiDefaults.PARAM_VALIDATE_NOT_TESTED); |
| | | } |
| | | if (aiParam.getStatus() == null) { |
| | | aiParam.setStatus(StatusType.ENABLE.val); |
| | | } |
| | | } |
| | | |
| | | private void applyValidation(AiParam aiParam) { |
| | | AiParamValidateResultDto validateResult = aiParamValidationSupport.validate(aiParam); |
| | | aiParam.setValidateStatus(validateResult.getStatus()); |
| | | aiParam.setLastValidateMessage(validateResult.getMessage()); |
| | | aiParam.setLastValidateElapsedMs(validateResult.getElapsedMs()); |
| | | aiParam.setLastValidateTime(parseDate(validateResult.getValidatedAt())); |
| | | if (!AiDefaults.PARAM_VALIDATE_VALID.equals(validateResult.getStatus())) { |
| | | throw new CoolException(validateResult.getMessage()); |
| | | } |
| | | } |
| | | |
| | | private Date parseDate(String dateTime) { |
| | | if (!StringUtils.hasText(dateTime)) { |
| | | return null; |
| | | } |
| | | try { |
| | | return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateTime); |
| | | } catch (Exception e) { |
| | | throw new CoolException("解析校验时间失败: " + e.getMessage()); |
| | | } |
| | | } |
| | | } |