v0.3.29: 推送用户改为单一渠道+参数输入 — 选频道后显示 webhook/ token 等输入框,列表显示渠道摘要

This commit is contained in:
2026-05-17 19:18:52 +08:00
parent 26b579717c
commit 063fa6b065
34 changed files with 153 additions and 102 deletions

View File

@@ -558,7 +558,7 @@
/>
</el-select>
<el-select v-model="pushUserForm.channels" multiple collapse-tags collapse-tags-tooltip placeholder="选择您所需的消息频道" style="width:260px;">
<el-select v-model="pushUserForm.channel" clearable placeholder="选择消息频道" style="width:220px;" @change="onPushUserChannelChange">
<el-option
v-for="(np, nkey) in enabledNotifyProviders"
:key="nkey"
@@ -567,10 +567,32 @@
/>
</el-select>
<el-switch v-model="pushUserForm.events.on_save_success" active-text="转存成功" />
<el-switch v-model="pushUserForm.events.on_save_fail" active-text="转存失败" />
<el-switch v-model="pushUserForm.events.on_cookie_expire" active-text="Cookie过期" />
<el-switch v-model="pushUserForm.events.on_cleanup" active-text="清理完成" />
<!-- Channel params inputs -->
<template v-if="pushUserForm.channel && notifyProviders[pushUserForm.channel]">
<div v-for="p in notifyProviders[pushUserForm.channel].params" :key="p.key" style="display:inline-flex; align-items:center; gap:4px;">
<span style="font-size:13px; color:var(--el-text-color-secondary); white-space:nowrap;">{{ p.label }}:</span>
<el-input
v-if="p.type === 'password'"
v-model="pushUserForm.channelParams[p.key]"
type="password" show-password
:placeholder="p.placeholder || p.label"
style="width:200px;" size="small"
/>
<el-input
v-else
v-model="pushUserForm.channelParams[p.key]"
:placeholder="p.placeholder || p.label"
style="width:200px;" size="small"
/>
</div>
</template>
<div style="display:flex; align-items:center; gap:12px; flex-wrap:wrap;">
<el-switch v-model="pushUserForm.events.on_save_success" active-text="转存成功" />
<el-switch v-model="pushUserForm.events.on_save_fail" active-text="转存失败" />
<el-switch v-model="pushUserForm.events.on_cookie_expire" active-text="Cookie过期" />
<el-switch v-model="pushUserForm.events.on_cleanup" active-text="清理完成" />
</div>
<el-button type="primary" size="small" :loading="pushUserSaving" @click="savePushUser">{{ pushUserForm.id ? '更新' : '确认添加' }}</el-button>
<el-button v-if="pushUserForm.id" size="small" @click="cancelEditPushUser">取消编辑</el-button>
@@ -605,10 +627,13 @@
<span v-else style="color:#ccc;"></span>
</template>
</el-table-column>
<el-table-column label="已启用的通道" min-width="220">
<el-table-column label="消息频道" min-width="180">
<template #default="{ row }">
<el-tag v-for="(_, key) in getEnabledChannels(row)" :key="key" size="small" style="margin-right:4px;margin-bottom:2px;">{{ getProviderLabel(key) }}</el-tag>
<span v-if="!hasEnabledChannels(row)" style="color:#909399;font-size:12px;">走全局推送</span>
<template v-if="hasEnabledChannels(row)">
<el-tag v-for="(params, key) in getEnabledChannels(row)" :key="key" size="small" style="margin-right:4px;margin-bottom:2px;">{{ getProviderLabel(key) }}</el-tag>
<span style="font-size:11px; color:var(--el-text-color-secondary); margin-left:4px;">{{ getChannelParamsSummary(row) }}</span>
</template>
<span v-else style="color:#909399;font-size:12px;">走全局推送</span>
</template>
</el-table-column>
<el-table-column label="操作" width="180" fixed="right">
@@ -675,11 +700,11 @@
<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">{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">{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> 错误信息
@@ -687,7 +712,7 @@
</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-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 和 {变量}" />
@@ -887,7 +912,8 @@ async function loadPushUserAccountOptions() {
const pushUserForm = reactive<any>({
id: null,
account: '',
channels: [],
channel: '',
channelParams: {} as Record<string, string>,
events: {
on_save_success: true,
on_save_fail: true,
@@ -895,6 +921,10 @@ const pushUserForm = reactive<any>({
on_cleanup: false,
},
})
function onPushUserChannelChange() {
// Reset params when channel changes
pushUserForm.channelParams = {}
}
// Only show channels that are enabled in global notification settings
const enabledNotifyProviders = computed(() => {
@@ -934,7 +964,9 @@ function editPushUser(row?: any) {
pushUserForm.id = row.id
pushUserForm.account = row.account
const nc = row.notify_config || {}
pushUserForm.channels = Object.keys(nc.channels || {})
const chKeys = Object.keys(nc.channels || {})
pushUserForm.channel = chKeys[0] || ''
pushUserForm.channelParams = chKeys[0] ? (nc.channels[chKeys[0]] || {}) : {}
pushUserForm.events = {
on_save_success: nc.events?.on_save_success !== false,
on_save_fail: nc.events?.on_save_fail !== false,
@@ -944,7 +976,8 @@ function editPushUser(row?: any) {
} else {
pushUserForm.id = null
pushUserForm.account = ''
pushUserForm.channels = []
pushUserForm.channel = ''
pushUserForm.channelParams = {}
pushUserForm.events = { on_save_success: true, on_save_fail: true, on_cookie_expire: true, on_cleanup: false }
}
}
@@ -952,7 +985,8 @@ function editPushUser(row?: any) {
function cancelEditPushUser() {
pushUserForm.id = null
pushUserForm.account = ''
pushUserForm.channels = []
pushUserForm.channel = ''
pushUserForm.channelParams = {}
pushUserForm.events = { on_save_success: true, on_save_fail: true, on_cookie_expire: true, on_cleanup: false }
}
@@ -973,10 +1007,10 @@ async function savePushUser() {
account: pushUserForm.account,
notify_config: { channels: {}, events: pushUserForm.events },
}
// Build channels from selected keys (no params — use global config at push time)
// Build channel with params
const ch: Record<string, any> = {}
for (const key of pushUserForm.channels) {
ch[key] = {}
if (pushUserForm.channel) {
ch[pushUserForm.channel] = { ...pushUserForm.channelParams }
}
payload.notify_config.channels = ch
if (pushUserForm.id) {
@@ -995,7 +1029,8 @@ async function savePushUser() {
const isUpdate = !!pushUserForm.id
pushUserForm.id = null
pushUserForm.account = ''
pushUserForm.channels = []
pushUserForm.channel = ''
pushUserForm.channelParams = {}
pushUserForm.events = { on_save_success: true, on_save_fail: true, on_cookie_expire: true, on_cleanup: false }
ElMessage.success(isUpdate ? '推送用户已更新' : '推送用户已添加')
await loadPushUsers()
@@ -1052,6 +1087,22 @@ function getProviderLabel(key: string): string {
function hasEnabledChannels(row: any): boolean {
return Object.keys(getEnabledChannels(row)).length > 0
}
function getChannelParamsSummary(row: any): string {
const ch = row.notify_config?.channels || {}
const keys = Object.keys(ch)
if (keys.length === 0) return ''
const params = ch[keys[0]] || {}
const parts: string[] = []
for (const [k, v] of Object.entries(params)) {
if (v && typeof v === 'string') {
const masked = k.includes('token') || k.includes('key') || k.includes('secret') || k.includes('password')
? (v as string).substring(0, 4) + '***'
: (v as string).length > 20 ? (v as string).substring(0, 20) + '...' : v
parts.push(masked)
}
}
return parts.join(' | ')
}
// ==================== End Push User Notifications ====================