1
This commit is contained in:
35
src/api/jarvis/socialMediaPrompt.js
Normal file
35
src/api/jarvis/socialMediaPrompt.js
Normal file
@@ -0,0 +1,35 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
// 获取提示词模板列表
|
||||
export function listPromptTemplates() {
|
||||
return request({
|
||||
url: '/jarvis/social-media/prompt/list',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 获取单个提示词模板
|
||||
export function getPromptTemplate(key) {
|
||||
return request({
|
||||
url: '/jarvis/social-media/prompt/' + key,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 保存提示词模板
|
||||
export function savePromptTemplate(data) {
|
||||
return request({
|
||||
url: '/jarvis/social-media/prompt/save',
|
||||
method: 'post',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除提示词模板(恢复默认)
|
||||
export function deletePromptTemplate(key) {
|
||||
return request({
|
||||
url: '/jarvis/social-media/prompt/' + key,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
289
src/views/system/social-media/prompt-config.vue
Normal file
289
src/views/system/social-media/prompt-config.vue
Normal file
@@ -0,0 +1,289 @@
|
||||
<template>
|
||||
<div class="prompt-config-container">
|
||||
<el-card class="box-card">
|
||||
<div slot="header" class="clearfix">
|
||||
<span class="card-title">
|
||||
<i class="el-icon-setting"></i>
|
||||
DS提示词模板配置
|
||||
</span>
|
||||
<el-button
|
||||
style="float: right; padding: 3px 0"
|
||||
type="text"
|
||||
@click="showHelp = !showHelp">
|
||||
{{ showHelp ? '隐藏帮助' : '显示帮助' }}
|
||||
</el-button>
|
||||
</div>
|
||||
|
||||
<!-- 帮助说明 -->
|
||||
<el-collapse-transition>
|
||||
<div v-show="showHelp" class="help-section">
|
||||
<el-alert
|
||||
title="使用说明"
|
||||
type="info"
|
||||
:closable="false"
|
||||
show-icon>
|
||||
<div slot="default">
|
||||
<p><strong>功能说明:</strong></p>
|
||||
<ul>
|
||||
<li>配置DS(DeepSeek)AI的提示词模板,用于生成关键词和文案</li>
|
||||
<li>模板存储在Redis中,修改后立即生效</li>
|
||||
<li>支持占位符:%s 用于替换实际内容</li>
|
||||
<li>删除模板将恢复为系统默认模板</li>
|
||||
</ul>
|
||||
<p><strong>模板类型:</strong></p>
|
||||
<ul>
|
||||
<li><strong>关键词提取模板</strong>:用于提取商品关键词,占位符:%s = 商品名称</li>
|
||||
<li><strong>小红书文案模板</strong>:用于生成小红书风格文案,占位符:%s = 商品名称,%s = 价格信息,%s = 关键词</li>
|
||||
<li><strong>抖音文案模板</strong>:用于生成抖音风格文案,占位符:%s = 商品名称,%s = 价格信息,%s = 关键词</li>
|
||||
<li><strong>通用文案模板</strong>:用于生成通用风格文案,占位符:%s = 商品名称,%s = 价格信息,%s = 关键词</li>
|
||||
</ul>
|
||||
</div>
|
||||
</el-alert>
|
||||
</div>
|
||||
</el-collapse-transition>
|
||||
|
||||
<!-- 模板列表 -->
|
||||
<div class="template-list">
|
||||
<el-tabs v-model="activeTab" type="border-card">
|
||||
<el-tab-pane
|
||||
v-for="(template, key) in templates"
|
||||
:key="key"
|
||||
:label="getTemplateLabel(key)"
|
||||
:name="key">
|
||||
<div class="template-editor">
|
||||
<div class="template-info">
|
||||
<el-alert
|
||||
:title="template.description"
|
||||
type="info"
|
||||
:closable="false"
|
||||
show-icon
|
||||
style="margin-bottom: 15px;">
|
||||
</el-alert>
|
||||
|
||||
<div class="template-status">
|
||||
<el-tag :type="template.isDefault ? 'info' : 'success'" size="small">
|
||||
{{ template.isDefault ? '使用默认模板' : '使用自定义模板' }}
|
||||
</el-tag>
|
||||
<el-button
|
||||
v-if="!template.isDefault"
|
||||
type="text"
|
||||
size="small"
|
||||
icon="el-icon-refresh-left"
|
||||
@click="handleResetTemplate(key)"
|
||||
style="margin-left: 10px;">
|
||||
恢复默认
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-input
|
||||
v-model="template.template"
|
||||
type="textarea"
|
||||
:rows="12"
|
||||
placeholder="请输入提示词模板..."
|
||||
class="template-textarea">
|
||||
</el-input>
|
||||
|
||||
<div class="template-actions">
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="el-icon-check"
|
||||
@click="handleSaveTemplate(key)"
|
||||
:loading="saving[key]">
|
||||
保存模板
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="el-icon-refresh"
|
||||
@click="handleLoadTemplate(key)">
|
||||
重新加载
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listPromptTemplates, getPromptTemplate, savePromptTemplate, deletePromptTemplate } from '@/api/jarvis/socialMediaPrompt'
|
||||
|
||||
export default {
|
||||
name: 'SocialMediaPromptConfig',
|
||||
data() {
|
||||
return {
|
||||
showHelp: false,
|
||||
activeTab: 'keywords',
|
||||
templates: {},
|
||||
saving: {}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.loadTemplates()
|
||||
},
|
||||
methods: {
|
||||
/** 加载所有模板 */
|
||||
async loadTemplates() {
|
||||
try {
|
||||
const res = await listPromptTemplates()
|
||||
if (res.code === 200 && res.data) {
|
||||
this.templates = res.data
|
||||
// 初始化保存状态
|
||||
Object.keys(this.templates).forEach(key => {
|
||||
this.$set(this.saving, key, false)
|
||||
})
|
||||
} else {
|
||||
this.$message.error(res.msg || '加载模板失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载模板失败', error)
|
||||
this.$message.error('加载模板失败:' + (error.message || '未知错误'))
|
||||
}
|
||||
},
|
||||
|
||||
/** 加载单个模板 */
|
||||
async handleLoadTemplate(key) {
|
||||
try {
|
||||
const res = await getPromptTemplate(key)
|
||||
if (res.code === 200 && res.data) {
|
||||
this.$set(this.templates, key, res.data)
|
||||
this.$message.success('重新加载成功')
|
||||
} else {
|
||||
this.$message.error(res.msg || '加载失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载模板失败', error)
|
||||
this.$message.error('加载失败:' + (error.message || '未知错误'))
|
||||
}
|
||||
},
|
||||
|
||||
/** 保存模板 */
|
||||
async handleSaveTemplate(key) {
|
||||
const template = this.templates[key]
|
||||
if (!template || !template.template || template.template.trim() === '') {
|
||||
this.$message.warning('模板内容不能为空')
|
||||
return
|
||||
}
|
||||
|
||||
this.$set(this.saving, key, true)
|
||||
try {
|
||||
const res = await savePromptTemplate({
|
||||
key: key,
|
||||
template: template.template.trim()
|
||||
})
|
||||
|
||||
if (res.code === 200) {
|
||||
this.$message.success('保存成功!')
|
||||
// 更新状态
|
||||
this.$set(template, 'isDefault', false)
|
||||
// 重新加载以确认
|
||||
await this.handleLoadTemplate(key)
|
||||
} else {
|
||||
this.$message.error(res.msg || '保存失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('保存模板失败', error)
|
||||
this.$message.error('保存失败:' + (error.message || '未知错误'))
|
||||
} finally {
|
||||
this.$set(this.saving, key, false)
|
||||
}
|
||||
},
|
||||
|
||||
/** 恢复默认模板 */
|
||||
async handleResetTemplate(key) {
|
||||
try {
|
||||
await this.$confirm('确定要恢复默认模板吗?自定义模板将被删除。', '提示', {
|
||||
type: 'warning'
|
||||
})
|
||||
|
||||
const res = await deletePromptTemplate(key)
|
||||
if (res.code === 200) {
|
||||
this.$message.success('已恢复默认模板')
|
||||
// 重新加载
|
||||
await this.handleLoadTemplate(key)
|
||||
} else {
|
||||
this.$message.error(res.msg || '恢复失败')
|
||||
}
|
||||
} catch (error) {
|
||||
if (error !== 'cancel') {
|
||||
console.error('恢复默认模板失败', error)
|
||||
this.$message.error('恢复失败:' + (error.message || '未知错误'))
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/** 获取模板标签 */
|
||||
getTemplateLabel(key) {
|
||||
const labels = {
|
||||
'keywords': '关键词提取',
|
||||
'content:xhs': '小红书文案',
|
||||
'content:douyin': '抖音文案',
|
||||
'content:both': '通用文案'
|
||||
}
|
||||
return labels[key] || key
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.prompt-config-container {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.help-section {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.help-section ul {
|
||||
margin: 10px 0;
|
||||
padding-left: 20px;
|
||||
}
|
||||
|
||||
.help-section li {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
.template-list {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.template-editor {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.template-info {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.template-status {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.template-textarea {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.template-textarea >>> .el-textarea__inner {
|
||||
font-family: 'Consolas', 'Monaco', 'Courier New', monospace;
|
||||
font-size: 13px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.template-actions {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.template-actions .el-button {
|
||||
margin-left: 10px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user