fix: 三平台内容差异化 + admin敏感词管理表格化
- writer.py: _expand_section() 去除 <100字阈值,始终调用 LLM 平台专属扩写
- prompt_loader.py: 新增 section_expansion_zhihu/wechat/xiaohongshu 三个独立 prompt
- admin.html: 配置管理标签页 + 敏感词/清理规则子标签 + 敏感词表格化管理(编辑/删除)
- config_items.py: PUT /sensitive-words/{id} 支持更新 word/category
- compliance_checker.py: AI 套话从 DB 加载 + 人称规则修正
- initial_data.py: PlatformConfig 字数迁移 + 新种子
- 各前端页面: LLM 配置 rate_limit 字段 + 供应商列表排序
This commit is contained in:
@@ -65,7 +65,7 @@
|
||||
<script src="uni-nav.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
<div id="app" v-cloak>
|
||||
<uni-nav title="任务管理" :username="currentUser.username" :is-admin="isAdmin" current-page="tasks" @navigate="redirectToPage" @logout="handleLogout">
|
||||
</uni-nav>
|
||||
<div class="main-content">
|
||||
@@ -103,7 +103,7 @@
|
||||
<div><span>最后运行</span><span>{{ mod.last_run || '从未' }}<span v-if="mod.last_status" :style="{marginLeft:'6px',padding:'1px 6px',borderRadius:'8px',fontSize:'11px',fontWeight:500}"><span v-if="mod.last_status==='success'" style="color:#67c23a;">✅成功</span><span v-else-if="mod.last_status==='failed'" style="color:#f56c6c;">❌失败</span><span v-else-if="mod.last_status==='running'" style="color:#e6a23c;">⏳运行中</span></span></span></div>
|
||||
<div><span>下次运行</span><span>{{ mod.next_run || '—' }}</span></div>
|
||||
<div><span>累计运行</span><span>{{ mod.total_runs }} 次 <span style="color:#67c23a;">{{ mod.success_runs }} 成功</span> <span style="color:#f56c6c;">{{ mod.failed_runs }} 失败</span><span v-if="mod.running > 0" style="color:#e6a23c;"> {{ mod.running }} 运行中</span></span></div>
|
||||
<div><span>LLM 模型</span><span>{{ (mod.params && mod.params.llm_provider) || (defaultLlmLabel || '默认') }}</span></div>
|
||||
<div><span>LLM 模型</span><span>{{ llmLabel(mod) }}</span></div>
|
||||
<div style="margin-top:10px; border-bottom:none;">
|
||||
<el-button size="small" type="primary" @click.stop="triggerModule(mod.module_id)" :loading="runningModule === mod.module_id" :disabled="!mod.enabled">立即运行</el-button>
|
||||
<el-button size="small" @click.stop="openModuleDetail(mod)">查看详情</el-button>
|
||||
@@ -349,15 +349,15 @@
|
||||
</div>
|
||||
<div style="display:flex;gap:16px;align-items:center;margin-bottom:12px;">
|
||||
<span style="font-size:13px;color:#606266;width:60px;">LLM</span>
|
||||
<el-select v-model="drawerData.params.llm_provider" size="small" style="width:200px;" clearable placeholder="系统默认" @change="saveModuleConfig" :disabled="savingConfig">
|
||||
<el-option v-for="c in llmConfigs.filter(x=>x.is_active)" :key="c.id" :label="c.provider + ' (' + c.model + ')' + (c.is_default ? ' (默认)' : '')" :value="c.provider"/>
|
||||
<el-select v-model="drawerData.params.llm_provider" size="small" style="width:280px;" clearable placeholder="系统默认" @change="onLLMProviderChange" :disabled="savingConfig">
|
||||
<el-option v-for="c in llmConfigs.filter(x=>x.is_active)" :key="c.id" :label="c.provider + '/' + c.model + (c.rate_limit ? ' (' + c.rate_limit + '次/' + (c.rate_limit_window_minutes||300) + '分)' : '') + (c.is_default ? ' (默认)' : '')" :value="c.provider"/>
|
||||
</el-select>
|
||||
<span style="font-size:12px;color:#909399;">留空则使用系统默认模型</span>
|
||||
<span style="font-size:12px;color:#909399;">留空则使用系统默认</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="Object.keys(drawerData.params || {}).filter(k => k !== 'llm_provider').length > 0">
|
||||
<div v-if="Object.keys(drawerData.params || {}).filter(k => k !== 'llm_provider' && k !== 'llm_model').length > 0">
|
||||
<div style="font-size:13px;font-weight:600;margin-bottom:12px;">参数配置</div>
|
||||
<div v-for="(val, key) in drawerData.params" v-if="key !== 'llm_provider'" :key="key" style="margin-bottom:12px;display:flex;align-items:center;gap:12px;">
|
||||
<div v-for="(val, key) in drawerData.params" v-if="key !== 'llm_provider' && key !== 'llm_model'" :key="key" style="margin-bottom:12px;display:flex;align-items:center;gap:12px;">
|
||||
<span style="font-size:13px;color:#606266;width:120px;">{{ key }}</span>
|
||||
<el-input v-if="typeof val === 'string'" v-model="drawerData.params[key]" size="small" style="flex:1;" @change="saveModuleConfig" :disabled="savingConfig"></el-input>
|
||||
<el-input-number v-else-if="typeof val === 'number'" v-model="drawerData.params[key]" size="small" :disabled="savingConfig" @change="saveModuleConfig"></el-input-number>
|
||||
@@ -672,9 +672,29 @@ const TasksApp = {
|
||||
const configs = await this.api('/api/admin/llmconfigs');
|
||||
this.llmConfigs = configs || [];
|
||||
const def = (configs || []).find(c => c.is_default);
|
||||
this.defaultLlmLabel = def ? def.provider + ' (' + def.model + ')' : '';
|
||||
this.defaultLlmLabel = def ? def.provider + '/' + def.model : '';
|
||||
} catch (e) { console.error('loadLLMConfigs error:', e); this.llmConfigs = []; }
|
||||
},
|
||||
llmLabel(mod) {
|
||||
const p = (mod.params && mod.params.llm_provider) || '';
|
||||
const m = (mod.params && mod.params.llm_model) || '';
|
||||
if (p && m) return p + '/' + m;
|
||||
if (p) {
|
||||
const match = (this.llmConfigs || []).find(c => c.provider === p && c.is_active);
|
||||
if (match) return p + '/' + match.model;
|
||||
}
|
||||
return this.defaultLlmLabel || '默认';
|
||||
},
|
||||
onLLMProviderChange(val) {
|
||||
if (!val) {
|
||||
delete this.drawerData.params.llm_provider;
|
||||
delete this.drawerData.params.llm_model;
|
||||
} else {
|
||||
const match = (this.llmConfigs || []).find(c => c.provider === val && c.is_active);
|
||||
if (match) this.drawerData.params.llm_model = match.model;
|
||||
}
|
||||
this.saveModuleConfig();
|
||||
},
|
||||
async openModuleDetail(mod) {
|
||||
this.showDrawer = true;
|
||||
this.drawerTitle = mod.title + ' 详情';
|
||||
|
||||
Reference in New Issue
Block a user