package com.vincent.rsf.server.ai.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.vincent.rsf.framework.exception.CoolException; import com.vincent.rsf.server.ai.dto.AiPromptPreviewDto; import com.vincent.rsf.server.ai.dto.AiPromptPreviewRequest; import com.vincent.rsf.server.ai.entity.AiPrompt; import com.vincent.rsf.server.ai.mapper.AiPromptMapper; import com.vincent.rsf.server.ai.service.AiPromptService; import com.vincent.rsf.server.system.enums.StatusType; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; @Service("aiPromptService") @RequiredArgsConstructor public class AiPromptServiceImpl extends ServiceImpl implements AiPromptService { private final AiPromptRenderSupport aiPromptRenderSupport; @Override public AiPrompt getActivePrompt(String code, Long tenantId) { ensureTenantId(tenantId); AiPrompt aiPrompt = this.getOne(new LambdaQueryWrapper() .eq(AiPrompt::getTenantId, tenantId) .eq(AiPrompt::getCode, code) .eq(AiPrompt::getStatus, StatusType.ENABLE.val) .eq(AiPrompt::getDeleted, 0) .last("limit 1")); if (aiPrompt == null) { throw new CoolException("未找到启用中的 Prompt:" + code); } return aiPrompt; } @Override public void validateBeforeSave(AiPrompt aiPrompt, Long tenantId) { ensureTenantId(tenantId); aiPrompt.setTenantId(tenantId); ensureRequiredFields(aiPrompt); ensureUniqueCode(aiPrompt.getCode(), tenantId, null); } @Override public void validateBeforeUpdate(AiPrompt aiPrompt, Long tenantId) { ensureTenantId(tenantId); if (aiPrompt.getId() == null) { throw new CoolException("Prompt ID 不能为空"); } AiPrompt current = requireOwnedRecord(aiPrompt.getId(), tenantId); aiPrompt.setTenantId(current.getTenantId()); ensureRequiredFields(aiPrompt); ensureUniqueCode(aiPrompt.getCode(), tenantId, aiPrompt.getId()); } @Override public AiPromptPreviewDto renderPreview(AiPromptPreviewRequest request, Long tenantId) { ensureTenantId(tenantId); if (request == null) { throw new CoolException("Prompt 预览参数不能为空"); } if (!StringUtils.hasText(request.getSystemPrompt())) { throw new CoolException("系统 Prompt 不能为空"); } return aiPromptRenderSupport.render( request.getSystemPrompt(), request.getUserPromptTemplate(), request.getInput(), request.getMetadata() ); } private void ensureRequiredFields(AiPrompt aiPrompt) { if (!StringUtils.hasText(aiPrompt.getName())) { throw new CoolException("Prompt 名称不能为空"); } if (!StringUtils.hasText(aiPrompt.getCode())) { throw new CoolException("Prompt 编码不能为空"); } if (!StringUtils.hasText(aiPrompt.getSystemPrompt())) { throw new CoolException("系统 Prompt 不能为空"); } if (aiPrompt.getStatus() == null) { aiPrompt.setStatus(StatusType.ENABLE.val); } } private void ensureUniqueCode(String code, Long tenantId, Long selfId) { LambdaQueryWrapper wrapper = new LambdaQueryWrapper() .eq(AiPrompt::getTenantId, tenantId) .eq(AiPrompt::getCode, code) .eq(AiPrompt::getDeleted, 0); if (selfId != null) { wrapper.ne(AiPrompt::getId, selfId); } if (this.count(wrapper) > 0) { throw new CoolException("Prompt 编码已存在"); } } private AiPrompt requireOwnedRecord(Long id, Long tenantId) { AiPrompt aiPrompt = this.getOne(new LambdaQueryWrapper() .eq(AiPrompt::getId, id) .eq(AiPrompt::getTenantId, tenantId) .eq(AiPrompt::getDeleted, 0) .last("limit 1")); if (aiPrompt == null) { throw new CoolException("Prompt 不存在或无权访问"); } return aiPrompt; } private void ensureTenantId(Long tenantId) { if (tenantId == null) { throw new CoolException("当前租户不存在"); } } }