186 lines
6.0 KiB
JavaScript
186 lines
6.0 KiB
JavaScript
const { createApp, ref, onMounted } = Vue;
|
|
|
|
createApp({
|
|
setup() {
|
|
const currentView = ref('channels');
|
|
const channels = ref([]);
|
|
const notifications = ref([]);
|
|
const showChannelModal = ref(false);
|
|
const sending = ref(false);
|
|
const message = ref(null);
|
|
|
|
const channelForm = ref({
|
|
name: '',
|
|
type: 'discord',
|
|
configJson: '{}',
|
|
tags: '',
|
|
is_active: true
|
|
});
|
|
|
|
const sendForm = ref({
|
|
channels: [],
|
|
title: '',
|
|
body: '',
|
|
priority: 'normal'
|
|
});
|
|
|
|
const API_BASE = '/api';
|
|
|
|
const showMessage = (text, type = 'success') => {
|
|
message.value = { text, type };
|
|
setTimeout(() => message.value = null, 3000);
|
|
};
|
|
|
|
const fetchChannels = async () => {
|
|
try {
|
|
const res = await fetch(`${API_BASE}/channels`);
|
|
const data = await res.json();
|
|
channels.value = data.channels;
|
|
} catch (e) {
|
|
showMessage('获取通道失败', 'error');
|
|
}
|
|
};
|
|
|
|
const fetchNotifications = async () => {
|
|
try {
|
|
const res = await fetch(`${API_BASE}/notifications`);
|
|
const data = await res.json();
|
|
notifications.value = data.notifications;
|
|
} catch (e) {
|
|
showMessage('获取历史失败', 'error');
|
|
}
|
|
};
|
|
|
|
const saveChannel = async () => {
|
|
try {
|
|
const config = JSON.parse(channelForm.value.configJson);
|
|
const tags = channelForm.value.tags.split(',').map(t => t.trim()).filter(t => t);
|
|
|
|
const res = await fetch(`${API_BASE}/channels`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
name: channelForm.value.name,
|
|
type: channelForm.value.type,
|
|
config,
|
|
tags,
|
|
is_active: channelForm.value.is_active
|
|
})
|
|
});
|
|
|
|
if (res.ok) {
|
|
showMessage('通道创建成功');
|
|
showChannelModal.value = false;
|
|
fetchChannels();
|
|
} else {
|
|
const err = await res.json();
|
|
showMessage(err.detail || '创建失败', 'error');
|
|
}
|
|
} catch (e) {
|
|
showMessage('配置 JSON 格式错误', 'error');
|
|
}
|
|
};
|
|
|
|
const deleteChannel = async (id) => {
|
|
if (!confirm('确定删除此通道?')) return;
|
|
|
|
try {
|
|
const res = await fetch(`${API_BASE}/channels/${id}`, { method: 'DELETE' });
|
|
if (res.ok) {
|
|
showMessage('删除成功');
|
|
fetchChannels();
|
|
} else {
|
|
showMessage('删除失败', 'error');
|
|
}
|
|
} catch (e) {
|
|
showMessage('删除失败', 'error');
|
|
}
|
|
};
|
|
|
|
const testChannel = async (id) => {
|
|
try {
|
|
const res = await fetch(`${API_BASE}/channels/${id}/test`, { method: 'POST' });
|
|
if (res.ok) {
|
|
showMessage('测试消息已发送');
|
|
} else {
|
|
showMessage('测试失败', 'error');
|
|
}
|
|
} catch (e) {
|
|
showMessage('测试失败', 'error');
|
|
}
|
|
};
|
|
|
|
const sendNotification = async () => {
|
|
if (!sendForm.value.body) {
|
|
showMessage('请输入消息内容', 'error');
|
|
return;
|
|
}
|
|
if (sendForm.value.channels.length === 0) {
|
|
showMessage('请至少选择一个通道', 'error');
|
|
return;
|
|
}
|
|
|
|
sending.value = true;
|
|
try {
|
|
const res = await fetch(`${API_BASE}/notify`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({
|
|
channels: sendForm.value.channels,
|
|
title: sendForm.value.title,
|
|
body: sendForm.value.body,
|
|
priority: sendForm.value.priority
|
|
})
|
|
});
|
|
|
|
if (res.ok) {
|
|
showMessage('通知发送成功');
|
|
sendForm.value = { channels: [], title: '', body: '', priority: 'normal' };
|
|
} else {
|
|
showMessage('发送失败', 'error');
|
|
}
|
|
} catch (e) {
|
|
showMessage('发送失败', 'error');
|
|
} finally {
|
|
sending.value = false;
|
|
}
|
|
};
|
|
|
|
const formatDate = (dateStr) => {
|
|
if (!dateStr) return '-';
|
|
return new Date(dateStr).toLocaleString('zh-CN');
|
|
};
|
|
|
|
const getStatusClass = (status) => {
|
|
return {
|
|
'px-2 py-1 rounded text-xs': true,
|
|
'bg-green-100 text-green-800': status === 'sent',
|
|
'bg-red-100 text-red-800': status === 'failed',
|
|
'bg-yellow-100 text-yellow-800': status === 'pending'
|
|
};
|
|
};
|
|
|
|
onMounted(() => {
|
|
fetchChannels();
|
|
fetchNotifications();
|
|
});
|
|
|
|
return {
|
|
currentView,
|
|
channels,
|
|
notifications,
|
|
showChannelModal,
|
|
channelForm,
|
|
sendForm,
|
|
sending,
|
|
message,
|
|
saveChannel,
|
|
deleteChannel,
|
|
testChannel,
|
|
sendNotification,
|
|
formatDate,
|
|
getStatusClass
|
|
};
|
|
}
|
|
}).mount('#app');
|