/**
* settings.js — 设置页(系统提示词 + 模板正文 + LLM 参数)
* 所有配置持久化到 SQLite,通过 /api/prompts 读写
*/
const SettingsPage = {
state: {
template: 'simple',
configs: null, // 从 API 加载的配置(含自定义值)
llmParams: null, // LLM 参数
systemPrompt: '', // 系统提示词(编辑框值,空=使用默认)
templateText: '', // 模板正文(编辑框值,空=使用默认)
saveStatus: '', // 保存状态提示
loading: true,
error: null,
},
render() {
if (this.state.loading) {
return `
设置
${UI.spinner(20)}加载配置中...
`;
}
if (this.state.error) {
return `
设置
${UI.errorState(this.state.error, 'SettingsPage.init()')}
`;
}
const tpl = TEMPLATES.find(t => t.value === this.state.template);
const llm = this.state.llmParams || {};
return `
设置
配置系统提示词、问答模板和 LLM 参数,所有设置持久化到数据库。
定义 AI 的角色和基本行为。留空使用默认值。
${TEMPLATES.map(t => `
`).join('')}
自定义模板正文,必须包含 {context} 和 {question} 占位符。留空使用预设模板。
查看预设模板参考(当前: ${tpl?.label || ''})
${this._escapeHtml(PROMPT_DEFAULTS['template_' + this.state.template] || '')}
LLM 参数
Thinking 开启时,AI 会先思考再回答(可折叠查看)。Max Tokens 是总 token 上限(含 thinking)。
`;
},
async init() {
await this.loadConfigs();
},
async loadConfigs() {
this.state.loading = true;
const content = document.getElementById('content');
if (content) content.innerHTML = this.render();
try {
const resp = await API.get('/api/prompts');
this.state.configs = resp.data.configs;
this.state.llmParams = resp.data.llm_params;
// 系统提示词:直接显示数据库值(空则用默认值填充)
this.state.systemPrompt = this.state.configs.system_prompt || PROMPT_DEFAULTS.system_prompt;
// 当前模板正文:直接显示数据库值(空则用默认值填充)
this._loadTemplateText();
this.state.loading = false;
this.state.error = null;
if (content) content.innerHTML = this.render();
} catch (e) {
this.state.loading = false;
this.state.error = e.message;
if (content) content.innerHTML = this.render();
}
},
_loadTemplateText() {
const tplKey = `template_${this.state.template}`;
this.state.templateText = this.state.configs[tplKey] || PROMPT_DEFAULTS[tplKey];
},
setTemplate(t) {
this.state.template = t;
if (this.state.configs) this._loadTemplateText();
const content = document.getElementById('content');
content.innerHTML = this.render();
},
// ===== 系统提示词 =====
async saveSystemPrompt(val) {
this.state.systemPrompt = val;
this._showSaveStatus('保存中...');
try {
await API.put('/api/prompts', { system_prompt: val });
this._showSaveStatus('已保存');
} catch (e) {
this._showSaveStatus('保存失败');
}
},
async resetSystemPrompt() {
this.state.systemPrompt = '';
this._showSaveStatus('重置中...');
try {
await API.put('/api/prompts', { system_prompt: '' });
const el = document.getElementById('settings-system-prompt');
if (el) el.value = '';
this._showSaveStatus('已恢复默认');
} catch (e) {
this._showSaveStatus('重置失败');
}
},
// ===== 模板正文 =====
async saveTemplateText(val) {
this.state.templateText = val;
this._showSaveStatus('保存中...');
try {
const body = {};
body[`template_${this.state.template}`] = val;
await API.put('/api/prompts', body);
this._showSaveStatus('已保存');
} catch (e) {
this._showSaveStatus('保存失败');
}
},
async resetTemplateText() {
this.state.templateText = '';
this._showSaveStatus('重置中...');
try {
const body = {};
body[`template_${this.state.template}`] = '';
await API.put('/api/prompts', body);
const el = document.getElementById('settings-template-text');
if (el) el.value = '';
this._showSaveStatus('已恢复默认');
} catch (e) {
this._showSaveStatus('重置失败');
}
},
// ===== LLM 参数 =====
async saveLLMParam(key, value) {
this._showSaveStatus('保存中...');
try {
const body = {};
body[key] = String(value);
await API.put('/api/prompts', body);
this._showSaveStatus('已保存');
// 重新加载参数
const resp = await API.get('/api/prompts');
this.state.llmParams = resp.data.llm_params;
} catch (e) {
this._showSaveStatus('保存失败');
}
},
// ===== 工具方法 =====
_showSaveStatus(msg) {
this.state.saveStatus = msg;
const el = document.getElementById('settings-save-status');
if (el) {
el.textContent = msg;
el.style.opacity = '1';
setTimeout(() => { el.style.opacity = '0'; }, 2000);
}
},
_escapeHtml(text) {
if (!text) return '';
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
},
};