更新国际化支持:为通知渠道卡片及相关组件添加多语言文本,提升用户体验

This commit is contained in:
jxxghp
2025-04-28 20:34:37 +08:00
parent fa6ba8b1fc
commit c14dfe0bee
4 changed files with 281 additions and 86 deletions

View File

@@ -8,6 +8,9 @@ import slack_image from '@images/logos/slack.webp'
import chrome_image from '@images/logos/chrome.png'
import { useToast } from 'vue-toast-notification'
import { cloneDeep } from 'lodash-es'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
// 定义输入
const props = defineProps({
@@ -42,24 +45,24 @@ const notificationInfo = ref<NotificationConf>({
// 各通知类型的名称字典
const notificationTypeNames: { [key: string]: string } = {
wechat: '企业微信',
telegram: 'Telegram',
vocechat: 'VoceChat',
synologychat: 'Synology Chat',
slack: 'Slack',
webpush: 'WebPush',
wechat: t('notification.wechat.name'),
telegram: t('notification.telegram.name'),
vocechat: t('notification.vocechat.name'),
synologychat: t('notification.synologychat.name'),
slack: t('notification.slack.name'),
webpush: t('notification.webpush.name'),
}
// 消息类型下拉字典
const notificationTypes = [
{ value: '资源下载', title: '资源下载' },
{ value: '整理入库', title: '整理入库' },
{ value: '订阅', title: '订阅' },
{ value: '站点', title: '站点' },
{ value: '媒体服务器', title: '媒体服务器' },
{ value: '手动处理', title: '手动处理' },
{ value: '插件', title: '插件' },
{ value: '其它', title: '其它' },
{ value: '资源下载', title: t('notificationSwitch.resourceDownload') },
{ value: '整理入库', title: t('notificationSwitch.organize') },
{ value: '订阅', title: t('notificationSwitch.subscribe') },
{ value: '站点', title: t('notificationSwitch.site') },
{ value: '媒体服务器', title: t('notificationSwitch.mediaServer') },
{ value: '手动处理', title: t('notificationSwitch.manual') },
{ value: '插件', title: t('notificationSwitch.plugin') },
{ value: '其它', title: t('notificationSwitch.other') },
]
// 打开详情弹窗
@@ -73,12 +76,12 @@ function openNotificationInfoDialog() {
function saveNotificationInfo() {
// 为空不保存,跳出警告框
if (!notificationInfo.value.name) {
$toast.error('名称不能为空,请输入后再确定')
$toast.error(t('notification.name') + t('common.required'))
return
}
// 重名判断
if (props.notifications.some(item => item.name === notificationInfo.value.name && item !== props.notification)) {
$toast.error(`通知渠道${notificationInfo.value.name}已存在,请替换`)
$toast.error(t('notification.channel') + `${notificationInfo.value.name}` + t('common.exists'))
return
}
notificationInfoDialog.value = false
@@ -132,21 +135,21 @@ function onClose() {
</VCardText>
</VCard>
<VDialog v-if="notificationInfoDialog" v-model="notificationInfoDialog" scrollable max-width="40rem" persistent>
<VCard :title="`${props.notification.name} - 配置`" class="rounded-t">
<VCard :title="`${props.notification.name} - ${t('notification.config')}`" class="rounded-t">
<VDialogCloseBtn v-model="notificationInfoDialog" />
<VDivider />
<VCardText>
<VForm>
<VRow>
<VCol cols="12" md="6">
<VSwitch v-model="notificationInfo.enabled" label="启用通知" />
<VSwitch v-model="notificationInfo.enabled" :label="t('notification.enabled')" />
</VCol>
<VCol cols="12">
<VSelect
v-model="notificationInfo.switchs"
:items="notificationTypes"
label="消息类型"
hint="开启通知的消息类型"
:label="t('notification.type')"
:hint="t('notification.typeHint')"
multiple
clearable
chips
@@ -158,66 +161,66 @@ function onClose() {
<VCol cols="12" md="6">
<VTextField
v-model="notificationInfo.name"
label="名称"
placeholder="别名"
hint="通知渠道的别名"
:label="t('notification.name')"
:placeholder="t('notification.name')"
:hint="t('notification.nameHint')"
persistent-hint
/>
</VCol>
<VCol cols="12" md="6">
<VTextField
v-model="notificationInfo.config.WECHAT_CORPID"
label="企业ID"
hint="企业微信后台企业信息中的企业ID"
:label="t('notification.wechat.corpId')"
:hint="t('notification.wechat.corpIdHint')"
persistent-hint
/>
</VCol>
<VCol cols="12" md="6">
<VTextField
v-model="notificationInfo.config.WECHAT_APP_ID"
label="应用 AgentId"
hint="企业微信自建应用的AgentId"
:label="t('notification.wechat.appId')"
:hint="t('notification.wechat.appIdHint')"
persistent-hint
/>
</VCol>
<VCol cols="12" md="6">
<VTextField
v-model="notificationInfo.config.WECHAT_APP_SECRET"
label="应用 Secret"
hint="企业微信自建应用的Secret"
:label="t('notification.wechat.appSecret')"
:hint="t('notification.wechat.appSecretHint')"
persistent-hint
/>
</VCol>
<VCol cols="12" md="6">
<VTextField
v-model="notificationInfo.config.WECHAT_PROXY"
label="代理地址"
hint="微信消息的转发代理地址2022年6月20日后创建的自建应用才需要不使用代理时需要保留默认值"
:label="t('notification.wechat.proxy')"
:hint="t('notification.wechat.proxyHint')"
persistent-hint
/>
</VCol>
<VCol cols="12" md="6">
<VTextField
v-model="notificationInfo.config.WECHAT_TOKEN"
label="Token"
hint="微信企业自建应用->API接收消息配置中的Token"
:label="t('notification.wechat.token')"
:hint="t('notification.wechat.tokenHint')"
persistent-hint
/>
</VCol>
<VCol cols="12" md="6">
<VTextField
v-model="notificationInfo.config.WECHAT_ENCODING_AESKEY"
label="EncodingAESKey"
hint="微信企业自建应用->API接收消息配置中的EncodingAESKey"
:label="t('notification.wechat.encodingAesKey')"
:hint="t('notification.wechat.encodingAesKeyHint')"
persistent-hint
/>
</VCol>
<VCol cols="12" md="6">
<VTextField
v-model="notificationInfo.config.WECHAT_ADMINS"
label="管理员白名单"
placeholder="多个用,分隔"
hint="可使用管理菜单及命令的用户ID列表多个ID使用,分隔"
:label="t('notification.wechat.admins')"
:placeholder="t('notification.wechat.adminsPlaceholder')"
:hint="t('notification.wechat.adminsHint')"
persistent-hint
/>
</VCol>
@@ -226,43 +229,43 @@ function onClose() {
<VCol cols="12" md="6">
<VTextField
v-model="notificationInfo.name"
label="名称"
placeholder="别名"
hint="通知渠道的别名"
:label="t('notification.name')"
:placeholder="t('notification.name')"
:hint="t('notification.nameHint')"
persistent-hint
/>
</VCol>
<VCol cols="12" md="6">
<VTextField
v-model="notificationInfo.config.TELEGRAM_TOKEN"
label="Bot Token"
hint="Telegram机器人token格式123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11"
:label="t('notification.telegram.token')"
:hint="t('notification.telegram.tokenHint')"
persistent-hint
/>
</VCol>
<VCol cols="12" md="6">
<VTextField
v-model="notificationInfo.config.TELEGRAM_CHAT_ID"
label="Chat ID"
hint="接受消息通知的用户、群组或频道Chat ID"
:label="t('notification.telegram.chatId')"
:hint="t('notification.telegram.chatIdHint')"
persistent-hint
/>
</VCol>
<VCol cols="12" md="6">
<VTextField
v-model="notificationInfo.config.TELEGRAM_USERS"
label="用户白名单"
placeholder="多个用,分隔"
hint="可使用Telegram机器人的用户ID清单多个用户用,分隔,不填写则所有用户都能使用"
:label="t('notification.telegram.users')"
:placeholder="t('notification.telegram.usersPlaceholder')"
:hint="t('notification.telegram.usersHint')"
persistent-hint
/>
</VCol>
<VCol cols="12" md="6">
<VTextField
v-model="notificationInfo.config.TELEGRAM_ADMINS"
label="管理员白名单"
placeholder="多个用,分隔"
hint="可使用管理菜单及命令的用户ID列表多个ID使用,分隔"
:label="t('notification.telegram.admins')"
:placeholder="t('notification.telegram.adminsPlaceholder')"
:hint="t('notification.telegram.adminsHint')"
persistent-hint
/>
</VCol>
@@ -271,36 +274,36 @@ function onClose() {
<VCol cols="12" md="6">
<VTextField
v-model="notificationInfo.name"
label="名称"
placeholder="别名"
hint="通知渠道的别名"
:label="t('notification.name')"
:placeholder="t('notification.name')"
:hint="t('notification.nameHint')"
persistent-hint
/>
</VCol>
<VCol cols="12" md="6">
<VTextField
v-model="notificationInfo.config.SLACK_OAUTH_TOKEN"
label="Slack Bot User OAuth Token"
placeholder="xoxb-xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx"
hint="Slack应用`OAuth & Permissions`页面中的`Bot User OAuth Token`"
:label="t('notification.slack.oauthToken')"
:placeholder="t('notification.slack.oauthTokenPlaceholder')"
:hint="t('notification.slack.oauthTokenHint')"
persistent-hint
/>
</VCol>
<VCol cols="12" md="6">
<VTextField
v-model="notificationInfo.config.SLACK_APP_TOKEN"
label="Slack App-Level Token"
placeholder="xapp-xxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxx"
hint="Slack应用`OAuth & Permissions`页面中的`App-Level Token`"
:label="t('notification.slack.appToken')"
:placeholder="t('notification.slack.appTokenPlaceholder')"
:hint="t('notification.slack.appTokenHint')"
persistent-hint
/>
</VCol>
<VCol cols="12" md="6">
<VTextField
v-model="notificationInfo.config.SLACK_CHANNEL"
label="频道名称"
placeholder="全体"
hint="消息发送频道,默认`全体`"
:label="t('notification.slack.channel')"
:placeholder="t('notification.slack.channelPlaceholder')"
:hint="t('notification.slack.channelHint')"
persistent-hint
/>
</VCol>
@@ -309,25 +312,25 @@ function onClose() {
<VCol cols="12" md="6">
<VTextField
v-model="notificationInfo.name"
label="名称"
placeholder="别名"
hint="通知渠道的别名"
:label="t('notification.name')"
:placeholder="t('notification.name')"
:hint="t('notification.nameHint')"
persistent-hint
/>
</VCol>
<VCol cols="12" md="6">
<VTextField
v-model="notificationInfo.config.SYNOLOGYCHAT_WEBHOOK"
label="机器人传入URL"
hint="Synology Chat机器人传入URL"
:label="t('notification.synologychat.webhook')"
:hint="t('notification.synologychat.webhookHint')"
persistent-hint
/>
</VCol>
<VCol cols="12" md="6">
<VTextField
v-model="notificationInfo.config.SYNOLOGYCHAT_TOKEN"
label="令牌"
hint="Synology Chat机器人令牌"
:label="t('notification.synologychat.token')"
:hint="t('notification.synologychat.tokenHint')"
persistent-hint
/>
</VCol>
@@ -336,34 +339,34 @@ function onClose() {
<VCol cols="12" md="6">
<VTextField
v-model="notificationInfo.name"
label="名称"
placeholder="别名"
hint="通知渠道的别名"
:label="t('notification.name')"
:placeholder="t('notification.name')"
:hint="t('notification.nameHint')"
persistent-hint
/>
</VCol>
<VCol cols="12" md="6">
<VTextField
v-model="notificationInfo.config.VOCECHAT_HOST"
label="地址"
hint="VoceChat服务端地址格式http(s)://ip:port"
:label="t('notification.vocechat.host')"
:hint="t('notification.vocechat.hostHint')"
persistent-hint
/>
</VCol>
<VCol cols="12" md="6">
<VTextField
v-model="notificationInfo.config.VOCECHAT_API_KEY"
label="机器人密钥"
hint="VoceChat机器人密钥"
:label="t('notification.vocechat.apiKey')"
:hint="t('notification.vocechat.apiKeyHint')"
persistent-hint
/>
</VCol>
<VCol cols="12" md="6">
<VTextField
v-model="notificationInfo.config.VOCECHAT_CHANNEL_ID"
label="频道ID"
placeholder="不包含#号"
hint="VoceChat的频道ID不包含#号"
:label="t('notification.vocechat.channelId')"
:placeholder="t('notification.vocechat.channelIdPlaceholder')"
:hint="t('notification.vocechat.channelIdHint')"
persistent-hint
/>
</VCol>
@@ -372,17 +375,17 @@ function onClose() {
<VCol cols="12" md="6">
<VTextField
v-model="notificationInfo.name"
label="名称"
placeholder="别名"
hint="通知渠道的别名"
:label="t('notification.name')"
:placeholder="t('notification.name')"
:hint="t('notification.nameHint')"
persistent-hint
/>
</VCol>
<VCol cols="12" md="6">
<VTextField
v-model="notificationInfo.config.WEBPUSH_USERNAME"
label="登录用户名"
hint="只有对应的用户登录后才会推送消息"
:label="t('notification.webpush.username')"
:hint="t('notification.webpush.usernameHint')"
persistent-hint
/>
</VCol>
@@ -391,7 +394,7 @@ function onClose() {
</VCardText>
<VCardActions class="pt-3">
<VBtn @click="saveNotificationInfo" variant="elevated" prepend-icon="mdi-content-save" class="px-5">
确定
{{ t('common.confirm') }}
</VBtn>
</VCardActions>
</VCard>

View File

@@ -213,6 +213,71 @@ export default {
center: 'Notification Center',
markRead: 'Mark as Read',
empty: 'No Notifications',
channel: 'Notification Channel',
name: 'Name',
type: 'Type',
typeHint: 'Select the types of notifications to receive',
enabled: 'Enabled',
config: 'Configuration',
wechat: {
name: 'WeChat Work',
corpId: 'Corp ID',
corpIdHint: 'Corp ID in WeChat Work backend enterprise information',
appId: 'App AgentId',
appIdHint: 'AgentId of self-built app in WeChat Work',
appSecret: 'App Secret',
appSecretHint: 'Secret of self-built app in WeChat Work',
proxy: 'Proxy Address',
proxyHint:
'Proxy address for WeChat message forwarding, required for self-built apps created after June 20, 2022',
token: 'Token',
tokenHint: 'Token in WeChat Work self-built app -> API message receiving configuration',
encodingAesKey: 'EncodingAESKey',
encodingAesKeyHint: 'EncodingAESKey in WeChat Work self-built app -> API message receiving configuration',
admins: 'Admin Whitelist',
adminsHint: 'User IDs that can use admin menu and commands, separated by commas',
},
telegram: {
name: 'Telegram',
token: 'Bot Token',
tokenHint: 'Telegram bot token, format: 123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11',
chatId: 'Chat ID',
chatIdHint: 'Chat ID of user, group or channel that receives notifications',
users: 'User Whitelist',
usersHint: 'User IDs that can use Telegram bot, separated by commas. Leave empty to allow all users',
admins: 'Admin Whitelist',
adminsHint: 'User IDs that can use admin menu and commands, separated by commas',
},
slack: {
name: 'Slack',
oauthToken: 'Slack Bot User OAuth Token',
oauthTokenHint: 'Bot User OAuth Token in Slack app OAuth & Permissions page',
appToken: 'Slack App-Level Token',
appTokenHint: 'App-Level Token in Slack app OAuth & Permissions page',
channel: 'Channel Name',
channelHint: 'Channel to send messages, default is "all"',
},
synologychat: {
name: 'Synology Chat',
webhook: 'Webhook URL',
webhookHint: 'Synology Chat bot webhook URL',
token: 'Token',
tokenHint: 'Synology Chat bot token',
},
vocechat: {
name: 'VoceChat',
host: 'Address',
hostHint: 'VoceChat server address, format: http(s)://ip:port',
apiKey: 'Bot API Key',
apiKeyHint: 'VoceChat bot API key',
channelId: 'Channel ID',
channelIdHint: 'VoceChat channel ID, without #',
},
webpush: {
name: 'WebPush',
username: 'Login Username',
usernameHint: 'Only push messages to the corresponding logged-in user',
},
},
shortcut: {
title: 'Shortcuts',

View File

@@ -213,6 +213,69 @@ export default {
center: '通知中心',
markRead: '设为已读',
empty: '暂无通知',
channel: '通知渠道',
name: '名称',
type: '类型',
enabled: '启用',
config: '配置',
wechat: {
name: '企业微信',
corpId: '企业ID',
corpIdHint: '企业微信后台企业信息中的企业ID',
appId: '应用 AgentId',
appIdHint: '企业微信自建应用的AgentId',
appSecret: '应用 Secret',
appSecretHint: '企业微信自建应用的Secret',
proxy: '代理地址',
proxyHint: '微信消息的转发代理地址2022年6月20日后创建的自建应用才需要不使用代理时需要保留默认值',
token: 'Token',
tokenHint: '微信企业自建应用->API接收消息配置中的Token',
encodingAesKey: 'EncodingAESKey',
encodingAesKeyHint: '微信企业自建应用->API接收消息配置中的EncodingAESKey',
admins: '管理员白名单',
adminsHint: '可使用管理菜单及命令的用户ID列表多个ID使用,分隔',
},
telegram: {
name: 'Telegram',
token: 'Bot Token',
tokenHint: 'Telegram机器人token格式123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11',
chatId: 'Chat ID',
chatIdHint: '接受消息通知的用户、群组或频道Chat ID',
users: '用户白名单',
usersHint: '可使用Telegram机器人的用户ID清单多个用户用,分隔,不填写则所有用户都能使用',
admins: '管理员白名单',
adminsHint: '可使用管理菜单及命令的用户ID列表多个ID使用,分隔',
},
slack: {
name: 'Slack',
oauthToken: 'Slack Bot User OAuth Token',
oauthTokenHint: 'Slack应用`OAuth & Permissions`页面中的`Bot User OAuth Token`',
appToken: 'Slack App-Level Token',
appTokenHint: 'Slack应用`OAuth & Permissions`页面中的`App-Level Token`',
channel: '频道名称',
channelHint: '消息发送频道,默认`全体`',
},
synologychat: {
name: 'Synology Chat',
webhook: '机器人传入URL',
webhookHint: 'Synology Chat机器人传入URL',
token: '令牌',
tokenHint: 'Synology Chat机器人令牌',
},
vocechat: {
name: 'VoceChat',
host: '地址',
hostHint: 'VoceChat服务端地址格式http(s)://ip:port',
apiKey: '机器人密钥',
apiKeyHint: 'VoceChat机器人密钥',
channelId: '频道ID',
channelIdHint: 'VoceChat的频道ID不包含#号',
},
webpush: {
name: 'WebPush',
username: '登录用户名',
usernameHint: '只有对应的用户登录后才会推送消息',
},
},
shortcut: {
title: '捷径',

View File

@@ -213,6 +213,70 @@ export default {
center: '通知中心',
markRead: '設為已讀',
empty: '暫無通知',
channel: '通知渠道',
name: '名稱',
type: '類型',
typeHint: '選擇需要接收的通知類型',
enabled: '啟用',
config: '配置',
wechat: {
name: '企業微信',
corpId: '企業ID',
corpIdHint: '企業微信後台企業信息中的企業ID',
appId: '應用 AgentId',
appIdHint: '企業微信自建應用的AgentId',
appSecret: '應用 Secret',
appSecretHint: '企業微信自建應用的Secret',
proxy: '代理地址',
proxyHint: '微信消息的轉發代理地址2022年6月20日後創建的自建應用才需要不使用代理時需要保留默認值',
token: 'Token',
tokenHint: '微信企業自建應用->API接收消息配置中的Token',
encodingAesKey: 'EncodingAESKey',
encodingAesKeyHint: '微信企業自建應用->API接收消息配置中的EncodingAESKey',
admins: '管理員白名單',
adminsHint: '可使用管理菜單及命令的用戶ID列表多個ID使用,分隔',
},
telegram: {
name: 'Telegram',
token: 'Bot Token',
tokenHint: 'Telegram機器人token格式123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11',
chatId: 'Chat ID',
chatIdHint: '接受消息通知的用戶、群組或頻道Chat ID',
users: '用戶白名單',
usersHint: '可使用Telegram機器人的用戶ID清單多個用戶用,分隔,不填寫則所有用戶都能使用',
admins: '管理員白名單',
adminsHint: '可使用管理菜單及命令的用戶ID列表多個ID使用,分隔',
},
slack: {
name: 'Slack',
oauthToken: 'Slack Bot User OAuth Token',
oauthTokenHint: 'Slack應用`OAuth & Permissions`頁面中的`Bot User OAuth Token`',
appToken: 'Slack App-Level Token',
appTokenHint: 'Slack應用`OAuth & Permissions`頁面中的`App-Level Token`',
channel: '頻道名稱',
channelHint: '消息發送頻道,默認`全體`',
},
synologychat: {
name: 'Synology Chat',
webhook: '機器人傳入URL',
webhookHint: 'Synology Chat機器人傳入URL',
token: '令牌',
tokenHint: 'Synology Chat機器人令牌',
},
vocechat: {
name: 'VoceChat',
host: '地址',
hostHint: 'VoceChat服務端地址格式http(s)://ip:port',
apiKey: '機器人密鑰',
apiKeyHint: 'VoceChat機器人密鑰',
channelId: '頻道ID',
channelIdHint: 'VoceChat的頻道ID不包含#號',
},
webpush: {
name: 'WebPush',
username: '登錄用戶名',
usernameHint: '只有對應的用戶登錄後才會推送消息',
},
},
shortcut: {
title: '捷徑',