v0.3.28: 消息模板改为弹窗编辑 — 每个事件开关旁加✏️按钮,点击弹窗编辑标题和内容,变量带中文说明

This commit is contained in:
2026-05-17 19:09:16 +08:00
parent 4131ccece9
commit 26b579717c
34 changed files with 144 additions and 101 deletions

View File

@@ -522,27 +522,25 @@
</div>
</div>
<el-divider content-position="left">全局事件开关</el-divider>
<div style="display:flex; flex-wrap:wrap; gap:16px;">
<el-switch v-model="globalNotifyForm.events.on_save_success" active-text="转存成功" />
<el-switch v-model="globalNotifyForm.events.on_save_fail" active-text="转存失败" />
<el-switch v-model="globalNotifyForm.events.on_cookie_expire" active-text="Cookie过期" />
<el-switch v-model="globalNotifyForm.events.on_cleanup" active-text="清理完成" />
<div style="display:flex; flex-direction:column; gap:6px;">
<div style="display:flex; align-items:center; gap:8px;">
<el-switch v-model="globalNotifyForm.events.on_save_success" active-text="转存成功" />
<el-button size="small" text type="primary" @click="openTemplateEditor('on_save_success')"> 编辑模板</el-button>
</div>
<div style="display:flex; align-items:center; gap:8px;">
<el-switch v-model="globalNotifyForm.events.on_save_fail" active-text="转存失败" />
<el-button size="small" text type="primary" @click="openTemplateEditor('on_save_fail')"> 编辑模板</el-button>
</div>
<div style="display:flex; align-items:center; gap:8px;">
<el-switch v-model="globalNotifyForm.events.on_cookie_expire" active-text="Cookie过期" />
<el-button size="small" text type="primary" @click="openTemplateEditor('on_cookie_expire')"> 编辑模板</el-button>
</div>
<div style="display:flex; align-items:center; gap:8px;">
<el-switch v-model="globalNotifyForm.events.on_cleanup" active-text="清理完成" />
<el-button size="small" text type="primary" @click="openTemplateEditor('on_cleanup')"> 编辑模板</el-button>
</div>
</div>
<div class="form-tip" style="margin-top:8px;">全局推送作为兜底通道设置了推送用户的网盘配置走用户推送未设置的走全局推送</div>
<el-divider content-position="left">自定义消息模板</el-divider>
<div class="form-tip" style="margin-bottom:12px;">可用变量<code>{'{cloud_type}'}</code> <code>{'{nickname}'}</code> <code>{'{file_name}'}</code> <code>{'{file_size}'}</code> <code>{'{duration}'}</code> <code>{'{share_url}'}</code> <code>{'{fail_count}'}</code> <code>{'{error_message}'}</code></div>
<div v-for="(tpl, tkey) in globalNotifyForm.eventTemplates" :key="tkey" style="border:1px solid var(--el-border-color-light); border-radius:6px; padding:10px 14px; margin-bottom:10px;">
<div style="display:flex; align-items:center; gap:8px; margin-bottom:8px;">
<el-tag size="small" :type="globalNotifyForm.events[tkey] ? 'success' : 'info'">{{ tkey === 'on_save_success' ? '转存成功' : tkey === 'on_save_fail' ? '转存失败' : tkey === 'on_cookie_expire' ? 'Cookie过期' : '清理完成' }}</el-tag>
<el-switch v-model="globalNotifyForm.events[tkey]" size="small" />
</div>
<el-form-item label="标题" style="margin-bottom:6px;">
<el-input v-model="tpl.title" placeholder="消息标题,支持变量" style="max-width:500px" />
</el-form-item>
<el-form-item label="内容" style="margin-bottom:0;">
<el-input v-model="tpl.content" type="textarea" :rows="3" placeholder="消息内容,支持变量和 Markdown" style="max-width:500px" />
</el-form-item>
</div>
</el-form>
</div>
</el-collapse-item>
@@ -673,6 +671,33 @@
<!-- 🔄 系统维护 --> <el-card id="section-sys-maintenance" v-show="!activeSection || activeSection === 'sys-maintenance'"> <template #header> <span>🔄 系统维护</span> </template> <el-form label-width="180px" label-position="left"> <el-form-item label="自动更新镜像"> <el-switch v-model="autoUpdateEnabled" active-text="启用" inactive-text="禁用" /> <div class="form-tip">启用后 CloudSearch 将自动检测并更新到最新镜像版本</div> <div class="form-tip" style="color: var(--(--el-color-warning,#e6a23c));"> 当前需手动在服务器执行docker-compose -f /opt/CloudSearch/docker-compose.yml pull && docker-compose -f /opt/CloudSearch/docker-compose.yml up -d </div> </el-form-item> </el-form> </el-card>
<!-- 消息模板编辑弹窗 -->
<el-dialog v-model="templateEditorVisible" :title="'✏️ 编辑消息模板 — ' + templateEditorLabel" width="560px" @close="templateEditorKey = ''">
<div style="margin-bottom:10px; font-size:12px; color:var(--el-text-color-secondary); line-height:2;">
可用变量<br/>
<el-tag size="small" style="margin:2px">{cloud_type}</el-tag> 网盘类型夸克/百度/阿里
<el-tag size="small" style="margin:2px">{nickname}</el-tag> 网盘昵称
<el-tag size="small" style="margin:2px">{file_name}</el-tag> 文件名
<el-tag size="small" style="margin:2px">{file_size}</el-tag> 文件大小
<el-tag size="small" style="margin:2px">{duration}</el-tag> 耗时
<el-tag size="small" style="margin:2px">{share_url}</el-tag> 分享链接
<el-tag size="small" style="margin:2px">{fail_count}</el-tag> 连续失败次数
<el-tag size="small" style="margin:2px">{error_message}</el-tag> 错误信息
<el-tag size="small" style="margin:2px">{freed_space}</el-tag> 释放空间
</div>
<el-form v-if="templateEditorKey && globalNotifyForm.eventTemplates[templateEditorKey]" label-width="60px">
<el-form-item label="标题">
<el-input v-model="globalNotifyForm.eventTemplates[templateEditorKey].title" placeholder="消息标题,支持 {变量}" />
</el-form-item>
<el-form-item label="内容">
<el-input v-model="globalNotifyForm.eventTemplates[templateEditorKey].content" type="textarea" :rows="5" placeholder="消息正文,支持 Markdown 和 {变量}" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="templateEditorVisible = false">关闭</el-button>
</template>
</el-dialog>
<!-- 保存按钮 -->
<div class="save-bar">
<el-button type="primary" size="large" :loading="saving" @click="handleSave">
@@ -889,6 +914,7 @@ const globalNotifyForm = reactive<{ channels: Record<string, any>; events: Recor
on_save_success: { title: '✅ 转存成功', content: '**{cloud_type}** · {nickname}\n文件: {file_name}\n大小: {file_size}\n耗时: {duration}s\n链接: {share_url}' },
on_save_fail: { title: '❌ 转存连续失败 {fail_count} 次', content: '**{cloud_type}** · {nickname}\n连续失败次数: {fail_count}\n最后失败: {error_message}\n请检查网盘状态' },
on_cookie_expire: { title: '⚠️ Cookie 已过期', content: '**{cloud_type}** · {nickname}\nCookie 已过期或失效,请重新登录\n最后操作: {share_url}' },
on_cleanup: { title: '🧹 清理完成', content: '**{cloud_type}** · {nickname}\n清理完成\n释放空间: {freed_space}' },
},
})
@@ -1070,9 +1096,7 @@ async function loadGlobalNotifyConfig() {
}
if (parsed.eventTemplates) {
for (const [ek, et] of Object.entries(parsed.eventTemplates)) {
if (globalNotifyForm.eventTemplates[ek]) {
globalNotifyForm.eventTemplates[ek] = et as any
}
globalNotifyForm.eventTemplates[ek] = et as any
}
}
} catch {}
@@ -1080,6 +1104,21 @@ async function loadGlobalNotifyConfig() {
} catch {}
}
// ── 消息模板编辑器 ──
const templateEditorVisible = ref(false)
const templateEditorKey = ref('')
const templateEditorLabel = computed(() => {
const labels: Record<string, string> = { on_save_success: '转存成功', on_save_fail: '转存失败', on_cookie_expire: 'Cookie过期', on_cleanup: '清理完成' }
return labels[templateEditorKey.value] || ''
})
function openTemplateEditor(key: string) {
templateEditorKey.value = key
templateEditorVisible.value = true
if (!globalNotifyForm.eventTemplates[key]) {
globalNotifyForm.eventTemplates[key] = { title: '', content: '' }
}
}
async function testGlobalChannel(channelName: string) {
const ch = globalNotifyForm.channels[channelName]
if (!ch || !ch._enabled) return