You've already forked FrameTour-BE
render_v2
This commit is contained in:
@@ -1161,6 +1161,228 @@ fallbackService.clearAllFallbackCache("zt-render-worker");
|
|||||||
- **Active (isActive=1)**: Worker is available for tasks
|
- **Active (isActive=1)**: Worker is available for tasks
|
||||||
- **Inactive (isActive=0)**: Worker is disabled
|
- **Inactive (isActive=0)**: Worker is disabled
|
||||||
|
|
||||||
|
## Render Template Integration (ZT-Render-Worker Microservice)
|
||||||
|
|
||||||
|
### Key Components
|
||||||
|
|
||||||
|
#### Feign Clients
|
||||||
|
- **RenderTemplateV2Client**: Template CRUD operations, segment management
|
||||||
|
|
||||||
|
#### Services
|
||||||
|
- **RenderTemplateIntegrationService**: High-level template operations (with automatic fallback for queries)
|
||||||
|
|
||||||
|
### Usage Examples
|
||||||
|
|
||||||
|
#### Basic Template Operations
|
||||||
|
```java
|
||||||
|
@Autowired
|
||||||
|
private RenderTemplateIntegrationService templateService;
|
||||||
|
|
||||||
|
// Create template (direct operation, fails immediately on error)
|
||||||
|
CreateTemplateRequest createRequest = new CreateTemplateRequest();
|
||||||
|
createRequest.setScenicId(1001L);
|
||||||
|
createRequest.setName("新年贺卡模板");
|
||||||
|
createRequest.setDescription("用于新年祝福的模板");
|
||||||
|
createRequest.setDefaultDurationMs(10000L);
|
||||||
|
|
||||||
|
OutputSpecDTO outputSpec = new OutputSpecDTO();
|
||||||
|
outputSpec.setWidth(1080);
|
||||||
|
outputSpec.setHeight(1920);
|
||||||
|
outputSpec.setFps(30);
|
||||||
|
createRequest.setOutputSpec(outputSpec);
|
||||||
|
|
||||||
|
TemplateV2DTO template = templateService.createTemplate(createRequest);
|
||||||
|
|
||||||
|
// Get template details (automatically falls back to cache on failure)
|
||||||
|
TemplateV2DTO templateInfo = templateService.getTemplate(templateId);
|
||||||
|
|
||||||
|
// Get template with segments (automatically falls back to cache on failure)
|
||||||
|
TemplateV2WithSegmentsDTO templateWithSegments = templateService.getTemplateWithSegments(templateId);
|
||||||
|
|
||||||
|
// List templates (no fallback for list operations)
|
||||||
|
PageResponse<TemplateV2DTO> templates = templateService.listTemplates(1, 10, scenicId, 1, null);
|
||||||
|
|
||||||
|
// Update template (direct operation, fails immediately on error)
|
||||||
|
UpdateTemplateRequest updateRequest = new UpdateTemplateRequest();
|
||||||
|
updateRequest.setName("更新后的模板名称");
|
||||||
|
templateService.updateTemplate(templateId, updateRequest);
|
||||||
|
|
||||||
|
// Publish template (direct operation, fails immediately on error)
|
||||||
|
templateService.publishTemplate(templateId);
|
||||||
|
|
||||||
|
// Create new version (direct operation, fails immediately on error)
|
||||||
|
TemplateV2DTO newVersion = templateService.createTemplateVersion(templateId);
|
||||||
|
|
||||||
|
// Delete template (direct operation, fails immediately on error)
|
||||||
|
templateService.deleteTemplate(templateId);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Segment Management
|
||||||
|
```java
|
||||||
|
// Get template segments (automatically falls back to cache on failure)
|
||||||
|
List<TemplateV2SegmentDTO> segments = templateService.getTemplateSegments(templateId);
|
||||||
|
|
||||||
|
// Create segment (direct operation, fails immediately on error)
|
||||||
|
CreateSegmentRequest segmentRequest = new CreateSegmentRequest();
|
||||||
|
segmentRequest.setSegmentIndex(0);
|
||||||
|
segmentRequest.setSegmentType("RENDER");
|
||||||
|
segmentRequest.setSourceType("SLOT");
|
||||||
|
segmentRequest.setSourceRef("slot1");
|
||||||
|
segmentRequest.setDurationMs(2000L);
|
||||||
|
segmentRequest.setTransitionType("fade");
|
||||||
|
segmentRequest.setTransitionMs(500);
|
||||||
|
|
||||||
|
RenderSpecDTO renderSpec = new RenderSpecDTO();
|
||||||
|
renderSpec.setCropEnable(true);
|
||||||
|
renderSpec.setSpeed("1.0");
|
||||||
|
segmentRequest.setRenderSpec(renderSpec);
|
||||||
|
|
||||||
|
TemplateV2SegmentDTO segment = templateService.createSegment(templateId, segmentRequest);
|
||||||
|
|
||||||
|
// Update segment (direct operation, fails immediately on error)
|
||||||
|
UpdateSegmentRequest updateSegmentRequest = new UpdateSegmentRequest();
|
||||||
|
updateSegmentRequest.setDurationMs(3000L);
|
||||||
|
templateService.updateSegment(templateId, segmentId, updateSegmentRequest);
|
||||||
|
|
||||||
|
// Delete segment (direct operation, fails immediately on error)
|
||||||
|
templateService.deleteSegment(templateId, segmentId);
|
||||||
|
|
||||||
|
// Replace all segments (direct operation, fails immediately on error)
|
||||||
|
ReplaceSegmentsRequest replaceRequest = new ReplaceSegmentsRequest();
|
||||||
|
replaceRequest.setSegments(Arrays.asList(segmentRequest1, segmentRequest2));
|
||||||
|
templateService.replaceSegments(templateId, replaceRequest);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Template Status
|
||||||
|
- **0**: Draft - Template is being edited
|
||||||
|
- **1**: Published - Template is live and available for rendering
|
||||||
|
|
||||||
|
### Segment Types
|
||||||
|
- **FIXED**: Fixed asset segment
|
||||||
|
- **RENDER**: Segment that needs to be rendered with user materials
|
||||||
|
|
||||||
|
### Source Types
|
||||||
|
- **ASSET**: Fixed asset resource
|
||||||
|
- **PLACEHOLDER_VIDEO**: Video placeholder slot
|
||||||
|
- **PLACEHOLDER_IMAGE**: Image placeholder slot
|
||||||
|
- **SLOT**: Material slot
|
||||||
|
|
||||||
|
## Render Job Integration (ZT-Render-Worker Microservice)
|
||||||
|
|
||||||
|
### Key Components
|
||||||
|
|
||||||
|
#### Feign Clients
|
||||||
|
- **RenderJobV2Client**: Job creation, status queries, admin operations
|
||||||
|
|
||||||
|
#### Services
|
||||||
|
- **RenderJobIntegrationService**: High-level job operations (with automatic fallback for queries)
|
||||||
|
|
||||||
|
### Usage Examples
|
||||||
|
|
||||||
|
#### Creating and Managing Render Jobs
|
||||||
|
```java
|
||||||
|
@Autowired
|
||||||
|
private RenderJobIntegrationService jobService;
|
||||||
|
|
||||||
|
// Create preview job (direct operation, fails immediately on error)
|
||||||
|
CreatePreviewRequest previewRequest = new CreatePreviewRequest();
|
||||||
|
previewRequest.setTemplateId(123L);
|
||||||
|
previewRequest.setScenicId(456L);
|
||||||
|
previewRequest.setFaceId(789L);
|
||||||
|
previewRequest.setMemberId(101L);
|
||||||
|
|
||||||
|
// Set materials by slot
|
||||||
|
Map<String, List<MaterialDTO>> materialsBySlot = new HashMap<>();
|
||||||
|
MaterialDTO material = new MaterialDTO();
|
||||||
|
material.setUrl("https://example.com/video.mp4");
|
||||||
|
material.setType("video");
|
||||||
|
material.setDuration(5000L);
|
||||||
|
materialsBySlot.put("slot1", Arrays.asList(material));
|
||||||
|
previewRequest.setMaterialsBySlot(materialsBySlot);
|
||||||
|
|
||||||
|
CreatePreviewResponse previewResponse = jobService.createPreview(previewRequest);
|
||||||
|
log.info("作业创建成功, jobId: {}, playUrl: {}", previewResponse.getJobId(), previewResponse.getPlayUrl());
|
||||||
|
|
||||||
|
// Get job status (automatically falls back to cache on failure)
|
||||||
|
JobStatusResponse status = jobService.getJobStatus(jobId);
|
||||||
|
log.info("作业状态: {}, 进度: {}%", status.getStatus(), status.getProgress());
|
||||||
|
|
||||||
|
// Get playlist info (automatically falls back to cache on failure)
|
||||||
|
PlaylistInfoDTO playlistInfo = jobService.getPlaylistInfo(jobId);
|
||||||
|
log.info("总片段: {}, 已发布: {}", playlistInfo.getSegmentCount(), playlistInfo.getPublishedCount());
|
||||||
|
|
||||||
|
// Get HLS playlist (direct call, returns M3U8 content)
|
||||||
|
String hlsPlaylist = jobService.getHlsPlaylist(jobId);
|
||||||
|
|
||||||
|
// Cancel job (direct operation, fails immediately on error)
|
||||||
|
jobService.cancelJob(jobId);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Admin Operations
|
||||||
|
```java
|
||||||
|
// List jobs (no fallback for list operations)
|
||||||
|
PageResponse<RenderJobV2DTO> jobs = jobService.listJobs(scenicId, templateId, "RUNNING", "PREVIEW", 1, 20);
|
||||||
|
log.info("查询到 {} 条作业", jobs.getTotal());
|
||||||
|
|
||||||
|
// Get job detail (automatically falls back to cache on failure)
|
||||||
|
RenderJobV2DTO jobDetail = jobService.getJobDetail(jobId);
|
||||||
|
log.info("作业详情: templateId={}, status={}", jobDetail.getTemplateId(), jobDetail.getStatus());
|
||||||
|
|
||||||
|
// Get job segments (automatically falls back to cache on failure)
|
||||||
|
List<RenderJobSegmentV2DTO> jobSegments = jobService.getJobSegments(jobId);
|
||||||
|
for (RenderJobSegmentV2DTO segment : jobSegments) {
|
||||||
|
log.info("片段 {}: status={}, tsUrl={}", segment.getPlanSegmentIndex(), segment.getStatus(), segment.getTsUrl());
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Job Status
|
||||||
|
- **PENDING**: Job is waiting to be processed
|
||||||
|
- **RUNNING**: Job is currently being processed
|
||||||
|
- **SUCCESS**: Job completed successfully
|
||||||
|
- **FAILED**: Job failed
|
||||||
|
- **CANCELED**: Job was canceled
|
||||||
|
|
||||||
|
### Job Types
|
||||||
|
- **PREVIEW**: Preview job (HLS streaming)
|
||||||
|
- **PREVIEW_HLS**: HLS preview job
|
||||||
|
- **FINAL_MP4**: Final MP4 export job
|
||||||
|
|
||||||
|
### Segment Status
|
||||||
|
- **PENDING**: Segment is waiting to be processed
|
||||||
|
- **RENDERING**: Segment is being rendered
|
||||||
|
- **VIDEO_READY**: Video is ready
|
||||||
|
- **PACKAGING**: Segment is being packaged
|
||||||
|
- **TS_READY**: TS file is ready
|
||||||
|
- **PUBLISHED**: Segment is published and available
|
||||||
|
- **FAILED**: Segment processing failed
|
||||||
|
|
||||||
|
### Fallback Cache Management for Templates and Jobs
|
||||||
|
```java
|
||||||
|
@Autowired
|
||||||
|
private IntegrationFallbackService fallbackService;
|
||||||
|
|
||||||
|
// Check fallback cache status for templates
|
||||||
|
boolean hasTemplateCache = fallbackService.hasFallbackCache("zt-render-worker", "template:1001");
|
||||||
|
boolean hasTemplateSegmentsCache = fallbackService.hasFallbackCache("zt-render-worker", "template:segments:1001");
|
||||||
|
|
||||||
|
// Check fallback cache status for jobs
|
||||||
|
boolean hasJobStatusCache = fallbackService.hasFallbackCache("zt-render-worker", "job:status:2001");
|
||||||
|
boolean hasJobDetailCache = fallbackService.hasFallbackCache("zt-render-worker", "job:detail:2001");
|
||||||
|
|
||||||
|
// Get cache statistics
|
||||||
|
IntegrationFallbackService.FallbackCacheStats stats =
|
||||||
|
fallbackService.getFallbackCacheStats("zt-render-worker");
|
||||||
|
log.info("Render fallback cache: {} items, TTL: {} days",
|
||||||
|
stats.getTotalCacheCount(), stats.getFallbackTtlDays());
|
||||||
|
|
||||||
|
// Clear specific cache
|
||||||
|
fallbackService.clearFallbackCache("zt-render-worker", "template:1001");
|
||||||
|
fallbackService.clearFallbackCache("zt-render-worker", "job:status:2001");
|
||||||
|
|
||||||
|
// Clear all render worker caches
|
||||||
|
fallbackService.clearAllFallbackCache("zt-render-worker");
|
||||||
|
```
|
||||||
|
|
||||||
## ZT-Message Integration (Kafka Producer)
|
## ZT-Message Integration (Kafka Producer)
|
||||||
|
|
||||||
### Overview
|
### Overview
|
||||||
|
|||||||
@@ -0,0 +1,75 @@
|
|||||||
|
package com.ycwl.basic.integration.render.client;
|
||||||
|
|
||||||
|
import com.ycwl.basic.integration.common.response.CommonResponse;
|
||||||
|
import com.ycwl.basic.integration.common.response.PageResponse;
|
||||||
|
import com.ycwl.basic.integration.render.dto.job.*;
|
||||||
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 渲染作业V2客户端
|
||||||
|
*/
|
||||||
|
@FeignClient(name = "zt-render-worker", contextId = "render-job-v2", path = "/api/render/v2")
|
||||||
|
public interface RenderJobV2Client {
|
||||||
|
|
||||||
|
// ==================== 小程序侧接口 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建预览作业
|
||||||
|
*/
|
||||||
|
@PostMapping("/preview")
|
||||||
|
CommonResponse<CreatePreviewResponse> createPreview(@RequestBody CreatePreviewRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取作业状态
|
||||||
|
*/
|
||||||
|
@GetMapping("/jobs/{jobId}")
|
||||||
|
CommonResponse<JobStatusResponse> getJobStatus(@PathVariable("jobId") Long jobId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取HLS播放列表
|
||||||
|
* 返回M3U8格式的文本内容
|
||||||
|
*/
|
||||||
|
@GetMapping("/jobs/{jobId}/index.m3u8")
|
||||||
|
String getHlsPlaylist(@PathVariable("jobId") Long jobId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取播放列表信息
|
||||||
|
*/
|
||||||
|
@GetMapping("/jobs/{jobId}/playlist-info")
|
||||||
|
CommonResponse<PlaylistInfoDTO> getPlaylistInfo(@PathVariable("jobId") Long jobId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消作业
|
||||||
|
*/
|
||||||
|
@PostMapping("/jobs/{jobId}/cancel")
|
||||||
|
CommonResponse<Void> cancelJob(@PathVariable("jobId") Long jobId);
|
||||||
|
|
||||||
|
// ==================== 管理端接口 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取作业列表
|
||||||
|
*/
|
||||||
|
@GetMapping("/admin/jobs")
|
||||||
|
CommonResponse<PageResponse<RenderJobV2DTO>> listJobs(
|
||||||
|
@RequestParam(required = false) Long scenicId,
|
||||||
|
@RequestParam(required = false) Long templateId,
|
||||||
|
@RequestParam(required = false) String status,
|
||||||
|
@RequestParam(required = false) String jobType,
|
||||||
|
@RequestParam(defaultValue = "1") Integer page,
|
||||||
|
@RequestParam(defaultValue = "20") Integer pageSize);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取作业详情
|
||||||
|
*/
|
||||||
|
@GetMapping("/admin/jobs/{jobId}")
|
||||||
|
CommonResponse<RenderJobV2DTO> getJobDetail(@PathVariable("jobId") Long jobId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取作业片段列表
|
||||||
|
*/
|
||||||
|
@GetMapping("/admin/jobs/{jobId}/segments")
|
||||||
|
CommonResponse<List<RenderJobSegmentV2DTO>> getJobSegments(@PathVariable("jobId") Long jobId);
|
||||||
|
}
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
package com.ycwl.basic.integration.render.client;
|
||||||
|
|
||||||
|
import com.ycwl.basic.integration.common.response.CommonResponse;
|
||||||
|
import com.ycwl.basic.integration.common.response.PageResponse;
|
||||||
|
import com.ycwl.basic.integration.render.dto.template.*;
|
||||||
|
import org.springframework.cloud.openfeign.FeignClient;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 渲染模板V2客户端
|
||||||
|
*/
|
||||||
|
@FeignClient(name = "zt-render-worker", contextId = "render-template-v2", path = "/api/render/template/v2")
|
||||||
|
public interface RenderTemplateV2Client {
|
||||||
|
|
||||||
|
// ==================== Template CRUD Operations ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建模板
|
||||||
|
*/
|
||||||
|
@PostMapping
|
||||||
|
CommonResponse<TemplateV2DTO> createTemplate(@RequestBody CreateTemplateRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取模板列表
|
||||||
|
*/
|
||||||
|
@GetMapping
|
||||||
|
CommonResponse<PageResponse<TemplateV2DTO>> listTemplates(
|
||||||
|
@RequestParam(defaultValue = "1") Integer page,
|
||||||
|
@RequestParam(defaultValue = "10") Integer pageSize,
|
||||||
|
@RequestParam(required = false) Long scenicId,
|
||||||
|
@RequestParam(required = false) Integer status,
|
||||||
|
@RequestParam(required = false) String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取模板详情
|
||||||
|
*/
|
||||||
|
@GetMapping("/{id}")
|
||||||
|
CommonResponse<TemplateV2DTO> getTemplate(@PathVariable("id") Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取模板及其片段
|
||||||
|
*/
|
||||||
|
@GetMapping("/{id}/with-segments")
|
||||||
|
CommonResponse<TemplateV2WithSegmentsDTO> getTemplateWithSegments(@PathVariable("id") Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新模板
|
||||||
|
*/
|
||||||
|
@PutMapping("/{id}")
|
||||||
|
CommonResponse<Void> updateTemplate(@PathVariable("id") Long id,
|
||||||
|
@RequestBody UpdateTemplateRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除模板
|
||||||
|
*/
|
||||||
|
@DeleteMapping("/{id}")
|
||||||
|
CommonResponse<Void> deleteTemplate(@PathVariable("id") Long id);
|
||||||
|
|
||||||
|
// ==================== Template Operations ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发布模板
|
||||||
|
*/
|
||||||
|
@PostMapping("/{id}/publish")
|
||||||
|
CommonResponse<Void> publishTemplate(@PathVariable("id") Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建新版本
|
||||||
|
*/
|
||||||
|
@PostMapping("/{id}/version")
|
||||||
|
CommonResponse<TemplateV2DTO> createTemplateVersion(@PathVariable("id") Long id);
|
||||||
|
|
||||||
|
// ==================== Segment Management ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取模板片段列表
|
||||||
|
*/
|
||||||
|
@GetMapping("/{id}/segments")
|
||||||
|
CommonResponse<List<TemplateV2SegmentDTO>> getTemplateSegments(@PathVariable("id") Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建片段
|
||||||
|
*/
|
||||||
|
@PostMapping("/{id}/segments")
|
||||||
|
CommonResponse<TemplateV2SegmentDTO> createSegment(@PathVariable("id") Long id,
|
||||||
|
@RequestBody CreateSegmentRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新片段
|
||||||
|
*/
|
||||||
|
@PutMapping("/{id}/segments/{segmentId}")
|
||||||
|
CommonResponse<Void> updateSegment(@PathVariable("id") Long id,
|
||||||
|
@PathVariable("segmentId") Long segmentId,
|
||||||
|
@RequestBody UpdateSegmentRequest request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除片段
|
||||||
|
*/
|
||||||
|
@DeleteMapping("/{id}/segments/{segmentId}")
|
||||||
|
CommonResponse<Void> deleteSegment(@PathVariable("id") Long id,
|
||||||
|
@PathVariable("segmentId") Long segmentId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 替换所有片段
|
||||||
|
*/
|
||||||
|
@PostMapping("/{id}/segments/replace")
|
||||||
|
CommonResponse<Void> replaceSegments(@PathVariable("id") Long id,
|
||||||
|
@RequestBody ReplaceSegmentsRequest request);
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
package com.ycwl.basic.integration.render.dto.common;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 音频参数DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class AudioSpecDTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 音频素材URL
|
||||||
|
*/
|
||||||
|
private String audioUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 音量 (0.0-1.0)
|
||||||
|
*/
|
||||||
|
private Double volume;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 淡入时长(毫秒)
|
||||||
|
*/
|
||||||
|
private Integer fadeInMs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 淡出时长(毫秒)
|
||||||
|
*/
|
||||||
|
private Integer fadeOutMs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 音频开始位置(毫秒)
|
||||||
|
*/
|
||||||
|
private Integer startMs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 延迟播放(毫秒)
|
||||||
|
*/
|
||||||
|
private Integer delayMs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否循环
|
||||||
|
*/
|
||||||
|
private Boolean loopEnable;
|
||||||
|
}
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
package com.ycwl.basic.integration.render.dto.common;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输出规格DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class OutputSpecDTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 宽度
|
||||||
|
*/
|
||||||
|
private Integer width;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 高度
|
||||||
|
*/
|
||||||
|
private Integer height;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 帧率
|
||||||
|
*/
|
||||||
|
private Integer fps;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 比特率
|
||||||
|
*/
|
||||||
|
private Integer bitrate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频编解码器 (默认h264)
|
||||||
|
*/
|
||||||
|
private String codec;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 音频编解码器 (默认aac)
|
||||||
|
*/
|
||||||
|
private String audioCodec;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 采样率 (默认48000)
|
||||||
|
*/
|
||||||
|
private Integer sampleRate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 声道数 (默认2)
|
||||||
|
*/
|
||||||
|
private Integer channels;
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package com.ycwl.basic.integration.render.dto.common;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 渲染参数DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class RenderSpecDTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否启用人脸裁切
|
||||||
|
*/
|
||||||
|
private Boolean cropEnable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 裁切后大小
|
||||||
|
*/
|
||||||
|
private String cropSize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 倍速
|
||||||
|
*/
|
||||||
|
private String speed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 调色LUT文件URL
|
||||||
|
*/
|
||||||
|
private String lutUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 叠加蒙版URL
|
||||||
|
*/
|
||||||
|
private String overlayUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 特效配置
|
||||||
|
*/
|
||||||
|
private String effects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否缩放裁切
|
||||||
|
*/
|
||||||
|
private Boolean zoomCut;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 竖屏切割位置
|
||||||
|
*/
|
||||||
|
private String videoCrop;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 人脸位置参数
|
||||||
|
*/
|
||||||
|
private String facePos;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转场效果
|
||||||
|
*/
|
||||||
|
private String transitions;
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package com.ycwl.basic.integration.render.dto.job;
|
||||||
|
|
||||||
|
import com.ycwl.basic.integration.render.dto.common.OutputSpecDTO;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建预览请求
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class CreatePreviewRequest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模板ID (必填)
|
||||||
|
*/
|
||||||
|
private Long templateId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 景区ID (必填)
|
||||||
|
*/
|
||||||
|
private Long scenicId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 人脸ID (可选)
|
||||||
|
*/
|
||||||
|
private Long faceId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会员ID (可选)
|
||||||
|
*/
|
||||||
|
private Long memberId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 素材槽映射 (可选)
|
||||||
|
* key: 槽位键
|
||||||
|
* value: 素材列表
|
||||||
|
*/
|
||||||
|
private Map<String, List<MaterialDTO>> materialsBySlot;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义输出规格 (可选)
|
||||||
|
*/
|
||||||
|
private OutputSpecDTO outputSpec;
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.ycwl.basic.integration.render.dto.job;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建预览响应
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class CreatePreviewResponse {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 作业ID
|
||||||
|
*/
|
||||||
|
private Long jobId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态
|
||||||
|
*/
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 播放URL
|
||||||
|
*/
|
||||||
|
private String playUrl;
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package com.ycwl.basic.integration.render.dto.job;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 作业状态响应
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class JobStatusResponse {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 作业ID
|
||||||
|
*/
|
||||||
|
private Long jobId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态 (PENDING, RUNNING, SUCCESS, FAILED, CANCELED)
|
||||||
|
*/
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 进度 (0.0 - 100.0)
|
||||||
|
*/
|
||||||
|
private Double progress;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 总片段数
|
||||||
|
*/
|
||||||
|
private Integer segmentCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 已发布片段数
|
||||||
|
*/
|
||||||
|
private Integer publishedCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 播放URL
|
||||||
|
*/
|
||||||
|
private String playUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MP4下载URL
|
||||||
|
*/
|
||||||
|
private String mp4Url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误码
|
||||||
|
*/
|
||||||
|
private String errorCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误信息
|
||||||
|
*/
|
||||||
|
private String errorMessage;
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package com.ycwl.basic.integration.render.dto.job;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 素材信息DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class MaterialDTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 素材URL
|
||||||
|
*/
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类型 (video, image)
|
||||||
|
*/
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时长(毫秒)
|
||||||
|
*/
|
||||||
|
private Long duration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 人脸分数
|
||||||
|
*/
|
||||||
|
private String score;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 人脸位置
|
||||||
|
*/
|
||||||
|
private String facePos;
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.ycwl.basic.integration.render.dto.job;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 播放列表信息DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class PlaylistInfoDTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 总片段数
|
||||||
|
*/
|
||||||
|
private Integer segmentCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 进度 (0.0 - 100.0)
|
||||||
|
*/
|
||||||
|
private Double progress;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 已发布片段数
|
||||||
|
*/
|
||||||
|
private Integer publishedCount;
|
||||||
|
}
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
package com.ycwl.basic.integration.render.dto.job;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import com.ycwl.basic.integration.render.dto.common.AudioSpecDTO;
|
||||||
|
import com.ycwl.basic.integration.render.dto.common.RenderSpecDTO;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 渲染作业片段V2 DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class RenderJobSegmentV2DTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 片段ID
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 作业ID
|
||||||
|
*/
|
||||||
|
private Long jobId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模板片段索引
|
||||||
|
*/
|
||||||
|
private Integer templateSegmentIndex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计划片段索引
|
||||||
|
*/
|
||||||
|
private Integer planSegmentIndex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始时间(毫秒)
|
||||||
|
*/
|
||||||
|
private Long startTimeMs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时长(毫秒)
|
||||||
|
*/
|
||||||
|
private Long durationMs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 片段类型 (RENDER, FIXED)
|
||||||
|
*/
|
||||||
|
private String segmentType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态 (PENDING, RENDERING, VIDEO_READY, PACKAGING, TS_READY, PUBLISHED, FAILED)
|
||||||
|
*/
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 素材来源类型
|
||||||
|
*/
|
||||||
|
private String sourceType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 素材来源引用
|
||||||
|
*/
|
||||||
|
private String sourceRef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定素材URL
|
||||||
|
*/
|
||||||
|
private String boundMaterialUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 渲染参数JSON
|
||||||
|
*/
|
||||||
|
@JsonProperty("renderSpecJson")
|
||||||
|
private RenderSpecDTO renderSpecJson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 音频参数JSON
|
||||||
|
*/
|
||||||
|
@JsonProperty("audioSpecJson")
|
||||||
|
private AudioSpecDTO audioSpecJson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 视频URL
|
||||||
|
*/
|
||||||
|
private String videoUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TS文件URL
|
||||||
|
*/
|
||||||
|
private String tsUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TS时长(秒)
|
||||||
|
*/
|
||||||
|
private Double tsDuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@JsonProperty("createTime")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
@JsonProperty("updateTime")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||||
|
private Date updateTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,144 @@
|
|||||||
|
package com.ycwl.basic.integration.render.dto.job;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 渲染作业V2 DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class RenderJobV2DTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 作业ID
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 作业类型 (PREVIEW, PREVIEW_HLS, FINAL_MP4)
|
||||||
|
*/
|
||||||
|
private String jobType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态 (PENDING, RUNNING, SUCCESS, FAILED, CANCELED)
|
||||||
|
*/
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 景区ID
|
||||||
|
*/
|
||||||
|
private Long scenicId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模板ID
|
||||||
|
*/
|
||||||
|
private Long templateId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模板版本
|
||||||
|
*/
|
||||||
|
private Integer templateVersion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 人脸ID
|
||||||
|
*/
|
||||||
|
private Long faceId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会员ID
|
||||||
|
*/
|
||||||
|
private Long memberId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 总时长(毫秒)
|
||||||
|
*/
|
||||||
|
private Long totalDurationMs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输出规格JSON
|
||||||
|
*/
|
||||||
|
@JsonProperty("outputSpecJson")
|
||||||
|
private Map<String, Object> outputSpecJson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 渲染计划JSON
|
||||||
|
*/
|
||||||
|
private String planJson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 总片段数
|
||||||
|
*/
|
||||||
|
private Integer segmentCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 已发布片段数
|
||||||
|
*/
|
||||||
|
private Integer publishedCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 已完成片段数
|
||||||
|
*/
|
||||||
|
private Integer completedCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* M3U8播放地址
|
||||||
|
*/
|
||||||
|
private String m3u8Url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 音频URL
|
||||||
|
*/
|
||||||
|
private String audioUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MP4下载地址
|
||||||
|
*/
|
||||||
|
private String mp4Url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误码
|
||||||
|
*/
|
||||||
|
private String errorCode;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误信息
|
||||||
|
*/
|
||||||
|
private String errorMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 幂等键
|
||||||
|
*/
|
||||||
|
private String idempotencyKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始时间
|
||||||
|
*/
|
||||||
|
@JsonProperty("startTime")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||||
|
private Date startTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 完成时间
|
||||||
|
*/
|
||||||
|
@JsonProperty("finishTime")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||||
|
private Date finishTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@JsonProperty("createTime")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
@JsonProperty("updateTime")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||||
|
private Date updateTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,84 @@
|
|||||||
|
package com.ycwl.basic.integration.render.dto.template;
|
||||||
|
|
||||||
|
import com.ycwl.basic.integration.render.dto.common.AudioSpecDTO;
|
||||||
|
import com.ycwl.basic.integration.render.dto.common.RenderSpecDTO;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建片段请求
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class CreateSegmentRequest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 片段索引
|
||||||
|
*/
|
||||||
|
private Integer segmentIndex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 片段类型 (RENDER, FIXED)
|
||||||
|
*/
|
||||||
|
private String segmentType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否可缓存
|
||||||
|
*/
|
||||||
|
private Boolean cacheable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 位置是否固定
|
||||||
|
*/
|
||||||
|
private Boolean positionFixed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 素材来源类型 (ASSET, PLACEHOLDER_VIDEO, PLACEHOLDER_IMAGE, SLOT)
|
||||||
|
*/
|
||||||
|
private String sourceType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 素材来源引用
|
||||||
|
*/
|
||||||
|
private String sourceRef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时长(毫秒)
|
||||||
|
*/
|
||||||
|
private Long durationMs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转场类型
|
||||||
|
*/
|
||||||
|
private String transitionType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转场时长(毫秒)
|
||||||
|
*/
|
||||||
|
private Integer transitionMs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 素材槽位键
|
||||||
|
*/
|
||||||
|
private String slotKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 条件表达式
|
||||||
|
*/
|
||||||
|
private Map<String, Object> onlyIfExpr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 渲染参数
|
||||||
|
*/
|
||||||
|
private RenderSpecDTO renderSpec;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 音频参数
|
||||||
|
*/
|
||||||
|
private AudioSpecDTO audioSpec;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 扩展属性
|
||||||
|
*/
|
||||||
|
private Map<String, Object> extendedProps;
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package com.ycwl.basic.integration.render.dto.template;
|
||||||
|
|
||||||
|
import com.ycwl.basic.integration.render.dto.common.OutputSpecDTO;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建模板请求
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class CreateTemplateRequest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 景区ID
|
||||||
|
*/
|
||||||
|
private Long scenicId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模板名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 描述
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缩略图URL
|
||||||
|
*/
|
||||||
|
private String thumbnailUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认时长(毫秒)
|
||||||
|
*/
|
||||||
|
private Long defaultDurationMs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输出规格
|
||||||
|
*/
|
||||||
|
private OutputSpecDTO outputSpec;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 背景音乐URL
|
||||||
|
*/
|
||||||
|
private String bgmUrl;
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package com.ycwl.basic.integration.render.dto.template;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 替换所有片段请求
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ReplaceSegmentsRequest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 片段列表
|
||||||
|
*/
|
||||||
|
private List<CreateSegmentRequest> segments;
|
||||||
|
}
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
package com.ycwl.basic.integration.render.dto.template;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import com.ycwl.basic.integration.render.dto.common.OutputSpecDTO;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 渲染模板V2 DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class TemplateV2DTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模板ID
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 景区ID
|
||||||
|
*/
|
||||||
|
private Long scenicId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模板名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 版本号
|
||||||
|
*/
|
||||||
|
private Integer version;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 状态 (0-草稿, 1-已发布)
|
||||||
|
*/
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 描述
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缩略图URL
|
||||||
|
*/
|
||||||
|
private String thumbnailUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认时长(毫秒)
|
||||||
|
*/
|
||||||
|
private Long defaultDurationMs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输出规格
|
||||||
|
*/
|
||||||
|
private OutputSpecDTO outputSpec;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输出宽度
|
||||||
|
*/
|
||||||
|
private Integer outputWidth;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输出高度
|
||||||
|
*/
|
||||||
|
private Integer outputHeight;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输出帧率
|
||||||
|
*/
|
||||||
|
private Integer outputFps;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 背景音乐URL
|
||||||
|
*/
|
||||||
|
private String bgmUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 背景音乐是否固定
|
||||||
|
*/
|
||||||
|
private Boolean bgmFixed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 封面URL
|
||||||
|
*/
|
||||||
|
private String coverUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@JsonProperty("createTime")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
@JsonProperty("updateTime")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||||
|
private Date updateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除标记
|
||||||
|
*/
|
||||||
|
private Integer deleted;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除时间
|
||||||
|
*/
|
||||||
|
@JsonProperty("deletedAt")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||||
|
private Date deletedAt;
|
||||||
|
}
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
package com.ycwl.basic.integration.render.dto.template;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
import com.ycwl.basic.integration.render.dto.common.AudioSpecDTO;
|
||||||
|
import com.ycwl.basic.integration.render.dto.common.RenderSpecDTO;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模板片段V2 DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class TemplateV2SegmentDTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 片段ID
|
||||||
|
*/
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模板ID
|
||||||
|
*/
|
||||||
|
private Long templateId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 片段索引
|
||||||
|
*/
|
||||||
|
private Integer segmentIndex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 片段类型 (RENDER, FIXED)
|
||||||
|
*/
|
||||||
|
private String segmentType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否可缓存
|
||||||
|
*/
|
||||||
|
private Boolean cacheable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 位置是否固定
|
||||||
|
*/
|
||||||
|
private Boolean positionFixed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时长(毫秒)
|
||||||
|
*/
|
||||||
|
private Long durationMs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转场类型
|
||||||
|
*/
|
||||||
|
private String transitionType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转场时长(毫秒)
|
||||||
|
*/
|
||||||
|
private Integer transitionMs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 素材槽位键
|
||||||
|
*/
|
||||||
|
private String slotKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 条件表达式JSON
|
||||||
|
*/
|
||||||
|
@JsonProperty("onlyIfExprJson")
|
||||||
|
private Map<String, Object> onlyIfExprJson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 素材来源类型 (ASSET, PLACEHOLDER_VIDEO, PLACEHOLDER_IMAGE, SLOT)
|
||||||
|
*/
|
||||||
|
private String sourceType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 素材来源引用
|
||||||
|
*/
|
||||||
|
private String sourceRef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 渲染参数JSON
|
||||||
|
*/
|
||||||
|
@JsonProperty("renderSpecJson")
|
||||||
|
private RenderSpecDTO renderSpecJson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 音频参数JSON
|
||||||
|
*/
|
||||||
|
@JsonProperty("audioSpecJson")
|
||||||
|
private AudioSpecDTO audioSpecJson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 扩展属性JSON
|
||||||
|
*/
|
||||||
|
@JsonProperty("extendedPropsJson")
|
||||||
|
private Map<String, Object> extendedPropsJson;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建时间
|
||||||
|
*/
|
||||||
|
@JsonProperty("createTime")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新时间
|
||||||
|
*/
|
||||||
|
@JsonProperty("updateTime")
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||||
|
private Date updateTime;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.ycwl.basic.integration.render.dto.template;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模板及其片段响应DTO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class TemplateV2WithSegmentsDTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模板信息
|
||||||
|
*/
|
||||||
|
private TemplateV2DTO template;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 片段列表
|
||||||
|
*/
|
||||||
|
private List<TemplateV2SegmentDTO> segments;
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
package com.ycwl.basic.integration.render.dto.template;
|
||||||
|
|
||||||
|
import com.ycwl.basic.integration.render.dto.common.AudioSpecDTO;
|
||||||
|
import com.ycwl.basic.integration.render.dto.common.RenderSpecDTO;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新片段请求
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class UpdateSegmentRequest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 片段索引
|
||||||
|
*/
|
||||||
|
private Integer segmentIndex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 片段类型 (RENDER, FIXED)
|
||||||
|
*/
|
||||||
|
private String segmentType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否可缓存
|
||||||
|
*/
|
||||||
|
private Boolean cacheable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 素材来源类型 (ASSET, PLACEHOLDER_VIDEO, PLACEHOLDER_IMAGE, SLOT)
|
||||||
|
*/
|
||||||
|
private String sourceType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 素材来源引用
|
||||||
|
*/
|
||||||
|
private String sourceRef;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 时长(毫秒)
|
||||||
|
*/
|
||||||
|
private Long durationMs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转场类型
|
||||||
|
*/
|
||||||
|
private String transitionType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转场时长(毫秒)
|
||||||
|
*/
|
||||||
|
private Integer transitionMs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 素材槽位键
|
||||||
|
*/
|
||||||
|
private String slotKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 条件表达式
|
||||||
|
*/
|
||||||
|
private Map<String, Object> onlyIfExpr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 渲染参数
|
||||||
|
*/
|
||||||
|
private RenderSpecDTO renderSpec;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 音频参数
|
||||||
|
*/
|
||||||
|
private AudioSpecDTO audioSpec;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 扩展属性
|
||||||
|
*/
|
||||||
|
private Map<String, Object> extendedProps;
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package com.ycwl.basic.integration.render.dto.template;
|
||||||
|
|
||||||
|
import com.ycwl.basic.integration.render.dto.common.OutputSpecDTO;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新模板请求
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class UpdateTemplateRequest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模板名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 描述
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 缩略图URL
|
||||||
|
*/
|
||||||
|
private String thumbnailUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 默认时长(毫秒)
|
||||||
|
*/
|
||||||
|
private Long defaultDurationMs;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输出规格
|
||||||
|
*/
|
||||||
|
private OutputSpecDTO outputSpec;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 背景音乐URL
|
||||||
|
*/
|
||||||
|
private String bgmUrl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 背景音乐是否固定
|
||||||
|
*/
|
||||||
|
private Boolean bgmFixed;
|
||||||
|
}
|
||||||
@@ -0,0 +1,168 @@
|
|||||||
|
package com.ycwl.basic.integration.render.service;
|
||||||
|
|
||||||
|
import com.ycwl.basic.integration.common.exception.IntegrationException;
|
||||||
|
import com.ycwl.basic.integration.common.response.CommonResponse;
|
||||||
|
import com.ycwl.basic.integration.common.response.PageResponse;
|
||||||
|
import com.ycwl.basic.integration.common.service.IntegrationFallbackService;
|
||||||
|
import com.ycwl.basic.integration.render.client.RenderJobV2Client;
|
||||||
|
import com.ycwl.basic.integration.render.dto.job.*;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 渲染作业集成服务
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class RenderJobIntegrationService {
|
||||||
|
|
||||||
|
private final RenderJobV2Client renderJobV2Client;
|
||||||
|
private final IntegrationFallbackService fallbackService;
|
||||||
|
|
||||||
|
private static final String SERVICE_NAME = "zt-render-worker";
|
||||||
|
|
||||||
|
// ==================== 小程序侧接口 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建预览作业(直接调用,不降级)
|
||||||
|
*/
|
||||||
|
public CreatePreviewResponse createPreview(CreatePreviewRequest request) {
|
||||||
|
log.debug("创建预览作业, templateId: {}, scenicId: {}", request.getTemplateId(), request.getScenicId());
|
||||||
|
CommonResponse<CreatePreviewResponse> response = renderJobV2Client.createPreview(request);
|
||||||
|
return handleResponse(response, "创建预览作业失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取作业状态(带降级)
|
||||||
|
*/
|
||||||
|
public JobStatusResponse getJobStatus(Long jobId) {
|
||||||
|
log.debug("获取作业状态, jobId: {}", jobId);
|
||||||
|
return fallbackService.executeWithFallback(
|
||||||
|
SERVICE_NAME,
|
||||||
|
"job:status:" + jobId,
|
||||||
|
() -> {
|
||||||
|
CommonResponse<JobStatusResponse> response = renderJobV2Client.getJobStatus(jobId);
|
||||||
|
return handleResponse(response, "获取作业状态失败");
|
||||||
|
},
|
||||||
|
JobStatusResponse.class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取HLS播放列表
|
||||||
|
* 返回M3U8格式的文本内容(不降级)
|
||||||
|
*/
|
||||||
|
public String getHlsPlaylist(Long jobId) {
|
||||||
|
log.debug("获取HLS播放列表, jobId: {}", jobId);
|
||||||
|
try {
|
||||||
|
return renderJobV2Client.getHlsPlaylist(jobId);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("获取HLS播放列表失败, jobId: {}", jobId, e);
|
||||||
|
throw new IntegrationException(5000, "获取HLS播放列表失败: " + e.getMessage(), SERVICE_NAME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取播放列表信息(带降级)
|
||||||
|
*/
|
||||||
|
public PlaylistInfoDTO getPlaylistInfo(Long jobId) {
|
||||||
|
log.debug("获取播放列表信息, jobId: {}", jobId);
|
||||||
|
return fallbackService.executeWithFallback(
|
||||||
|
SERVICE_NAME,
|
||||||
|
"job:playlist-info:" + jobId,
|
||||||
|
() -> {
|
||||||
|
CommonResponse<PlaylistInfoDTO> response = renderJobV2Client.getPlaylistInfo(jobId);
|
||||||
|
return handleResponse(response, "获取播放列表信息失败");
|
||||||
|
},
|
||||||
|
PlaylistInfoDTO.class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 取消作业(直接调用,不降级)
|
||||||
|
*/
|
||||||
|
public void cancelJob(Long jobId) {
|
||||||
|
log.debug("取消作业, jobId: {}", jobId);
|
||||||
|
CommonResponse<Void> response = renderJobV2Client.cancelJob(jobId);
|
||||||
|
handleVoidResponse(response, "取消作业失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== 管理端接口 ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取作业列表(不降级)
|
||||||
|
*/
|
||||||
|
public PageResponse<RenderJobV2DTO> listJobs(Long scenicId, Long templateId, String status,
|
||||||
|
String jobType, Integer page, Integer pageSize) {
|
||||||
|
log.debug("查询作业列表, scenicId: {}, templateId: {}, status: {}, jobType: {}, page: {}, pageSize: {}",
|
||||||
|
scenicId, templateId, status, jobType, page, pageSize);
|
||||||
|
CommonResponse<PageResponse<RenderJobV2DTO>> response =
|
||||||
|
renderJobV2Client.listJobs(scenicId, templateId, status, jobType, page, pageSize);
|
||||||
|
return handleResponse(response, "查询作业列表失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取作业详情(带降级)
|
||||||
|
*/
|
||||||
|
public RenderJobV2DTO getJobDetail(Long jobId) {
|
||||||
|
log.debug("获取作业详情, jobId: {}", jobId);
|
||||||
|
return fallbackService.executeWithFallback(
|
||||||
|
SERVICE_NAME,
|
||||||
|
"job:detail:" + jobId,
|
||||||
|
() -> {
|
||||||
|
CommonResponse<RenderJobV2DTO> response = renderJobV2Client.getJobDetail(jobId);
|
||||||
|
return handleResponse(response, "获取作业详情失败");
|
||||||
|
},
|
||||||
|
RenderJobV2DTO.class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取作业片段列表(带降级)
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public List<RenderJobSegmentV2DTO> getJobSegments(Long jobId) {
|
||||||
|
log.debug("获取作业片段列表, jobId: {}", jobId);
|
||||||
|
return fallbackService.executeWithFallback(
|
||||||
|
SERVICE_NAME,
|
||||||
|
"job:segments:" + jobId,
|
||||||
|
() -> {
|
||||||
|
CommonResponse<List<RenderJobSegmentV2DTO>> response =
|
||||||
|
renderJobV2Client.getJobSegments(jobId);
|
||||||
|
return handleResponse(response, "获取作业片段列表失败");
|
||||||
|
},
|
||||||
|
(Class<List<RenderJobSegmentV2DTO>>) (Class<?>) List.class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== Helper Methods ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理通用响应
|
||||||
|
*/
|
||||||
|
private <T> T handleResponse(CommonResponse<T> response, String errorMessage) {
|
||||||
|
if (response == null || !response.getSuccess()) {
|
||||||
|
String msg = response != null && response.getMessage() != null ?
|
||||||
|
response.getMessage() : errorMessage;
|
||||||
|
Integer code = response != null ? response.getCode() : 5000;
|
||||||
|
throw new IntegrationException(code, msg, SERVICE_NAME);
|
||||||
|
}
|
||||||
|
return response.getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理空响应
|
||||||
|
*/
|
||||||
|
private void handleVoidResponse(CommonResponse<Void> response, String errorMessage) {
|
||||||
|
if (response == null || !response.getSuccess()) {
|
||||||
|
String msg = response != null && response.getMessage() != null ?
|
||||||
|
response.getMessage() : errorMessage;
|
||||||
|
Integer code = response != null ? response.getCode() : 5000;
|
||||||
|
throw new IntegrationException(code, msg, SERVICE_NAME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,207 @@
|
|||||||
|
package com.ycwl.basic.integration.render.service;
|
||||||
|
|
||||||
|
import com.ycwl.basic.integration.common.exception.IntegrationException;
|
||||||
|
import com.ycwl.basic.integration.common.response.CommonResponse;
|
||||||
|
import com.ycwl.basic.integration.common.response.PageResponse;
|
||||||
|
import com.ycwl.basic.integration.common.service.IntegrationFallbackService;
|
||||||
|
import com.ycwl.basic.integration.render.client.RenderTemplateV2Client;
|
||||||
|
import com.ycwl.basic.integration.render.dto.template.*;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 渲染模板集成服务
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Service
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class RenderTemplateIntegrationService {
|
||||||
|
|
||||||
|
private final RenderTemplateV2Client renderTemplateV2Client;
|
||||||
|
private final IntegrationFallbackService fallbackService;
|
||||||
|
|
||||||
|
private static final String SERVICE_NAME = "zt-render-worker";
|
||||||
|
|
||||||
|
// ==================== Template CRUD Operations ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建模板(直接调用,不降级)
|
||||||
|
*/
|
||||||
|
public TemplateV2DTO createTemplate(CreateTemplateRequest request) {
|
||||||
|
log.debug("创建渲染模板, scenicId: {}, name: {}", request.getScenicId(), request.getName());
|
||||||
|
CommonResponse<TemplateV2DTO> response = renderTemplateV2Client.createTemplate(request);
|
||||||
|
return handleResponse(response, "创建渲染模板失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取模板列表(不降级)
|
||||||
|
*/
|
||||||
|
public PageResponse<TemplateV2DTO> listTemplates(Integer page, Integer pageSize, Long scenicId,
|
||||||
|
Integer status, String name) {
|
||||||
|
log.debug("查询渲染模板列表, page: {}, pageSize: {}, scenicId: {}, status: {}, name: {}",
|
||||||
|
page, pageSize, scenicId, status, name);
|
||||||
|
CommonResponse<PageResponse<TemplateV2DTO>> response =
|
||||||
|
renderTemplateV2Client.listTemplates(page, pageSize, scenicId, status, name);
|
||||||
|
return handleResponse(response, "查询渲染模板列表失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取模板详情(带降级)
|
||||||
|
*/
|
||||||
|
public TemplateV2DTO getTemplate(Long id) {
|
||||||
|
log.debug("获取渲染模板信息, id: {}", id);
|
||||||
|
return fallbackService.executeWithFallback(
|
||||||
|
SERVICE_NAME,
|
||||||
|
"template:" + id,
|
||||||
|
() -> {
|
||||||
|
CommonResponse<TemplateV2DTO> response = renderTemplateV2Client.getTemplate(id);
|
||||||
|
return handleResponse(response, "获取渲染模板信息失败");
|
||||||
|
},
|
||||||
|
TemplateV2DTO.class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取模板及其片段(带降级)
|
||||||
|
*/
|
||||||
|
public TemplateV2WithSegmentsDTO getTemplateWithSegments(Long id) {
|
||||||
|
log.debug("获取渲染模板及片段, id: {}", id);
|
||||||
|
return fallbackService.executeWithFallback(
|
||||||
|
SERVICE_NAME,
|
||||||
|
"template:with-segments:" + id,
|
||||||
|
() -> {
|
||||||
|
CommonResponse<TemplateV2WithSegmentsDTO> response =
|
||||||
|
renderTemplateV2Client.getTemplateWithSegments(id);
|
||||||
|
return handleResponse(response, "获取渲染模板及片段失败");
|
||||||
|
},
|
||||||
|
TemplateV2WithSegmentsDTO.class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新模板(直接调用,不降级)
|
||||||
|
*/
|
||||||
|
public void updateTemplate(Long id, UpdateTemplateRequest request) {
|
||||||
|
log.debug("更新渲染模板, id: {}, name: {}", id, request.getName());
|
||||||
|
CommonResponse<Void> response = renderTemplateV2Client.updateTemplate(id, request);
|
||||||
|
handleVoidResponse(response, "更新渲染模板失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除模板(直接调用,不降级)
|
||||||
|
*/
|
||||||
|
public void deleteTemplate(Long id) {
|
||||||
|
log.debug("删除渲染模板, id: {}", id);
|
||||||
|
CommonResponse<Void> response = renderTemplateV2Client.deleteTemplate(id);
|
||||||
|
handleVoidResponse(response, "删除渲染模板失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== Template Operations ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发布模板(直接调用,不降级)
|
||||||
|
*/
|
||||||
|
public void publishTemplate(Long id) {
|
||||||
|
log.debug("发布渲染模板, id: {}", id);
|
||||||
|
CommonResponse<Void> response = renderTemplateV2Client.publishTemplate(id);
|
||||||
|
handleVoidResponse(response, "发布渲染模板失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建新版本(直接调用,不降级)
|
||||||
|
*/
|
||||||
|
public TemplateV2DTO createTemplateVersion(Long id) {
|
||||||
|
log.debug("创建渲染模板新版本, id: {}", id);
|
||||||
|
CommonResponse<TemplateV2DTO> response = renderTemplateV2Client.createTemplateVersion(id);
|
||||||
|
return handleResponse(response, "创建渲染模板新版本失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== Segment Management ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取模板片段列表(带降级)
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public List<TemplateV2SegmentDTO> getTemplateSegments(Long id) {
|
||||||
|
log.debug("获取渲染模板片段列表, templateId: {}", id);
|
||||||
|
return fallbackService.executeWithFallback(
|
||||||
|
SERVICE_NAME,
|
||||||
|
"template:segments:" + id,
|
||||||
|
() -> {
|
||||||
|
CommonResponse<List<TemplateV2SegmentDTO>> response =
|
||||||
|
renderTemplateV2Client.getTemplateSegments(id);
|
||||||
|
return handleResponse(response, "获取渲染模板片段列表失败");
|
||||||
|
},
|
||||||
|
(Class<List<TemplateV2SegmentDTO>>) (Class<?>) List.class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建片段(直接调用,不降级)
|
||||||
|
*/
|
||||||
|
public TemplateV2SegmentDTO createSegment(Long templateId, CreateSegmentRequest request) {
|
||||||
|
log.debug("创建模板片段, templateId: {}, segmentIndex: {}", templateId, request.getSegmentIndex());
|
||||||
|
CommonResponse<TemplateV2SegmentDTO> response =
|
||||||
|
renderTemplateV2Client.createSegment(templateId, request);
|
||||||
|
return handleResponse(response, "创建模板片段失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新片段(直接调用,不降级)
|
||||||
|
*/
|
||||||
|
public void updateSegment(Long templateId, Long segmentId, UpdateSegmentRequest request) {
|
||||||
|
log.debug("更新模板片段, templateId: {}, segmentId: {}", templateId, segmentId);
|
||||||
|
CommonResponse<Void> response =
|
||||||
|
renderTemplateV2Client.updateSegment(templateId, segmentId, request);
|
||||||
|
handleVoidResponse(response, "更新模板片段失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除片段(直接调用,不降级)
|
||||||
|
*/
|
||||||
|
public void deleteSegment(Long templateId, Long segmentId) {
|
||||||
|
log.debug("删除模板片段, templateId: {}, segmentId: {}", templateId, segmentId);
|
||||||
|
CommonResponse<Void> response = renderTemplateV2Client.deleteSegment(templateId, segmentId);
|
||||||
|
handleVoidResponse(response, "删除模板片段失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 替换所有片段(直接调用,不降级)
|
||||||
|
*/
|
||||||
|
public void replaceSegments(Long templateId, ReplaceSegmentsRequest request) {
|
||||||
|
log.debug("替换所有模板片段, templateId: {}, segmentCount: {}",
|
||||||
|
templateId, request.getSegments() != null ? request.getSegments().size() : 0);
|
||||||
|
CommonResponse<Void> response = renderTemplateV2Client.replaceSegments(templateId, request);
|
||||||
|
handleVoidResponse(response, "替换所有模板片段失败");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== Helper Methods ====================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理通用响应
|
||||||
|
*/
|
||||||
|
private <T> T handleResponse(CommonResponse<T> response, String errorMessage) {
|
||||||
|
if (response == null || !response.getSuccess()) {
|
||||||
|
String msg = response != null && response.getMessage() != null ?
|
||||||
|
response.getMessage() : errorMessage;
|
||||||
|
Integer code = response != null ? response.getCode() : 5000;
|
||||||
|
throw new IntegrationException(code, msg, SERVICE_NAME);
|
||||||
|
}
|
||||||
|
return response.getData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理空响应
|
||||||
|
*/
|
||||||
|
private void handleVoidResponse(CommonResponse<Void> response, String errorMessage) {
|
||||||
|
if (response == null || !response.getSuccess()) {
|
||||||
|
String msg = response != null && response.getMessage() != null ?
|
||||||
|
response.getMessage() : errorMessage;
|
||||||
|
Integer code = response != null ? response.getCode() : 5000;
|
||||||
|
throw new IntegrationException(code, msg, SERVICE_NAME);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user