提交 8840c701 authored 作者: 王鹏飞's avatar 王鹏飞

chore: update

上级 be3d1054
......@@ -4,7 +4,7 @@ export function useChat() {
const messages = ref([])
const isLoading = ref(false)
async function post(message) {
async function post(message, isReplace = true) {
isLoading.value = true
await fetchEventSource('/api/lab/v1/experiment/qwen/chat', {
method: 'POST',
......@@ -19,6 +19,9 @@ export function useChat() {
},
onmessage(res) {
console.log(res.data)
if (res.data === '[DONE]') {
isLoading.value = false
}
try {
const message = JSON.parse(res.data)
if (message.error) {
......@@ -28,13 +31,14 @@ export function useChat() {
const id = message.id
const messageIndex = messages.value.findIndex((session) => session.id === id)
let content = message?.choices[0]?.delta.content || ''
content = content.replaceAll('\n', '<br/>')
if (isReplace) {
content = content.replaceAll('\n', '<br/>')
}
if (messageIndex === -1) {
messages.value.push({ id, role: 'assistant', content })
} else {
messages.value[messageIndex].content = messages.value[messageIndex].content + content
}
isLoading.value = false
} catch (error) {
console.log(error)
isLoading.value = false
......
......@@ -22,12 +22,13 @@ const emit = defineEmits(['update:modelValue'])
const index = ref(0)
const { open, onChange } = useFileDialog({
const { open, onChange, reset } = useFileDialog({
accept: props.accept,
multiple: props.multiple,
})
onChange(async (files) => {
if (!files) return
const [file] = files
const res = await upload(file)
const nowTime = dayjs().format('YYYY-MM-DD HH:mm:ss')
......@@ -39,6 +40,7 @@ onChange(async (files) => {
updatedValue[index.value] = result
emit('update:modelValue', updatedValue)
}
reset()
})
const handleOpen = (i = 0) => {
......
......@@ -86,7 +86,14 @@ watch(
messages,
() => {
const lastMessage = messages.value[messages.value.length - 1]
if (lastMessage) {
if (lastMessage && aiActive.value === 1) {
form.selling_point = lastMessage.content
}
if (lastMessage && aiActive.value === 2) {
form.marketing_campaign = lastMessage.content
}
if (lastMessage && aiActive.value === 3) {
form.content = lastMessage.content
.replace(/(商品引入|商品讲解|引导转化)/g, wrapWithStyle)
.replace(
......@@ -98,17 +105,43 @@ watch(
{ deep: true }
)
function handleAIGenerate() {
post({
role: 'user',
content: `你是一位网络主播。请根据以下要求撰写直播话术:
const aiActive = ref(1)
function handleAIGenerate(index) {
aiActive.value = index
let content = ''
// 商品卖点
if (index === 1) {
content = `请根据下面的商品名称,生成3~6个商品卖点。
商品名称:${product.value.title}
要求:
1. 卖点应突出商品的特点和优势。
2. 每个卖点应简洁明了,不超过10个字。
3. 卖点应具有一定的吸引力,能够引起消费者的兴趣和购买欲望。
4. 卖点应真实反映商品的实际特点,不得夸大或误导消费者。
5. 每个卖点之间使用分号分割`
}
if (index === 2) {
content = `请根据以下商品名称,生成2~6个商品的营销活动。
商品名称:${product.value.title}
要求:
1. 营销活动应围绕商品的特点和优势展开。
2. 营销活动应包含对目标受众的定位、产品策略、价格策略、渠道策略、促销策略等。
3. 营销活动应具有创意和吸引力,能够引起目标受众的共鸣和购买欲望。
4. 营销活动应考虑到市场竞争和消费者需求,确保活动的可行性和有效性。
5. 营销活动应简洁明了,易于理解和执行,不超过10个字。
6. 每个活动之间使用分号分割。`
}
if (index === 3) {
content = `你是一位网络主播。请根据以下要求撰写直播话术:
1. 直播话术匹配的直播时长为:${form.duration}分钟。
2. 直播的商品是:${product.value.title}
3. 商品的卖点有:${form.selling_point}
4. 营销活动有:${form.marketing_campaign}
5. 直播话术要求包含:商品引入(开场互动、引出话题、引出商品、目标人群锁定)、商品讲解(产品卖点讲解、观众互动、价格福利)、引导转化(催单话术、强调购买方式、结尾互动)等内容模块。而且按照模块进行内容区分。
请确保话术简洁明了,突出商品特点,并吸引观众购买。同时,注意控制直播时长,确保在${form.duration}分钟内完成。`,
})
请确保话术简洁明了,突出商品特点,并吸引观众购买。同时,注意控制直播时长,确保在${form.duration}分钟内完成。`
}
post({ role: 'user', content }, index === 3)
}
</script>
......@@ -124,6 +157,16 @@ function handleAIGenerate() {
<LiveProductSelect v-model="form.live_commodity_id"></LiveProductSelect>
</el-form-item>
<el-form-item label="商品卖点" prop="selling_point">
<div class="form-tips">
<el-button
type="primary"
plain
size="small"
@click="handleAIGenerate(1)"
:loading="isLoading && aiActive === 1"
>AI一键生成</el-button
>
</div>
<el-input
type="textarea"
v-model="form.selling_point"
......@@ -131,6 +174,16 @@ function handleAIGenerate() {
:rows="4"></el-input>
</el-form-item>
<el-form-item label="营销活动" prop="marketing_campaign">
<div class="form-tips">
<el-button
type="primary"
plain
size="small"
@click="handleAIGenerate(2)"
:loading="isLoading && aiActive === 2"
>AI一键生成</el-button
>
</div>
<el-input
type="textarea"
v-model="form.marketing_campaign"
......@@ -147,7 +200,7 @@ function handleAIGenerate() {
<el-col :sm="24" :md="12" style="border-left: 1px solid #dcdfe6">
<div style="text-align: center; margin-bottom: 20px">
<h2 style="margin-bottom: 20px">直播话术</h2>
<el-button type="primary" size="large" @click="handleAIGenerate" :loading="isLoading">
<el-button type="primary" size="large" @click="handleAIGenerate(3)" :loading="isLoading && aiActive === 3">
{{ messages.length ? '再次生成直播话术' : 'AI生成直播话术' }}
</el-button>
</div>
......@@ -173,3 +226,14 @@ function handleAIGenerate() {
</template>
</el-dialog>
</template>
<style scoped>
.form-tips {
position: absolute;
right: 0;
top: -30px;
z-index: 100;
line-height: 22px;
color: #92939a;
}
</style>
......@@ -19,7 +19,13 @@ const listOptions = {
},
columns: [
{ label: '序号', type: 'index', width: 60 },
{ label: '主播', prop: 'id' },
{
label: '主播',
prop: 'current_user',
computed({ row }) {
return row.current_user.real_name || row.current_user.nickname || row.current_user.username
},
},
{
label: '直播时长',
prop: 'live_duration',
......
......@@ -42,7 +42,7 @@ export interface UseLiveChatOptions {
}
export function useLiveChat(options: UseLiveChatOptions = {}) {
const { initViewerCount = 20, autoStart = false, updateInterval = 500, defaultMessages } = options
const { initViewerCount = 20, autoStart = false, updateInterval = 1000, defaultMessages } = options
const viewers = ref<Viewer[]>([])
const messages = ref<Message[]>([])
const currentTime = ref(0)
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论