feat(ai): 写作模式拆成自由创作与模板两条路(issue 18)
自由创作不再解析自然语言:原话整段作为 userContent 下发,docType 留空,由后端转 「AI 创意助手」。选了文体才提交 docType 等结构化条件,走「内容创作与宣传助手」。 - writing-params.js 删掉 parseWritingRequest 与关键字表,只留选项常量;`auto` 改语义为「自由创作」。 - 字数选择器只在选中文体后显示;未选文体时不下发 number。 - 撤掉图片比例选择器:上游创意助手开始节点没有比例变量,只能拼进 user_content, 那等于替上游写 prompt。要恢复需先在上游加变量。 - 稿件页同步:默认「自由创作」,选了模板才展开标题、活动类型、时间地点等可选项。
This commit is contained in:
@@ -5,13 +5,14 @@
|
||||
<view class="hero-kicker">AI CONTENT STUDIO</view>
|
||||
<view class="hero-title">AI 内容创作与宣传助手</view>
|
||||
<view class="hero-desc">
|
||||
面向团委宣传、活动报道、新闻稿和推文草稿的快速生成场景。填写创作条件后,页面会调用
|
||||
`/ai/manuscriptGen` 并通过 WebSocket 实时接收生成内容。
|
||||
两种用法:不选模板(自由创作)时只需描述想写什么,由「AI 创意助手」生成;选了稿件类型后再展开活动信息等可选项,
|
||||
由「内容创作与宣传助手」按体裁生成。结果通过 WebSocket 实时回传。
|
||||
</view>
|
||||
<view class="hero-actions">
|
||||
<view class="hero-action" @tap="fillDemo('news')">活动新闻稿</view>
|
||||
<view class="hero-action" @tap="fillDemo('wechat')">公众号推文</view>
|
||||
<view class="hero-action" @tap="fillDemo('speech')">发言稿提纲</view>
|
||||
<view class="hero-action" @tap="fillDemo('free')">自由创作示例</view>
|
||||
<view class="hero-action hero-action--primary" @tap="goChatPage">进入问答助手</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -19,17 +20,6 @@
|
||||
<view class="panel-card">
|
||||
<view class="panel-title">创作配置</view>
|
||||
<view class="field-list">
|
||||
<view class="field-item">
|
||||
<view class="field-label">稿件标题</view>
|
||||
<uv-input
|
||||
v-model="form.theme"
|
||||
class="field-input"
|
||||
placeholder="例如:广西医科大学开展2026年春季志愿服务活动"
|
||||
placeholder-style="color: #c0c4cc;"
|
||||
:maxlength="-1"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view class="field-item">
|
||||
<view class="field-label">稿件类型</view>
|
||||
<picker mode="selector" :range="docTypeLabels" :value="docTypeIndex" @change="handleDocTypeChange">
|
||||
@@ -37,9 +27,22 @@
|
||||
<text class="field-value">{{ form.docType || '请选择稿件类型' }}</text>
|
||||
</view>
|
||||
</picker>
|
||||
<view class="field-tip">选「自由创作」= 不套稿件模板,只描述你想写什么;选具体模板后才会展开下方其它可选项。</view>
|
||||
</view>
|
||||
|
||||
<view class="field-item">
|
||||
<template v-if="templateMode">
|
||||
<view class="field-item">
|
||||
<view class="field-label">稿件标题</view>
|
||||
<uv-input
|
||||
v-model="form.theme"
|
||||
class="field-input"
|
||||
placeholder="例如:广西医科大学开展2026年春季志愿服务活动"
|
||||
placeholder-style="color: #c0c4cc;"
|
||||
:maxlength="-1"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view class="field-item">
|
||||
<view class="field-label">活动类型</view>
|
||||
<picker mode="selector" :range="eventTypeLabels" :value="eventTypeIndex" @change="handleEventTypeChange">
|
||||
<view class="field-picker">
|
||||
@@ -127,6 +130,23 @@
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<template v-else>
|
||||
<view class="field-item">
|
||||
<view class="field-label">想创作什么</view>
|
||||
<textarea
|
||||
v-model="form.freeContent"
|
||||
class="field-textarea field-textarea--free"
|
||||
placeholder="直接描述你的创作需求,例如:帮我写一段迎新晚会的主持人开场词,口语化一点"
|
||||
placeholder-style="color: #c0c4cc;"
|
||||
maxlength="-1"
|
||||
/>
|
||||
</view>
|
||||
<view class="free-tip">
|
||||
自由模式不套用稿件模板,内容将交给「AI 创意助手」生成。想按新闻稿、推文等固定体裁写,请在上方选择对应模板。
|
||||
</view>
|
||||
</template>
|
||||
</view>
|
||||
|
||||
<view class="submit-bar">
|
||||
@@ -139,7 +159,8 @@
|
||||
<view class="hint-block">
|
||||
<view class="hint-title">提交说明</view>
|
||||
<view class="hint-text">
|
||||
页面会先提交 `POST /ai/manuscriptGen`,再通过 WebSocket 流式接收生成结果;如果后端直接返回正文,也会自动兼容显示。
|
||||
自由模式只提交一段内容(`docType` 留空),由后端转「AI 创意助手」;选了模板才提交 `docType`、活动类型、时间地点等结构化条件。
|
||||
两种都会先 `POST /ai/manuscriptGen`,再通过 WebSocket 流式接收生成结果;如果后端直接返回正文,也会自动兼容显示。
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -207,11 +228,14 @@
|
||||
const THINK_OPEN_TAG = '<think>'
|
||||
const THINK_CLOSE_TAG = '</think>'
|
||||
|
||||
const DOC_TYPE_OPTIONS = ['新闻稿', '公众号推文', '宣传稿', '活动总结', '发言稿', '短视频脚本']
|
||||
const DOC_TYPE_FREE = '自由创作'
|
||||
// 「自由创作」是默认项:不选具体模板时只填一段内容,后端转「AI 创意助手」。
|
||||
const DOC_TYPE_OPTIONS = [DOC_TYPE_FREE, '新闻稿', '公众号推文', '宣传稿', '活动总结', '发言稿', '短视频脚本']
|
||||
const EVENT_TYPE_OPTIONS = ['校园活动', '志愿服务', '会议论坛', '社会实践', '文体活动', '品牌项目']
|
||||
|
||||
const createDefaultForm = () => ({
|
||||
docType: '新闻稿',
|
||||
docType: DOC_TYPE_FREE,
|
||||
freeContent: '',
|
||||
eventType: '校园活动',
|
||||
theme: '',
|
||||
time: '',
|
||||
@@ -254,7 +278,16 @@
|
||||
const index = this.eventTypeLabels.indexOf(this.form.eventType)
|
||||
return index > -1 ? index : 0
|
||||
},
|
||||
freeMode() {
|
||||
return !this.form.docType || this.form.docType === DOC_TYPE_FREE
|
||||
},
|
||||
templateMode() {
|
||||
return !this.freeMode
|
||||
},
|
||||
canSubmit() {
|
||||
if (this.freeMode) {
|
||||
return !!String(this.form.freeContent || '').trim()
|
||||
}
|
||||
return !!(
|
||||
String(this.form.theme || '').trim() ||
|
||||
String(this.form.highlights || '').trim() ||
|
||||
@@ -329,6 +362,13 @@
|
||||
}
|
||||
},
|
||||
buildPayload() {
|
||||
if (this.freeMode) {
|
||||
// 自由模式:不发 docType,只发一段用户原话。后端据此转「AI 创意助手」。
|
||||
return {
|
||||
docType: '',
|
||||
userContent: String(this.form.freeContent || '').trim()
|
||||
}
|
||||
}
|
||||
return {
|
||||
docType: this.form.docType,
|
||||
eventType: this.form.eventType,
|
||||
@@ -640,6 +680,11 @@
|
||||
this.uploadedFiles = []
|
||||
},
|
||||
fillDemo(type) {
|
||||
if (type === 'free') {
|
||||
this.form.docType = DOC_TYPE_FREE
|
||||
this.form.freeContent = '帮我写一段迎新晚会的主持人开场词,口语化一点,时长两分钟左右'
|
||||
return
|
||||
}
|
||||
if (type === 'news') {
|
||||
this.form.theme = '广西医科大学青年志愿者开展“清洁校园”志愿服务活动'
|
||||
this.form.docType = '新闻稿'
|
||||
@@ -731,7 +776,9 @@
|
||||
return
|
||||
}
|
||||
if (!this.canSubmit) {
|
||||
this.showToast('请至少填写稿件标题、亮点内容或上传附件中的一项')
|
||||
this.showToast(this.freeMode
|
||||
? '请先描述你想创作什么'
|
||||
: '请至少填写稿件标题、亮点内容或上传附件中的一项')
|
||||
return
|
||||
}
|
||||
this.loading = true
|
||||
@@ -740,7 +787,9 @@
|
||||
this.responseSummary = '正在建立 WebSocket 连接...'
|
||||
try {
|
||||
await this.connectWebSocket()
|
||||
this.responseSummary = '连接成功,已提交生成任务,等待流式返回...'
|
||||
this.responseSummary = this.freeMode
|
||||
? '自由创作已提交给 AI 创意助手,生成完成后一次性返回...'
|
||||
: '连接成功,已提交生成任务,等待流式返回...'
|
||||
const waitStream = this.createStreamWaiter()
|
||||
const result = await manuscriptGen(this.buildPayload())
|
||||
if (!this.streamStarted && this.shouldTreatAsDirectResult(result)) {
|
||||
@@ -911,6 +960,25 @@
|
||||
min-height: 220rpx;
|
||||
}
|
||||
|
||||
.field-textarea--free {
|
||||
min-height: 300rpx;
|
||||
}
|
||||
|
||||
.field-tip,
|
||||
.free-tip {
|
||||
margin-top: 10rpx;
|
||||
font-size: 22rpx;
|
||||
line-height: 1.7;
|
||||
color: #8f959e;
|
||||
}
|
||||
|
||||
.free-tip {
|
||||
padding: 18rpx 22rpx;
|
||||
border-radius: 18rpx;
|
||||
background: rgba(20, 150, 242, 0.06);
|
||||
color: #6b7d8f;
|
||||
}
|
||||
|
||||
.field-value {
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user