Skip to content

Commit 1763067

Browse files
pythonHuangclaude
andcommitted
feat: 模型助手管理增加辅助提问词按钮列表-助手配置可维护提问词清单,运行页显示为快捷按钮点击填入补充说明(换行追加)
Co-Authored-By: Claude Code <noreply@anthropic.com>
1 parent e344f80 commit 1763067

6 files changed

Lines changed: 32 additions & 1 deletion

File tree

‎Juggle.Api/Controllers/Api/AiController.cs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ public async Task<ApiResult> SaveAssistant([FromBody] AiAssistantSaveRequest req
232232
entity.SystemPrompt = req.SystemPrompt;
233233
entity.InputParams = req.InputParams;
234234
entity.OutputParams = req.OutputParams;
235+
entity.QuickPrompts = req.QuickPrompts;
235236
entity.Enabled = req.Enabled ? 1 : 0;
236237
entity.UpdatedAt = DateTime.Now.ToString("o");
237238
await _db.SaveChangesAsync();
@@ -347,6 +348,7 @@ public class AiAssistantSaveRequest
347348
public string? SystemPrompt { get; set; }
348349
public string? InputParams { get; set; }
349350
public string? OutputParams { get; set; }
351+
public string? QuickPrompts { get; set; }
350352
public bool Enabled { get; set; } = true;
351353
}
352354

‎Juggle.Api/Program.cs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ await ctx.Response.WriteAsync(
251251
try { db.Database.ExecuteSqlRaw("CREATE TABLE IF NOT EXISTS t_ai_provider(id INTEGER PRIMARY KEY AUTOINCREMENT, provider_name TEXT, base_url TEXT, api_key TEXT, model TEXT, models TEXT, enabled INTEGER DEFAULT 1, remark TEXT, created_at TEXT, created_by INTEGER, updated_at TEXT, updated_by INTEGER, tenant_id INTEGER, deleted INTEGER DEFAULT 0);"); } catch { }
252252
// AI 自定义助手表
253253
try { db.Database.ExecuteSqlRaw("CREATE TABLE IF NOT EXISTS t_ai_assistant(id INTEGER PRIMARY KEY AUTOINCREMENT, assistant_name TEXT, description TEXT, system_prompt TEXT, input_params TEXT, output_params TEXT, enabled INTEGER DEFAULT 1, created_at TEXT, created_by INTEGER, updated_at TEXT, updated_by INTEGER, tenant_id INTEGER, deleted INTEGER DEFAULT 0);"); } catch { }
254+
try { db.Database.ExecuteSqlRaw("ALTER TABLE t_ai_assistant ADD COLUMN quick_prompts TEXT DEFAULT NULL;"); } catch { }
254255
// 补建参数位置字段
255256
try { db.Database.ExecuteSqlRaw("ALTER TABLE t_parameter ADD COLUMN param_position TEXT DEFAULT NULL;"); } catch { }
256257
}

‎Juggle.Domain/Entities/AiAssistantEntity.cs‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ public class AiAssistantEntity : BaseEntity
2222
/// <summary>输出参数列表(JSON: [{name,label,type}])</summary>
2323
public string? OutputParams { get; set; }
2424

25+
/// <summary>辅助提问词列表(JSON 字符串数组,运行页显示为快捷按钮)</summary>
26+
public string? QuickPrompts { get; set; }
27+
2528
/// <summary>是否启用:1=启用(出现在菜单) 0=禁用</summary>
2629
public int Enabled { get; set; } = 1;
2730
}

‎Juggle.Infrastructure/Persistence/JuggleDbContext.cs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder)
121121
e.Property(p => p.SystemPrompt).HasColumnName("system_prompt");
122122
e.Property(p => p.InputParams).HasColumnName("input_params");
123123
e.Property(p => p.OutputParams).HasColumnName("output_params");
124+
e.Property(p => p.QuickPrompts).HasColumnName("quick_prompts");
124125
e.Property(p => p.Enabled).HasColumnName("enabled");
125126
});
126127
modelBuilder.Entity<AlertRuleEntity>().ToTable("t_alert_rule");

‎JuggleNet6.Frontend/src/views/ai/AiAssistantList.vue‎

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,16 @@
7171
<div style="font-size:11px;color:#909399;margin-top:4px">配置输出参数后,运行时会要求模型按 JSON 返回并在结果区按参数展示。</div>
7272
</div>
7373
</el-form-item>
74+
<el-form-item label="辅助提问词">
75+
<div style="width:100%">
76+
<div v-for="(_q, i) in quickPrompts" :key="i" style="display:flex;gap:4px;margin-bottom:4px">
77+
<el-input v-model="quickPrompts[i]" :placeholder="i === 0 ? '如 帮我写一篇本周工作总结' : '提问词'" size="small" style="flex:1" />
78+
<el-button size="small" type="danger" link @click="quickPrompts.splice(i,1)">删</el-button>
79+
</div>
80+
<el-button size="small" @click="quickPrompts.push('')">+添加提问词</el-button>
81+
<div style="font-size:11px;color:#909399;margin-top:4px">运行页中显示为快捷按钮,点击即填入补充说明,方便常用提问一键发起。</div>
82+
</div>
83+
</el-form-item>
7484
<el-form-item label="启用"><el-switch v-model="form.enabled" /></el-form-item>
7585
</el-form>
7686
<template #footer>
@@ -92,6 +102,7 @@ const dialogVisible = ref(false)
92102
const form = ref<any>({ id: 0, assistantName: '', description: '', systemPrompt: '', enabled: true })
93103
const inputParams = ref<any[]>([])
94104
const outputParams = ref<any[]>([])
105+
const quickPrompts = ref<string[]>([])
95106
96107
onMounted(loadData)
97108
@@ -111,19 +122,22 @@ function openAdd() {
111122
form.value = { id: 0, assistantName: '', description: '', systemPrompt: '', enabled: true }
112123
inputParams.value = []
113124
outputParams.value = []
125+
quickPrompts.value = []
114126
dialogVisible.value = true
115127
}
116128
function openEdit(row: any) {
117129
form.value = { ...row, enabled: row.enabled === 1 }
118130
try { inputParams.value = JSON.parse(row.inputParams || '[]') } catch { inputParams.value = [] }
119131
try { outputParams.value = JSON.parse(row.outputParams || '[]') } catch { outputParams.value = [] }
132+
try { quickPrompts.value = JSON.parse(row.quickPrompts || '[]') } catch { quickPrompts.value = [] }
120133
dialogVisible.value = true
121134
}
122135
async function doSave() {
123136
await request.post('/ai/assistant/save', {
124137
...form.value,
125138
inputParams: JSON.stringify(inputParams.value),
126-
outputParams: JSON.stringify(outputParams.value)
139+
outputParams: JSON.stringify(outputParams.value),
140+
quickPrompts: JSON.stringify(quickPrompts.value.filter((q: string) => q.trim()))
127141
})
128142
ElMessage.success('保存成功')
129143
dialogVisible.value = false

‎JuggleNet6.Frontend/src/views/ai/AssistantRun.vue‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@
3030
</div>
3131
</div>
3232
<el-input v-model="extraText" type="textarea" :rows="3" style="margin-top:10px" placeholder="补充说明(可选,如:语气轻松一点)" />
33+
<div v-if="quickPrompts.length > 0" style="margin-top:8px;display:flex;gap:6px;flex-wrap:wrap">
34+
<el-button v-for="(q, i) in quickPrompts" :key="i" size="small" round @click="fillPrompt(q)">{{ q }}</el-button>
35+
</div>
3336
<div style="margin-top:10px">
3437
<el-button type="primary" icon="Promotion" :loading="running" @click="doRun">运行</el-button>
3538
</div>
@@ -64,6 +67,7 @@ const assistantId = Number(route.params.id) || 0
6467
const assistant = ref<any>(null)
6568
const inputParams = ref<any[]>([])
6669
const outputParams = ref<any[]>([])
70+
const quickPrompts = ref<string[]>([])
6771
const inputs = ref<Record<string, any>>({})
6872
const extraText = ref('')
6973
const providers = ref<any[]>([])
@@ -90,6 +94,7 @@ onMounted(async () => {
9094
document.title = assistant.value.assistantName
9195
try { inputParams.value = JSON.parse(assistant.value.inputParams || '[]') } catch { inputParams.value = [] }
9296
try { outputParams.value = JSON.parse(assistant.value.outputParams || '[]') } catch { outputParams.value = [] }
97+
try { quickPrompts.value = JSON.parse(assistant.value.quickPrompts || '[]') } catch { quickPrompts.value = [] }
9398
for (const p of inputParams.value) {
9499
inputs.value[p.name] = p.type === 'switch' ? (p.default === true || p.default === 'true') : (p.default || '')
95100
}
@@ -113,6 +118,11 @@ function selectOptions(p: any): string[] {
113118
return String(p.options || '').split(/[,,\n]/).map((s: string) => s.trim()).filter(Boolean)
114119
}
115120
121+
/** 点击辅助提问词按钮 → 填入补充说明(已有内容时换行追加) */
122+
function fillPrompt(q: string) {
123+
extraText.value = extraText.value.trim() ? extraText.value.trim() + '\n' + q : q
124+
}
125+
116126
async function doRun() {
117127
if (!providerId.value) { ElMessage.warning('请先在系统设置 → 大模型设置中启用供应商'); return }
118128
running.value = true

0 commit comments

Comments
 (0)