feat: expand EasyCode software factory workflows
This commit is contained in:
@@ -3,6 +3,7 @@ package com.ruoyi.web.controller.front;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
@@ -13,6 +14,8 @@ import com.ruoyi.common.core.domain.model.LoginUser;
|
||||
import com.ruoyi.common.utils.SecurityUtils;
|
||||
import com.ruoyi.framework.web.service.TokenService;
|
||||
import com.ruoyi.generator.domain.front.dto.FrontLoginBody;
|
||||
import com.ruoyi.generator.domain.front.dto.FrontPasswordUpdateBody;
|
||||
import com.ruoyi.generator.domain.front.dto.FrontProfileUpdateBody;
|
||||
import com.ruoyi.generator.domain.front.dto.FrontRegisterBody;
|
||||
import com.ruoyi.generator.service.front.IFrontUserService;
|
||||
import com.ruoyi.web.service.front.FrontAuthService;
|
||||
@@ -53,6 +56,18 @@ public class FrontAuthController extends BaseController
|
||||
return AjaxResult.success(frontAuthService.profile(SecurityUtils.getUserId()));
|
||||
}
|
||||
|
||||
@PutMapping("/profile")
|
||||
public AjaxResult updateProfile(@RequestBody FrontProfileUpdateBody body)
|
||||
{
|
||||
return AjaxResult.success(frontAuthService.updateProfile(SecurityUtils.getUserId(), body));
|
||||
}
|
||||
|
||||
@PutMapping("/password")
|
||||
public AjaxResult updatePassword(@RequestBody FrontPasswordUpdateBody body)
|
||||
{
|
||||
return toAjax(frontAuthService.updatePassword(SecurityUtils.getUserId(), body));
|
||||
}
|
||||
|
||||
@PostMapping("/logout")
|
||||
public AjaxResult logout()
|
||||
{
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
package com.ruoyi.web.controller.front;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.utils.SecurityUtils;
|
||||
import com.ruoyi.generator.factory.dsl.ProjectSpecQueryService;
|
||||
import com.ruoyi.generator.factory.dsl.model.ProjectSpecV1;
|
||||
import com.ruoyi.generator.factory.diff.ProjectSpecVersionDiffService;
|
||||
import com.ruoyi.generator.factory.generation.ProjectSpecGenerationService;
|
||||
import com.ruoyi.generator.factory.generation.ProjectSpecGenerationRunService;
|
||||
import com.ruoyi.generator.factory.patch.ProjectSpecPatchService;
|
||||
import com.ruoyi.generator.factory.patch.model.ProjectSpecPatchRequest;
|
||||
import com.ruoyi.generator.factory.validation.ProjectSpecValidationService;
|
||||
import com.ruoyi.generator.factory.version.ProjectSpecVersionService;
|
||||
import com.ruoyi.generator.factory.version.model.ProjectSpecRollbackRequest;
|
||||
import com.ruoyi.generator.factory.version.model.ProjectSpecSnapshotRequest;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/front/factory/projects")
|
||||
public class FrontFactoryProjectController extends BaseController
|
||||
{
|
||||
@Autowired
|
||||
private ProjectSpecQueryService projectSpecQueryService;
|
||||
@Autowired
|
||||
private ProjectSpecVersionService projectSpecVersionService;
|
||||
@Autowired
|
||||
private ProjectSpecValidationService projectSpecValidationService;
|
||||
@Autowired
|
||||
private ProjectSpecPatchService projectSpecPatchService;
|
||||
@Autowired
|
||||
private ProjectSpecVersionDiffService projectSpecVersionDiffService;
|
||||
@Autowired
|
||||
private ProjectSpecGenerationService projectSpecGenerationService;
|
||||
@Autowired
|
||||
private ProjectSpecGenerationRunService projectSpecGenerationRunService;
|
||||
|
||||
@GetMapping("/{projectId}/spec")
|
||||
public AjaxResult getCurrentSpec(@PathVariable Long projectId)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return AjaxResult.success(projectSpecQueryService.getCurrentSpec(userId, projectId));
|
||||
}
|
||||
|
||||
@PostMapping("/{projectId}/spec/validate")
|
||||
public AjaxResult validateSpec(@PathVariable Long projectId, @RequestBody(required = false) ProjectSpecV1 spec)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return AjaxResult.success(projectSpecValidationService.validate(userId, projectId, spec));
|
||||
}
|
||||
|
||||
@PostMapping("/{projectId}/spec/patch/preview")
|
||||
public AjaxResult previewSpecPatch(@PathVariable Long projectId, @RequestBody ProjectSpecPatchRequest request)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return AjaxResult.success(projectSpecPatchService.preview(userId, projectId, request));
|
||||
}
|
||||
|
||||
@PostMapping("/{projectId}/spec/patch")
|
||||
public AjaxResult applySpecPatch(@PathVariable Long projectId, @RequestBody ProjectSpecPatchRequest request)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return AjaxResult.success(projectSpecPatchService.apply(userId, projectId, request));
|
||||
}
|
||||
|
||||
@PostMapping("/{projectId}/versions")
|
||||
public AjaxResult snapshotCurrentSpec(@PathVariable Long projectId,
|
||||
@RequestBody(required = false) ProjectSpecSnapshotRequest request)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
String summary = request == null ? null : request.getChangeSummary();
|
||||
return AjaxResult.success(projectSpecVersionService.snapshotCurrent(userId, projectId, summary));
|
||||
}
|
||||
|
||||
@GetMapping("/{projectId}/versions")
|
||||
public AjaxResult listSpecVersions(@PathVariable Long projectId)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return AjaxResult.success(projectSpecVersionService.listVersions(userId, projectId));
|
||||
}
|
||||
|
||||
@GetMapping("/{projectId}/versions/{specVersionId}")
|
||||
public AjaxResult getSpecVersion(@PathVariable Long projectId, @PathVariable Long specVersionId)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return AjaxResult.success(projectSpecVersionService.getVersion(userId, projectId, specVersionId));
|
||||
}
|
||||
|
||||
@PostMapping("/{projectId}/versions/{specVersionId}/generate")
|
||||
public AjaxResult generateSpecVersion(@PathVariable Long projectId, @PathVariable Long specVersionId)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return AjaxResult.success(projectSpecGenerationService.generate(userId, projectId, specVersionId));
|
||||
}
|
||||
|
||||
@GetMapping("/{projectId}/generation-runs")
|
||||
public AjaxResult listGenerationRuns(@PathVariable Long projectId)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return AjaxResult.success(projectSpecGenerationRunService.list(userId, projectId));
|
||||
}
|
||||
|
||||
@GetMapping("/{projectId}/generation-runs/{generationRunId}")
|
||||
public AjaxResult getGenerationRun(@PathVariable Long projectId, @PathVariable Long generationRunId)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return AjaxResult.success(projectSpecGenerationRunService.get(userId, projectId, generationRunId));
|
||||
}
|
||||
|
||||
@GetMapping("/{projectId}/generation-runs/{leftRunId}/diff/{rightRunId}")
|
||||
public AjaxResult diffGenerationRuns(@PathVariable Long projectId, @PathVariable Long leftRunId,
|
||||
@PathVariable Long rightRunId)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return AjaxResult.success(projectSpecGenerationRunService.diff(userId, projectId,
|
||||
leftRunId, rightRunId));
|
||||
}
|
||||
|
||||
@PostMapping("/{projectId}/versions/{specVersionId}/rollback")
|
||||
public AjaxResult rollbackSpecVersion(@PathVariable Long projectId, @PathVariable Long specVersionId,
|
||||
@RequestBody(required = false) ProjectSpecRollbackRequest request)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
String summary = request == null ? null : request.getChangeSummary();
|
||||
return AjaxResult.success(projectSpecVersionService.rollback(userId, projectId, specVersionId, summary));
|
||||
}
|
||||
|
||||
@GetMapping("/{projectId}/versions/{leftVersionId}/diff/{rightVersionId}")
|
||||
public AjaxResult diffSpecVersions(@PathVariable Long projectId, @PathVariable Long leftVersionId,
|
||||
@PathVariable Long rightVersionId)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return AjaxResult.success(projectSpecVersionDiffService.diff(userId, projectId,
|
||||
leftVersionId, rightVersionId));
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,12 @@
|
||||
package com.ruoyi.web.controller.front;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -13,28 +19,60 @@ import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.utils.SecurityUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.file.FileUtils;
|
||||
import com.ruoyi.generator.domain.front.FrontProject;
|
||||
import com.ruoyi.generator.domain.front.dto.DatabaseDesignResponse;
|
||||
import com.ruoyi.generator.domain.front.FrontProjectDiagram;
|
||||
import com.ruoyi.generator.domain.front.FrontProjectGeneration;
|
||||
import com.ruoyi.generator.domain.front.FrontProjectPaper;
|
||||
import com.ruoyi.generator.domain.front.dto.AiGenerationTaskCreateRequest;
|
||||
import com.ruoyi.generator.domain.front.dto.BusinessLoopAuditResult;
|
||||
import com.ruoyi.generator.domain.front.dto.CodeAnalysisResponse;
|
||||
import com.ruoyi.generator.domain.front.dto.BusinessLoopPlan;
|
||||
import com.ruoyi.generator.domain.front.dto.DatabaseDesignResponse;
|
||||
import com.ruoyi.generator.domain.front.dto.FrontProjectCreateRequest;
|
||||
import com.ruoyi.generator.domain.front.dto.FrontProjectUpdateRequest;
|
||||
import com.ruoyi.generator.domain.front.dto.GenerateAppBlueprintRequest;
|
||||
import com.ruoyi.generator.domain.front.dto.GenerateBusinessBlueprintRequest;
|
||||
import com.ruoyi.generator.domain.front.dto.GenerateFlowConfigRequest;
|
||||
import com.ruoyi.generator.domain.front.dto.SimpleFlowConfig;
|
||||
import com.ruoyi.generator.domain.front.dto.GenerateCodeAnalysisRequest;
|
||||
import com.ruoyi.generator.domain.front.dto.GenerateDatabaseRequest;
|
||||
import com.ruoyi.generator.domain.front.dto.GenerateDiagramRequest;
|
||||
import com.ruoyi.generator.domain.front.dto.GeneratePaperDraftRequest;
|
||||
import com.ruoyi.generator.domain.front.dto.GeneratePaperOutlineRequest;
|
||||
import com.ruoyi.generator.domain.front.dto.GenerateRequirementRequest;
|
||||
import com.ruoyi.generator.domain.front.dto.ParseErSqlRequest;
|
||||
import com.ruoyi.generator.domain.front.dto.FrontendPageDesignRequest;
|
||||
import com.ruoyi.generator.domain.front.dto.PreviewFileRequest;
|
||||
import com.ruoyi.generator.domain.front.dto.ProjectDeliveryReadiness;
|
||||
import com.ruoyi.generator.factory.quality.ProjectQualityRunService;
|
||||
import com.ruoyi.generator.factory.artifact.CertifiedArtifactService;
|
||||
import com.ruoyi.generator.factory.artifact.model.ProjectCertifiedArtifact;
|
||||
import com.ruoyi.generator.factory.acceptance.FactoryV1AcceptanceService;
|
||||
import com.ruoyi.generator.service.ITemplateBundleService;
|
||||
import com.ruoyi.generator.service.front.IAiGenerateService;
|
||||
import com.ruoyi.generator.service.front.IAiGenerationTaskService;
|
||||
import com.ruoyi.generator.service.front.BusinessBlockRegistryService;
|
||||
import com.ruoyi.generator.service.front.BusinessLoopCoverageValidator;
|
||||
import com.ruoyi.generator.service.front.BusinessRequirementCoverageValidator;
|
||||
import com.ruoyi.generator.service.front.FlowConfigContractService;
|
||||
import com.ruoyi.generator.service.front.FrontProjectAssetService;
|
||||
import com.ruoyi.generator.service.front.FrontendPageDesignService;
|
||||
import com.ruoyi.generator.service.front.IFrontProjectPreviewService;
|
||||
import com.ruoyi.generator.service.front.IFrontProjectRunPreviewService;
|
||||
import com.ruoyi.generator.service.front.IFrontProjectService;
|
||||
import com.ruoyi.generator.service.front.IProjectDeliveryReadinessService;
|
||||
import com.ruoyi.generator.service.front.SqlDdlParseService;
|
||||
import com.ruoyi.generator.factory.flow.FlowConfigCompilation;
|
||||
import com.ruoyi.generator.factory.flow.FlowConfigProjector;
|
||||
import com.ruoyi.generator.service.front.PageLayoutTemplateRegistry;
|
||||
import com.ruoyi.generator.service.front.PageStylePresetRegistry;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/front/project")
|
||||
@@ -47,6 +85,14 @@ public class FrontProjectController extends BaseController
|
||||
@Autowired
|
||||
private IAiGenerationTaskService aiGenerationTaskService;
|
||||
@Autowired
|
||||
private BusinessLoopCoverageValidator businessLoopCoverageValidator;
|
||||
@Autowired
|
||||
private BusinessRequirementCoverageValidator businessRequirementCoverageValidator;
|
||||
@Autowired
|
||||
private FlowConfigContractService flowConfigContractService;
|
||||
@Autowired
|
||||
private FrontProjectAssetService frontProjectAssetService;
|
||||
@Autowired
|
||||
private FrontendPageDesignService frontendPageDesignService;
|
||||
@Autowired
|
||||
private BusinessBlockRegistryService businessBlockRegistryService;
|
||||
@@ -54,6 +100,22 @@ public class FrontProjectController extends BaseController
|
||||
private IFrontProjectPreviewService frontProjectPreviewService;
|
||||
@Autowired
|
||||
private IFrontProjectRunPreviewService frontProjectRunPreviewService;
|
||||
@Autowired
|
||||
private SqlDdlParseService sqlDdlParseService;
|
||||
@Autowired
|
||||
private ITemplateBundleService templateBundleService;
|
||||
@Autowired
|
||||
private IProjectDeliveryReadinessService projectDeliveryReadinessService;
|
||||
@Autowired
|
||||
private ProjectQualityRunService projectQualityRunService;
|
||||
@Autowired
|
||||
private CertifiedArtifactService certifiedArtifactService;
|
||||
@Autowired
|
||||
private FactoryV1AcceptanceService factoryV1AcceptanceService;
|
||||
@Autowired
|
||||
private PageStylePresetRegistry pageStylePresetRegistry;
|
||||
@Autowired
|
||||
private PageLayoutTemplateRegistry pageLayoutTemplateRegistry;
|
||||
|
||||
@PostMapping("/create")
|
||||
public AjaxResult create(@RequestBody FrontProjectCreateRequest request)
|
||||
@@ -75,6 +137,31 @@ public class FrontProjectController extends BaseController
|
||||
return AjaxResult.success(frontProjectService.listAvailableModules());
|
||||
}
|
||||
|
||||
@GetMapping("/options/code-templates")
|
||||
public AjaxResult codeTemplates()
|
||||
{
|
||||
return AjaxResult.success(templateBundleService.listEnabledBundles());
|
||||
}
|
||||
|
||||
@GetMapping("/options/page-templates")
|
||||
public AjaxResult pageTemplates()
|
||||
{
|
||||
pageStylePresetRegistry.refreshFromDatabase();
|
||||
pageLayoutTemplateRegistry.refreshFromDatabase();
|
||||
Map<String, Object> options = new LinkedHashMap<String, Object>();
|
||||
options.put("themes", pageStylePresetRegistry.options());
|
||||
options.put("solutions", pageStylePresetRegistry.options());
|
||||
options.put("layouts", pageLayoutTemplateRegistry.options());
|
||||
return AjaxResult.success(options);
|
||||
}
|
||||
|
||||
@PostMapping("/generate-requirement")
|
||||
public AjaxResult generateRequirement(@RequestBody GenerateRequirementRequest request)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return AjaxResult.success(aiGenerateService.generateRequirementSuggestion(userId, request));
|
||||
}
|
||||
|
||||
@GetMapping("/{projectId}")
|
||||
public AjaxResult get(@PathVariable Long projectId)
|
||||
{
|
||||
@@ -110,6 +197,14 @@ public class FrontProjectController extends BaseController
|
||||
return AjaxResult.success(frontProjectService.saveDatabase(userId, projectId, request));
|
||||
}
|
||||
|
||||
@PostMapping("/{projectId}/er/parse-sql")
|
||||
public AjaxResult parseErSql(@PathVariable Long projectId, @RequestBody ParseErSqlRequest request)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
frontProjectService.getProject(userId, projectId);
|
||||
return AjaxResult.success(sqlDdlParseService.parse(request == null ? "" : request.getSql()));
|
||||
}
|
||||
|
||||
@GetMapping("/{projectId}/page-designs")
|
||||
public AjaxResult pageDesigns(@PathVariable Long projectId,
|
||||
@RequestParam(defaultValue = "frontend") String scope)
|
||||
@@ -127,6 +222,41 @@ public class FrontProjectController extends BaseController
|
||||
return AjaxResult.success(businessBlockRegistryService.listDefinitions(scope));
|
||||
}
|
||||
|
||||
@GetMapping("/{projectId}/diagrams")
|
||||
public AjaxResult diagrams(@PathVariable Long projectId)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return AjaxResult.success(frontProjectAssetService.listDiagrams(userId, projectId));
|
||||
}
|
||||
|
||||
@PostMapping("/{projectId}/diagrams")
|
||||
public AjaxResult saveDiagram(@PathVariable Long projectId, @RequestBody FrontProjectDiagram request)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return AjaxResult.success(frontProjectAssetService.saveDiagram(userId, projectId, request));
|
||||
}
|
||||
|
||||
@DeleteMapping("/{projectId}/diagrams/{diagramId}")
|
||||
public AjaxResult deleteDiagram(@PathVariable Long projectId, @PathVariable Long diagramId)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return toAjax(frontProjectAssetService.deleteDiagram(userId, projectId, diagramId));
|
||||
}
|
||||
|
||||
@GetMapping("/{projectId}/paper")
|
||||
public AjaxResult paper(@PathVariable Long projectId)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return AjaxResult.success(frontProjectAssetService.getPaper(userId, projectId));
|
||||
}
|
||||
|
||||
@PutMapping("/{projectId}/paper")
|
||||
public AjaxResult savePaper(@PathVariable Long projectId, @RequestBody FrontProjectPaper request)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return AjaxResult.success(frontProjectAssetService.savePaper(userId, projectId, request));
|
||||
}
|
||||
|
||||
@PostMapping("/{projectId}/page-designs/init")
|
||||
public AjaxResult initPageDesigns(@PathVariable Long projectId,
|
||||
@RequestParam(defaultValue = "frontend") String scope)
|
||||
@@ -135,6 +265,17 @@ public class FrontProjectController extends BaseController
|
||||
return AjaxResult.success(frontendPageDesignService.initializePageDesigns(userId, projectId, scope));
|
||||
}
|
||||
|
||||
@PostMapping("/{projectId}/page-designs/apply-business-loop-bindings")
|
||||
public AjaxResult applyBusinessLoopBindings(@PathVariable Long projectId,
|
||||
@RequestParam(defaultValue = "frontend") String scope)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
FrontProject project = frontProjectService.getProject(userId, projectId);
|
||||
frontendPageDesignService.applyBusinessLoopBindings(userId, projectId,
|
||||
FlowConfigProjector.compile(project).getLoopPlan(), scope);
|
||||
return AjaxResult.success(frontendPageDesignService.listPageDesigns(userId, projectId, scope));
|
||||
}
|
||||
|
||||
@PostMapping("/{projectId}/page-designs")
|
||||
public AjaxResult createPageDesign(@PathVariable Long projectId,
|
||||
@RequestParam(defaultValue = "frontend") String scope,
|
||||
@@ -152,6 +293,23 @@ public class FrontProjectController extends BaseController
|
||||
return AjaxResult.success(frontendPageDesignService.getPageDesign(userId, projectId, designId, scope));
|
||||
}
|
||||
|
||||
@GetMapping("/{projectId}/page-designs/{designId}/dsl")
|
||||
public AjaxResult pageDsl(@PathVariable Long projectId, @PathVariable Long designId,
|
||||
@RequestParam(defaultValue = "frontend") String scope)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return AjaxResult.success(frontendPageDesignService.getPageDsl(userId, projectId, designId, scope));
|
||||
}
|
||||
|
||||
@PostMapping("/{projectId}/page-designs/{designId}/compose")
|
||||
public AjaxResult composePageDesign(@PathVariable Long projectId, @PathVariable Long designId,
|
||||
@RequestParam(defaultValue = "frontend") String scope,
|
||||
@RequestBody(required = false) FrontendPageDesignRequest request)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return AjaxResult.success(frontendPageDesignService.composePageDesign(userId, projectId, designId, request, scope));
|
||||
}
|
||||
|
||||
@PutMapping("/{projectId}/page-designs/{designId}")
|
||||
public AjaxResult savePageDesign(@PathVariable Long projectId, @PathVariable Long designId,
|
||||
@RequestParam(defaultValue = "frontend") String scope,
|
||||
@@ -184,11 +342,132 @@ public class FrontProjectController extends BaseController
|
||||
return success(aiGenerateService.generateAppBlueprint(userId, projectId, request));
|
||||
}
|
||||
|
||||
@PostMapping("/{projectId}/generate-business-blueprint")
|
||||
public AjaxResult generateBusinessBlueprint(@PathVariable Long projectId, @RequestBody GenerateBusinessBlueprintRequest request)
|
||||
@PostMapping("/{projectId}/generate-flow-config")
|
||||
public AjaxResult generateFlowConfig(@PathVariable Long projectId, @RequestBody GenerateFlowConfigRequest request)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return success(aiGenerateService.generateBusinessBlueprint(userId, projectId, request));
|
||||
return success(aiGenerateService.generateFlowConfig(userId, projectId, request));
|
||||
}
|
||||
|
||||
@PutMapping("/{projectId}/flow-config")
|
||||
public AjaxResult saveFlowConfig(@PathVariable Long projectId, @RequestBody SimpleFlowConfig flowConfig)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return toAjax(frontProjectService.updateFlowConfig(userId, projectId, JSON.toJSONString(flowConfig)));
|
||||
}
|
||||
|
||||
@PostMapping("/{projectId}/diagram")
|
||||
public AjaxResult generateDiagram(@PathVariable Long projectId, @RequestBody GenerateDiagramRequest request)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return success(aiGenerateService.generateDiagram(userId, projectId, request));
|
||||
}
|
||||
|
||||
@PostMapping("/{projectId}/paper-outline")
|
||||
public AjaxResult generatePaperOutline(@PathVariable Long projectId, @RequestBody GeneratePaperOutlineRequest request)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return success(aiGenerateService.generatePaperOutline(userId, projectId, request));
|
||||
}
|
||||
|
||||
@PostMapping("/{projectId}/paper-draft")
|
||||
public AjaxResult generatePaperDraft(@PathVariable Long projectId, @RequestBody GeneratePaperDraftRequest request)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return success(aiGenerateService.generatePaperDraft(userId, projectId, request));
|
||||
}
|
||||
|
||||
@PostMapping(value = "/{projectId}/paper-draft/stream", produces = "text/plain;charset=UTF-8")
|
||||
public StreamingResponseBody streamPaperDraft(@PathVariable Long projectId,
|
||||
@RequestBody GeneratePaperDraftRequest request)
|
||||
{
|
||||
final Long userId = SecurityUtils.getUserId();
|
||||
return outputStream ->
|
||||
{
|
||||
final Writer writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
|
||||
aiGenerateService.streamPaperDraft(userId, projectId, request, content ->
|
||||
{
|
||||
writer.write(content);
|
||||
writer.flush();
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@PostMapping("/{projectId}/code-analysis")
|
||||
public AjaxResult createCodeAnalysis(@PathVariable Long projectId,
|
||||
@RequestBody(required = false) GenerateCodeAnalysisRequest request)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
assertCodeAnalysisPreviewReady(userId, projectId);
|
||||
return success(aiGenerationTaskService.createTask(userId, projectId, toCodeAnalysisTaskRequest(request)));
|
||||
}
|
||||
|
||||
@PostMapping(value = "/{projectId}/code-analysis/stream", produces = "text/plain;charset=UTF-8")
|
||||
public StreamingResponseBody streamCodeAnalysis(@PathVariable Long projectId,
|
||||
@RequestBody(required = false) GenerateCodeAnalysisRequest request)
|
||||
{
|
||||
final Long userId = SecurityUtils.getUserId();
|
||||
assertCodeAnalysisPreviewReady(userId, projectId);
|
||||
return outputStream ->
|
||||
{
|
||||
final Writer writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
|
||||
aiGenerateService.streamCodeAnalysis(userId, projectId, request, content ->
|
||||
{
|
||||
writer.write(content);
|
||||
writer.flush();
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@GetMapping("/{projectId}/code-analysis/history")
|
||||
public AjaxResult codeAnalysisHistory(@PathVariable Long projectId)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return success(aiGenerationTaskService.listGenerations(userId, projectId, "code_analysis"));
|
||||
}
|
||||
|
||||
@PostMapping("/{projectId}/code-analysis/{generationId}/continue")
|
||||
public AjaxResult continueCodeAnalysis(@PathVariable Long projectId, @PathVariable Long generationId,
|
||||
@RequestBody(required = false) GenerateCodeAnalysisRequest request)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
assertCodeAnalysisPreviewReady(userId, projectId);
|
||||
FrontProjectGeneration previous = aiGenerationTaskService.getGeneration(userId, projectId, generationId);
|
||||
if (!"code_analysis".equals(previous.getGenerateType()))
|
||||
{
|
||||
throw new ServiceException("只能基于代码解读历史继续生成");
|
||||
}
|
||||
GenerateCodeAnalysisRequest nextRequest = request == null ? new GenerateCodeAnalysisRequest() : request;
|
||||
nextRequest.setMode("continue");
|
||||
nextRequest.setPreviousGenerationId(generationId);
|
||||
nextRequest.setPreviousMarkdown(readCodeAnalysisMarkdown(previous.getResponsePayload()));
|
||||
return success(aiGenerationTaskService.createTask(userId, projectId, toCodeAnalysisTaskRequest(nextRequest)));
|
||||
}
|
||||
|
||||
@PostMapping(value = "/{projectId}/code-analysis/{generationId}/continue/stream", produces = "text/plain;charset=UTF-8")
|
||||
public StreamingResponseBody continueCodeAnalysisStream(@PathVariable Long projectId, @PathVariable Long generationId,
|
||||
@RequestBody(required = false) GenerateCodeAnalysisRequest request)
|
||||
{
|
||||
final Long userId = SecurityUtils.getUserId();
|
||||
assertCodeAnalysisPreviewReady(userId, projectId);
|
||||
final GenerateCodeAnalysisRequest nextRequest = toContinueCodeAnalysisRequest(userId, projectId, generationId,
|
||||
request);
|
||||
return outputStream ->
|
||||
{
|
||||
final Writer writer = new OutputStreamWriter(outputStream, StandardCharsets.UTF_8);
|
||||
aiGenerateService.streamCodeAnalysis(userId, projectId, nextRequest, content ->
|
||||
{
|
||||
writer.write(content);
|
||||
writer.flush();
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
@GetMapping("/ai-tasks/one-click-overview")
|
||||
public AjaxResult oneClickTaskOverview()
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return success(aiGenerationTaskService.listOneClickTaskOverview(userId));
|
||||
}
|
||||
|
||||
@PostMapping("/{projectId}/ai-tasks")
|
||||
@@ -198,6 +477,62 @@ public class FrontProjectController extends BaseController
|
||||
return success(aiGenerationTaskService.createTask(userId, projectId, request));
|
||||
}
|
||||
|
||||
@GetMapping("/{projectId}/ai-tasks/one-click-history")
|
||||
public AjaxResult oneClickTaskHistory(@PathVariable Long projectId)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return success(aiGenerationTaskService.listOneClickTaskHistory(userId, projectId));
|
||||
}
|
||||
|
||||
@GetMapping("/{projectId}/delivery-readiness")
|
||||
public AjaxResult deliveryReadiness(@PathVariable Long projectId)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return success(projectDeliveryReadinessService.get(userId, projectId));
|
||||
}
|
||||
|
||||
@PostMapping("/{projectId}/quality-runs")
|
||||
public AjaxResult createQualityRun(@PathVariable Long projectId)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return success(projectQualityRunService.createSummary(userId, projectId));
|
||||
}
|
||||
|
||||
@GetMapping("/{projectId}/quality-runs")
|
||||
public AjaxResult qualityRuns(@PathVariable Long projectId)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return success(projectQualityRunService.listSummaries(userId, projectId));
|
||||
}
|
||||
|
||||
@GetMapping("/{projectId}/quality-runs/latest")
|
||||
public AjaxResult latestQualityRun(@PathVariable Long projectId)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return success(projectQualityRunService.latestSummary(userId, projectId));
|
||||
}
|
||||
|
||||
@PostMapping("/{projectId}/v1-acceptance-runs")
|
||||
public AjaxResult startV1Acceptance(@PathVariable Long projectId)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return success(factoryV1AcceptanceService.start(userId, projectId));
|
||||
}
|
||||
|
||||
@GetMapping("/{projectId}/v1-acceptance-runs/latest")
|
||||
public AjaxResult latestV1Acceptance(@PathVariable Long projectId)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return success(factoryV1AcceptanceService.latest(userId, projectId));
|
||||
}
|
||||
|
||||
@GetMapping("/{projectId}/v1-acceptance-runs")
|
||||
public AjaxResult v1Acceptances(@PathVariable Long projectId)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return success(factoryV1AcceptanceService.list(userId, projectId));
|
||||
}
|
||||
|
||||
@GetMapping("/{projectId}/ai-tasks/{taskId}")
|
||||
public AjaxResult getAiTask(@PathVariable Long projectId, @PathVariable Long taskId)
|
||||
{
|
||||
@@ -226,6 +561,35 @@ public class FrontProjectController extends BaseController
|
||||
return success(aiGenerationTaskService.listGenerations(userId, projectId));
|
||||
}
|
||||
|
||||
@GetMapping("/{projectId}/business-loop-audit")
|
||||
public AjaxResult businessLoopAudit(@PathVariable Long projectId)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
FrontProject project = frontProjectService.getProject(userId, projectId);
|
||||
SimpleFlowConfig flowConfig = FlowConfigProjector.read(project);
|
||||
FlowConfigCompilation flow = flowConfig == null
|
||||
? new FlowConfigCompilation() : flowConfigContractService.compile(flowConfig);
|
||||
BusinessLoopPlan plan = flow.getLoopPlan();
|
||||
DatabaseDesignResponse database = frontProjectService.getDatabase(userId, projectId);
|
||||
Map<String, Object> result = new LinkedHashMap<String, Object>();
|
||||
BusinessLoopAuditResult databaseAudit = flowConfig == null
|
||||
? businessLoopCoverageValidator.auditDatabase(plan, database)
|
||||
: flowConfigContractService.auditDatabase(flowConfig, database);
|
||||
BusinessLoopAuditResult actionAudit = businessLoopCoverageValidator.auditBusinessActions(plan,
|
||||
flow.getBusinessActions());
|
||||
String requirement = StringUtils.defaultString(project.getProjectDesc());
|
||||
if (StringUtils.isNotBlank(project.getRequirementKeyword()))
|
||||
{
|
||||
requirement += "\n补充要求:" + project.getRequirementKeyword();
|
||||
}
|
||||
BusinessLoopAuditResult requirementAudit = businessRequirementCoverageValidator.audit(requirement, flowConfig);
|
||||
result.put("requirements", requirementAudit);
|
||||
result.put("database", databaseAudit);
|
||||
result.put("businessActions", actionAudit);
|
||||
result.put("complete", requirementAudit.isComplete() && databaseAudit.isComplete() && actionAudit.isComplete());
|
||||
return success(result);
|
||||
}
|
||||
|
||||
@GetMapping("/ai-quota")
|
||||
public AjaxResult aiQuota()
|
||||
{
|
||||
@@ -237,14 +601,10 @@ public class FrontProjectController extends BaseController
|
||||
public AjaxResult preview(@PathVariable Long projectId)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
FrontProject project = frontProjectService.getProject(userId, projectId);
|
||||
frontProjectPreviewService.getStructure(userId, projectId, "backend");
|
||||
if (!"0".equals(project.getFrontendEnabled()))
|
||||
for (String type : frontProjectPreviewService.getSupportedTemplateTypes(userId, projectId))
|
||||
{
|
||||
frontProjectPreviewService.getStructure(userId, projectId, "frontend");
|
||||
frontProjectPreviewService.getStructure(userId, projectId, type);
|
||||
}
|
||||
frontProjectPreviewService.getStructure(userId, projectId, "admin_frontend");
|
||||
frontProjectPreviewService.getStructure(userId, projectId, "sql");
|
||||
return toAjax(frontProjectPreviewService.markPreviewReady(userId, projectId));
|
||||
}
|
||||
|
||||
@@ -269,6 +629,18 @@ public class FrontProjectController extends BaseController
|
||||
return success(frontProjectRunPreviewService.stop(userId, projectId));
|
||||
}
|
||||
|
||||
@GetMapping("/{projectId}/run-preview/{previewJobId}/screenshot")
|
||||
public void runPreviewScreenshot(@PathVariable Long projectId, @PathVariable Long previewJobId,
|
||||
HttpServletResponse response) throws IOException
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
byte[] data = frontProjectRunPreviewService.screenshot(userId, projectId, previewJobId);
|
||||
response.reset();
|
||||
response.setContentType("image/png");
|
||||
response.addHeader("Content-Length", String.valueOf(data.length));
|
||||
IOUtils.write(data, response.getOutputStream());
|
||||
}
|
||||
|
||||
@GetMapping("/{projectId}/structure")
|
||||
public AjaxResult structure(@PathVariable Long projectId, @RequestParam String templateType)
|
||||
{
|
||||
@@ -276,6 +648,13 @@ public class FrontProjectController extends BaseController
|
||||
return success(frontProjectPreviewService.getStructure(userId, projectId, templateType));
|
||||
}
|
||||
|
||||
@GetMapping("/{projectId}/template-types")
|
||||
public AjaxResult templateTypes(@PathVariable Long projectId)
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
return success(frontProjectPreviewService.getSupportedTemplateTypes(userId, projectId));
|
||||
}
|
||||
|
||||
@GetMapping("/{projectId}/file-content")
|
||||
public AjaxResult fileContent(@PathVariable Long projectId, PreviewFileRequest request)
|
||||
{
|
||||
@@ -284,15 +663,50 @@ public class FrontProjectController extends BaseController
|
||||
}
|
||||
|
||||
@GetMapping("/{projectId}/download")
|
||||
public void download(@PathVariable Long projectId, @RequestParam(required = false) String templateType, HttpServletResponse response) throws IOException
|
||||
public void download(@PathVariable Long projectId,
|
||||
@RequestParam(required = false) String templateType,
|
||||
@RequestParam(required = false, defaultValue = ProjectDeliveryReadiness.ARTIFACT_DRAFT) String artifactType,
|
||||
HttpServletResponse response) throws IOException
|
||||
{
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
String normalizedArtifactType = StringUtils.isEmpty(artifactType)
|
||||
? ProjectDeliveryReadiness.ARTIFACT_DRAFT
|
||||
: artifactType.trim().toUpperCase(Locale.ROOT);
|
||||
ProjectDeliveryReadiness readiness = projectDeliveryReadinessService
|
||||
.assertDownloadAllowed(userId, projectId, normalizedArtifactType);
|
||||
FrontProject project = frontProjectService.getProject(userId, projectId);
|
||||
byte[] data = StringUtils.isNotEmpty(templateType)
|
||||
? frontProjectPreviewService.download(userId, projectId, templateType)
|
||||
: frontProjectPreviewService.downloadAll(userId, projectId);
|
||||
ProjectCertifiedArtifact certifiedArtifact = null;
|
||||
byte[] data;
|
||||
if (ProjectDeliveryReadiness.ARTIFACT_CERTIFIED.equals(normalizedArtifactType))
|
||||
{
|
||||
if (StringUtils.isNotEmpty(templateType))
|
||||
{
|
||||
throw new ServiceException("认证制品只支持下载完整冻结源码");
|
||||
}
|
||||
if (readiness.getQualityRun() == null || readiness.getQualityRun().getQualityRunId() == null)
|
||||
{
|
||||
throw new ServiceException("认证制品缺少质量运行身份");
|
||||
}
|
||||
certifiedArtifact = certifiedArtifactService.getReady(userId, projectId,
|
||||
readiness.getQualityRun().getQualityRunId());
|
||||
data = certifiedArtifactService.read(certifiedArtifact);
|
||||
}
|
||||
else
|
||||
{
|
||||
data = StringUtils.isNotEmpty(templateType)
|
||||
? frontProjectPreviewService.download(userId, projectId, templateType)
|
||||
: frontProjectPreviewService.downloadAll(userId, projectId);
|
||||
}
|
||||
response.reset();
|
||||
FileUtils.setAttachmentResponseHeader(response, sourceZipName(project));
|
||||
response.addHeader("X-Factory-Artifact-Type", normalizedArtifactType);
|
||||
response.addHeader("X-Factory-Certification-Level", readiness.getCertificationLevel());
|
||||
if (certifiedArtifact != null)
|
||||
{
|
||||
response.addHeader("X-Factory-Artifact-Id", String.valueOf(certifiedArtifact.getArtifactId()));
|
||||
response.addHeader("X-Factory-Zip-SHA256", certifiedArtifact.getZipSha256());
|
||||
response.addHeader("X-Factory-Report-SHA256", certifiedArtifact.getReportSha256());
|
||||
}
|
||||
response.addHeader("Content-Length", "" + data.length);
|
||||
response.setContentType("application/octet-stream; charset=UTF-8");
|
||||
IOUtils.write(data, response.getOutputStream());
|
||||
@@ -311,4 +725,76 @@ public class FrontProjectController extends BaseController
|
||||
}
|
||||
return safeName + ".zip";
|
||||
}
|
||||
|
||||
private AiGenerationTaskCreateRequest toCodeAnalysisTaskRequest(GenerateCodeAnalysisRequest source)
|
||||
{
|
||||
AiGenerationTaskCreateRequest request = new AiGenerationTaskCreateRequest();
|
||||
request.setGenerateType("code_analysis");
|
||||
if (source != null)
|
||||
{
|
||||
request.setMode(source.getMode());
|
||||
request.setPreviousGenerationId(source.getPreviousGenerationId());
|
||||
request.setPreviousMarkdown(source.getPreviousMarkdown());
|
||||
request.setExtraRequirements(source.getExtraRequirements());
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
private void assertCodeAnalysisPreviewReady(Long userId, Long projectId)
|
||||
{
|
||||
FrontProject project = frontProjectService.getProject(userId, projectId);
|
||||
if (project == null || !"1".equals(project.getPreviewStatus()))
|
||||
{
|
||||
throw new ServiceException("请先生成源码预览后再进行代码解读");
|
||||
}
|
||||
}
|
||||
|
||||
private GenerateCodeAnalysisRequest toContinueCodeAnalysisRequest(Long userId, Long projectId, Long generationId,
|
||||
GenerateCodeAnalysisRequest request)
|
||||
{
|
||||
FrontProjectGeneration previous = aiGenerationTaskService.getGeneration(userId, projectId, generationId);
|
||||
if (!"code_analysis".equals(previous.getGenerateType()))
|
||||
{
|
||||
throw new ServiceException("只能基于代码解读历史继续生成");
|
||||
}
|
||||
GenerateCodeAnalysisRequest nextRequest = request == null ? new GenerateCodeAnalysisRequest() : request;
|
||||
nextRequest.setMode("continue");
|
||||
nextRequest.setPreviousGenerationId(generationId);
|
||||
if (StringUtils.isBlank(nextRequest.getPreviousMarkdown()))
|
||||
{
|
||||
nextRequest.setPreviousMarkdown(readCodeAnalysisMarkdown(previous.getResponsePayload()));
|
||||
}
|
||||
return nextRequest;
|
||||
}
|
||||
|
||||
private String readCodeAnalysisMarkdown(String responsePayload)
|
||||
{
|
||||
if (StringUtils.isEmpty(responsePayload))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
try
|
||||
{
|
||||
CodeAnalysisResponse response = JSON.parseObject(responsePayload, CodeAnalysisResponse.class);
|
||||
if (response != null && StringUtils.isNotEmpty(response.getMarkdown()))
|
||||
{
|
||||
return response.getMarkdown();
|
||||
}
|
||||
}
|
||||
catch (RuntimeException ignored)
|
||||
{
|
||||
return responsePayload;
|
||||
}
|
||||
return responsePayload;
|
||||
}
|
||||
|
||||
private BusinessLoopPlan readBusinessLoopPlan(String json)
|
||||
{
|
||||
if (StringUtils.isEmpty(json))
|
||||
{
|
||||
return new BusinessLoopPlan();
|
||||
}
|
||||
BusinessLoopPlan plan = JSON.parseObject(json, BusinessLoopPlan.class);
|
||||
return plan == null ? new BusinessLoopPlan() : plan;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ import com.ruoyi.common.utils.SecurityUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.framework.web.service.TokenService;
|
||||
import com.ruoyi.generator.domain.front.FrontUser;
|
||||
import com.ruoyi.generator.domain.front.dto.FrontPasswordUpdateBody;
|
||||
import com.ruoyi.generator.domain.front.dto.FrontProfileUpdateBody;
|
||||
import com.ruoyi.generator.service.front.IFrontUserService;
|
||||
|
||||
@Component
|
||||
@@ -68,6 +70,79 @@ public class FrontAuthService
|
||||
return frontUser;
|
||||
}
|
||||
|
||||
public FrontUser updateProfile(Long userId, FrontProfileUpdateBody body)
|
||||
{
|
||||
if (userId == null)
|
||||
{
|
||||
throw new ServiceException("登录状态异常,请重新登录");
|
||||
}
|
||||
if (body == null)
|
||||
{
|
||||
throw new ServiceException("用户资料不能为空");
|
||||
}
|
||||
|
||||
String nickname = trimToEmpty(body.getNickname());
|
||||
String email = trimToEmpty(body.getEmail());
|
||||
String phone = trimToEmpty(body.getPhone());
|
||||
validateProfile(nickname, email, phone);
|
||||
|
||||
FrontUser user = new FrontUser();
|
||||
user.setUserId(userId);
|
||||
user.setNickname(nickname);
|
||||
user.setEmail(email);
|
||||
user.setPhone(phone);
|
||||
|
||||
if (frontUserService.updateProfile(user) <= 0)
|
||||
{
|
||||
throw new ServiceException("更新个人资料失败");
|
||||
}
|
||||
return profile(userId);
|
||||
}
|
||||
|
||||
public int updatePassword(Long userId, FrontPasswordUpdateBody body)
|
||||
{
|
||||
if (userId == null)
|
||||
{
|
||||
throw new ServiceException("登录状态异常,请重新登录");
|
||||
}
|
||||
if (body == null || StringUtils.isEmpty(body.getOldPassword()))
|
||||
{
|
||||
throw new ServiceException("旧密码不能为空");
|
||||
}
|
||||
if (StringUtils.isEmpty(body.getNewPassword()))
|
||||
{
|
||||
throw new ServiceException("新密码不能为空");
|
||||
}
|
||||
if (!body.getNewPassword().equals(body.getConfirmPassword()))
|
||||
{
|
||||
throw new ServiceException("两次输入的新密码不一致");
|
||||
}
|
||||
if (body.getNewPassword().length() < 5 || body.getNewPassword().length() > 50)
|
||||
{
|
||||
throw new ServiceException("新密码长度必须在5到50个字符之间");
|
||||
}
|
||||
|
||||
FrontUser existing = frontUserService.selectById(userId);
|
||||
if (existing == null || StringUtils.isEmpty(existing.getPassword()))
|
||||
{
|
||||
throw new ServiceException("用户不存在");
|
||||
}
|
||||
if (!matchesPassword(body.getOldPassword(), existing.getPassword()))
|
||||
{
|
||||
throw new ServiceException("旧密码错误");
|
||||
}
|
||||
|
||||
FrontUser user = new FrontUser();
|
||||
user.setUserId(userId);
|
||||
user.setPassword(SecurityUtils.encryptPassword(body.getNewPassword()));
|
||||
int rows = frontUserService.updatePassword(user);
|
||||
if (rows <= 0)
|
||||
{
|
||||
throw new ServiceException("修改密码失败");
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
private boolean matchesPassword(String password, String encodedPassword)
|
||||
{
|
||||
try
|
||||
@@ -80,6 +155,35 @@ public class FrontAuthService
|
||||
}
|
||||
}
|
||||
|
||||
private void validateProfile(String nickname, String email, String phone)
|
||||
{
|
||||
if (nickname.length() > 50)
|
||||
{
|
||||
throw new ServiceException("昵称长度不能超过50个字符");
|
||||
}
|
||||
if (email.length() > 100)
|
||||
{
|
||||
throw new ServiceException("邮箱长度不能超过100个字符");
|
||||
}
|
||||
if (StringUtils.isNotEmpty(email) && !email.matches("^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$"))
|
||||
{
|
||||
throw new ServiceException("邮箱格式不正确");
|
||||
}
|
||||
if (phone.length() > 20)
|
||||
{
|
||||
throw new ServiceException("手机号长度不能超过20个字符");
|
||||
}
|
||||
if (StringUtils.isNotEmpty(phone) && !phone.matches("^[0-9+\\- ]+$"))
|
||||
{
|
||||
throw new ServiceException("手机号格式不正确");
|
||||
}
|
||||
}
|
||||
|
||||
private String trimToEmpty(String value)
|
||||
{
|
||||
return value == null ? "" : value.trim();
|
||||
}
|
||||
|
||||
private ServiceException credentialException()
|
||||
{
|
||||
return new ServiceException("用户名或密码错误");
|
||||
|
||||
@@ -17,12 +17,61 @@ ruoyi:
|
||||
deepseek:
|
||||
apiKey: sk-2aef3231d45048a9a0ba6f0367a072ca
|
||||
baseUrl: https://api.deepseek.com
|
||||
model: deepseek-v4-flash
|
||||
model: ${DEEPSEEK_MODEL:deepseek-v4-flash}
|
||||
timeout: ${DEEPSEEK_TIMEOUT:180000}
|
||||
maxTables: 12
|
||||
maxColumnsPerTable: 30
|
||||
skipSslVerify: true
|
||||
|
||||
easycode:
|
||||
one-click:
|
||||
run-preview-timeout-ms: ${EASYCODE_ONE_CLICK_RUN_PREVIEW_TIMEOUT_MS:300000}
|
||||
run-preview-poll-interval-ms: ${EASYCODE_ONE_CLICK_RUN_PREVIEW_POLL_INTERVAL_MS:1000}
|
||||
preview:
|
||||
execution-mode: ${EASYCODE_PREVIEW_EXECUTION_MODE:host}
|
||||
ttl-minutes: ${EASYCODE_PREVIEW_TTL_MINUTES:15}
|
||||
worker-enabled: ${EASYCODE_PREVIEW_WORKER_ENABLED:false}
|
||||
worker-root: ${EASYCODE_PREVIEW_WORKER_ROOT:preview-worker-data}
|
||||
docker-image: ${EASYCODE_PREVIEW_DOCKER_IMAGE:easycode/preview-worker:v1}
|
||||
docker-network: ${EASYCODE_PREVIEW_DOCKER_NETWORK:bridge}
|
||||
bind-host: ${EASYCODE_PREVIEW_BIND_HOST:127.0.0.1}
|
||||
cpu-limit: ${EASYCODE_PREVIEW_CPU_LIMIT:1.0}
|
||||
memory-limit-mb: ${EASYCODE_PREVIEW_MEMORY_LIMIT_MB:1024}
|
||||
pids-limit: ${EASYCODE_PREVIEW_PIDS_LIMIT:256}
|
||||
|
||||
factory:
|
||||
prompt-registry:
|
||||
database-enabled: ${FACTORY_PROMPT_REGISTRY_DATABASE_ENABLED:true}
|
||||
builtin-fallback-enabled: ${FACTORY_PROMPT_REGISTRY_BUILTIN_FALLBACK_ENABLED:false}
|
||||
plugin-registry:
|
||||
database-enabled: ${FACTORY_PLUGIN_REGISTRY_DATABASE_ENABLED:false}
|
||||
plugin-execution:
|
||||
executor-code: ${FACTORY_PLUGIN_EXECUTOR_CODE:dry-run:v1}
|
||||
environment-code: ${FACTORY_PLUGIN_EXECUTION_ENVIRONMENT_CODE:development}
|
||||
approval-required-for-non-dry-run: ${FACTORY_PLUGIN_APPROVAL_REQUIRED_FOR_NON_DRY_RUN:true}
|
||||
approval-separation-enabled: ${FACTORY_PLUGIN_APPROVAL_SEPARATION_ENABLED:true}
|
||||
approval-request-ttl-minutes: ${FACTORY_PLUGIN_APPROVAL_REQUEST_TTL_MINUTES:1440}
|
||||
approval-validity-minutes: ${FACTORY_PLUGIN_APPROVAL_VALIDITY_MINUTES:30}
|
||||
approval-requester-role-keys: ${FACTORY_PLUGIN_APPROVAL_REQUESTER_ROLE_KEYS:}
|
||||
approval-approver-role-keys: ${FACTORY_PLUGIN_APPROVAL_APPROVER_ROLE_KEYS:}
|
||||
executor-routes:
|
||||
database-migration-sql: ${FACTORY_PLUGIN_DATABASE_MIGRATION_SQL_EXECUTOR_CODE:}
|
||||
permission-backend: ${FACTORY_PLUGIN_PERMISSION_BACKEND_EXECUTOR_CODE:}
|
||||
menu-admin-frontend: ${FACTORY_PLUGIN_MENU_ADMIN_FRONTEND_EXECUTOR_CODE:}
|
||||
outbox-polling-enabled: ${FACTORY_PLUGIN_OUTBOX_POLLING_ENABLED:true}
|
||||
outbox-poll-interval-seconds: ${FACTORY_PLUGIN_OUTBOX_POLL_INTERVAL_SECONDS:5}
|
||||
outbox-batch-size: ${FACTORY_PLUGIN_OUTBOX_BATCH_SIZE:5}
|
||||
outbox-lease-seconds: ${FACTORY_PLUGIN_OUTBOX_LEASE_SECONDS:60}
|
||||
sql-target:
|
||||
enabled: ${FACTORY_PLUGIN_SQL_TARGET_ENABLED:false}
|
||||
environment-code: ${FACTORY_PLUGIN_SQL_TARGET_ENVIRONMENT_CODE:}
|
||||
jdbc-url: ${FACTORY_PLUGIN_SQL_TARGET_JDBC_URL:}
|
||||
username: ${FACTORY_PLUGIN_SQL_TARGET_USERNAME:}
|
||||
password: ${FACTORY_PLUGIN_SQL_TARGET_PASSWORD:}
|
||||
driver-class-name: ${FACTORY_PLUGIN_SQL_TARGET_DRIVER_CLASS_NAME:com.mysql.cj.jdbc.Driver}
|
||||
allowed-catalog: ${FACTORY_PLUGIN_SQL_TARGET_ALLOWED_CATALOG:}
|
||||
receipt-lease-seconds: ${FACTORY_PLUGIN_SQL_TARGET_RECEIPT_LEASE_SECONDS:300}
|
||||
|
||||
# 开发环境配置
|
||||
server:
|
||||
# 服务器的HTTP端口,默认为8080
|
||||
@@ -64,13 +113,16 @@ spring:
|
||||
basename: i18n/messages
|
||||
profiles:
|
||||
active: druid
|
||||
mvc:
|
||||
async:
|
||||
request-timeout: ${SPRING_MVC_ASYNC_REQUEST_TIMEOUT:600000}
|
||||
# 文件上传
|
||||
servlet:
|
||||
multipart:
|
||||
# 单个文件大小
|
||||
max-file-size: 10MB
|
||||
max-file-size: ${SPRING_SERVLET_MULTIPART_MAX_FILE_SIZE:100MB}
|
||||
# 设置总上传的文件大小
|
||||
max-request-size: 20MB
|
||||
max-request-size: ${SPRING_SERVLET_MULTIPART_MAX_REQUEST_SIZE:120MB}
|
||||
# 服务模块
|
||||
devtools:
|
||||
restart:
|
||||
|
||||
Reference in New Issue
Block a user