diff --git a/backend/routes/notifications.js b/backend/routes/notifications.js index 1ed720a..4c2d681 100644 --- a/backend/routes/notifications.js +++ b/backend/routes/notifications.js @@ -24,7 +24,7 @@ router.put('/:id', authenticate, requireRole('owner','admin'), async (req, res) const fields = {}; if (req.body.name) fields.name = req.body.name; if (req.body.webhook_url !== undefined) fields.webhook_url = req.body.webhook_url; - if (req.body.events) fields.events = req.body.events; + if (req.body.type) fields.type = req.body.type; if (req.body.active !== undefined) fields.active = req.body.active?1:0; if (!Object.keys(fields).length) return res.status(400).json({ error: '无更新内容' }); const sets = Object.keys(fields).map(k=>`${k}=?`).join(','); diff --git a/public/js/pages/notifications.js b/public/js/pages/notifications.js index 720adb6..ab8ab85 100644 --- a/public/js/pages/notifications.js +++ b/public/js/pages/notifications.js @@ -3,7 +3,7 @@ const NotificationsPage = { async mount() { document.getElementById('page-title').textContent = '通知配置'; - document.getElementById('page-actions').innerHTML = ''; + document.getElementById('page-actions').innerHTML = ''; await this.load(); }, @@ -11,60 +11,80 @@ const NotificationsPage = { const ct = document.getElementById('page-content'); try { const cfgs = await API.get('/notifications'); + const typeLabel = { webhook:'Discord', email:'邮件通知', generic:'通用Webhook' }; ct.innerHTML = cfgs.length ? cfgs.map(c => ` -
${U.esc(c.name)}${c.active?`启用`:`禁用`}
-
类型${c.type==='webhook'?'Webhook':'邮件'}
- ${c.webhook_url?`
地址${U.esc(c.webhook_url)}
`:''} +
${U.esc(c.name)}${c.active?`启用`:`禁用`}
+
类型${typeLabel[c.type]||c.type}
+ ${c.type!=='email' && c.webhook_url?`
地址${U.esc(c.webhook_url)}
`:''}
事件${EventsLabel(c.events)}
- - - + + ${c.type!=='email'?``:''} +
- `).join('') : '

暂无通知配置

添加Webhook后可自动推送工单状态变更通知

'; + `).join('') : '

暂无通知配置

'; } catch (e) { ct.innerHTML = `
${e.message}
`; } }, showCreate() { - U.modal('添加Webhook', ` -
-
-
-
-
${EventOptions('all')}
- -
-
+ U.modal('添加通知', ` +
+
+
+
+
+
${EventOptions('all')}
+ +
+ +
`); bindEventToggles(); document.getElementById('nc-form').onsubmit = async e => { e.preventDefault(); - try { await API.post('/notifications',{name:document.getElementById('nc-name').value,type:'webhook',webhook_url:document.getElementById('nc-url').value,events:document.getElementById('nc-events').value}); App.closeModal(); this.load(); } catch(ex){alert(ex.message);} + const type = document.getElementById('nc-type').value; + try { await API.post('/notifications',{name:document.getElementById('nc-name').value, type, webhook_url:document.getElementById('nc-url').value, events:document.getElementById('nc-events').value}); App.closeModal(); this.load(); } catch(ex){alert(ex.message);} }; }, - showEdit(id,name,type,url,events,active) { + toggleFields() { + const type = document.getElementById('nc-type')?.value || document.getElementById('ne-type')?.value; + const urlGroup = document.querySelector('#nc-url-group') || document.querySelector('#ne-url-group'); + if (urlGroup) urlGroup.style.display = type === 'email' ? 'none' : ''; + }, + + showEdit(id, name, type, url, events, active) { U.modal('编辑通知', ` -
-
+
+
+
${EventOptions(events)}
-
+ `); bindEventToggles(); document.getElementById('ne-form').onsubmit = async e => { e.preventDefault(); - try { await API.put(`/notifications/${id}`,{name:document.getElementById('ne-name').value,webhook_url:document.getElementById('ne-url').value,events:document.getElementById('ne-events').value,active:document.getElementById('ne-active').value==='1'}); App.closeModal(); this.load(); } catch(ex){alert(ex.message);} + const newType = document.getElementById('ne-type').value; + try { await API.put(`/notifications/${id}`,{name:document.getElementById('ne-name').value, webhook_url:document.getElementById('ne-url')?.value, events:document.getElementById('ne-events').value, active:document.getElementById('ne-active').value==='1', type:newType}); App.closeModal(); this.load(); } catch(ex){alert(ex.message);} }; }, async test(id) { try { alert((await API.post(`/notifications/${id}/test`)).message); } catch(ex){alert(ex.message);} }, - async del(id) { if(await U.confirm('确认删除此通知配置?')){ try { await API.req('DELETE',`/notifications/${id}`); this.load(); } catch(ex){alert(ex.message);} } } + async del(id) { if(await U.confirm('确认删除?')){ try { await API.req('DELETE',`/notifications/${id}`); this.load(); } catch(ex){alert(ex.message);} } } }; -function EventOptions(current) { return ['all','ticket_created','ticket_claimed','ticket_transferred','ticket_updated'].map(e=>``).join(''); } +function EventOptions(current) { return ['all','ticket_created','ticket_claimed','ticket_transferred','ticket_updated'].map(e=>``).join(''); } function EventsLabel(v) { return v==='all'?'全部事件':v.split(',').map(s=>s.trim()).map(EventsLabelSingle).join(', '); } function EventsLabelSingle(e) { return {all:'全部',ticket_created:'工单创建',ticket_claimed:'工单认领',ticket_transferred:'工单转交',ticket_updated:'工单更新'}[e]||e; } function bindEventToggles() {