From 46ff024549960e145dde8c4df09dc525f0371400 Mon Sep 17 00:00:00 2001 From: Megghy Date: Sat, 18 Oct 2025 13:32:47 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BD=BF=E7=94=A8=E6=96=B0=E7=BB=84?= =?UTF-8?q?=E4=BB=B6BiliUserSelector=E6=9B=BF=E6=8D=A2=E5=8E=9F=E6=9C=89?= =?UTF-8?q?=E7=9A=84UID=E8=BE=93=E5=85=A5=E7=BB=84=E4=BB=B6=E5=B9=B6?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=9B=B8=E5=85=B3=E4=BA=A4=E4=BA=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/client/ClientAutoAction.vue | 14 +- .../autoaction/settings/CheckInSettings.vue | 8 +- src/components.d.ts | 3 + src/components/common/BiliUserSelector.vue | 188 ++++++++++++++++++ src/views/manage/point/PointUserManage.vue | 32 ++- 5 files changed, 223 insertions(+), 22 deletions(-) create mode 100644 src/components/common/BiliUserSelector.vue diff --git a/src/client/ClientAutoAction.vue b/src/client/ClientAutoAction.vue index 34170be..c05a6e9 100644 --- a/src/client/ClientAutoAction.vue +++ b/src/client/ClientAutoAction.vue @@ -36,6 +36,7 @@ import DataManager from './components/autoaction/DataManager.vue' import CheckInSettings from './components/autoaction/settings/CheckInSettings.vue' import GlobalScheduledSettings from './components/autoaction/settings/GlobalScheduledSettings.vue' import TimerCountdown from './components/autoaction/TimerCountdown.vue' +import BiliUserSelector from '@/components/common/BiliUserSelector.vue' const autoActionStore = useAutoAction() const message = useMessage() @@ -66,7 +67,7 @@ const editingActionId = ref(null) const showSetNextModal = ref(false) const targetNextActionId = ref(null) const showTestModal = ref(false) -const testUid = ref('10004') +const testUid = ref(10004) const currentTestType = ref(null) const triggerTypeOptions = [ @@ -425,7 +426,7 @@ function handleTestClick(type: TriggerType) { if (type === TriggerType.GUARD) { // 为舰长相关(私信)测试显示UID输入对话框 currentTestType.value = type - testUid.value = '10004' // 默认值 + testUid.value = 10004 // 默认值 showTestModal.value = true } else { // 其他类型直接测试 @@ -441,8 +442,8 @@ function confirmTest() { showTestModal.value = false return } - const uid = Number.parseInt(testUid.value) - if (isNaN(uid) || uid <= 0) { + const uid = Number(testUid.value) + if (!Number.isFinite(uid) || uid <= 0) { message.error('请输入有效的UID') return } @@ -818,10 +819,9 @@ function confirmTest() { >
请输入私信接收者的UID:
- { - diff --git a/src/components.d.ts b/src/components.d.ts index 36d64ee..4b9e6cb 100644 --- a/src/components.d.ts +++ b/src/components.d.ts @@ -9,6 +9,7 @@ export {} declare module 'vue' { export interface GlobalComponents { AddressDisplay: typeof import('./components/manage/AddressDisplay.vue')['default'] + BiliUserSelector: typeof import('./components/common/BiliUserSelector.vue')['default'] DanmakuContainer: typeof import('./components/DanmakuContainer.vue')['default'] DanmakuItem: typeof import('./components/DanmakuItem.vue')['default'] DynamicForm: typeof import('./components/DynamicForm.vue')['default'] @@ -21,6 +22,8 @@ declare module 'vue' { NAvatar: typeof import('naive-ui')['NAvatar'] NButton: typeof import('naive-ui')['NButton'] NCard: typeof import('naive-ui')['NCard'] + NEllipsis: typeof import('naive-ui')['NEllipsis'] + NEmpty: typeof import('naive-ui')['NEmpty'] NFlex: typeof import('naive-ui')['NFlex'] NIcon: typeof import('naive-ui')['NIcon'] NImage: typeof import('naive-ui')['NImage'] diff --git a/src/components/common/BiliUserSelector.vue b/src/components/common/BiliUserSelector.vue new file mode 100644 index 0000000..abfe293 --- /dev/null +++ b/src/components/common/BiliUserSelector.vue @@ -0,0 +1,188 @@ + + + diff --git a/src/views/manage/point/PointUserManage.vue b/src/views/manage/point/PointUserManage.vue index 47ac441..d591721 100644 --- a/src/views/manage/point/PointUserManage.vue +++ b/src/views/manage/point/PointUserManage.vue @@ -37,6 +37,7 @@ import { QueryGetAPI } from '@/api/query' import { POINT_API_URL } from '@/data/constants' import { objectsToCSV } from '@/Utils' import PointUserDetailCard from './PointUserDetailCard.vue' +import BiliUserSelector from '@/components/common/BiliUserSelector.vue' // 用户积分设置类型定义 interface PointUserSettings { @@ -73,6 +74,7 @@ const isLoading = ref(true) const addPointCount = ref(0) const addPointReason = ref('') const addPointTarget = ref() +const selectedTargetUserName = ref() // 重置所有积分确认 const resetConfirmText = ref('') @@ -125,7 +127,7 @@ const userStats = computed(() => { total: users.value.length, authed: users.value.filter(u => u.isAuthed).length, totalPoints: Number(totalPoints.toFixed(1)), - totalOrders: users.value.reduce((sum, u) => sum + (u.orderCount || 0), 0), + totalOrders: users.value.reduce((sum, u) => sum + ((u.orderCount || 0) > 0 ? (u.orderCount || 0) : 0), 0), avgPoints: Number(avgPoints.toFixed(1)), filtered: filteredUsers.value.length, } @@ -282,14 +284,16 @@ async function givePoint() { isLoading.value = true try { - const data = await QueryGetAPI(`${POINT_API_URL}give-point`, { + const data = await QueryGetAPI<{ totalPoint: number, userName?: string, uId?: number }>(`${POINT_API_URL}give-point`, { uId: addPointTarget.value, count: addPointCount.value, reason: addPointReason.value || '', }) if (data.code == 200) { - message.success('添加成功') + const userName = data.data?.userName || selectedTargetUserName.value || `UID: ${addPointTarget.value}` + const action = addPointCount.value > 0 ? '添加' : '扣除' + message.success(`成功为 ${userName} ${action}了 ${Math.abs(addPointCount.value)} 积分`) showGivePointModal.value = false // 重新加载用户数据 @@ -301,6 +305,7 @@ async function givePoint() { addPointCount.value = 0 addPointReason.value = '' addPointTarget.value = undefined + selectedTargetUserName.value = undefined } else { message.error(`添加失败: ${data.message}`) } @@ -615,21 +620,26 @@ onMounted(async () => { align="center" :gap="8" > - - 目标用户 - + + 目标用户 + + - +
-

如果目标用户没在直播间发言过则无法显示用户名, 不过不影响使用

+

输入UID后会自动从B站获取用户信息

因为UID和B站提供的OpenID不兼容, 未认证用户可能会出现两个记录, 不过在认证完成后会合并成一个