|
@@ -282,12 +282,12 @@ class DeepSeekService
|
|
|
$script_name = pathinfo($originalName, PATHINFO_FILENAME);
|
|
$script_name = pathinfo($originalName, PATHINFO_FILENAME);
|
|
|
|
|
|
|
|
if (!$script_name) {
|
|
if (!$script_name) {
|
|
|
- $script_name = '剧本_' . date('YmdHis');
|
|
|
|
|
|
|
+ Utils::throwError('20003:未识别到剧本名,请联系管理员');
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 如果剧本名称已存在,添加时间戳后缀
|
|
|
|
|
- if (DB::table('mp_scripts')->where('script_name', $script_name)->where('is_deleted', 0)->exists()) {
|
|
|
|
|
- $script_name .= '_' . date('YmdHis');
|
|
|
|
|
|
|
+ // 如果同一用户的剧本名存在则提示
|
|
|
|
|
+ if (DB::table('mp_scripts')->where('script_name', $script_name)->where('user_id', $uid)->where('is_deleted', 0)->exists()) {
|
|
|
|
|
+ Utils::throwError('20003:你已上传过该剧本,请修改文件名后上传');
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 插入数据到mp_scripts表
|
|
// 插入数据到mp_scripts表
|
|
@@ -538,57 +538,109 @@ class DeepSeekService
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // 新增: 如果提供了script_id,创建剧本资产生成任务
|
|
|
|
|
+ $generateTaskId = 0;
|
|
|
|
|
+ if ($script_id > 0) {
|
|
|
|
|
+ $uid = Site::getUid();
|
|
|
|
|
+ $existingTask = DB::table('mp_script_generate_tasks')
|
|
|
|
|
+ ->where('uid', $uid)
|
|
|
|
|
+ ->where('script_id', $script_id)
|
|
|
|
|
+ ->orderByDesc('id')
|
|
|
|
|
+ ->first();
|
|
|
|
|
+
|
|
|
|
|
+ // 如果已有生成中的任务,则提示该剧本资产正在生成
|
|
|
|
|
+ if ($existingTask && in_array(getProp($existingTask, 'status'), ['pending', 'processing'])) {
|
|
|
|
|
+ Utils::throwError('20003:该剧本资产正在生成中,请稍后重试');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 创建新的生成任务
|
|
|
|
|
+ $generateTaskId = DB::table('mp_script_generate_tasks')->insertGetId([
|
|
|
|
|
+ 'uid' => $uid,
|
|
|
|
|
+ 'script_id' => $script_id,
|
|
|
|
|
+ 'sequence' => $sequence,
|
|
|
|
|
+ 'status' => 'processing',
|
|
|
|
|
+ 'prompt' => getProp($data, 'prompt', ''),
|
|
|
|
|
+ 'started_at' => date('Y-m-d H:i:s'),
|
|
|
|
|
+ 'created_at' => date('Y-m-d H:i:s'),
|
|
|
|
|
+ 'updated_at' => date('Y-m-d H:i:s')
|
|
|
|
|
+ ]);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// 根据模型类型选择调用方法(复用现有的chatOnly方法)
|
|
// 根据模型类型选择调用方法(复用现有的chatOnly方法)
|
|
|
- $aiResult = null;
|
|
|
|
|
- if (in_array($model, ['deepseek-reasoner', 'deepseek-chat', 'deepseek-v4-flash', 'deepseek-v4-pro'])) {
|
|
|
|
|
- // DeepSeek 官方模型使用现有的 chatOnly 方法
|
|
|
|
|
- $result = $this->chatOnly($post_data);
|
|
|
|
|
-
|
|
|
|
|
- // 记录实际使用的模型
|
|
|
|
|
- dLog('deepseek')->info('newGenerateText使用DeepSeek模型', ['requested_model' => $model, 'actual_model' => $model]);
|
|
|
|
|
-
|
|
|
|
|
- $aiResult = [
|
|
|
|
|
- 'content' => $result['fullContent'],
|
|
|
|
|
- 'reasoning_content' => $result['fullReasoningContent'],
|
|
|
|
|
- 'usage' => $result['usage'],
|
|
|
|
|
- 'model' => $model,
|
|
|
|
|
- 'finish_reason' => 'stop'
|
|
|
|
|
- ];
|
|
|
|
|
- } else if (in_array($model, $this->gpt_text_models)) {
|
|
|
|
|
- // GPT 模型使用现有的 gpt54ChatOnly 方法
|
|
|
|
|
- $result = $this->gpt54ChatOnly($post_data);
|
|
|
|
|
-
|
|
|
|
|
- dLog('deepseek')->info('newGenerateText使用GPT模型', ['requested_model' => $model]);
|
|
|
|
|
-
|
|
|
|
|
- $aiResult = [
|
|
|
|
|
- 'content' => $result['fullContent'],
|
|
|
|
|
- 'reasoning_content' => '',
|
|
|
|
|
- 'usage' => $result['usage'],
|
|
|
|
|
- 'model' => $model,
|
|
|
|
|
- 'finish_reason' => 'stop'
|
|
|
|
|
- ];
|
|
|
|
|
- } else if (in_array($model, $this->valid_text_models)) {
|
|
|
|
|
- // 火山引擎支持的模型使用火山引擎 API(非流式)
|
|
|
|
|
- $post_data['stream'] = false;
|
|
|
|
|
- $result = $this->volcEngineChatCompletion($post_data);
|
|
|
|
|
-
|
|
|
|
|
- dLog('deepseek')->info('newGenerateText使用火山引擎模型', [
|
|
|
|
|
- 'requested_model' => $model,
|
|
|
|
|
- 'result_keys' => array_keys($result),
|
|
|
|
|
- 'has_fullContent' => isset($result['fullContent']),
|
|
|
|
|
- 'has_content' => isset($result['content'])
|
|
|
|
|
|
|
+ try {
|
|
|
|
|
+ $aiResult = null;
|
|
|
|
|
+ if (in_array($model, ['deepseek-reasoner', 'deepseek-chat', 'deepseek-v4-flash', 'deepseek-v4-pro'])) {
|
|
|
|
|
+ // DeepSeek 官方模型使用现有的 chatOnly 方法
|
|
|
|
|
+ $result = $this->chatOnly($post_data);
|
|
|
|
|
+
|
|
|
|
|
+ // 记录实际使用的模型
|
|
|
|
|
+ dLog('deepseek')->info('newGenerateText使用DeepSeek模型', ['requested_model' => $model, 'actual_model' => $model]);
|
|
|
|
|
+
|
|
|
|
|
+ $aiResult = [
|
|
|
|
|
+ 'content' => $result['fullContent'],
|
|
|
|
|
+ 'reasoning_content' => $result['fullReasoningContent'],
|
|
|
|
|
+ 'usage' => $result['usage'],
|
|
|
|
|
+ 'model' => $model,
|
|
|
|
|
+ 'finish_reason' => 'stop'
|
|
|
|
|
+ ];
|
|
|
|
|
+ } else if (in_array($model, $this->gpt_text_models)) {
|
|
|
|
|
+ // GPT 模型使用现有的 gpt54ChatOnly 方法
|
|
|
|
|
+ $result = $this->gpt54ChatOnly($post_data);
|
|
|
|
|
+
|
|
|
|
|
+ dLog('deepseek')->info('newGenerateText使用GPT模型', ['requested_model' => $model]);
|
|
|
|
|
+
|
|
|
|
|
+ $aiResult = [
|
|
|
|
|
+ 'content' => $result['fullContent'],
|
|
|
|
|
+ 'reasoning_content' => '',
|
|
|
|
|
+ 'usage' => $result['usage'],
|
|
|
|
|
+ 'model' => $model,
|
|
|
|
|
+ 'finish_reason' => 'stop'
|
|
|
|
|
+ ];
|
|
|
|
|
+ } else if (in_array($model, $this->valid_text_models)) {
|
|
|
|
|
+ // 火山引擎支持的模型使用火山引擎 API(非流式)
|
|
|
|
|
+ $post_data['stream'] = false;
|
|
|
|
|
+ $result = $this->volcEngineChatCompletion($post_data);
|
|
|
|
|
+
|
|
|
|
|
+ dLog('deepseek')->info('newGenerateText使用火山引擎模型', [
|
|
|
|
|
+ 'requested_model' => $model,
|
|
|
|
|
+ 'result_keys' => array_keys($result),
|
|
|
|
|
+ 'has_fullContent' => isset($result['fullContent']),
|
|
|
|
|
+ 'has_content' => isset($result['content'])
|
|
|
|
|
+ ]);
|
|
|
|
|
+
|
|
|
|
|
+ // 火山引擎返回的数据结构使用 fullContent 和 fullReasoningContent
|
|
|
|
|
+ $aiResult = [
|
|
|
|
|
+ 'content' => $result['fullContent'] ?? $result['content'] ?? '',
|
|
|
|
|
+ 'reasoning_content' => $result['fullReasoningContent'] ?? $result['reasoning_content'] ?? '',
|
|
|
|
|
+ 'usage' => $result['usage'] ?? [],
|
|
|
|
|
+ 'model' => $model,
|
|
|
|
|
+ 'finish_reason' => $result['finish_reason'] ?? 'stop'
|
|
|
|
|
+ ];
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Utils::throwError('20003:不支持的模型: ' . $model);
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch (\Exception $e) {
|
|
|
|
|
+ // 生成失败,更新任务状态
|
|
|
|
|
+ if ($generateTaskId) {
|
|
|
|
|
+ DB::table('mp_script_generate_tasks')->where('id', $generateTaskId)->update([
|
|
|
|
|
+ 'status' => 'failed',
|
|
|
|
|
+ 'error_message' => $e->getMessage(),
|
|
|
|
|
+ 'completed_at' => date('Y-m-d H:i:s'),
|
|
|
|
|
+ 'updated_at' => date('Y-m-d H:i:s')
|
|
|
|
|
+ ]);
|
|
|
|
|
+ }
|
|
|
|
|
+ Utils::throwError('20003:' . str_replace(':',':',$e->getMessage()));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 生成成功,更新任务状态
|
|
|
|
|
+ if ($generateTaskId && $aiResult) {
|
|
|
|
|
+ DB::table('mp_script_generate_tasks')->where('id', $generateTaskId)->update([
|
|
|
|
|
+ 'status' => 'success',
|
|
|
|
|
+ 'result' => getProp($aiResult, 'content', ''),
|
|
|
|
|
+ 'completed_at' => date('Y-m-d H:i:s'),
|
|
|
|
|
+ 'updated_at' => date('Y-m-d H:i:s')
|
|
|
]);
|
|
]);
|
|
|
-
|
|
|
|
|
- // 火山引擎返回的数据结构使用 fullContent 和 fullReasoningContent
|
|
|
|
|
- $aiResult = [
|
|
|
|
|
- 'content' => $result['fullContent'] ?? $result['content'] ?? '',
|
|
|
|
|
- 'reasoning_content' => $result['fullReasoningContent'] ?? $result['reasoning_content'] ?? '',
|
|
|
|
|
- 'usage' => $result['usage'] ?? [],
|
|
|
|
|
- 'model' => $model,
|
|
|
|
|
- 'finish_reason' => $result['finish_reason'] ?? 'stop'
|
|
|
|
|
- ];
|
|
|
|
|
- } else {
|
|
|
|
|
- Utils::throwError('20003:不支持的模型: ' . $model);
|
|
|
|
|
|
|
+ $aiResult['generate_task_id'] = $generateTaskId;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// 新增: 如果提供了script_id,保存对话记录
|
|
// 新增: 如果提供了script_id,保存对话记录
|
|
@@ -658,6 +710,23 @@ class DeepSeekService
|
|
|
return $aiResult;
|
|
return $aiResult;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 获取剧本资产生成任务列表(按用户分页,每页15条)
|
|
|
|
|
+ *
|
|
|
|
|
+ * @param array $data
|
|
|
|
|
+ * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
|
|
|
|
|
+ */
|
|
|
|
|
+ public function getScriptGenerateTasks($data) {
|
|
|
|
|
+ $uid = Site::getUid();
|
|
|
|
|
+
|
|
|
|
|
+ return DB::table('mp_script_generate_tasks as t')
|
|
|
|
|
+ ->leftJoin('mp_scripts as s', 't.script_id', '=', 's.id')
|
|
|
|
|
+ ->where('t.uid', $uid)
|
|
|
|
|
+ ->select('t.id', 't.script_id', 's.script_name', 't.sequence', 't.status', 't.error_message', 't.started_at', 't.completed_at')
|
|
|
|
|
+ ->orderByDesc('t.id')
|
|
|
|
|
+ ->paginate(15);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
public function saveScriptChatHistory($data) {
|
|
public function saveScriptChatHistory($data) {
|
|
|
$uid = Site::getUid();
|
|
$uid = Site::getUid();
|
|
|
$rid = getProp($data, 'rid');
|
|
$rid = getProp($data, 'rid');
|
|
@@ -2338,11 +2407,17 @@ Q版卡通风格,头大身小,造型圆润可爱,线条简单,色彩明
|
|
|
$uid = Site::getUid();
|
|
$uid = Site::getUid();
|
|
|
$script_id = getProp($data, 'script_id');
|
|
$script_id = getProp($data, 'script_id');
|
|
|
$script_name = getProp($data, 'script_name');
|
|
$script_name = getProp($data, 'script_name');
|
|
|
|
|
+ $is_products = getProp($data, 'is_products');
|
|
|
|
|
|
|
|
$query = DB::table('mp_scripts')->where('is_deleted', 0)->where('user_id', $uid)->select('id as script_id', 'script_name');
|
|
$query = DB::table('mp_scripts')->where('is_deleted', 0)->where('user_id', $uid)->select('id as script_id', 'script_name');
|
|
|
if ($script_id) {
|
|
if ($script_id) {
|
|
|
$query->where('id', $script_id);
|
|
$query->where('id', $script_id);
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ if ($is_products !== '') {
|
|
|
|
|
+ $query->where('is_products', $is_products);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if ($script_name) {
|
|
if ($script_name) {
|
|
|
$query->where('script_name', 'like', "%{$script_name}%");
|
|
$query->where('script_name', 'like', "%{$script_name}%");
|
|
|
}
|
|
}
|