mirror of
https://github.com/jxxghp/MoviePilot-Frontend.git
synced 2026-09-05 07:28:37 +08:00
feat(settings): AccountSettingNotification
- 增加防抖。 - `card` 从父组件获取到的值改为深复制,解决 `card` 内修改数据,会直接导致在父组件中同步更新的问题。 - 微调图标位置。
This commit is contained in:
@@ -7,6 +7,7 @@ import synologychat_image from '@images/logos/synologychat.png'
|
|||||||
import slack_image from '@images/logos/slack.webp'
|
import slack_image from '@images/logos/slack.webp'
|
||||||
import chrome_image from '@images/logos/chrome.png'
|
import chrome_image from '@images/logos/chrome.png'
|
||||||
import { useToast } from 'vue-toast-notification'
|
import { useToast } from 'vue-toast-notification'
|
||||||
|
import { cloneDeep } from "lodash"
|
||||||
|
|
||||||
// 定义输入
|
// 定义输入
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -31,9 +32,6 @@ const $toast = useToast()
|
|||||||
// 通知详情弹窗
|
// 通知详情弹窗
|
||||||
const notificationInfoDialog = ref(false)
|
const notificationInfoDialog = ref(false)
|
||||||
|
|
||||||
// 通知名称
|
|
||||||
const notificationName = ref('')
|
|
||||||
|
|
||||||
// 通知详情
|
// 通知详情
|
||||||
const notificationInfo = ref<NotificationConf>({
|
const notificationInfo = ref<NotificationConf>({
|
||||||
name: '',
|
name: '',
|
||||||
@@ -66,26 +64,26 @@ const notificationTypes = [
|
|||||||
|
|
||||||
// 打开详情弹窗
|
// 打开详情弹窗
|
||||||
function openNotificationInfoDialog() {
|
function openNotificationInfoDialog() {
|
||||||
notificationInfo.value = props.notification
|
// 替换成深复制,避免修改时影响原数据
|
||||||
notificationName.value = props.notification.name
|
notificationInfo.value = cloneDeep(props.notification)
|
||||||
|
console.log(`当前卡片的通知信息:${JSON.stringify(notificationInfo.value)}`)
|
||||||
notificationInfoDialog.value = true
|
notificationInfoDialog.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// 保存详情数据
|
// 保存详情数据
|
||||||
function saveNotificationInfo() {
|
function saveNotificationInfo() {
|
||||||
// 为空不保存,跳出警告框
|
// 为空不保存,跳出警告框
|
||||||
if (!notificationName.value) {
|
if (!notificationInfo.value.name) {
|
||||||
$toast.error('名称不能为空,请输入后再确定')
|
$toast.error('名称不能为空,请输入后再确定')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 重名判断
|
// 重名判断
|
||||||
if (props.notifications.some(item => item.name === notificationName.value && item !== props.notification)) {
|
if (props.notifications.some(item => item.name === notificationInfo.value.name && item !== props.notification)) {
|
||||||
$toast.error(`【${notificationName.value}】已存在,请替换为其他名称`)
|
$toast.error(`通知渠道【${notificationInfo.value.name}】已存在,请替换`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
notificationInfoDialog.value = false
|
notificationInfoDialog.value = false
|
||||||
notificationInfo.value.name = notificationName.value
|
emit('change', notificationInfo.value, props.notification.name)
|
||||||
emit('change', notificationInfo.value)
|
|
||||||
emit('done')
|
emit('done')
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +129,7 @@ function onClose() {
|
|||||||
</div>
|
</div>
|
||||||
<div class="text-body-1 mb-3">{{ notificationTypeNames[notification.type] }}</div>
|
<div class="text-body-1 mb-3">{{ notificationTypeNames[notification.type] }}</div>
|
||||||
</div>
|
</div>
|
||||||
<VImg :src="getIcon" cover class="mt-5 me-7" max-width="3rem" />
|
<VImg :src="getIcon" cover class="mt-7 me-7" max-width="3rem" />
|
||||||
</VCardText>
|
</VCardText>
|
||||||
</VCard>
|
</VCard>
|
||||||
<VDialog v-model="notificationInfoDialog" scrollable max-width="40rem" persistent>
|
<VDialog v-model="notificationInfoDialog" scrollable max-width="40rem" persistent>
|
||||||
@@ -160,7 +158,7 @@ function onClose() {
|
|||||||
<VRow v-if="notificationInfo.type == 'wechat'">
|
<VRow v-if="notificationInfo.type == 'wechat'">
|
||||||
<VCol cols="12" md="6">
|
<VCol cols="12" md="6">
|
||||||
<VTextField
|
<VTextField
|
||||||
v-model="notificationName"
|
v-model="notificationInfo.name"
|
||||||
label="名称"
|
label="名称"
|
||||||
placeholder="别名"
|
placeholder="别名"
|
||||||
hint="通知渠道的别名"
|
hint="通知渠道的别名"
|
||||||
@@ -228,7 +226,7 @@ function onClose() {
|
|||||||
<VRow v-if="notificationInfo.type == 'telegram'">
|
<VRow v-if="notificationInfo.type == 'telegram'">
|
||||||
<VCol cols="12" md="6">
|
<VCol cols="12" md="6">
|
||||||
<VTextField
|
<VTextField
|
||||||
v-model="notificationName"
|
v-model="notificationInfo.name"
|
||||||
label="名称"
|
label="名称"
|
||||||
placeholder="别名"
|
placeholder="别名"
|
||||||
hint="通知渠道的别名"
|
hint="通知渠道的别名"
|
||||||
@@ -273,7 +271,7 @@ function onClose() {
|
|||||||
<VRow v-if="notificationInfo.type == 'slack'">
|
<VRow v-if="notificationInfo.type == 'slack'">
|
||||||
<VCol cols="12" md="6">
|
<VCol cols="12" md="6">
|
||||||
<VTextField
|
<VTextField
|
||||||
v-model="notificationName"
|
v-model="notificationInfo.name"
|
||||||
label="名称"
|
label="名称"
|
||||||
placeholder="别名"
|
placeholder="别名"
|
||||||
hint="通知渠道的别名"
|
hint="通知渠道的别名"
|
||||||
@@ -311,7 +309,7 @@ function onClose() {
|
|||||||
<VRow v-if="notificationInfo.type == 'synologychat'">
|
<VRow v-if="notificationInfo.type == 'synologychat'">
|
||||||
<VCol cols="12" md="6">
|
<VCol cols="12" md="6">
|
||||||
<VTextField
|
<VTextField
|
||||||
v-model="notificationName"
|
v-model="notificationInfo.name"
|
||||||
label="名称"
|
label="名称"
|
||||||
placeholder="别名"
|
placeholder="别名"
|
||||||
hint="通知渠道的别名"
|
hint="通知渠道的别名"
|
||||||
@@ -338,7 +336,7 @@ function onClose() {
|
|||||||
<VRow v-if="notificationInfo.type == 'vocechat'">
|
<VRow v-if="notificationInfo.type == 'vocechat'">
|
||||||
<VCol cols="12" md="6">
|
<VCol cols="12" md="6">
|
||||||
<VTextField
|
<VTextField
|
||||||
v-model="notificationName"
|
v-model="notificationInfo.name"
|
||||||
label="名称"
|
label="名称"
|
||||||
placeholder="别名"
|
placeholder="别名"
|
||||||
hint="通知渠道的别名"
|
hint="通知渠道的别名"
|
||||||
@@ -374,7 +372,7 @@ function onClose() {
|
|||||||
<VRow v-if="notificationInfo.type == 'webpush'">
|
<VRow v-if="notificationInfo.type == 'webpush'">
|
||||||
<VCol cols="12" md="6">
|
<VCol cols="12" md="6">
|
||||||
<VTextField
|
<VTextField
|
||||||
v-model="notificationName"
|
v-model="notificationInfo.name"
|
||||||
label="名称"
|
label="名称"
|
||||||
placeholder="别名"
|
placeholder="别名"
|
||||||
hint="通知渠道的别名"
|
hint="通知渠道的别名"
|
||||||
|
|||||||
@@ -4,10 +4,14 @@ import api from '@/api'
|
|||||||
import draggable from 'vuedraggable'
|
import draggable from 'vuedraggable'
|
||||||
import type { NotificationConf, NotificationSwitchConf } from '@/api/types'
|
import type { NotificationConf, NotificationSwitchConf } from '@/api/types'
|
||||||
import NotificationChannelCard from '@/components/cards/NotificationChannelCard.vue'
|
import NotificationChannelCard from '@/components/cards/NotificationChannelCard.vue'
|
||||||
|
import debounce from 'lodash/debounce'
|
||||||
|
|
||||||
// 所有消息渠道
|
// 所有消息渠道
|
||||||
const notifications = ref<NotificationConf[]>([])
|
const notifications = ref<NotificationConf[]>([])
|
||||||
|
|
||||||
|
// 防抖时间
|
||||||
|
const debounceTime = 500
|
||||||
|
|
||||||
// 提示框
|
// 提示框
|
||||||
const $toast = useToast()
|
const $toast = useToast()
|
||||||
|
|
||||||
@@ -58,8 +62,8 @@ async function reloadSystem() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 添加媒体服务器
|
// 添加通知渠道
|
||||||
function addNotification(notification: string) {
|
const addNotification = debounce((notification: string) => {
|
||||||
let name = `通知${notifications.value.length + 1}`;
|
let name = `通知${notifications.value.length + 1}`;
|
||||||
while (notifications.value.some(item => item.name === name)) {
|
while (notifications.value.some(item => item.name === name)) {
|
||||||
name = `通知${parseInt(name.split('通知')[1]) + 1}`;
|
name = `通知${parseInt(name.split('通知')[1]) + 1}`;
|
||||||
@@ -70,15 +74,15 @@ function addNotification(notification: string) {
|
|||||||
enabled: false,
|
enabled: false,
|
||||||
config: {},
|
config: {},
|
||||||
})
|
})
|
||||||
}
|
}, debounceTime)
|
||||||
|
|
||||||
// 移除媒体服务器
|
// 移除通知渠道
|
||||||
function removeNotification(notification: NotificationConf) {
|
function removeNotification(notification: NotificationConf) {
|
||||||
const index = notifications.value.indexOf(notification)
|
const index = notifications.value.indexOf(notification)
|
||||||
if (index > -1) notifications.value.splice(index, 1)
|
if (index > -1) notifications.value.splice(index, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 调用API查询通知设置
|
// 调用API查询通知渠道设置
|
||||||
async function loadNotificationSetting() {
|
async function loadNotificationSetting() {
|
||||||
try {
|
try {
|
||||||
const result: { [key: string]: any } = await api.get('system/setting/Notifications')
|
const result: { [key: string]: any } = await api.get('system/setting/Notifications')
|
||||||
@@ -89,7 +93,7 @@ async function loadNotificationSetting() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 调用API保存通知设置
|
// 调用API保存通知设置
|
||||||
async function saveNotificationSetting() {
|
const saveNotificationSetting = debounce(async () => {
|
||||||
try {
|
try {
|
||||||
const result: { [key: string]: any } = await api.post('system/setting/Notifications', notifications.value)
|
const result: { [key: string]: any } = await api.post('system/setting/Notifications', notifications.value)
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
@@ -99,6 +103,12 @@ async function saveNotificationSetting() {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
}
|
}
|
||||||
|
}, debounceTime)
|
||||||
|
|
||||||
|
// 通知渠道设置变化时赋值
|
||||||
|
function changNotificationSetting(notification: NotificationConf, name: string) {
|
||||||
|
const index = notifications.value.findIndex(item => item.name === name)
|
||||||
|
if (index !== -1) notifications.value[index] = notification
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加载消息类型开关
|
// 加载消息类型开关
|
||||||
@@ -112,7 +122,7 @@ async function loadNotificationSwitchs() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 保存消息类型开关
|
// 保存消息类型开关
|
||||||
async function saveNotificationSwitchs() {
|
const saveNotificationSwitchs = debounce(async () => {
|
||||||
try {
|
try {
|
||||||
const result: { [key: string]: any } = await api.post(
|
const result: { [key: string]: any } = await api.post(
|
||||||
'system/setting/NotificationSwitchs',
|
'system/setting/NotificationSwitchs',
|
||||||
@@ -123,7 +133,7 @@ async function saveNotificationSwitchs() {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(error)
|
console.log(error)
|
||||||
}
|
}
|
||||||
}
|
}, debounceTime)
|
||||||
|
|
||||||
// 加载数据
|
// 加载数据
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@@ -152,6 +162,7 @@ onMounted(() => {
|
|||||||
<NotificationChannelCard
|
<NotificationChannelCard
|
||||||
:notification="element"
|
:notification="element"
|
||||||
:notifications="notifications"
|
:notifications="notifications"
|
||||||
|
@change="changNotificationSetting"
|
||||||
@close="removeNotification(element)"
|
@close="removeNotification(element)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
@@ -161,7 +172,7 @@ onMounted(() => {
|
|||||||
<VForm @submit.prevent="() => {}">
|
<VForm @submit.prevent="() => {}">
|
||||||
<div class="d-flex flex-wrap gap-4 mt-4">
|
<div class="d-flex flex-wrap gap-4 mt-4">
|
||||||
<VBtn mtype="submit" @click="saveNotificationSetting"> 保存 </VBtn>
|
<VBtn mtype="submit" @click="saveNotificationSetting"> 保存 </VBtn>
|
||||||
<VBtn color="success" variant="tonal" @click="">
|
<VBtn color="success" variant="tonal">
|
||||||
<VIcon icon="mdi-plus" />
|
<VIcon icon="mdi-plus" />
|
||||||
<VMenu activator="parent" close-on-content-click>
|
<VMenu activator="parent" close-on-content-click>
|
||||||
<VList>
|
<VList>
|
||||||
@@ -225,7 +236,7 @@ onMounted(() => {
|
|||||||
<VCardText>
|
<VCardText>
|
||||||
<VForm @submit.prevent="() => {}">
|
<VForm @submit.prevent="() => {}">
|
||||||
<div class="d-flex flex-wrap gap-4 mt-4">
|
<div class="d-flex flex-wrap gap-4 mt-4">
|
||||||
<VBtn mtype="submit" @click="saveNotificationSwitchs"> 保存 </VBtn>
|
<VBtn type="submit" @click="saveNotificationSwitchs"> 保存 </VBtn>
|
||||||
</div>
|
</div>
|
||||||
</VForm>
|
</VForm>
|
||||||
</VCardText>
|
</VCardText>
|
||||||
|
|||||||
Reference in New Issue
Block a user