Compare commits
5 Commits
107966dabc
...
65f8d2d1e9
Author | SHA1 | Date | |
---|---|---|---|
|
65f8d2d1e9 | ||
|
e2b5e6bcbf | ||
|
9f9e96dc0c | ||
|
2d909b276b | ||
|
a6a5c20705 |
@ -9,10 +9,7 @@ useHead({
|
|||||||
{name: 'keywords', content: useI18n().t('appSetting.appKeyWords')},
|
{name: 'keywords', content: useI18n().t('appSetting.appKeyWords')},
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
const color = useColorMode()
|
|
||||||
const mode = computed(() => {
|
|
||||||
return color.value
|
|
||||||
})
|
|
||||||
|
|
||||||
// 添加路由中间件来处理过渡方向
|
// 添加路由中间件来处理过渡方向
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
@ -42,7 +39,7 @@ provide('slideDirection', slideDirection)
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VanConfigProvider :theme="mode">
|
<VanConfigProvider>
|
||||||
<NuxtLoadingIndicator
|
<NuxtLoadingIndicator
|
||||||
color="repeating-linear-gradient(to right,var(--c-primary) 0%,var(--c-primary-active) 100%)"/>
|
color="repeating-linear-gradient(to right,var(--c-primary) 0%,var(--c-primary-active) 100%)"/>
|
||||||
<NuxtLayout>
|
<NuxtLayout>
|
||||||
|
@ -18,7 +18,7 @@ onMounted(()=>{
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div v-if="show">
|
<div v-if="show" v-memo="[active]" >
|
||||||
<van-tabbar v-model="active" route placeholder fixed>
|
<van-tabbar v-model="active" route placeholder fixed>
|
||||||
<van-tabbar-item replace to="/">
|
<van-tabbar-item replace to="/">
|
||||||
<span>{{ $t('tabbar.home') }}</span>
|
<span>{{ $t('tabbar.home') }}</span>
|
||||||
|
@ -30,13 +30,12 @@ const subTitle = computed(() => {
|
|||||||
return route.meta.subTitle ? t(route.meta.subTitle) : ''
|
return route.meta.subTitle ? t(route.meta.subTitle) : ''
|
||||||
})
|
})
|
||||||
const showLeftArrow = computed(() => route.name && routeWhiteList.includes(route.name))
|
const showLeftArrow = computed(() => route.name && routeWhiteList.includes(route.name))
|
||||||
console.log('route.meta.i18n',route.meta.i18n)
|
|
||||||
console.log('t(route.meta.i18n)',route.meta.i18n)
|
|
||||||
console.log('route.meta.title',route.meta.title)
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<VanNavBar
|
<VanNavBar
|
||||||
|
v-memo="[title,fullLive,showLeftArrow,subTitle]"
|
||||||
:title="title"
|
:title="title"
|
||||||
:left-arrow="!showLeftArrow||fullLive"
|
:left-arrow="!showLeftArrow||fullLive"
|
||||||
placeholder clickable fixed
|
placeholder clickable fixed
|
||||||
|
@ -43,8 +43,8 @@ const props = defineProps({
|
|||||||
</div>
|
</div>
|
||||||
<div class="px-[16px] bg-#fff pt-12px pb-18px">
|
<div class="px-[16px] bg-#fff pt-12px pb-18px">
|
||||||
<div class="text-[#575757] text-[14px] mb-4px">竞价表:</div>
|
<div class="text-[#575757] text-[14px] mb-4px">竞价表:</div>
|
||||||
<div>
|
<div v-if="detailInfo?.priceRuleType!=='diy'">
|
||||||
<img src="@/static/images/1981736313.png" alt="">
|
<xImage :src="detailInfo?.priceRuleImage" alt=""/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { showImagePreview } from 'vant';
|
import { showImagePreview } from 'vant';
|
||||||
import { NuxtImg } from '#components'
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
src: {
|
src: {
|
||||||
type: String,
|
type: String,
|
||||||
@ -35,7 +34,9 @@ const showImage = () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
||||||
<nuxt-img
|
<nuxt-img
|
||||||
|
v-if="src"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
v-bind="{ ...props, ...$attrs }"
|
v-bind="{ ...props, ...$attrs }"
|
||||||
style="object-fit: cover"
|
style="object-fit: cover"
|
||||||
@ -46,6 +47,7 @@ const showImage = () => {
|
|||||||
:quality="quality"
|
:quality="quality"
|
||||||
placeholder
|
placeholder
|
||||||
/>
|
/>
|
||||||
|
<van-empty v-else description="暂无" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
|
21
app/composables/useWebSocket.ts
Normal file
21
app/composables/useWebSocket.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
export function useWebSocket() {
|
||||||
|
const { $ws } = useNuxtApp()
|
||||||
|
const messages = ref<any[]>([])
|
||||||
|
|
||||||
|
// 监听消息
|
||||||
|
const onMessage = (callback: (data: any) => void) => {
|
||||||
|
const handler = (event: CustomEvent) => callback(event.detail)
|
||||||
|
window.addEventListener('ws-message', handler as EventListener)
|
||||||
|
|
||||||
|
// 返回清理函数
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('ws-message', handler as EventListener)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
ws: $ws,
|
||||||
|
messages,
|
||||||
|
onMessage
|
||||||
|
}
|
||||||
|
}
|
@ -1,12 +1,16 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
|
import {goodStore} from "~/stores/goods/index.js";
|
||||||
|
import xImage from '@/components/x-image/index.vue'
|
||||||
|
const {
|
||||||
|
auctionDetail
|
||||||
|
} = goodStore()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="px-16px pt-14px">
|
<div class="px-16px pt-14px">
|
||||||
<div class="text-#575757 text-14px">
|
<div class="text-#575757 text-14px" v-html="auctionDetail.info">
|
||||||
这里是后台富文本配置的说明,啊即可打开三等奖撒度老师的湿答答是快乐的阿四大皆空
|
|
||||||
</div>
|
</div>
|
||||||
|
<xImage :src="auctionDetail.image" class="w-343px"></xImage>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ const openShow = async (item) => {
|
|||||||
@refresh="onRefresh"
|
@refresh="onRefresh"
|
||||||
>
|
>
|
||||||
<template #success>
|
<template #success>
|
||||||
<van-icon name="success" /> 刷新成功
|
<van-icon name="success" /> <span>刷新成功</span>
|
||||||
</template>
|
</template>
|
||||||
<van-list
|
<van-list
|
||||||
v-model:loading="storeLoading"
|
v-model:loading="storeLoading"
|
||||||
@ -65,7 +65,7 @@ const openShow = async (item) => {
|
|||||||
finished-text="没有更多了"
|
finished-text="没有更多了"
|
||||||
@load="loadMore"
|
@load="loadMore"
|
||||||
>
|
>
|
||||||
<div class="w-full flex gap-[16px]">
|
<div class="w-full flex gap-[16px]" v-memo="[itemList]">
|
||||||
<masonry-wall :items="itemList" :ssr-columns="2" :maxColumns="2" :minColumns="2" :gap="5">
|
<masonry-wall :items="itemList" :ssr-columns="2" :maxColumns="2" :minColumns="2" :gap="5">
|
||||||
<template #default="{ item, index }">
|
<template #default="{ item, index }">
|
||||||
<div
|
<div
|
||||||
|
@ -3,15 +3,18 @@ import liveRoom from '@/pages/liveRoom/index.client.vue';
|
|||||||
import {goodStore} from "@/stores/goods/index.js";
|
import {goodStore} from "@/stores/goods/index.js";
|
||||||
import ItemList from './components/ItemList/index.vue'
|
import ItemList from './components/ItemList/index.vue'
|
||||||
import Cescribe from './components/Cescribe/index.vue'
|
import Cescribe from './components/Cescribe/index.vue'
|
||||||
const {fullLive, liveRef} = goodStore();
|
const {fullLive,getAuctionDetail,auctionDetail} = goodStore();
|
||||||
const changeLive = () => {
|
const changeLive = () => {
|
||||||
fullLive.value = true;
|
fullLive.value = true;
|
||||||
};
|
};
|
||||||
|
if (!auctionDetail.value.uuid){
|
||||||
|
await getAuctionDetail()
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="flex-grow-1">
|
<div class="flex-grow-1">
|
||||||
<client-only>
|
<client-only>
|
||||||
<liveRoom @click="changeLive" :class="['changeLive', fullLive ? 'expanded' : 'collapsed']" ref="liveRef"
|
<liveRoom @click="changeLive" :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"
|
||||||
:fullLive="fullLive"/>
|
:fullLive="fullLive"/>
|
||||||
</client-only>
|
</client-only>
|
||||||
<div v-show="!fullLive" class="bg-#fff">
|
<div v-show="!fullLive" class="bg-#fff">
|
||||||
|
@ -8,6 +8,10 @@ import {liveStore} from "~/stores/live/index.js";
|
|||||||
import paymentResults from '~/pages/liveRoom/components/PaymentResults/index.vue'
|
import paymentResults from '~/pages/liveRoom/components/PaymentResults/index.vue'
|
||||||
import paymentInput from '~/pages/liveRoom/components/PaymentInput/index.vue'
|
import paymentInput from '~/pages/liveRoom/components/PaymentInput/index.vue'
|
||||||
import xButton from '@/components/x-button/index.vue'
|
import xButton from '@/components/x-button/index.vue'
|
||||||
|
import {goodStore} from "~/stores/goods/index.js";
|
||||||
|
import {authStore} from "~/stores/auth/index.js";
|
||||||
|
const {auctionDetail,getAuctionDetail} = goodStore();
|
||||||
|
const { token } = authStore()
|
||||||
const player = ref(null)
|
const player = ref(null)
|
||||||
const {quoteStatus, changeStatus, show, playerId, show1} = liveStore()
|
const {quoteStatus, changeStatus, show, playerId, show1} = liveStore()
|
||||||
const isPlayerReady = ref(false)
|
const isPlayerReady = ref(false)
|
||||||
@ -57,8 +61,23 @@ const initializePlayer = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(async () => {
|
||||||
|
if (!auctionDetail.value.uuid){
|
||||||
|
await getAuctionDetail()
|
||||||
|
}
|
||||||
/* initializePlayer()*/
|
/* initializePlayer()*/
|
||||||
|
const { ws, messages, onMessage } = useWebSocket()
|
||||||
|
|
||||||
|
// 连接
|
||||||
|
ws.connect('/api/v1/m/auction/live',{auctionUuid: auctionDetail.value.uuid,token:token.value})
|
||||||
|
|
||||||
|
/*// 发送消息
|
||||||
|
ws.send({ type: 'chat', content: 'Hello!' })*/
|
||||||
|
|
||||||
|
// 监听消息
|
||||||
|
onMessage((data) => {
|
||||||
|
console.log('收到消息:', data)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
if (player.value) {
|
if (player.value) {
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
definePageMeta({
|
|
||||||
title: '🎨 Unocss 示例',
|
|
||||||
i18n: 'menu.unocssExample',
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div>
|
|
||||||
<h1 class="text-6xl color-pink font-semibold">
|
|
||||||
{{ $t('unocss_page.hello', ['Unocss!']) }}
|
|
||||||
</h1>
|
|
||||||
|
|
||||||
<p class="mt-10 text-gray-700 dark:text-white">
|
|
||||||
{{ $t('unocss_page.desc') }}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<button class="mt-10 btn">
|
|
||||||
{{ $t('unocss_page.btn_txt') }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
86
app/plugins/websocket.ts
Normal file
86
app/plugins/websocket.ts
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
export default defineNuxtPlugin(() => {
|
||||||
|
const config = useRuntimeConfig()
|
||||||
|
const ws = reactive({
|
||||||
|
instance: null as WebSocket | null,
|
||||||
|
isConnected: false,
|
||||||
|
|
||||||
|
// 修改 connect 方法接收路径和数据对象
|
||||||
|
connect(path: string, data?: Record<string, any>) {
|
||||||
|
if (this.instance?.readyState === WebSocket.OPEN) {
|
||||||
|
this.instance.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建查询字符串
|
||||||
|
const queryString = data
|
||||||
|
? '?' + Object.entries(data)
|
||||||
|
.map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
|
||||||
|
.join('&')
|
||||||
|
: ''
|
||||||
|
|
||||||
|
// 构建完整的 WebSocket URL
|
||||||
|
const wsUrl = `${config.public.NUXT_PUBLIC_SOCKET_URL}${path}${queryString}`
|
||||||
|
this.instance = new WebSocket(wsUrl)
|
||||||
|
|
||||||
|
this.instance.onopen = () => {
|
||||||
|
this.isConnected = true
|
||||||
|
console.log('WebSocket 已连接')
|
||||||
|
}
|
||||||
|
|
||||||
|
this.instance.onclose = () => {
|
||||||
|
this.isConnected = false
|
||||||
|
console.log('WebSocket 已断开')
|
||||||
|
/* this.reconnect(path, data)*/
|
||||||
|
}
|
||||||
|
|
||||||
|
this.instance.onerror = (error) => {
|
||||||
|
console.error('WebSocket 错误:', error)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.instance.onmessage = (event) => {
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(event.data)
|
||||||
|
this.handleMessage(data)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('消息解析错误:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 更新重连方法以支持数据对象
|
||||||
|
reconnect(path: string, data?: Record<string, any>) {
|
||||||
|
setTimeout(() => {
|
||||||
|
console.log('尝试重新连接...')
|
||||||
|
this.connect(path, data)
|
||||||
|
}, 3000)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 发送消息
|
||||||
|
send(data: any) {
|
||||||
|
if (this.instance?.readyState === WebSocket.OPEN) {
|
||||||
|
this.instance.send(JSON.stringify(data))
|
||||||
|
} else {
|
||||||
|
console.warn('WebSocket 未连接,无法发送消息')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 关闭连接
|
||||||
|
disconnect() {
|
||||||
|
if (this.instance) {
|
||||||
|
this.instance.close()
|
||||||
|
this.instance = null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 消息处理
|
||||||
|
handleMessage(data: any) {
|
||||||
|
// 触发自定义事件,让组件可以监听
|
||||||
|
window.dispatchEvent(new CustomEvent('ws-message', { detail: data }))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
provide: {
|
||||||
|
ws
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
@ -6,7 +6,6 @@ export const goodStore = createGlobalState(() => {
|
|||||||
// 状态定义
|
// 状态定义
|
||||||
const actionDetails = ref({})
|
const actionDetails = ref({})
|
||||||
const fullLive = ref(false)
|
const fullLive = ref(false)
|
||||||
const liveRef = ref(null)
|
|
||||||
const currentItem = ref({})
|
const currentItem = ref({})
|
||||||
const myArtWorks = ref([])
|
const myArtWorks = ref([])
|
||||||
const pageRef = ref({
|
const pageRef = ref({
|
||||||
@ -97,7 +96,7 @@ export const goodStore = createGlobalState(() => {
|
|||||||
// 状态
|
// 状态
|
||||||
actionDetails,
|
actionDetails,
|
||||||
fullLive,
|
fullLive,
|
||||||
liveRef,
|
|
||||||
currentItem,
|
currentItem,
|
||||||
myArtWorks,
|
myArtWorks,
|
||||||
pageRef,
|
pageRef,
|
||||||
|
2
env/.env.test
vendored
2
env/.env.test
vendored
@ -2,6 +2,6 @@
|
|||||||
NUXT_PUBLIC_API_BASE=http://172.16.100.99:8005
|
NUXT_PUBLIC_API_BASE=http://172.16.100.99:8005
|
||||||
NUXT_PUBLIC_WS_URL=ws://test-ws.example.com
|
NUXT_PUBLIC_WS_URL=ws://test-ws.example.com
|
||||||
NUXT_API_SECRET=test-secret
|
NUXT_API_SECRET=test-secret
|
||||||
|
NUXT_PUBLIC_SOCKET_URL=ws://172.16.100.99:8005
|
||||||
# 阿里云播放器配置
|
# 阿里云播放器配置
|
||||||
NUXT_PUBLIC_PLAYER_SOURCE=artc://live-pull-sh-01.szjixun.cn/live/live?auth_key=1737080180-0-0-42ad4cf26ba26eee78ca7de9c524d1e0
|
NUXT_PUBLIC_PLAYER_SOURCE=artc://live-pull-sh-01.szjixun.cn/live/live?auth_key=1737080180-0-0-42ad4cf26ba26eee78ca7de9c524d1e0
|
@ -12,21 +12,18 @@ const publicConfig = Object.entries(process.env)
|
|||||||
}, {})
|
}, {})
|
||||||
|
|
||||||
export default defineNuxtConfig({
|
export default defineNuxtConfig({
|
||||||
|
|
||||||
modules: [
|
modules: [
|
||||||
'@vant/nuxt',
|
'@vant/nuxt',
|
||||||
'@unocss/nuxt',
|
'@unocss/nuxt',
|
||||||
'@nuxt/image',
|
'@nuxt/image',
|
||||||
'@nuxtjs/color-mode',
|
|
||||||
'@nuxtjs/i18n',
|
'@nuxtjs/i18n',
|
||||||
],
|
],
|
||||||
runtimeConfig: {
|
runtimeConfig: {
|
||||||
// 私有配置,只有在服务端可用
|
// 私有配置,只有在服务端可用
|
||||||
apiSecret: process.env.NUXT_API_SECRET || 'default_secret',
|
apiSecret: process.env.NUXT_API_SECRET,
|
||||||
// 公共配置,客户端和服务端都可用
|
// 公共配置,客户端和服务端都可用
|
||||||
public: publicConfig,
|
public: publicConfig,
|
||||||
},
|
},
|
||||||
|
|
||||||
css: [
|
css: [
|
||||||
'@unocss/reset/tailwind.css',
|
'@unocss/reset/tailwind.css',
|
||||||
'@/static/styles/default-theme.css',
|
'@/static/styles/default-theme.css',
|
||||||
@ -51,14 +48,6 @@ export default defineNuxtConfig({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
colorMode: {
|
|
||||||
classSuffix: '',
|
|
||||||
preference: 'system',
|
|
||||||
fallback: 'light',
|
|
||||||
storageKey: 'nuxt-color-mode',
|
|
||||||
},
|
|
||||||
|
|
||||||
i18n: {
|
i18n: {
|
||||||
locales: currentLocales,
|
locales: currentLocales,
|
||||||
lazy: true,
|
lazy: true,
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fingerprintjs/fingerprintjs": "^4.5.1",
|
"@fingerprintjs/fingerprintjs": "^4.5.1",
|
||||||
"@nuxtjs/color-mode": "^3.5.2",
|
|
||||||
"@nuxtjs/i18n": "^9.1.1",
|
"@nuxtjs/i18n": "^9.1.1",
|
||||||
"@vueuse/core": "^12.4.0",
|
"@vueuse/core": "^12.4.0",
|
||||||
"@yeger/vue-masonry-wall": "^5.0.17",
|
"@yeger/vue-masonry-wall": "^5.0.17",
|
||||||
|
2211
pnpm-lock.yaml
2211
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user