feat(ai): 助手页支持写作/生图等记录的历史列表与按类型筛选

- 三模式各自独立工作区:切模式不丢消息、草稿与当前记录
- 历史面板加类型徽标与筛选(全部/聊天/写作/图片/创意/活动策划),文案改「历史记录」
- 生成成功认领末帧 chatId 并刷新列表;聊天 __END__ 帧的 chatId 同样接受
- 生图回复支持多张 ![](url) 渲染
- 写作/图片记录支持「按原参数再来一次」(只回填、不自动发送)
- 三个独立页(文稿/创意/活动策划)加历史入口,/ai?type= 预置筛选
- 后台 aiChatList 加类型列与筛选;历史列表提示仅展示最近 30 条
This commit is contained in:
2026-10-24 17:37:46 +08:00
parent 73155d0bd2
commit 77378a2791
9 changed files with 726 additions and 45 deletions
@@ -6,6 +6,9 @@
<h1>活动策划大纲生成</h1>
<p>填写活动主题、受众、时间和预算,AI 给出一份结构完整的策划大纲,可直接改、复制或导出。</p>
</div>
<div class="hero-actions">
<a-button ghost @click="goHistory">历史记录</a-button>
</div>
</div>
<a-row :gutter="[24, 24]">
@@ -169,6 +172,7 @@
import zh_Hans from 'bytemd/locales/zh_Hans.json';
import { getProcessor } from 'bytemd';
import { computed, onBeforeUnmount, reactive, ref } from 'vue';
import { useRouter } from 'vue-router';
import { message } from 'ant-design-vue';
import { messageLoading } from 'ele-admin-pro';
import { saveAs } from 'file-saver';
@@ -183,6 +187,14 @@
import { FAILED_TEXT } from '@/utils/ai-result';
type ExampleType = 'volunteer' | 'salon' | 'sports';
const { push } = useRouter();
/** 活动策划记录统一在助手页查看,这里只带类型跳过去 */
const goHistory = () => {
push({ path: '/ai', query: { type: 'activity_outline' } });
};
/** 等「流结束」的挂起点:只由 __END__ 帧或请求收尾来 resolve */
type StreamResolver = {
resolve: () => void;
@@ -665,6 +677,18 @@
color: rgba(255, 238, 238, 0.9);
}
.hero-actions {
display: flex;
flex-wrap: wrap;
gap: 12px;
justify-content: flex-end;
flex: none;
}
.hero-actions :deep(.ant-btn) {
border-radius: 999px;
}
.quick-actions-panel {
margin-bottom: 14px;
padding: 16px;
@@ -805,5 +829,9 @@
.hero-panel h1 {
font-size: 28px;
}
.hero-actions {
justify-content: flex-start;
}
}
</style>
@@ -8,6 +8,9 @@
支持文本指令与多类型附件联合驱动工作流,自动返回视频、脚本 Markdown 或图像/排版结果。
</p>
</div>
<div class="hero-actions">
<a-button ghost @click="goHistory">历史记录</a-button>
</div>
</div>
<a-row :gutter="[24, 24]">
@@ -187,6 +190,7 @@
import highlight from '@bytemd/plugin-highlight-ssr';
import 'highlight.js/styles/default.css';
import { computed, ref } from 'vue';
import { useRouter } from 'vue-router';
import { message } from 'ant-design-vue';
import ByteMdViewer from '@/components/ByteMdViewer/index.vue';
import { runCreativeAssistantStream } from '@/utils/ai-stream';
@@ -200,6 +204,13 @@
type ExampleType = 'video' | 'script' | 'image';
const { push } = useRouter();
/** 创意助手记录统一在助手页查看,这里只带类型跳过去 */
const goHistory = () => {
push({ path: '/ai', query: { type: 'creative' } });
};
const plugins = ref([
gfm({
locale: zh_HansGfm
@@ -497,6 +508,18 @@
color: rgba(255, 239, 241, 0.88);
}
.hero-actions {
display: flex;
flex-wrap: wrap;
gap: 12px;
justify-content: flex-end;
flex: none;
}
.hero-actions :deep(.ant-btn) {
border-radius: 999px;
}
.panel-card {
border-radius: 20px;
box-shadow: 0 14px 34px rgba(87, 54, 30, 0.08);
@@ -824,6 +847,10 @@
font-size: 28px;
}
.hero-actions {
justify-content: flex-start;
}
.video-grid,
.photo-grid {
grid-template-columns: 1fr;
+6
View File
@@ -8,6 +8,7 @@
</div>
<div class="hero-actions">
<a-button type="primary" ghost @click="goChatPage">进入问答助手</a-button>
<a-button type="primary" ghost @click="goHistory">历史记录</a-button>
</div>
</div>
@@ -844,6 +845,11 @@
push('/ai');
};
/** 写作记录统一在助手页查看,这里只带类型跳过去 */
const goHistory = () => {
push({ path: '/ai', query: { type: 'writing' } });
};
onBeforeUnmount(() => {
clearStreamResolver();
});