|
|
@@ -22,23 +22,21 @@
|
|
|
<el-table-column prop="version" label="版本" width="60" />
|
|
|
<el-table-column prop="status" label="状态" width="70">
|
|
|
<template slot-scope="{ row }">
|
|
|
- <el-tag :type="row.status === 1 ? 'success' : 'info'" size="small">
|
|
|
- {{ row.status === 1 ? '启用' : '禁用' }}
|
|
|
+ <el-tag :type="row.status === 1 ? "success" : "info"" size="small">
|
|
|
+ {{ row.status === 1 ? "启用" : "禁用" }}
|
|
|
</el-tag>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
<el-table-column prop="updatedAt" label="更新时间" width="160">
|
|
|
<template slot-scope="{ row }">
|
|
|
- {{ row.updatedAt ? formatTime(row.updatedAt) : '-' }}
|
|
|
- </template>
|
|
|
- <template slot="header">
|
|
|
- <span class="sort-header" @click.stop="onSortClick('updatedAt', $event)">更新时间<span v-if="sortIndex('updatedAt') !== null" class="sort-index" :class="sortClass('updatedAt') === 'sort-asc' ? 'sort-asc-badge' : 'sort-desc-badge'">{{ sortIndex('updatedAt') }}</span>{{ sortIcon('updatedAt') }}</span>
|
|
|
+ {{ row.updatedAt ? formatTime(row.updatedAt) : "-" }}
|
|
|
</template>
|
|
|
</el-table-column>
|
|
|
- <el-table-column label="操作" width="180" fixed="right">
|
|
|
+ <el-table-column label="操作" width="240" fixed="right">
|
|
|
<template slot-scope="{ row }">
|
|
|
<el-button type="text" size="small" @click="showEdit(row)">编辑</el-button>
|
|
|
<el-button type="text" size="small" @click="showPreview(row)">预览</el-button>
|
|
|
+ <el-button type="text" size="small" @click="showVersions(row)">版本</el-button>
|
|
|
<el-button type="text" size="small" @click="resetToDefault(row)">重置</el-button>
|
|
|
<el-button type="text" size="small" style="color:#f56c6c" @click="deleteRow(row)">删除</el-button>
|
|
|
</template>
|
|
|
@@ -56,7 +54,7 @@
|
|
|
</el-card>
|
|
|
|
|
|
<!-- 编辑弹窗 -->
|
|
|
- <el-dialog :visible.sync="dialog.visible" :title="dialog.isEdit ? '编辑提示词' : '新增提示词'" width="700px" :close-on-click-modal="false">
|
|
|
+ <el-dialog :visible.sync="dialog.visible" :title="dialog.isEdit ? "编辑提示词" : "新增提示词"" width="700px" :close-on-click-modal="false">
|
|
|
<el-form :model="dialog.form" label-width="100px" size="small">
|
|
|
<el-form-item label="提示词键" :required="!dialog.isEdit">
|
|
|
<el-input v-model="dialog.form.promptKey" placeholder="如 health_coach(英文下划线)" :disabled="dialog.isEdit" />
|
|
|
@@ -74,7 +72,7 @@
|
|
|
<el-input v-model="dialog.form.content" type="textarea" :rows="18" placeholder="输入系统提示词内容..." />
|
|
|
</el-form-item>
|
|
|
<el-form-item label="备注">
|
|
|
- <el-input v-model="dialog.form.remark" placeholder="用途说明" />
|
|
|
+ <el-input v-model="dialog.form.remark" placeholder="本次变更说明(可选)" />
|
|
|
</el-form-item>
|
|
|
</el-form>
|
|
|
<div slot="footer">
|
|
|
@@ -92,49 +90,78 @@
|
|
|
<el-button size="small" @click="previewVisible = false">关闭</el-button>
|
|
|
</div>
|
|
|
</el-dialog>
|
|
|
+
|
|
|
+ <!-- 版本历史弹窗 -->
|
|
|
+ <el-dialog title="版本历史" :visible.sync="versionDialog.visible" width="900px">
|
|
|
+ <div style="margin-bottom:12px; color:#666; font-size:13px;">
|
|
|
+ 当前提示词: <strong>{{ versionDialog.promptKey }}</strong> — {{ versionDialog.title }}
|
|
|
+ </div>
|
|
|
+ <el-table :data="versionDialog.versions" border stripe size="small" max-height="400">
|
|
|
+ <el-table-column prop="version" label="版本号" width="80" align="center">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ <el-tag :type="row.version === currentVersion ? "primary" : "default"" size="mini">
|
|
|
+ v{{ row.version }}
|
|
|
+ </el-tag>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="operator" label="操作人" width="100" />
|
|
|
+ <el-table-column prop="remark" label="说明" min-width="120" show-overflow-tooltip />
|
|
|
+ <el-table-column prop="createdAt" label="时间" width="160">
|
|
|
+ <template slot-scope="{ row }">{{ formatTime(row.createdAt) }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="操作" width="100" fixed="right">
|
|
|
+ <template slot-scope="{ row }">
|
|
|
+ <el-button
|
|
|
+ v-if="row.version !== currentVersion"
|
|
|
+ type="text" size="small"
|
|
|
+ @click="doRollback(versionDialog.promptKey, row.version, row.title)"
|
|
|
+ :disabled="row.version === currentVersion">
|
|
|
+ 回滚到 v{{ row.version }}
|
|
|
+ </el-button>
|
|
|
+ <span v-else style="color:#909399; font-size:12px;">当前版本</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ <div slot="footer">
|
|
|
+ <el-button size="small" @click="versionDialog.visible = false">关闭</el-button>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import SortMixin from '@/mixins/SortMixin'
|
|
|
-import { getPromptList, savePrompt, resetPrompt, deletePrompt } from '@/api/systemPrompt'
|
|
|
+import { getPromptList, savePrompt, resetPrompt, deletePrompt, listVersions, rollbackPrompt } from "@/api/systemPrompt"
|
|
|
|
|
|
export default {
|
|
|
- name: 'SystemPromptManagement',
|
|
|
- mixins: [SortMixin],
|
|
|
+ name: "SystemPromptManagement",
|
|
|
data() {
|
|
|
return {
|
|
|
list: [],
|
|
|
loading: false,
|
|
|
- filters: { keyword: '' },
|
|
|
+ filters: { keyword: "" },
|
|
|
page: 1,
|
|
|
size: 20,
|
|
|
total: 0,
|
|
|
dialog: { visible: false, isEdit: false, form: {} },
|
|
|
saving: false,
|
|
|
previewVisible: false,
|
|
|
- previewContent: '',
|
|
|
- sortableColumns: { updatedAt: '更新时间' }
|
|
|
+ previewContent: "",
|
|
|
+ versionDialog: { visible: false, promptKey: "", title: "", versions: [], currentVersion: 0 }
|
|
|
}
|
|
|
},
|
|
|
created() {
|
|
|
this.fetchList()
|
|
|
},
|
|
|
methods: {
|
|
|
- loadList() {
|
|
|
- this.fetchList()
|
|
|
- },
|
|
|
formatTime(ts) {
|
|
|
- if (!ts) return ''
|
|
|
+ if (!ts) return ""
|
|
|
const d = new Date(ts)
|
|
|
- return d.toLocaleString('zh-CN', { hour12: false })
|
|
|
+ return d.toLocaleString("zh-CN", { hour12: false })
|
|
|
},
|
|
|
async fetchList() {
|
|
|
this.loading = true
|
|
|
try {
|
|
|
- var params = { keyword: this.filters.keyword, page: this.page, size: this.size }
|
|
|
- if (this.sortState.length > 0) params.sort = this.sortState
|
|
|
- const res = await getPromptList(params)
|
|
|
+ const res = await getPromptList({ keyword: this.filters.keyword, page: this.page, size: this.size })
|
|
|
if (res && res.data) {
|
|
|
this.list = res.data.records || []
|
|
|
this.total = res.data.total || 0
|
|
|
@@ -145,19 +172,19 @@ export default {
|
|
|
},
|
|
|
showEdit(row) {
|
|
|
this.dialog.isEdit = !!row
|
|
|
- this.dialog.form = row ? Object.assign({}, row) : { promptKey: '', title: '', content: '', status: 1, remark: '' }
|
|
|
+ this.dialog.form = row ? Object.assign({}, row) : { promptKey: "", title: "", content: "", status: 1, remark: "" }
|
|
|
this.dialog.visible = true
|
|
|
},
|
|
|
async savePrompt() {
|
|
|
const form = this.dialog.form
|
|
|
if (!form.promptKey || !form.title || !form.content) {
|
|
|
- this.$message.warning('请填写完整')
|
|
|
+ this.$message.warning("请填写完整")
|
|
|
return
|
|
|
}
|
|
|
this.saving = true
|
|
|
try {
|
|
|
await savePrompt(form)
|
|
|
- this.$message.success('保存成功')
|
|
|
+ this.$message.success("保存成功")
|
|
|
this.dialog.visible = false
|
|
|
this.fetchList()
|
|
|
} finally {
|
|
|
@@ -165,16 +192,16 @@ export default {
|
|
|
}
|
|
|
},
|
|
|
async resetToDefault(row) {
|
|
|
- this.$confirm('确定要重置为出厂默认内容吗?', '提示', { type: 'warning' }).then(async () => {
|
|
|
+ this.$confirm("确定要重置为出厂默认内容吗?", "提示", { type: "warning" }).then(async () => {
|
|
|
await resetPrompt(row.promptKey)
|
|
|
- this.$message.success('已重置')
|
|
|
+ this.$message.success("已重置")
|
|
|
this.fetchList()
|
|
|
}).catch(() => {})
|
|
|
},
|
|
|
deleteRow(row) {
|
|
|
- this.$confirm('确定要删除该提示词吗?', '提示', { type: 'warning' }).then(async () => {
|
|
|
+ this.$confirm("确定要删除该提示词吗?", "提示", { type: "warning" }).then(async () => {
|
|
|
await deletePrompt(row.id)
|
|
|
- this.$message.success('删除成功')
|
|
|
+ this.$message.success("删除成功")
|
|
|
this.fetchList()
|
|
|
}).catch(() => {})
|
|
|
},
|
|
|
@@ -182,6 +209,33 @@ export default {
|
|
|
this.previewContent = row.content
|
|
|
this.previewVisible = true
|
|
|
},
|
|
|
+ async showVersions(row) {
|
|
|
+ this.versionDialog.promptKey = row.promptKey
|
|
|
+ this.versionDialog.title = row.title
|
|
|
+ this.versionDialog.currentVersion = row.version
|
|
|
+ this.versionDialog.versions = []
|
|
|
+ this.versionDialog.visible = true
|
|
|
+ try {
|
|
|
+ const res = await listVersions(row.promptKey)
|
|
|
+ if (res && res.data) {
|
|
|
+ this.versionDialog.versions = res.data
|
|
|
+ }
|
|
|
+ } catch (e) {
|
|
|
+ this.$message.error("加载版本历史失败")
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async doRollback(promptKey, targetVersion, targetTitle) {
|
|
|
+ this.$confirm(`确定要回滚到 v${targetVersion}(${targetTitle})吗?当前版本将被备份后恢复。`, "确认回滚", { type: "warning" }).then(async () => {
|
|
|
+ try {
|
|
|
+ await rollbackPrompt(promptKey, targetVersion)
|
|
|
+ this.$message.success("回滚成功")
|
|
|
+ this.versionDialog.visible = false
|
|
|
+ this.fetchList()
|
|
|
+ } catch (e) {
|
|
|
+ this.$message.error("回滚失败")
|
|
|
+ }
|
|
|
+ }).catch(() => {})
|
|
|
+ },
|
|
|
handlePageChange(page) {
|
|
|
this.page = page
|
|
|
this.fetchList()
|
|
|
@@ -194,18 +248,4 @@ export default {
|
|
|
.system-prompt-page {
|
|
|
padding: 0;
|
|
|
}
|
|
|
-.sort-header {
|
|
|
- cursor: pointer;
|
|
|
- user-select: none;
|
|
|
- font-weight: 500;
|
|
|
- font-size: 12px;
|
|
|
-}
|
|
|
-.sort-header:hover {
|
|
|
- color: #409eff;
|
|
|
-}
|
|
|
-.sort-tag {
|
|
|
- margin-left: 8px;
|
|
|
- cursor: pointer;
|
|
|
- white-space: nowrap;
|
|
|
-}
|
|
|
</style>
|