fix danmakutype: enter

This commit is contained in:
2024-02-21 22:34:49 +08:00
parent 27336f6e82
commit c70bc65f30
3 changed files with 121 additions and 46 deletions

View File

@@ -25,7 +25,6 @@ import {
NList, NList,
NListItem, NListItem,
NModal, NModal,
NPopover,
NRadioButton, NRadioButton,
NRadioGroup, NRadioGroup,
NSkeleton, NSkeleton,
@@ -34,7 +33,6 @@ import {
NSwitch, NSwitch,
NTag, NTag,
NTooltip, NTooltip,
NVirtualList,
} from 'naive-ui' } from 'naive-ui'
import { computed, nextTick, onMounted, ref, watch } from 'vue' import { computed, nextTick, onMounted, ref, watch } from 'vue'
import LiveInfoContainer from './LiveInfoContainer.vue' import LiveInfoContainer from './LiveInfoContainer.vue'
@@ -57,11 +55,11 @@ const accountInfo = useAccount()
const debouncedFn = useDebounceFn(() => { const debouncedFn = useDebounceFn(() => {
UpdateDanmakus() UpdateDanmakus()
}, 750) }, 750)
let isLoading = ref(false) const isLoading = ref(false)
let showModal = ref(false) const showModal = ref(false)
let showExportModal = ref(false) const showExportModal = ref(false)
let userDanmakus = ref<DanmakuModel[] | undefined>() const userDanmakus = ref<DanmakuModel[] | undefined>()
let hideAvatar = useLocalStorage('Setting.HideAvatar', false) const hideAvatar = useLocalStorage('Setting.HideAvatar', false)
const { width } = useWindowSize() const { width } = useWindowSize()
interface Props { interface Props {
@@ -113,7 +111,7 @@ const emit = defineEmits<{
defineExpose({ defineExpose({
InsertDanmakus, InsertDanmakus,
}) })
let danmakus = ref<DanmakuModel[]>([]) const danmakus = ref<DanmakuModel[]>([])
watch( watch(
() => showTools, () => showTools,
(newV, oldV) => { (newV, oldV) => {
@@ -128,25 +126,26 @@ watch(danmakuRef, (newValue) => {
danmakus.value = GetFilteredDanmakus(newValue) danmakus.value = GetFilteredDanmakus(newValue)
}) })
let keyword = ref('') const keyword = ref('')
let enableRegex = ref(false) const enableRegex = ref(false)
let deselect = ref(false) const deselect = ref(false)
let price = ref<number | undefined>() const price = ref<number | undefined>()
let filterSelected = ref(defaultFilterSelected) const filterSelected = ref(defaultFilterSelected)
let innerShowTools = ref(showTools) const innerShowTools = ref(showTools)
let modalShowTools = ref(false) const modalShowTools = ref(false)
let orderDecreasing = ref(false) const orderDecreasing = ref(false)
let orderByPrice = ref(false) const orderByPrice = ref(false)
let processing = ref(false) const processing = ref(false)
let isRanking = ref(false) const isRanking = ref(false)
let rankInfo = ref<RankInfo[]>([]) const rankInfo = ref<RankInfo[]>([])
let currentRankInfo = ref<RankInfo[]>([]) const currentRankInfo = ref<RankInfo[]>([])
let rankType = ref(RankType.Danmaku) const rankType = ref(RankType.Danmaku)
let hideEmoji = ref(false) const hideEmoji = ref(false)
const existEnterMessage = ref(false)
let exportType = ref<'json' | 'xml' | 'csv'>('json') const exportType = ref<'json' | 'xml' | 'csv'>('json')
let onlyExportFilteredDanmakus = ref(false) const onlyExportFilteredDanmakus = ref(false)
let isExporting = ref(false) const isExporting = ref(false)
function OnNameClick(uId: number) { function OnNameClick(uId: number) {
if (isInModal) { if (isInModal) {
@@ -257,7 +256,17 @@ function GetRankIndexColor(index: number) {
function Export() { function Export() {
isExporting.value = true isExporting.value = true
saveAs( saveAs(
new Blob([GetString(accountInfo.value, currentLive, onlyExportFilteredDanmakus.value ? danmakus.value : currentDanmakus, exportType.value)], { type: 'text/plain;charset=utf-8' }), new Blob(
[
GetString(
accountInfo.value,
currentLive,
onlyExportFilteredDanmakus.value ? danmakus.value : currentDanmakus,
exportType.value,
),
],
{ type: 'text/plain;charset=utf-8' },
),
`${Date.now()}_${currentLive.startAt}_${currentLive.title.replace('_', '-')}_${accountInfo.value?.name}.${exportType.value}`, `${Date.now()}_${currentLive.startAt}_${currentLive.title.replace('_', '-')}_${accountInfo.value?.name}.${exportType.value}`,
) )
isExporting.value = false isExporting.value = false
@@ -283,7 +292,9 @@ function GetFilteredDanmakus(targetDanmakus?: DanmakuModel[]) {
tempDanmakus = tempDanmakus.filter((d) => d.type != EventDataTypes.Message || !d.isEmoji) tempDanmakus = tempDanmakus.filter((d) => d.type != EventDataTypes.Message || !d.isEmoji)
} }
if (orderByPrice.value) { if (orderByPrice.value) {
tempDanmakus = tempDanmakus.filter((d) => d.type != EventDataTypes.Message).sort((a, b) => (a.price ?? 0) - (b.price ?? 0)) tempDanmakus = tempDanmakus
.filter((d) => d.type != EventDataTypes.Message)
.sort((a, b) => (a.price ?? 0) - (b.price ?? 0))
} else { } else {
tempDanmakus = tempDanmakus.sort((a, b) => a.time - b.time) tempDanmakus = tempDanmakus.sort((a, b) => a.time - b.time)
} }
@@ -295,7 +306,11 @@ function GetFilteredDanmakus(targetDanmakus?: DanmakuModel[]) {
if (d.uId.toString() == keyword.value || d.uName == keyword.value) { if (d.uId.toString() == keyword.value || d.uName == keyword.value) {
return true return true
} }
return enableRegex.value ? (d.msg?.match(keyword.value) ? true : false) : d.msg?.toLowerCase().includes(keyword.value.toLowerCase()) == true return enableRegex.value
? d.msg?.match(keyword.value)
? true
: false
: d.msg?.toLowerCase().includes(keyword.value.toLowerCase()) == true
} }
if (price.value && price.value > 0) { if (price.value && price.value > 0) {
tempDanmakus = tempDanmakus.filter((d) => (d.price ?? 0) >= (price.value ?? 0)) tempDanmakus = tempDanmakus.filter((d) => (d.price ?? 0) >= (price.value ?? 0))
@@ -317,14 +332,22 @@ function RoundNumber(num: number) {
} }
onMounted(() => { onMounted(() => {
danmakus.value = currentDanmakus danmakus.value = GetFilteredDanmakus()
existEnterMessage.value = danmakus.value.some((d) => d.type == EventDataTypes.Message)
//defaultFilterSelected.push(EventDataTypes.Enter)
}) })
</script> </script>
<template> <template>
<NSkeleton v-if="isLoading"> </NSkeleton> <NSkeleton v-if="isLoading"> </NSkeleton>
<NSpin v-else :show="processing"> <NSpin v-else :show="processing">
<NModal v-model:show="showModal" @after-leave="userDanmakus = undefined" preset="card" :style="'width: 600px;max-width: 90vw;max-height: 90vh;'" content-style="overflow-y: auto"> <NModal
v-model:show="showModal"
@after-leave="userDanmakus = undefined"
preset="card"
:style="'width: 600px;max-width: 90vw;max-height: 90vh;'"
content-style="overflow-y: auto"
>
<template #header> <template #header>
{{ userDanmakus?.[0].uName }} {{ userDanmakus?.[0].uName }}
</template> </template>
@@ -337,7 +360,15 @@ onMounted(() => {
</template> </template>
</NSwitch> </NSwitch>
</template> </template>
<DanmakuContainer :show-live-info="false" :current-danmakus="userDanmakus ?? []" :current-live="currentLive" :height="500" :show-border="false" :show-tools="modalShowTools" to="space" /> <DanmakuContainer
:show-live-info="false"
:current-danmakus="userDanmakus ?? []"
:current-live="currentLive"
:height="500"
:show-border="false"
:show-tools="modalShowTools"
to="space"
/>
</NModal> </NModal>
<NModal v-model:show="showExportModal" preset="card" style="width: 500px; max-width: 90vw; height: auto"> <NModal v-model:show="showExportModal" preset="card" style="width: 500px; max-width: 90vw; height: auto">
<template #header> 导出 </template> <template #header> 导出 </template>
@@ -363,9 +394,10 @@ onMounted(() => {
<NCollapse> <NCollapse>
<NCollapseItem title="关于" name="1"> <NCollapseItem title="关于" name="1">
<div> <div>
文件名格式: {<NTooltip><template #trigger>生成时间</template>Unix</NTooltip>}_{<NTooltip><template #trigger>开始时间</template>Unix: {{ currentLive.startAt }} </NTooltip>}_{<NTooltip 文件名格式: {<NTooltip><template #trigger>生成时间</template>Unix</NTooltip>}_{<NTooltip
><template #trigger>直播间标题</template>' _ ' 将被转义为 ' - '</NTooltip ><template #trigger>开始时间</template>Unix: {{ currentLive.startAt }} </NTooltip
>}_{<NTooltip><template #trigger>用户名</template>{{ accountInfo?.name }}</NTooltip >}_{<NTooltip><template #trigger>直播间标题</template>' _ ' 将被转义为 ' - '</NTooltip>}_{<NTooltip
><template #trigger>用户名</template>{{ accountInfo?.name }}</NTooltip
>}.{{ exportType }} >}.{{ exportType }}
<br /> <br />
弹幕Type对应: 弹幕Type对应:
@@ -410,7 +442,9 @@ onMounted(() => {
<NCollapseTransition :show="innerShowTools && !isRanking"> <NCollapseTransition :show="innerShowTools && !isRanking">
<NSpace vertical style="padding-bottom: 16px"> <NSpace vertical style="padding-bottom: 16px">
<NSpace align="center"> <NSpace align="center">
<NButton type="primary" size="small" @click="showExportModal = true" @update:value="UpdateDanmakus"> 导出 </NButton> <NButton type="primary" size="small" @click="showExportModal = true" @update:value="UpdateDanmakus">
导出
</NButton>
<NCheckbox v-model:checked="orderDecreasing" @update:checked="UpdateDanmakus"> 降序 </NCheckbox> <NCheckbox v-model:checked="orderDecreasing" @update:checked="UpdateDanmakus"> 降序 </NCheckbox>
<NCollapseTransition :show="filterSelected.includes(EventDataTypes.Message)"> <NCollapseTransition :show="filterSelected.includes(EventDataTypes.Message)">
<NCheckbox v-model:checked="hideEmoji" @update:checked="UpdateDanmakus"> 隐藏表情 </NCheckbox> <NCheckbox v-model:checked="hideEmoji" @update:checked="UpdateDanmakus"> 隐藏表情 </NCheckbox>
@@ -419,7 +453,14 @@ onMounted(() => {
<NCheckbox v-model:checked="orderByPrice" @update:checked="UpdateDanmakus"> 按价格排序 </NCheckbox> <NCheckbox v-model:checked="orderByPrice" @update:checked="UpdateDanmakus"> 按价格排序 </NCheckbox>
</NSpace> </NSpace>
<NSpace align="center"> <NSpace align="center">
<NInput v-model:value="keyword" size="small" style="max-width: 200px" placeholder="内容筛选" clearable @update:value="debouncedFn"> <NInput
v-model:value="keyword"
size="small"
style="max-width: 200px"
placeholder="内容筛选"
clearable
@update:value="debouncedFn"
>
<template #prefix> <template #prefix>
<NIcon :component="Search24Filled" /> <NIcon :component="Search24Filled" />
</template> </template>
@@ -428,7 +469,15 @@ onMounted(() => {
<NCheckbox v-model:checked="deselect" @update:checked="UpdateDanmakus"> 反选 </NCheckbox> <NCheckbox v-model:checked="deselect" @update:checked="UpdateDanmakus"> 反选 </NCheckbox>
</NSpace> </NSpace>
<NSpace align="center"> <NSpace align="center">
<NInputNumber v-model:value="price" placeholder="最低价格" size="small" style="max-width: 200px" clearable :min="0" @update:value="debouncedFn"> <NInputNumber
v-model:value="price"
placeholder="最低价格"
size="small"
style="max-width: 200px"
clearable
:min="0"
@update:value="debouncedFn"
>
<template #prefix> <template #prefix>
<NIcon :component="Money20Regular" /> <NIcon :component="Money20Regular" />
</template> </template>
@@ -445,6 +494,8 @@ onMounted(() => {
<NCheckbox :value="EventDataTypes.Gift" label="礼物" /> <NCheckbox :value="EventDataTypes.Gift" label="礼物" />
<NCheckbox :value="EventDataTypes.Guard" label="舰长" /> <NCheckbox :value="EventDataTypes.Guard" label="舰长" />
<NCheckbox :value="EventDataTypes.SC" label="Superchat" /> <NCheckbox :value="EventDataTypes.SC" label="Superchat" />
<NCheckbox v-if="existEnterMessage" :value="EventDataTypes.Enter" label="入场" />
</NSpace> </NSpace>
</NCheckboxGroup> </NCheckboxGroup>
</NSpace> </NSpace>
@@ -462,15 +513,39 @@ onMounted(() => {
</NDivider> </NDivider>
</NCollapseTransition> </NCollapseTransition>
<div :style="isRanking ? 'display:none' : ''"> <div :style="isRanking ? 'display:none' : ''">
<SimpleVirtualList v-if="danmakus.length > itemRange" :items="danmakus" :default-size="itemHeight" :default-height="height ?? 1000"> <SimpleVirtualList
v-if="danmakus.length > itemRange"
:items="danmakus"
:default-size="itemHeight"
:default-height="height ?? 1000"
>
<template #default="{ item }"> <template #default="{ item }">
<p :style="`min-height: ${itemHeight}px;width:97%;display:flex;align-items:center;`"> <p :style="`min-height: ${itemHeight}px;width:97%;display:flex;align-items:center;`">
<DanmakuItem :danmaku="item" :account-info="accountInfo" @on-click-name="OnNameClick" :show-name="showName" :show-avatar="!hideAvatar" :height="itemHeight" /> <DanmakuItem
:danmaku="item"
:account-info="accountInfo"
@on-click-name="OnNameClick"
:show-name="showName"
:show-avatar="!hideAvatar"
:height="itemHeight"
/>
</p> </p>
</template> </template>
</SimpleVirtualList> </SimpleVirtualList>
<p v-else v-for="item in danmakus" :style="`min-height: ${itemHeight}px;width:97%;display:flex;align-items:center;`" v-bind:key="item.id"> <p
<DanmakuItem :danmaku="item" :account-info="accountInfo" @on-click-name="OnNameClick" :show-name="showName" :show-avatar="!hideAvatar" :height="itemHeight" /> v-else
v-for="item in danmakus"
:style="`min-height: ${itemHeight}px;width:97%;display:flex;align-items:center;`"
v-bind:key="item.id"
>
<DanmakuItem
:danmaku="item"
:account-info="accountInfo"
@on-click-name="OnNameClick"
:show-name="showName"
:show-avatar="!hideAvatar"
:height="itemHeight"
/>
</p> </p>
</div> </div>
<div v-if="isRanking"> <div v-if="isRanking">

View File

@@ -25,7 +25,6 @@ const renderCountdown: CountdownProps['render'] = (info: { hours: number; minute
} }
function onClick() { function onClick() {
if (props.canClick == true) { if (props.canClick == true) {
console.log(props.item.id)
router.push({ name: 'manage-videoCollect-Detail', params: { id: props.item.id } }) router.push({ name: 'manage-videoCollect-Detail', params: { id: props.item.id } })
} }
} }

View File

@@ -101,13 +101,13 @@ const createRules: FormRules = {
} }
const paddingVideos = computed(() => { const paddingVideos = computed(() => {
return videoDetail.value.videos.filter((v) => v.info.status == VideoStatus.Pending) return videoDetail.value?.videos?.filter((v) => v.info.status == VideoStatus.Pending) ?? []
}) })
const rejectVideos = computed(() => { const rejectVideos = computed(() => {
return videoDetail.value.videos.filter((v) => v.info.status == VideoStatus.Rejected) return videoDetail.value?.videos?.filter((v) => v.info.status == VideoStatus.Rejected) ?? []
}) })
const acceptVideos = computed(() => { const acceptVideos = computed(() => {
return videoDetail.value.videos.filter((v) => v.info.status == VideoStatus.Accepted) return videoDetail.value?.videos?.filter((v) => v.info.status == VideoStatus.Accepted) ?? []
}) })
async function getData() { async function getData() {
@@ -121,6 +121,7 @@ async function getData() {
description: data.data.table.description, description: data.data.table.description,
maxVideoCount: data.data.table.maxVideoCount, maxVideoCount: data.data.table.maxVideoCount,
} as VideoCollectCreateModel } as VideoCollectCreateModel
console.log(data.data)
return data.data return data.data
} }
} catch (err) { } catch (err) {