mirror of
https://github.com/Megghy/vtsuru.live.git
synced 2025-12-06 18:36:55 +08:00
feat: 更新API模型和组件以支持售罄自动下架功能
- 在api-models.ts中为设置添加shouldDiscontinueWhenSoldOut字段 - 在PointSettings.vue中新增售罄自动下架的选项 - 在多个组件中调整按钮文本和状态逻辑 - 在PointUserHistoryView.vue中添加主播筛选功能
This commit is contained in:
@@ -228,6 +228,7 @@ export interface Setting_Point {
|
||||
scPointPercent: number // double maps to number in TypeScript
|
||||
giftPointPercent: number // double maps to number in TypeScript
|
||||
giftAllowType: SettingPointGiftAllowType
|
||||
shouldDiscontinueWhenSoldOut: boolean
|
||||
|
||||
// 签到系统设置
|
||||
enableCheckIn: boolean // 是否启用签到功能
|
||||
|
||||
@@ -94,13 +94,43 @@ const historyColumn: DataTableColumns<ResponsePointHisrotyModel> = [
|
||||
: null,
|
||||
])
|
||||
case PointFrom.Manual:
|
||||
return h(
|
||||
return h(NFlex, { align: 'center' }, () => [
|
||||
h(
|
||||
NTag,
|
||||
{ type: row.point > 0 ? 'success' : 'error', bordered: false, size: 'small' },
|
||||
() => '主播' + (row.point > 0 ? '赠予' : '扣除'),
|
||||
),
|
||||
row.extra?.user
|
||||
? h(
|
||||
NButton,
|
||||
{
|
||||
tag: 'a',
|
||||
href: '/@' + row.extra.user?.name,
|
||||
target: '_blank',
|
||||
text: true,
|
||||
type: 'info',
|
||||
},
|
||||
() => row.extra.user?.name,
|
||||
)
|
||||
: null,
|
||||
])
|
||||
case PointFrom.Use:
|
||||
return h(NTag, { type: 'warning', bordered: false, size: 'small' }, () => '使用')
|
||||
return h(NFlex, { align: 'center' }, () => [
|
||||
h(NTag, { type: 'warning', bordered: false, size: 'small' }, () => '使用'),
|
||||
row.extra?.user
|
||||
? h(
|
||||
NButton,
|
||||
{
|
||||
tag: 'a',
|
||||
href: '/@' + row.extra.user?.name,
|
||||
target: '_blank',
|
||||
text: true,
|
||||
type: 'success',
|
||||
},
|
||||
() => row.extra.user?.name,
|
||||
)
|
||||
: null,
|
||||
])
|
||||
case PointFrom.CheckIn:
|
||||
return h(NFlex, { align: 'center' }, () => [
|
||||
h(NTag, { type: 'success', bordered: false, size: 'small' }, () => '签到'),
|
||||
@@ -131,12 +161,12 @@ const historyColumn: DataTableColumns<ResponsePointHisrotyModel> = [
|
||||
case PointFrom.Danmaku:
|
||||
switch (row.type) {
|
||||
case EventDataTypes.Guard:
|
||||
return h(NFlex, { justify: 'center', align: 'center' }, () => [
|
||||
return h(NFlex, { align: 'center' }, () => [
|
||||
h(NTag, { type: 'error', size: 'small' }, () => '上舰'),
|
||||
row.extra?.danmaku.msg,
|
||||
])
|
||||
case EventDataTypes.Gift:
|
||||
return h(NFlex, { justify: 'center', align: 'center' }, () => [
|
||||
return h(NFlex, { align: 'center' }, () => [
|
||||
h(NTag, { type: 'info', size: 'small', style: { margin: '0' } }, () => '礼物'),
|
||||
row.extra?.danmaku.msg,
|
||||
h(
|
||||
@@ -146,7 +176,7 @@ const historyColumn: DataTableColumns<ResponsePointHisrotyModel> = [
|
||||
),
|
||||
])
|
||||
case EventDataTypes.SC:
|
||||
return h(NFlex, { justify: 'center' }, () => [
|
||||
return h(NFlex, { align: 'center' }, () => [
|
||||
h(NTag, { type: 'warning', size: 'small', style: { margin: '0' } }, () => 'SC'),
|
||||
row.extra?.danmaku.price,
|
||||
])
|
||||
|
||||
@@ -54,6 +54,7 @@ const defaultSettingPoint: Setting_Point = {
|
||||
maxBonusPoints: 0,
|
||||
allowSelfCheckIn: false,
|
||||
requireAuth: false,
|
||||
shouldDiscontinueWhenSoldOut: false,
|
||||
}
|
||||
|
||||
// 响应式设置对象
|
||||
@@ -262,6 +263,20 @@ async function SaveComboSetting() {
|
||||
</NCheckbox>
|
||||
</NFlex>
|
||||
|
||||
<NFlex
|
||||
align="center"
|
||||
:gap="12"
|
||||
>
|
||||
<span>其他: </span>
|
||||
<NCheckbox
|
||||
v-model:checked="setting.shouldDiscontinueWhenSoldOut"
|
||||
:disabled="!canEdit"
|
||||
@update:checked="updateSettings"
|
||||
>
|
||||
礼物售罄时自动下架
|
||||
</NCheckbox>
|
||||
</NFlex>
|
||||
|
||||
<!-- 积分来源设置 -->
|
||||
<NFlex
|
||||
align="center"
|
||||
|
||||
@@ -328,9 +328,10 @@ onMounted(async () => {
|
||||
<NButton
|
||||
type="primary"
|
||||
:loading="isLoading"
|
||||
:disabled="!addPointCount || addPointCount === 0"
|
||||
@click="givePoint"
|
||||
>
|
||||
{{ addPointCount > 0 ? '给予' : '扣除' }}
|
||||
{{ !addPointCount || addPointCount === 0 ? '确定' : (addPointCount > 0 ? '给予' : '扣除') }}
|
||||
</NButton>
|
||||
</NFlex>
|
||||
</NModal>
|
||||
|
||||
@@ -577,9 +577,10 @@ onMounted(async () => {
|
||||
<NButton
|
||||
type="primary"
|
||||
:loading="isLoading"
|
||||
:disabled="!addPointCount || addPointCount === 0"
|
||||
@click="givePoint"
|
||||
>
|
||||
{{ addPointCount > 0 ? '给予' : '扣除' }}
|
||||
{{ !addPointCount || addPointCount === 0 ? '确定' : (addPointCount > 0 ? '给予' : '扣除') }}
|
||||
</NButton>
|
||||
</NFlex>
|
||||
</NModal>
|
||||
|
||||
@@ -1,16 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
import { ResponsePointHisrotyModel } from '@/api/api-models'
|
||||
import { ResponsePointHisrotyModel, PointFrom } from '@/api/api-models'
|
||||
import PointHistoryCard from '@/components/manage/PointHistoryCard.vue'
|
||||
import { POINT_API_URL } from '@/data/constants'
|
||||
import { useBiliAuth } from '@/store/useBiliAuth'
|
||||
import { NButton, NEmpty, NFlex, NSpin, useMessage } from 'naive-ui'
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { NButton, NEmpty, NFlex, NSelect, NSpin, useMessage } from 'naive-ui'
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
|
||||
const message = useMessage()
|
||||
const useAuth = useBiliAuth()
|
||||
const isLoading = ref(false)
|
||||
|
||||
const history = ref<ResponsePointHisrotyModel[]>([])
|
||||
const streamerFilter = ref<string | null>('')
|
||||
|
||||
// 定义加载完成的事件
|
||||
const emit = defineEmits(['dataLoaded'])
|
||||
@@ -42,6 +43,7 @@ async function getHistories() {
|
||||
// 提供给父组件调用的重置方法
|
||||
function reset() {
|
||||
history.value = []
|
||||
streamerFilter.value = ''
|
||||
}
|
||||
|
||||
// 暴露方法给父组件
|
||||
@@ -53,20 +55,74 @@ defineExpose({
|
||||
onMounted(async () => {
|
||||
history.value = await getHistories()
|
||||
})
|
||||
|
||||
// 根据主播名称筛选历史记录
|
||||
const filteredHistory = computed(() => {
|
||||
if (streamerFilter.value === '' || streamerFilter.value === null) {
|
||||
return history.value
|
||||
}
|
||||
return history.value.filter(item => {
|
||||
// 只筛选主播操作、弹幕来源和签到
|
||||
if ([PointFrom.Manual, PointFrom.Danmaku, PointFrom.CheckIn].includes(item.from)) {
|
||||
// 精确匹配主播名称
|
||||
return item.extra?.user?.name === streamerFilter.value
|
||||
}
|
||||
// 如果是使用积分的记录,则始终显示
|
||||
if (item.from === PointFrom.Use) {
|
||||
return true
|
||||
}
|
||||
// 其他类型的记录,在筛选时隐藏
|
||||
return false
|
||||
})
|
||||
})
|
||||
|
||||
// 计算可选的主播列表
|
||||
const streamerOptions = computed(() => {
|
||||
const names = new Set<string>()
|
||||
history.value.forEach(item => {
|
||||
if ([PointFrom.Manual, PointFrom.Danmaku, PointFrom.CheckIn].includes(item.from) && item.extra?.user?.name) {
|
||||
names.add(item.extra.user.name)
|
||||
}
|
||||
})
|
||||
// 添加"全部主播"选项
|
||||
const options = [{ label: '全部主播', value: '' }]
|
||||
names.forEach(name => {
|
||||
options.push({ label: name, value: name })
|
||||
})
|
||||
return options
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NSpin :show="isLoading">
|
||||
<NFlex justify="end" style="margin-bottom: 10px">
|
||||
<NButton size="small" type="primary" @click="getHistories">刷新记录</NButton>
|
||||
<NFlex
|
||||
justify="end"
|
||||
align="center"
|
||||
style="margin-bottom: 10px"
|
||||
>
|
||||
<NSelect
|
||||
v-model:value="streamerFilter"
|
||||
:options="streamerOptions"
|
||||
placeholder="按主播筛选"
|
||||
clearable
|
||||
size="small"
|
||||
style="max-width: 200px; margin-right: 10px"
|
||||
/>
|
||||
<NButton
|
||||
size="small"
|
||||
type="primary"
|
||||
@click="getHistories"
|
||||
>
|
||||
刷新记录
|
||||
</NButton>
|
||||
</NFlex>
|
||||
<NEmpty
|
||||
v-if="history.length == 0"
|
||||
description="暂无积分记录"
|
||||
v-if="filteredHistory.length == 0"
|
||||
description="暂无符合条件的积分记录"
|
||||
/>
|
||||
<PointHistoryCard
|
||||
v-else
|
||||
:histories="history"
|
||||
:histories="filteredHistory"
|
||||
/>
|
||||
</NSpin>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user