|
|
@@ -1375,46 +1375,50 @@ class AnimeController extends BaseController
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 校验生图/视频请求的 context_data 解密结果是否与 prompt 逐字节一致
|
|
|
+ * 按「prompt 优先」策略确定本次生成使用的提示词
|
|
|
*
|
|
|
- * 未携带 context_data 时兼容旧客户端放行;携带但解密失败或与 prompt 不一致时中断请求,
|
|
|
- * 解密失败与解密后不一致分别记录日志,便于联调定位。
|
|
|
+ * - 请求带 prompt:直接使用 prompt,不再拼接 context_data 的解密内容;
|
|
|
+ * - 请求不带 prompt:解密 context_data 作为提示词,解密失败直接报错;
|
|
|
+ * - 两者都没有:保持原逻辑放行,由业务层校验提示词为空。
|
|
|
*
|
|
|
- * @param array $data 请求参数
|
|
|
+ * @param array $data 请求参数(引用传递,无 prompt 时写回解密结果)
|
|
|
* @param string $scene 场景标识(用于日志区分接口)
|
|
|
*/
|
|
|
- protected function assertGenerationContext($data, $scene)
|
|
|
+ protected function applyGenerationContext(&$data, $scene)
|
|
|
{
|
|
|
$prompt = is_array($data) ? getProp($data, 'prompt', null) : null;
|
|
|
$contextData = is_array($data) ? getProp($data, 'context_data', null) : null;
|
|
|
|
|
|
- $result = GenerationContext::verify($prompt, $contextData);
|
|
|
-
|
|
|
- $logData = [
|
|
|
- 'scene' => $scene,
|
|
|
- 'status' => $result['status'],
|
|
|
- 'prompt_bytes' => $result['prompt_bytes'],
|
|
|
- 'decoded_bytes' => $result['decoded_bytes'],
|
|
|
- ];
|
|
|
-
|
|
|
- if ($result['status'] === GenerationContext::STATUS_OK) {
|
|
|
+ // 有 prompt 时优先使用 prompt,不拼接 context_data 解密内容
|
|
|
+ if (is_string($prompt) && trim($prompt) !== '') {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- // 未升级的旧客户端暂不携带 context_data,本阶段保持原逻辑放行
|
|
|
- if ($result['status'] === GenerationContext::STATUS_MISSING) {
|
|
|
- dLog('anime')->warning('生成接口未携带 context_data', $logData);
|
|
|
- return;
|
|
|
- }
|
|
|
+ // 没有 prompt 时,用 context_data 解密结果作为本次提示词
|
|
|
+ if ($contextData !== null && $contextData !== '') {
|
|
|
+ try {
|
|
|
+ $decoded = GenerationContext::decode($contextData);
|
|
|
+ } catch (\RuntimeException $e) {
|
|
|
+ dLog('anime')->error('生成接口 context_data 解密失败', [
|
|
|
+ 'scene' => $scene,
|
|
|
+ 'detail' => $e->getMessage(),
|
|
|
+ ]);
|
|
|
+ Utils::throwError('20003:' . $e->getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ $data['prompt'] = $decoded;
|
|
|
|
|
|
- $logData['detail'] = $result['message'];
|
|
|
- if ($result['status'] === GenerationContext::STATUS_MISMATCH) {
|
|
|
- $logData['prompt_sha256'] = is_string($prompt) ? substr(hash('sha256', $prompt), 0, 16) : '';
|
|
|
- $logData['decoded_sha256'] = $result['decoded_sha256'];
|
|
|
+ dLog('anime')->info('生成接口使用 context_data 解密结果作为提示词', [
|
|
|
+ 'scene' => $scene,
|
|
|
+ 'decoded_bytes' => strlen($decoded),
|
|
|
+ ]);
|
|
|
+ return;
|
|
|
}
|
|
|
- dLog('anime')->error('生成接口 context_data 校验失败', $logData);
|
|
|
|
|
|
- Utils::throwError('20003:' . $result['message']);
|
|
|
+ // prompt 与 context_data 均为空:交给后续业务校验处理
|
|
|
+ dLog('anime')->warning('生成接口未提供 prompt 与 context_data', [
|
|
|
+ 'scene' => $scene,
|
|
|
+ ]);
|
|
|
}
|
|
|
|
|
|
// 文生图(通用)
|
|
|
@@ -1430,7 +1434,7 @@ class AnimeController extends BaseController
|
|
|
|
|
|
if (!$useStream) {
|
|
|
// 原有逻辑:同步等待结果,普通 JSON 响应(格式保持不变)
|
|
|
- $this->assertGenerationContext($data, 'generateImg');
|
|
|
+ $this->applyGenerationContext($data, 'generateImg');
|
|
|
$result = $this->AnimeService->generateImg($data);
|
|
|
|
|
|
// 多张图片:data为首图URL,image_urls为全部图片URL数组,task_center_id为任务中心ID
|
|
|
@@ -1470,8 +1474,8 @@ class AnimeController extends BaseController
|
|
|
}
|
|
|
|
|
|
try {
|
|
|
- // 校验 context_data 解密结果与 prompt 是否逐字节一致,失败通过 SSE type=error 返回
|
|
|
- $this->assertGenerationContext($data, 'generateImg');
|
|
|
+ // 解密 context_data 并与用户提示词拼接,失败通过 SSE type=error 返回
|
|
|
+ $this->applyGenerationContext($data, 'generateImg');
|
|
|
// 创建图片生成任务,任务创建后立即回调发送init消息(包含任务中心ID和任务信息)
|
|
|
$result = $this->AnimeService->generateImg($data, function ($taskCenterId, $taskInfo) {
|
|
|
echo "data: " . json_encode([
|
|
|
@@ -2818,8 +2822,8 @@ class AnimeController extends BaseController
|
|
|
];
|
|
|
|
|
|
try {
|
|
|
- // 校验 context_data 解密结果与 prompt 是否逐字节一致,失败统一走 SSE type=error
|
|
|
- $this->assertGenerationContext($data, 'generateVideo');
|
|
|
+ // 解密 context_data 并与用户提示词拼接,失败统一走 SSE type=error
|
|
|
+ $this->applyGenerationContext($data, 'generateVideo');
|
|
|
// 创建视频生成任务
|
|
|
$result = $this->AnimeService->generateVideo($data);
|
|
|
$taskId = $result['task_id'];
|