allow filter goods tag

This commit is contained in:
Megghy
2024-09-26 16:36:03 +08:00
parent 4393e3d9a7
commit f61bb626ac
4 changed files with 88 additions and 37 deletions

View File

@@ -1,7 +1,7 @@
/* eslint-disable indent */ /* eslint-disable indent */
import { apiFail } from '@/data/constants'
import { useLocalStorage } from '@vueuse/core' import { useLocalStorage } from '@vueuse/core'
import { APIRoot, PaginationResponse } from './api-models' import { APIRoot, PaginationResponse } from './api-models'
import { apiFail } from '@/data/constants'
const cookie = useLocalStorage('JWT_Token', '') const cookie = useLocalStorage('JWT_Token', '')
@@ -62,6 +62,7 @@ export async function QueryGetAPI<T>(
return await QueryGetAPIInternal<APIRoot<T>>(urlString, params, headers) return await QueryGetAPIInternal<APIRoot<T>>(urlString, params, headers)
} }
async function QueryGetAPIInternal<T>(urlString: string, params?: any, headers?: [string, string][]) { async function QueryGetAPIInternal<T>(urlString: string, params?: any, headers?: [string, string][]) {
try {
const url = new URL(urlString) const url = new URL(urlString)
url.search = getParams(params) url.search = getParams(params)
if (cookie.value) { if (cookie.value) {
@@ -72,6 +73,10 @@ async function QueryGetAPIInternal<T>(urlString: string, params?: any, headers?:
method: 'get', method: 'get',
headers: headers, headers: headers,
}) })
} catch (err) {
console.log(`url:${urlString}, error:${err}`)
throw err
}
} }
function getParams(params: any) { function getParams(params: any) {
const urlParams = new URLSearchParams(window.location.search) const urlParams = new URLSearchParams(window.location.search)

View File

@@ -0,0 +1,8 @@
<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
</script>
<template>
1
</template>

View File

@@ -31,6 +31,7 @@ import { computed, h, onMounted, ref } from 'vue'
import PointUserDetailCard from './PointUserDetailCard.vue' import PointUserDetailCard from './PointUserDetailCard.vue'
import { Info24Filled } from '@vicons/fluent' import { Info24Filled } from '@vicons/fluent'
import { objectsToCSV } from '@/Utils' import { objectsToCSV } from '@/Utils'
import { format } from 'date-fns'
const props = defineProps<{ const props = defineProps<{
goods: ResponsePointGoodModel[] goods: ResponsePointGoodModel[]
@@ -245,6 +246,22 @@ async function deleteUser(user: ResponsePointUserModel) {
isLoading.value = false isLoading.value = false
} }
} }
function exportData() {
/* const text = objectsToCSV(
users.value.map((s) => {
const gift = props.goods.find((g) => g.id == s.goodsId)
return {
}
}),
)
const BOM = new Uint8Array([0xef, 0xbb, 0xbf])
const utf8encoder = new TextEncoder()
const utf8array = utf8encoder.encode(text)
saveAs(
new Blob([BOM, utf8array], { type: 'text/csv;charset=utf-8;' }),
`用户积分_${format(Date.now(), 'yyyy-MM-dd HH:mm:ss')}_${accountInfo.value?.name}_.csv`,
)*/
}
onMounted(async () => { onMounted(async () => {
await refresh() await refresh()
@@ -266,6 +283,7 @@ onMounted(async () => {
<NFlex> <NFlex>
<NButton type="primary" @click="refresh">刷新</NButton> <NButton type="primary" @click="refresh">刷新</NButton>
<NButton type="info" @click="showGivePointModal = true">给予/扣除积分</NButton> <NButton type="info" @click="showGivePointModal = true">给予/扣除积分</NButton>
<NButton type="info" @click="exportData">导出积分数据</NButton>
</NFlex> </NFlex>
</template> </template>
<NFlex align="center"> <NFlex align="center">

View File

@@ -21,8 +21,6 @@ import {
NFlex, NFlex,
NForm, NForm,
NFormItem, NFormItem,
NGrid,
NGridItem,
NInputNumber, NInputNumber,
NModal, NModal,
NSelect, NSelect,
@@ -32,7 +30,7 @@ import {
NTooltip, NTooltip,
SelectOption, SelectOption,
useDialog, useDialog,
useMessage, useMessage
} from 'naive-ui' } from 'naive-ui'
import { computed, h, onMounted, ref } from 'vue' import { computed, h, onMounted, ref } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
@@ -62,6 +60,15 @@ const selectedAddress = ref<AddressInfo>()
const canDoBuy = computed(() => { const canDoBuy = computed(() => {
return currentGoods.value && currentGoods.value.price * buyCount.value <= currentPoint.value return currentGoods.value && currentGoods.value.price * buyCount.value <= currentPoint.value
}) })
const tags = computed(() => {
return Array.from(new Set(goods.value.flatMap((g) => g.tags)))
})
const selectedTag = ref<string>()
const selectedItems = computed(() => {
return selectedTag.value
? goods.value.filter((g) => g.tags.includes(selectedTag.value))
: goods.value
})
const addressOptions = computed(() => { const addressOptions = computed(() => {
if (!biliAuth.value.id) return [] if (!biliAuth.value.id) return []
@@ -208,10 +215,23 @@ onMounted(async () => {
<NText> 你在 {{ userInfo.extra?.streamerInfo?.name ?? userInfo.name }} 的直播间的积分为 {{ currentPoint }} </NText> <NText> 你在 {{ userInfo.extra?.streamerInfo?.name ?? userInfo.name }} 的直播间的积分为 {{ currentPoint }} </NText>
</NCard> </NCard>
<NDivider /> <NDivider />
<NCard size="small" title="标签">
<NFlex align="center" justify="center">
<NButton v-for="tag in tags"
:type="tag == selectedTag ? 'success' : 'default'"
@click="selectedTag = selectedTag == tag ? undefined : tag"
:borderd="false"
style="margin: 4px"
size="small">
{{ tag }}
</NButton>
</NFlex>
</NCard>
<NDivider />
<NSpin :show="isLoading"> <NSpin :show="isLoading">
<NEmpty v-if="goods.length == 0"> 暂无礼物 </NEmpty> <NEmpty v-if="selectedItems.length == 0"> 暂无礼物 </NEmpty>
<NFlex justify="center"> <NFlex justify="center">
<PointGoodsItem v-for="item in goods" :key="item.id" :goods="item" content-style="max-width: 300px;height: 365px"> <PointGoodsItem v-for="item in selectedItems" :key="item.id" :goods="item" content-style="max-width: 300px;height: 365px">
<template #footer> <template #footer>
<NFlex justify="space-between" align="center"> <NFlex justify="space-between" align="center">
<NTooltip> <NTooltip>