Merge branch 'main' of https://gitea-inner.fontree.cn/scout666/liveh5-nuxt
This commit is contained in:
commit
4202d94a44
@ -54,6 +54,14 @@ export async function logSendlog(data) {
|
|||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
export async function signOnline(data) {
|
||||||
|
|
||||||
|
return await request( {
|
||||||
|
url:'/api/v1/contract/sign-online',
|
||||||
|
method: 'POST',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
export async function signOffline(data) {
|
export async function signOffline(data) {
|
||||||
|
|
||||||
return await request( {
|
return await request( {
|
||||||
@ -69,4 +77,20 @@ export async function fddCheck(data) {
|
|||||||
method: 'POST',
|
method: 'POST',
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
export async function createBuyOrder(data) {
|
||||||
|
|
||||||
|
return await request( {
|
||||||
|
url:'/api/v1/m/auction/createBuyOrder',
|
||||||
|
method: 'POST',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
export async function orderQuery(data) {
|
||||||
|
|
||||||
|
return await request( {
|
||||||
|
url:'/api/v1/payment/order/query',
|
||||||
|
method: 'POST',
|
||||||
|
data
|
||||||
|
})
|
||||||
}
|
}
|
@ -82,5 +82,7 @@ provide('slideDirection', slideDirection)
|
|||||||
:root {
|
:root {
|
||||||
--safe-area-inset-bottom: env(safe-area-inset-bottom);
|
--safe-area-inset-bottom: env(safe-area-inset-bottom);
|
||||||
}
|
}
|
||||||
|
.van-cell.van-field .van-cell__title, .van-cell__value{
|
||||||
|
flex: initial;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
@ -7,7 +7,7 @@ const route = useRoute()
|
|||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const {auctionDetail} = goodStore();
|
const {auctionDetail} = goodStore();
|
||||||
function onBack() {
|
function onBack() {
|
||||||
if (fullLive.value){
|
if (fullLive.value&&route.name==='index'){
|
||||||
fullLive.value=false
|
fullLive.value=false
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -31,7 +31,7 @@ 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.name',route.name)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
106
app/components/liveLoading/index.vue
Normal file
106
app/components/liveLoading/index.vue
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
<template>
|
||||||
|
<div class="custom-loading-container" v-if="loading">
|
||||||
|
<div class="loadingio-spinner-pulse-2by998twmg8">
|
||||||
|
<div class="ldio-yzaezf3dcmj">
|
||||||
|
<div></div>
|
||||||
|
<div></div>
|
||||||
|
<div></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const props = defineProps({
|
||||||
|
loading: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.custom-loading-container {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: rgba(0, 0, 0, 0.7);
|
||||||
|
z-index: 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-text {
|
||||||
|
color: #fff;
|
||||||
|
margin-top: 20px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* loading 动画样式 */
|
||||||
|
@keyframes ldio-yzaezf3dcmj-1 {
|
||||||
|
0% { top: 36px; height: 128px }
|
||||||
|
50% { top: 60px; height: 80px }
|
||||||
|
100% { top: 60px; height: 80px }
|
||||||
|
}
|
||||||
|
@keyframes ldio-yzaezf3dcmj-2 {
|
||||||
|
0% { top: 41.99999999999999px; height: 116.00000000000001px }
|
||||||
|
50% { top: 60px; height: 80px }
|
||||||
|
100% { top: 60px; height: 80px }
|
||||||
|
}
|
||||||
|
@keyframes ldio-yzaezf3dcmj-3 {
|
||||||
|
0% { top: 48px; height: 104px }
|
||||||
|
50% { top: 60px; height: 80px }
|
||||||
|
100% { top: 60px; height: 80px }
|
||||||
|
}
|
||||||
|
|
||||||
|
.ldio-yzaezf3dcmj div {
|
||||||
|
position: absolute;
|
||||||
|
width: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ldio-yzaezf3dcmj div:nth-child(1) {
|
||||||
|
left: 35px;
|
||||||
|
background: #e15b64;
|
||||||
|
animation: ldio-yzaezf3dcmj-1 1s cubic-bezier(0,0.5,0.5,1) infinite;
|
||||||
|
animation-delay: -0.2s
|
||||||
|
}
|
||||||
|
|
||||||
|
.ldio-yzaezf3dcmj div:nth-child(2) {
|
||||||
|
left: 85px;
|
||||||
|
background: #f8b26a;
|
||||||
|
animation: ldio-yzaezf3dcmj-2 1s cubic-bezier(0,0.5,0.5,1) infinite;
|
||||||
|
animation-delay: -0.1s
|
||||||
|
}
|
||||||
|
|
||||||
|
.ldio-yzaezf3dcmj div:nth-child(3) {
|
||||||
|
left: 135px;
|
||||||
|
background: #abbd81;
|
||||||
|
animation: ldio-yzaezf3dcmj-3 1s cubic-bezier(0,0.5,0.5,1) infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loadingio-spinner-pulse-2by998twmg8 {
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
display: inline-block;
|
||||||
|
overflow: hidden;
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ldio-yzaezf3dcmj {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
transform: translateZ(0) scale(1);
|
||||||
|
backface-visibility: hidden;
|
||||||
|
transform-origin: 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ldio-yzaezf3dcmj div {
|
||||||
|
box-sizing: content-box;
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,3 +1,3 @@
|
|||||||
|
|
||||||
export const useAppFooterRouteNames= ['index', 'profile']
|
export const useAppFooterRouteNames= ['index', 'profile']
|
||||||
export const useAppHeaderRouteNames= ['index', 'profile','login','collectCode-login','collectCode-mine']
|
export const useAppHeaderRouteNames= ['index', 'profile','login','collectCode-login','collectCode-mine','payment-result']
|
||||||
|
@ -9,24 +9,29 @@ import {liveStore} from "~/stores/live/index.js";
|
|||||||
const {getAuctionDetail, auctionDetail} = goodStore();
|
const {getAuctionDetail, auctionDetail} = goodStore();
|
||||||
const {fullLive} = liveStore()
|
const {fullLive} = liveStore()
|
||||||
const changeLive = () => {
|
const changeLive = () => {
|
||||||
fullLive.value = true;
|
if (auctionDetail.value.isLiving===1){
|
||||||
};
|
fullLive.value = true;
|
||||||
if (!auctionDetail.value.uuid) {
|
}
|
||||||
await getAuctionDetail()
|
|
||||||
}
|
}
|
||||||
|
await getAuctionDetail()
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="grow-1">
|
<div class="grow-1">
|
||||||
<client-only>
|
<client-only>
|
||||||
<div class="relative" @click="changeLive">
|
<div class="relative" @click="changeLive">
|
||||||
<liveRoom :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"/>
|
<liveRoom :class="['changeLive', fullLive ? 'expanded' : 'collapsed']"/>
|
||||||
<div class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center">
|
<div v-if="auctionDetail.isLiving===1" class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center">
|
||||||
<div class="text-18px mb-5px">{{ auctionDetail.title }}</div>
|
<div class="text-18px mb-5px">{{ auctionDetail.title }}</div>
|
||||||
<div class="text-12px mb-54px">{{ $t('home.text1') }}<van-icon name="arrow" /></div>
|
<div class="text-12px mb-54px">{{ $t('home.text1') }}<van-icon name="arrow" /></div>
|
||||||
<div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ auctionDetail.totalNum }}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div>
|
<div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ auctionDetail.totalNum }}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div>
|
||||||
<div class="text-12px">{{auctionDetail.startDate}} {{$t('home.text2')}}</div>
|
<div class="text-12px">{{auctionDetail.startDate}} {{$t('home.text2')}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-else class="absolute h-188px w-screen pt-36px flex flex-col text-#fff top-0 left-0 items-center bg-[url('@/static/images/z6022@2x.png')]">
|
||||||
|
<div class="text-18px mb-5px">{{ auctionDetail.title }}</div>
|
||||||
|
<div class="text-12px mb-54px">本场拍卖会{{auctionDetail.isLiving===2?'未开始':'已结束'}}</div>
|
||||||
|
<div><span>-</span> <span class="text-12px mx-5px">{{auctionDetail.totalNum}}{{ $t('common.items') }}{{ $t('common.auction') }}</span> <span>-</span></div>
|
||||||
|
<div class="text-12px">{{auctionDetail.startDate}} {{$t('home.text2')}}</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</client-only>
|
</client-only>
|
||||||
<div v-if="!fullLive" class="bg-#fff">
|
<div v-if="!fullLive" class="bg-#fff">
|
||||||
|
@ -54,7 +54,6 @@ const handleCapture = () => {
|
|||||||
onClick:()=>{
|
onClick:()=>{
|
||||||
router.replace('/')
|
router.replace('/')
|
||||||
fullLive.value=true
|
fullLive.value=true
|
||||||
console.log('执行')
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -7,25 +7,42 @@ import xButton from '@/components/x-button/index.vue'
|
|||||||
import tangPopup from './tangPopup.vue'
|
import tangPopup from './tangPopup.vue'
|
||||||
import { goodStore } from "@/stores/goods/index.js"
|
import { goodStore } from "@/stores/goods/index.js"
|
||||||
import { authStore } from "~/stores/auth/index.js"
|
import { authStore } from "~/stores/auth/index.js"
|
||||||
|
import {showMinWindow} from "~/components/liveMinWindow/createMinWindow.js";
|
||||||
|
|
||||||
const { quoteStatus, changeStatus, show, auctionData, getSocketData } = liveStore()
|
const { quoteStatus, changeStatus, show, auctionData, getSocketData ,lastSnapshot,fullLive} = liveStore()
|
||||||
const { pageRef } = goodStore()
|
const { pageRef } = goodStore()
|
||||||
const { userInfo } = authStore()
|
const { userInfo } = authStore()
|
||||||
const showTang = ref(false)
|
const showTang = ref(false)
|
||||||
|
const router = useRouter()
|
||||||
// 拖动相关状态
|
// 拖动相关状态
|
||||||
const isDragging = ref(false)
|
const isDragging = ref(false)
|
||||||
|
const startX = ref(0)
|
||||||
const startY = ref(0)
|
const startY = ref(0)
|
||||||
const currentTop = ref(196) // 初始 top 值
|
const currentTop = ref(196)
|
||||||
|
const currentLeft = ref(window.innerWidth - 60)
|
||||||
const sidebarRef = ref(null)
|
const sidebarRef = ref(null)
|
||||||
|
|
||||||
// 限制拖动范围
|
// 限制拖动范围
|
||||||
const minTop = 0 // 最小 top 值
|
const minTop = 0
|
||||||
const maxTop = window.innerHeight - 180 // 最大 top 值,减去组件高度
|
const maxTop = window.innerHeight - 180
|
||||||
|
const minLeft = 0
|
||||||
|
const maxLeft = window.innerWidth - 60
|
||||||
|
|
||||||
|
// 吸附相关
|
||||||
|
const snapThreshold = 30
|
||||||
|
const snapPosition = () => {
|
||||||
|
const centerX = currentLeft.value + 30
|
||||||
|
if (centerX < window.innerWidth / 2) {
|
||||||
|
currentLeft.value = 0
|
||||||
|
} else {
|
||||||
|
currentLeft.value = window.innerWidth - 60
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 开始拖动
|
// 开始拖动
|
||||||
const handleMouseDown = (e) => {
|
const handleMouseDown = (e) => {
|
||||||
isDragging.value = true
|
isDragging.value = true
|
||||||
|
startX.value = e.clientX - currentLeft.value
|
||||||
startY.value = e.clientY - currentTop.value
|
startY.value = e.clientY - currentTop.value
|
||||||
document.addEventListener('mousemove', handleMouseMove)
|
document.addEventListener('mousemove', handleMouseMove)
|
||||||
document.addEventListener('mouseup', handleMouseUp)
|
document.addEventListener('mouseup', handleMouseUp)
|
||||||
@ -36,26 +53,37 @@ const handleMouseMove = (e) => {
|
|||||||
if (!isDragging.value) return
|
if (!isDragging.value) return
|
||||||
|
|
||||||
let newTop = e.clientY - startY.value
|
let newTop = e.clientY - startY.value
|
||||||
|
let newLeft = e.clientX - startX.value
|
||||||
|
|
||||||
// 限制范围
|
// 限制范围
|
||||||
newTop = Math.max(minTop, Math.min(newTop, maxTop))
|
newTop = Math.max(minTop, Math.min(newTop, maxTop))
|
||||||
|
newLeft = Math.max(minLeft, Math.min(newLeft, maxLeft))
|
||||||
|
|
||||||
currentTop.value = newTop
|
currentTop.value = newTop
|
||||||
|
currentLeft.value = newLeft
|
||||||
|
|
||||||
// 更新位置
|
// 更新位置
|
||||||
if (sidebarRef.value) {
|
if (sidebarRef.value) {
|
||||||
sidebarRef.value.style.top = `${newTop}px`
|
sidebarRef.value.style.top = `${newTop}px`
|
||||||
|
sidebarRef.value.style.left = `${newLeft}px`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 结束拖动
|
// 结束拖动
|
||||||
const handleMouseUp = () => {
|
const handleMouseUp = () => {
|
||||||
isDragging.value = false
|
isDragging.value = false
|
||||||
|
snapPosition()
|
||||||
|
if (sidebarRef.value) {
|
||||||
|
sidebarRef.value.style.left = `${currentLeft.value}px`
|
||||||
|
}
|
||||||
document.removeEventListener('mousemove', handleMouseMove)
|
document.removeEventListener('mousemove', handleMouseMove)
|
||||||
document.removeEventListener('mouseup', handleMouseUp)
|
document.removeEventListener('mouseup', handleMouseUp)
|
||||||
}
|
}
|
||||||
|
|
||||||
// 触摸事件处理(移动端支持)
|
// 触摸事件处理
|
||||||
const handleTouchStart = (e) => {
|
const handleTouchStart = (e) => {
|
||||||
isDragging.value = true
|
isDragging.value = true
|
||||||
|
startX.value = e.touches[0].clientX - currentLeft.value
|
||||||
startY.value = e.touches[0].clientY - currentTop.value
|
startY.value = e.touches[0].clientY - currentTop.value
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,22 +91,68 @@ const handleTouchMove = (e) => {
|
|||||||
if (!isDragging.value) return
|
if (!isDragging.value) return
|
||||||
|
|
||||||
let newTop = e.touches[0].clientY - startY.value
|
let newTop = e.touches[0].clientY - startY.value
|
||||||
|
let newLeft = e.touches[0].clientX - startX.value
|
||||||
|
|
||||||
newTop = Math.max(minTop, Math.min(newTop, maxTop))
|
newTop = Math.max(minTop, Math.min(newTop, maxTop))
|
||||||
|
newLeft = Math.max(minLeft, Math.min(newLeft, maxLeft))
|
||||||
|
|
||||||
currentTop.value = newTop
|
currentTop.value = newTop
|
||||||
|
currentLeft.value = newLeft
|
||||||
|
|
||||||
if (sidebarRef.value) {
|
if (sidebarRef.value) {
|
||||||
sidebarRef.value.style.top = `${newTop}px`
|
sidebarRef.value.style.top = `${newTop}px`
|
||||||
|
sidebarRef.value.style.left = `${newLeft}px`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleTouchEnd = () => {
|
const handleTouchEnd = () => {
|
||||||
isDragging.value = false
|
isDragging.value = false
|
||||||
|
snapPosition()
|
||||||
|
if (sidebarRef.value) {
|
||||||
|
sidebarRef.value.style.left = `${currentLeft.value}px`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const captureVideoFrame = () => {
|
||||||
|
try {
|
||||||
|
const video = document.querySelector('#J_prismPlayer video')
|
||||||
|
if (!video) {
|
||||||
|
console.error('未找到视频元素')
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const canvas = document.createElement('canvas')
|
||||||
|
canvas.width = video.videoWidth
|
||||||
|
canvas.height = video.videoHeight
|
||||||
|
|
||||||
|
const ctx = canvas.getContext('2d')
|
||||||
|
ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
|
||||||
|
return canvas.toDataURL('image/jpeg', 0.9)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('获取视频截图失败:', error)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCapture = () => {
|
||||||
|
const imageUrl = captureVideoFrame()
|
||||||
|
if (imageUrl) {
|
||||||
|
lastSnapshot.value=imageUrl
|
||||||
|
showMinWindow(lastSnapshot.value,{
|
||||||
|
onClick:()=>{
|
||||||
|
router.replace('/')
|
||||||
|
fullLive.value=true
|
||||||
|
console.log('执行')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 组件挂载时添加事件监听
|
// 组件挂载时添加事件监听
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (sidebarRef.value) {
|
if (sidebarRef.value) {
|
||||||
sidebarRef.value.style.top = `${currentTop.value}px`
|
sidebarRef.value.style.top = `${currentTop.value}px`
|
||||||
|
sidebarRef.value.style.left = `${currentLeft.value}px`
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -102,14 +176,15 @@ const paySide = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const goPay = () => {
|
const goPay = () => {
|
||||||
show.value = true
|
handleCapture()
|
||||||
|
router.push('/signature/protocol')
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
ref="sidebarRef"
|
ref="sidebarRef"
|
||||||
class="bg-white w-60px rounded-l-4px overflow-hidden absolute right-0 z-999 cursor-move"
|
class="bg-white w-60px rounded-4px overflow-hidden absolute z-999 cursor-move"
|
||||||
@mousedown="handleMouseDown"
|
@mousedown="handleMouseDown"
|
||||||
@touchstart="handleTouchStart"
|
@touchstart="handleTouchStart"
|
||||||
@touchmove="handleTouchMove"
|
@touchmove="handleTouchMove"
|
||||||
@ -160,8 +235,8 @@ const goPay = () => {
|
|||||||
@click="goPay"
|
@click="goPay"
|
||||||
>
|
>
|
||||||
<div class="text-center flex flex-col justify-center items-center text-yellow-600">
|
<div class="text-center flex flex-col justify-center items-center text-yellow-600">
|
||||||
<div class="text-10px">RMB</div>
|
<div class="text-10px">{{auctionData?.nowAuctionPrice?.currency}}</div>
|
||||||
<div class="text-12px">5,000</div>
|
<div class="text-12px">{{auctionData?.nowAuctionPrice?.successPrice}}</div>
|
||||||
<div class="text-10px">{{ $t('art_detail_page.button') }}</div>
|
<div class="text-10px">{{ $t('art_detail_page.button') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</van-button>
|
</van-button>
|
||||||
@ -173,5 +248,6 @@ const goPay = () => {
|
|||||||
cursor: move;
|
cursor: move;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
touch-action: none;
|
touch-action: none;
|
||||||
|
transition: left 0.3s ease;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
@ -1,10 +1,11 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import {ref, onMounted, onBeforeUnmount, watch} from 'vue'
|
import {ref, onMounted, onBeforeUnmount, watch} from 'vue'
|
||||||
import Aliplayer from 'aliyun-aliplayer'
|
import AliyunPlayer from 'aliyun-aliplayer'
|
||||||
import 'aliyun-aliplayer/build/skins/default/aliplayer-min.css'
|
import 'aliyun-aliplayer/build/skins/default/aliplayer-min.css'
|
||||||
import sideButton from '@/pages/liveRoom/components/SideButton/index.vue'
|
import sideButton from '@/pages/liveRoom/components/SideButton/index.vue'
|
||||||
import broadcast from '@/pages/liveRoom/components/Broadcast/index.vue'
|
import broadcast from '@/pages/liveRoom/components/Broadcast/index.vue'
|
||||||
import {liveStore} from "@/stores/live/index.js"
|
import {liveStore} from "@/stores/live/index.js"
|
||||||
|
import liveLoading from '@/components/liveLoading/index.vue'
|
||||||
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 {goodStore} from "@/stores/goods/index.js"
|
import {goodStore} from "@/stores/goods/index.js"
|
||||||
@ -12,67 +13,98 @@ import {message} from "~/components/x-message/useMessage.js"
|
|||||||
import {showConfirmDialog} from 'vant';
|
import {showConfirmDialog} from 'vant';
|
||||||
import {artworkBuy} from "@/api/goods/index.js"
|
import {artworkBuy} from "@/api/goods/index.js"
|
||||||
import {useI18n} from 'vue-i18n'
|
import {useI18n} from 'vue-i18n'
|
||||||
import gsap from 'gsap'
|
|
||||||
import {CountUp} from 'countup.js'
|
import {CountUp} from 'countup.js'
|
||||||
|
const { t } = useI18n()
|
||||||
const countUpRef = ref(null)
|
const countUpRef = ref(null)
|
||||||
const nextPriceRef = ref(null)
|
const nextPriceRef = ref(null)
|
||||||
|
const { auctionDetail} = goodStore();
|
||||||
const player = ref(null)
|
const player = ref(null)
|
||||||
const {quoteStatus, show, playerId, show1, auctionData, getSocketData, getLiveLink, fullLive} = liveStore()
|
const {quoteStatus, show, playerId, show1, auctionData, getSocketData, getLiveLink, fullLive} = liveStore()
|
||||||
const pullLink = ref('')
|
const pullLink = ref('')
|
||||||
|
|
||||||
definePageMeta({
|
|
||||||
i18n: 'login.title',
|
|
||||||
})
|
|
||||||
const handlePlayerError = (error) => {
|
const handlePlayerError = (error) => {
|
||||||
console.error('播放器错误:', error)
|
console.error('播放器错误:', error)
|
||||||
player.value?.play()
|
player.value?.play()
|
||||||
}
|
}
|
||||||
|
const loading1=ref(false)
|
||||||
const initializePlayer = async () => {
|
const initializePlayer = async () => {
|
||||||
try {
|
try {
|
||||||
if (player.value) {
|
if (player.value) {
|
||||||
player.value.dispose()
|
player.value.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 判断是否是微信浏览器
|
||||||
|
const isWechat = /MicroMessenger/i.test(navigator.userAgent)
|
||||||
|
|
||||||
const playerConfig = {
|
const playerConfig = {
|
||||||
id: playerId.value,
|
id: playerId.value,
|
||||||
source: pullLink.value,
|
source: pullLink.value,
|
||||||
isLive: true,
|
isLive: true,
|
||||||
preload: true,
|
preload: true,
|
||||||
autoplay: false,
|
autoplay: true, // 改为 true
|
||||||
|
muted: true, // 默认静音
|
||||||
|
diagnosisButtonVisible:false,
|
||||||
autoplayPolicy: {
|
autoplayPolicy: {
|
||||||
fallbackToMute: true, // 有声自动播放失败后,是否降级为静音自动播放,默认为false
|
fallbackToMute: true
|
||||||
showUnmuteBtn: true, // 静音自动播放时,是否居中显示静音大按钮,默认为true
|
|
||||||
},
|
},
|
||||||
|
width: '100%', //容器的大小
|
||||||
|
height: '100%', //容器的大小
|
||||||
|
skinLayout: false,
|
||||||
controlBarVisibility: 'never',
|
controlBarVisibility: 'never',
|
||||||
|
license: {
|
||||||
|
domain: "szjixun.cn",
|
||||||
|
key: "OProxmWaOZ2XVHXLtf4030126521c43429403194970aa8af9"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
player.value = new Aliplayer(playerConfig, (playerInstance) => {
|
|
||||||
|
player.value = new AliyunPlayer(playerConfig, (playerInstance) => {
|
||||||
|
// 在微信环境下,需要用户手动触发播放
|
||||||
|
if (isWechat) {
|
||||||
|
console.log('当前是微信浏览器环境')
|
||||||
|
const startPlay = () => {
|
||||||
|
console.log('执行了startPlay')
|
||||||
|
playerInstance?.play()
|
||||||
|
document.removeEventListener('WeixinJSBridgeReady', startPlay)
|
||||||
|
document.removeEventListener('touchstart', startPlay)
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener('WeixinJSBridgeReady', startPlay)
|
||||||
|
document.addEventListener('touchstart', startPlay)
|
||||||
|
}
|
||||||
|
loading1.value = true
|
||||||
playerInstance?.play()
|
playerInstance?.play()
|
||||||
})
|
})
|
||||||
|
player.value.on('playing', () => {
|
||||||
|
console.log('playing')
|
||||||
|
loading1.value = false
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
player.value.on('error', handlePlayerError)
|
player.value.on('error', handlePlayerError)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
showConfirmDialog({
|
showConfirmDialog({
|
||||||
message: useI18n().t('live_room.error_mess'),
|
message: t('live_room.error_mess'),
|
||||||
showCancelButton: true
|
showCancelButton: true
|
||||||
|
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
location.reload()
|
location.reload()
|
||||||
// on close
|
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
// on cancel
|
|
||||||
})
|
})
|
||||||
console.error('播放器初始化失败:', error)
|
console.error('播放器初始化失败:', error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 添加取消静音方法
|
||||||
|
const unmutePlayer = () => {
|
||||||
|
if (player.value) {
|
||||||
|
player.value.muted = false
|
||||||
|
player.value.play()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
pullLink.value = await getLiveLink()
|
pullLink.value = await getLiveLink()
|
||||||
initializePlayer()
|
if (auctionDetail.value.isLiving===1){
|
||||||
|
initializePlayer()
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
@ -80,8 +112,6 @@ onBeforeUnmount(() => {
|
|||||||
player.value = null
|
player.value = null
|
||||||
})
|
})
|
||||||
const createCountUp = (element, value, options = {}) => {
|
const createCountUp = (element, value, options = {}) => {
|
||||||
console.log('element', element)
|
|
||||||
console.log('value', value)
|
|
||||||
const defaultOptions = {
|
const defaultOptions = {
|
||||||
duration: 1.5,
|
duration: 1.5,
|
||||||
separator: ',',
|
separator: ',',
|
||||||
@ -107,53 +137,61 @@ watch(() => fullLive.value, async (newVal) => {
|
|||||||
|
|
||||||
})
|
})
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
createCountUp(countUpRef.value, auctionData.value?.nowAuctionPrice?.nowPrice)
|
if (!fullLive.value) return
|
||||||
|
nextTick(()=>{
|
||||||
|
createCountUp(countUpRef.value, auctionData.value?.nowAuctionPrice?.nowPrice)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
|
if (!fullLive.value) return
|
||||||
|
nextTick(()=>{
|
||||||
createCountUp(nextPriceRef.value, auctionData.value?.nowAuctionPrice?.nextPrice)
|
createCountUp(nextPriceRef.value, auctionData.value?.nowAuctionPrice?.nextPrice)
|
||||||
})
|
})
|
||||||
|
})
|
||||||
const goBuy = async () => {
|
const goBuy = async () => {
|
||||||
const res = await artworkBuy({
|
const res = await artworkBuy({
|
||||||
auctionArtworkUuid: auctionData.value?.artwork?.uuid,
|
auctionArtworkUuid: auctionData.value?.artwork?.uuid,
|
||||||
buyMoney: String(auctionData.value?.nowAuctionPrice?.nextPrice ?? 0)
|
buyMoney: String(auctionData.value?.nowAuctionPrice?.nextPrice ?? 0)
|
||||||
})
|
})
|
||||||
if (res.status === 0) {
|
if (res.status === 0) {
|
||||||
message.success(useI18n().t('live_room.success_mess'))
|
message.success(t('live_room.success_mess'))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const tipOpen = () => {
|
const tipOpen = () => {
|
||||||
message.warning(useI18n().t('live_room.warn_mess'))
|
message.warning(t('live_room.warn_mess'))
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="relative h-full">
|
<div class="relative h-full">
|
||||||
<div :id="playerId" class="w-full h-full"></div>
|
<div :id="playerId" class="w-full h-full"></div>
|
||||||
|
<liveLoading :loading="loading1"></liveLoading>
|
||||||
|
|
||||||
<transition name="fade">
|
<transition name="fade">
|
||||||
<div v-if="fullLive">
|
<div v-if="fullLive">
|
||||||
<sideButton class="absolute top-196px right-0 z-999"></sideButton>
|
<sideButton class="absolute top-196px right-0 z-999"></sideButton>
|
||||||
<div class="absolute left-1/2 transform -translate-x-1/2 flex flex-col items-center"
|
<div class="absolute left-1/2 transform -translate-x-1/2 flex flex-col items-center"
|
||||||
style="bottom:calc(var(--safe-area-inset-bottom) + 26px)">
|
style="bottom:calc(var(--safe-area-inset-bottom) + 26px)">
|
||||||
<div class="text-16px text-#FFB25F font-600 flex">
|
<div class="text-16px text-#FFB25F font-600 flex">
|
||||||
<div class="mr-5px">{{ $t('live_room.now_price') }}:{{ auctionData?.nowAuctionPrice?.currency }}</div>
|
<div class="mr-5px">{{ t('live_room.now_price') }}:{{ auctionData?.nowAuctionPrice?.currency }}</div>
|
||||||
<div ref="countUpRef" class="min-w-50px"></div>
|
<div ref="countUpRef" class="min-w-50px"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-16px text-#fff font-600 flex">
|
<div class="text-16px text-#fff font-600 flex">
|
||||||
<div class="mr-5px">{{ $t('live_room.lower_price') }}:{{ auctionData?.nowAuctionPrice?.currency }}</div>
|
<div class="mr-5px">{{ t('live_room.lower_price') }}:{{ auctionData?.nowAuctionPrice?.currency }}</div>
|
||||||
<div ref="nextPriceRef" class="min-w-50px"></div>
|
<div ref="nextPriceRef" class="min-w-50px"></div>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="quoteStatus" class="mt-10px mb-10px">
|
<div v-if="quoteStatus" class="mt-10px mb-10px">
|
||||||
<van-button @click="goBuy" color="#FFB25F" class="w-344px !h-[40px]">
|
<van-button @click="goBuy" color="#FFB25F" class="w-344px !h-[40px]">
|
||||||
<div>{{
|
<div>{{
|
||||||
$t('live_room.confirm')` ${auctionData?.nowAuctionPrice?.currency} ${auctionData?.nowAuctionPrice?.nextPrice ?? 0}`
|
`${t('live_room.confirm')} ${auctionData?.nowAuctionPrice?.currency} ${auctionData?.nowAuctionPrice?.nextPrice ?? 0}`
|
||||||
}}
|
}}
|
||||||
</div>
|
</div>
|
||||||
</van-button>
|
</van-button>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="mt-10px mb-10px">
|
<div v-if="!quoteStatus" class="mt-10px mb-10px">
|
||||||
<van-button @click="tipOpen" color="#D6D6D8" class="w-344px !h-[40px]" v-if="!quoteStatus">
|
<van-button @click="tipOpen" color="#D6D6D8" class="w-344px !h-[40px]" >
|
||||||
<div class="text-#7D7D7F text-14px">{{ $t('live_room.button') }}</div>
|
<div class="text-#7D7D7F text-14px">{{ t('live_room.button') }}</div>
|
||||||
</van-button>
|
</van-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -167,30 +205,18 @@ const tipOpen = () => {
|
|||||||
class="w-344px h-31px rounded-4px absolute top-9px bg-[#151824]/45 backdrop-blur-[10px] backdrop-saturate-[180%] left-1/2 transform translate-x--1/2 flex text-#fff text-14px items-center px-12px line-height-none">
|
class="w-344px h-31px rounded-4px absolute top-9px bg-[#151824]/45 backdrop-blur-[10px] backdrop-saturate-[180%] left-1/2 transform translate-x--1/2 flex text-#fff text-14px items-center px-12px line-height-none">
|
||||||
<div class="mr-11px whitespace-nowrap">LOT{{ auctionData.artwork.index }}</div>
|
<div class="mr-11px whitespace-nowrap">LOT{{ auctionData.artwork.index }}</div>
|
||||||
<div class="mr-10px truncate">{{ auctionData.artwork.name }}</div>
|
<div class="mr-10px truncate">{{ auctionData.artwork.name }}</div>
|
||||||
<div class="whitespace-nowrap">{{ $t('live_room.start') }}</div>
|
<div class="whitespace-nowrap">{{ t('live_room.start') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
#J_prismPlayer {
|
|
||||||
width: 100%;
|
|
||||||
height: 100% !important;
|
|
||||||
|
|
||||||
& > video {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
/* 定义过渡动画 */
|
/* 定义过渡动画 */
|
||||||
.fade-enter-active {
|
.fade-enter-active {
|
||||||
transition: opacity 1.5s ease;
|
transition: opacity 1s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fade-leave-active {
|
.fade-leave-active {
|
||||||
|
15
app/pages/payment/external/index.vue
vendored
Normal file
15
app/pages/payment/external/index.vue
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
<script setup>
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<iframe>
|
||||||
|
|
||||||
|
</iframe>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
69
app/pages/payment/index.vue
Normal file
69
app/pages/payment/index.vue
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
<script setup>
|
||||||
|
import {liveStore} from "~/stores/live/index.js";
|
||||||
|
import {createBuyOrder} from "~/api/goods/index.js";
|
||||||
|
import {goodStore} from "~/stores/goods/index.js";
|
||||||
|
import { showLoadingToast ,closeToast} from 'vant';
|
||||||
|
import {authStore} from "~/stores/auth/index.js";
|
||||||
|
const {checkoutSessionUrl}= authStore()
|
||||||
|
const payStatus=ref(0)
|
||||||
|
const changePayStatus=()=>{
|
||||||
|
payStatus.value=payStatus.value===0?1:0
|
||||||
|
}
|
||||||
|
const { auctionData} = liveStore()
|
||||||
|
const validateInput = (e) => {
|
||||||
|
const value = e.target.value
|
||||||
|
const char = String.fromCharCode(e.charCode)
|
||||||
|
|
||||||
|
if (!/[\d.]/.test(char)) {
|
||||||
|
e.preventDefault()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (char === '.' && (value.includes('.') || !value)) {
|
||||||
|
e.preventDefault()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (value.includes('.') && value.split('.')[1]?.length >= 2) {
|
||||||
|
e.preventDefault()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const confirmPay=async ()=>{
|
||||||
|
showLoadingToast({
|
||||||
|
message: '加载中...',
|
||||||
|
forbidClick: true,
|
||||||
|
});
|
||||||
|
const res=await createBuyOrder({
|
||||||
|
buyUid:auctionData.value?.nowAuctionPrice?.successBuyUuid,
|
||||||
|
price:String(auctionData.value?.nowAuctionPrice?.successPrice),
|
||||||
|
currency:auctionData.value?.nowAuctionPrice?.currency
|
||||||
|
})
|
||||||
|
if (res.status===0){
|
||||||
|
window.location.href=res.data.checkoutSessionUrl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="w-[100vw] h-screen-nav bg-[url('@/static/images/3532@2x.png')] bg-cover flex-grow-1 flex flex-col items-center pt-183px px-30px">
|
||||||
|
<div class="mb-30px">
|
||||||
|
<img class="w-126px h-126px" src="@/static/images/dddf34@2x.png" alt="">
|
||||||
|
</div>
|
||||||
|
<div class="text-#1A1A1A text-16px mb-25px font-bold">{{payStatus===0?'支付全部':'支付部分'}}</div>
|
||||||
|
<div class="text-#999999 text-16px mb-24px font-bold" v-if="payStatus===0">{{auctionData?.nowAuctionPrice?.currency}} {{auctionData?.nowAuctionPrice?.successPrice}}</div>
|
||||||
|
<div class="mb-12px" v-else>
|
||||||
|
<input class="w-272px h-48px bg-#F3F3F3 px-11px text-16px" type="text" :placeholder="`最多${auctionData?.nowAuctionPrice?.currency}${auctionData?.nowAuctionPrice?.successPrice}`" @keydown="validateInput">
|
||||||
|
</div>
|
||||||
|
<div class="text-#2B53AC text-14px" @click="changePayStatus">{{payStatus===1?'支付全部':'支付部分'}}</div>
|
||||||
|
<div class="w-full mt-auto mb-40px">
|
||||||
|
<van-button type="primary" block @click="confirmPay">
|
||||||
|
确认支付
|
||||||
|
</van-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
44
app/pages/payment/result/index.vue
Normal file
44
app/pages/payment/result/index.vue
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<script setup>
|
||||||
|
import {orderQuery} from "~/api/goods/index.js";
|
||||||
|
definePageMeta({
|
||||||
|
i18n: 'payment.text1',
|
||||||
|
})
|
||||||
|
const router = useRouter()
|
||||||
|
const {t}=useI18n();
|
||||||
|
const route = useRoute();
|
||||||
|
const resData=ref({})
|
||||||
|
const res=await orderQuery({
|
||||||
|
orderNo:route.query.orderNo
|
||||||
|
})
|
||||||
|
if (res.status===0){
|
||||||
|
resData.value=res.data
|
||||||
|
}
|
||||||
|
const statusLabel={
|
||||||
|
1:t('payment.text2'),
|
||||||
|
2:t('payment.text3'),
|
||||||
|
3:t('payment.text4'),
|
||||||
|
4:t('payment.text5'),
|
||||||
|
}
|
||||||
|
const goHome=()=>{
|
||||||
|
router.push('/')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="w-[100vw] h-screen-nav bg-[url('@/static/images/3532@2x.png')] bg-cover grow-1 flex flex-col items-center px-30px">
|
||||||
|
<div class="flex flex-col items-center mt-150px">
|
||||||
|
<img class="w-119px h-120px mb-36px" src="@/static/images/5554@2x1.png" alt="">
|
||||||
|
<div class="text-#000 text-16px mb-25px">{{statusLabel[resData.status]}}!</div>
|
||||||
|
<div class="text-#999 text-16px">{{resData.currency}}{{resData.money}}</div>
|
||||||
|
</div>
|
||||||
|
<div class="w-full mt-auto mb-40px">
|
||||||
|
<van-button type="primary" block @click="goHome">
|
||||||
|
回到首页
|
||||||
|
</van-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
</style>
|
@ -8,7 +8,7 @@ definePageMeta({
|
|||||||
layout: 'default',
|
layout: 'default',
|
||||||
i18n: 'menu.profile',
|
i18n: 'menu.profile',
|
||||||
})
|
})
|
||||||
|
const {t}=useI18n();
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const { userInfo } = authStore()
|
const { userInfo } = authStore()
|
||||||
const showMyList = ref([])
|
const showMyList = ref([])
|
||||||
@ -47,9 +47,19 @@ const onRefresh = async () => {
|
|||||||
localState.value.refreshing = false
|
localState.value.refreshing = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const goPay = () => router.push('/signature/protocol')
|
const goPay = (status) => {
|
||||||
|
if (status===1){
|
||||||
|
router.push('/signature/protocol')
|
||||||
|
}else if (status===4){
|
||||||
|
router.push('/payment')
|
||||||
|
}
|
||||||
|
}
|
||||||
const goDetail = (item) => router.push({ path: '/artDetail', query: { uuid: item.uuid } })
|
const goDetail = (item) => router.push({ path: '/artDetail', query: { uuid: item.uuid } })
|
||||||
|
const statusLabel={
|
||||||
|
1:t('payment.text4'),
|
||||||
|
2:t('payment.text2'),
|
||||||
|
4:t('payment.text6'),
|
||||||
|
}
|
||||||
fetchData()
|
fetchData()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -109,17 +119,17 @@ fetchData()
|
|||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
<div>
|
<div>
|
||||||
<div class="text-#575757 text-14px line-height-none mb-5px">
|
<div class="text-#575757 text-14px line-height-none mb-5px">
|
||||||
{{ $t('home.start_price') }}:RMB 1,000
|
{{ $t('home.start_price') }}:{{item.auctionArtworkInfo?.soldPriceCurrency}} {{item.auctionArtworkInfo?.soldPrice}}
|
||||||
</div>
|
</div>
|
||||||
<div class="text-#B58047 text-14px line-height-none">
|
<div class="text-#B58047 text-14px line-height-none">
|
||||||
{{ $t('home.close_price') }}:RMB 10,000
|
{{ $t('home.close_price') }}:{{item.baseCurrency}} {{item.baseMoney}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<van-button
|
<van-button
|
||||||
v-if="[1,3,4].includes(item.status)"
|
v-if="[1,3,4].includes(item.status)"
|
||||||
class="w-73px !h-30px"
|
class="w-73px !h-30px"
|
||||||
type="primary"
|
type="primary"
|
||||||
@click.stop="goPay"
|
@click.stop="goPay(item.status)"
|
||||||
>
|
>
|
||||||
<span class="text-12px">{{ $t('art_detail_page.button') }}</span>
|
<span class="text-12px">{{ $t('art_detail_page.button') }}</span>
|
||||||
</van-button>
|
</van-button>
|
||||||
|
@ -60,8 +60,8 @@ const confirm=async ()=>{
|
|||||||
message.success(t('realAuth.success_mess'))
|
message.success(t('realAuth.success_mess'))
|
||||||
const res1=await fddCheck()
|
const res1=await fddCheck()
|
||||||
if (res1.status===0){
|
if (res1.status===0){
|
||||||
if (!res1.data.isNeedJump){
|
if (res1.data.isNeedJump){
|
||||||
window.open(res1.data.h5Url)
|
window.location.href=res1.data.h5Url
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -145,9 +145,7 @@ const goLogin=()=>{
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
:deep(.van-cell__title.van-field__label){
|
|
||||||
width: 80px;
|
|
||||||
}
|
|
||||||
:deep(.van-tabs__line) {
|
:deep(.van-tabs__line) {
|
||||||
height: 2px;
|
height: 2px;
|
||||||
width: 107px;
|
width: 107px;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import {showToast} from 'vant';
|
import {showToast} from 'vant';
|
||||||
import {onMounted, onUnmounted, ref} from 'vue';
|
import {onMounted, onUnmounted, ref} from 'vue';
|
||||||
import {signOffline} from "~/api/goods/index.js";
|
import {signOffline, signOnline} from "~/api/goods/index.js";
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
definePageMeta({
|
definePageMeta({
|
||||||
layout: ''
|
layout: ''
|
||||||
@ -56,12 +56,14 @@ const handleSignatureSubmit = async (data) => {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
const confirm = async () => {
|
|
||||||
const res = await signOffline({
|
|
||||||
signImgFileData: data.image
|
|
||||||
})
|
|
||||||
|
|
||||||
console.log('res', res)
|
const confirm = async () => {
|
||||||
|
const res = await signOnline({
|
||||||
|
signImgFileData: imgUrl.value
|
||||||
|
})
|
||||||
|
if (res.status===0){
|
||||||
|
router.push('/payment')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const goBack = () => {
|
const goBack = () => {
|
||||||
router.back()
|
router.back()
|
||||||
|
BIN
app/static/images/5554@2x1.png
Normal file
BIN
app/static/images/5554@2x1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
BIN
app/static/images/z6022@2x.png
Normal file
BIN
app/static/images/z6022@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 485 KiB |
@ -4,7 +4,9 @@ export const authStore = createGlobalState(() => {
|
|||||||
const RefreshToken=useLocalStorage('RefreshToken','')
|
const RefreshToken=useLocalStorage('RefreshToken','')
|
||||||
const userInfo=useLocalStorage('userInfo',{})
|
const userInfo=useLocalStorage('userInfo',{})
|
||||||
const fingerprint=useLocalStorage('fingerprint','')
|
const fingerprint=useLocalStorage('fingerprint','')
|
||||||
|
const checkoutSessionUrl=useLocalStorage('checkoutSessionUrl','')
|
||||||
return{
|
return{
|
||||||
|
checkoutSessionUrl,
|
||||||
userInfo,
|
userInfo,
|
||||||
RefreshToken,
|
RefreshToken,
|
||||||
token,
|
token,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { createGlobalState } from '@vueuse/core'
|
import {createGlobalState, useLocalStorage} from '@vueuse/core'
|
||||||
import {ref} from "vue";
|
import {ref} from "vue";
|
||||||
import {goodStore} from "@/stores/goods/index.js";
|
import {goodStore} from "@/stores/goods/index.js";
|
||||||
import {authStore} from "@/stores/auth/index.js";
|
import {authStore} from "@/stores/auth/index.js";
|
||||||
@ -17,7 +17,7 @@ export const liveStore = createGlobalState(() => {
|
|||||||
const cleanup = ref(null)
|
const cleanup = ref(null)
|
||||||
const show1=ref(false)
|
const show1=ref(false)
|
||||||
const playerId=ref('J_prismPlayer')
|
const playerId=ref('J_prismPlayer')
|
||||||
const auctionData=ref({})
|
const auctionData=useLocalStorage('auctionData',{})
|
||||||
const socket=ref(null)
|
const socket=ref(null)
|
||||||
const config = useRuntimeConfig()
|
const config = useRuntimeConfig()
|
||||||
const pullLink=ref('')
|
const pullLink=ref('')
|
||||||
@ -198,6 +198,7 @@ export const liveStore = createGlobalState(() => {
|
|||||||
|
|
||||||
ws.onMessage((data) => {
|
ws.onMessage((data) => {
|
||||||
auctionData.value = data.data
|
auctionData.value = data.data
|
||||||
|
console.log(' auctionData.value', auctionData.value)
|
||||||
const { wsType, tip } = data.data || {}
|
const { wsType, tip } = data.data || {}
|
||||||
|
|
||||||
switch (wsType) {
|
switch (wsType) {
|
||||||
@ -234,7 +235,7 @@ export const liveStore = createGlobalState(() => {
|
|||||||
}
|
}
|
||||||
const changeStatus = () => {
|
const changeStatus = () => {
|
||||||
if (auctionData.value.artwork.isSelling&&!auctionData.value.artwork.isSoled){
|
if (auctionData.value.artwork.isSelling&&!auctionData.value.artwork.isSoled){
|
||||||
quoteStatus.value = true
|
quoteStatus.value = !quoteStatus.value
|
||||||
}else {
|
}else {
|
||||||
if (quoteStatus.value){
|
if (quoteStatus.value){
|
||||||
quoteStatus.value = false
|
quoteStatus.value = false
|
||||||
|
@ -140,11 +140,20 @@
|
|||||||
"text7": "请期待下个拍品",
|
"text7": "请期待下个拍品",
|
||||||
"text8": "很遗憾,竞拍失败",
|
"text8": "很遗憾,竞拍失败",
|
||||||
"text9": "竞拍结束",
|
"text9": "竞拍结束",
|
||||||
"text10": "竞拍结束,谢谢参与",
|
"text10": "竞拍结束,谢谢参与"
|
||||||
},
|
},
|
||||||
"personal": {
|
"personal": {
|
||||||
"title": "请填写个人相关信息",
|
"title": "请填写个人相关信息",
|
||||||
"text":"文本",
|
"text":"文本",
|
||||||
"next": "下一步"
|
"next": "下一步"
|
||||||
|
},
|
||||||
|
"payment": {
|
||||||
|
"text1": "支付结果",
|
||||||
|
"text2":"支付成功",
|
||||||
|
"text3":"支付失败",
|
||||||
|
"text4":"未支付",
|
||||||
|
"text5":"支付过期",
|
||||||
|
"next": "下一步",
|
||||||
|
"text6": "部分支付"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -28,7 +28,6 @@
|
|||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
"gsap": "^3.12.7",
|
|
||||||
"nuxt": "^3.15.0",
|
"nuxt": "^3.15.0",
|
||||||
"pinyin": "4.0.0-alpha.2",
|
"pinyin": "4.0.0-alpha.2",
|
||||||
"qrcode": "^1.5.4",
|
"qrcode": "^1.5.4",
|
||||||
|
@ -38,9 +38,6 @@ importers:
|
|||||||
dotenv:
|
dotenv:
|
||||||
specifier: ^16.4.7
|
specifier: ^16.4.7
|
||||||
version: 16.4.7
|
version: 16.4.7
|
||||||
gsap:
|
|
||||||
specifier: ^3.12.7
|
|
||||||
version: 3.12.7
|
|
||||||
nuxt:
|
nuxt:
|
||||||
specifier: ^3.15.0
|
specifier: ^3.15.0
|
||||||
version: 3.15.4(@parcel/watcher@2.5.1)(@types/node@22.13.4)(db0@0.2.4)(eslint@9.20.1(jiti@2.4.2))(ioredis@5.5.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.34.6)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(typescript@5.7.3)(vite@6.1.0(@types/node@22.13.4)(jiti@2.4.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(yaml@2.7.0)
|
version: 3.15.4(@parcel/watcher@2.5.1)(@types/node@22.13.4)(db0@0.2.4)(eslint@9.20.1(jiti@2.4.2))(ioredis@5.5.0)(magicast@0.3.5)(optionator@0.9.4)(rollup@4.34.6)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(typescript@5.7.3)(vite@6.1.0(@types/node@22.13.4)(jiti@2.4.2)(sass@1.85.0)(terser@5.39.0)(tsx@4.19.2)(yaml@2.7.0))(yaml@2.7.0)
|
||||||
@ -2605,9 +2602,6 @@ packages:
|
|||||||
graceful-fs@4.2.11:
|
graceful-fs@4.2.11:
|
||||||
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
|
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
|
||||||
|
|
||||||
gsap@3.12.7:
|
|
||||||
resolution: {integrity: sha512-V4GsyVamhmKefvcAKaoy0h6si0xX7ogwBoBSs2CTJwt7luW0oZzC0LhdkyuKV8PJAXr7Yaj8pMjCKD4GJ+eEMg==}
|
|
||||||
|
|
||||||
gzip-size@6.0.0:
|
gzip-size@6.0.0:
|
||||||
resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==}
|
resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@ -7434,8 +7428,6 @@ snapshots:
|
|||||||
|
|
||||||
graceful-fs@4.2.11: {}
|
graceful-fs@4.2.11: {}
|
||||||
|
|
||||||
gsap@3.12.7: {}
|
|
||||||
|
|
||||||
gzip-size@6.0.0:
|
gzip-size@6.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
duplexer: 0.1.2
|
duplexer: 0.1.2
|
||||||
|
Loading…
Reference in New Issue
Block a user