feat(collectCode): 优化收款二维码功能

- 新增二维码生成和预览功能
- 添加拍品号验证逻辑
- 优化对话框样式和交互
-调整 API 调用方式
This commit is contained in:
xingyy 2025-02-10 15:47:26 +08:00
parent 34add8d226
commit 69ad600f0d
12 changed files with 345 additions and 122 deletions

View File

@ -12,6 +12,7 @@ const show = computed(() => {
const initData=()=>{
active.value=route.path==='/profile'?1:0
}
watchEffect(initData)
onMounted(()=>{
initData()
})

View File

@ -1,37 +1,101 @@
<script setup>
import itemDetail from '@/components/itemDetail/index.vue'
import {userArtwork} from "~/api/goods/index.js";
const route = useRoute()
const detail=ref({})
const uuid = route.query.uuid
const initData=async ()=>{
const res=await userArtwork({uuid})
if (res.status===0){
detail.value=res.data
const route = useRoute()
const detail = ref({})
const uuid = route.query.uuid
const initData = async () => {
const res = await userArtwork({uuid})
if (res.status === 0) {
detail.value = res.data
}
}
const position = ref({x: window?.innerWidth - 120 || 0, y: 240}) //
const startPosition = ref({x: 0, y: 0})
const isDragging = ref(false)
const startDrag = (e) => {
isDragging.value = true
const clientX = e.touches ? e.touches[0].clientX : e.clientX
const clientY = e.touches ? e.touches[0].clientY : e.clientY
startPosition.value = {
x: clientX - position.value.x,
y: clientY - position.value.y
}
}
const onDrag = (e) => {
if (isDragging.value) {
const clientX = e.touches ? e.touches[0].clientX : e.clientX
const clientY = e.touches ? e.touches[0].clientY : e.clientY
//
const maxX = window.innerWidth - 108 //
const maxY = window.innerHeight - 137 //
//
const x = Math.min(Math.max(0, clientX - startPosition.value.x), maxX)
const y = Math.min(Math.max(0, clientY - startPosition.value.y), maxY)
position.value = {x, y}
}
}
const stopDrag = () => {
isDragging.value = false
}
onMounted(() => {
//
document.addEventListener('mousemove', onDrag)
document.addEventListener('mouseup', stopDrag)
//
document.addEventListener('touchmove', onDrag)
document.addEventListener('touchend', stopDrag)
})
onUnmounted(() => {
document.removeEventListener('mousemove', onDrag)
document.removeEventListener('mouseup', stopDrag)
document.removeEventListener('touchmove', onDrag)
document.removeEventListener('touchend', stopDrag)
})
initData()
</script>
<template>
<div class="relative h-screen-nav flex flex-col">
<itemDetail class="grow-1" :detail-info="detail.auctionArtworkInfo"/>
<div v-if="[1,3,4].includes(detail.status)" class="h-81px bg-#fff flex justify-center pt-7px">
<van-button class="w-213px !h-38px" type="primary">
<span class="text-#fff text-14px">去支付 RMB10,000</span>
</van-button>
</div>
<div class="w-108px h-137px absolute bottom-240px right-6px">
<img src="@/static/images/zd5530@2x.png" class="w-full h-full" alt="">
<div class="flex flex-col items-center absolute bottom-25px text-14px text-#B58047 left-1/2 transform translate-x--1/2 whitespace-nowrap">
<div>恭喜您</div>
<div>竞拍成功</div>
<div class="relative h-screen-nav flex flex-col">
<itemDetail class="grow-1" :detail-info="detail.auctionArtworkInfo"/>
<div v-if="[1,3,4].includes(detail.status)" class="h-81px bg-#fff flex justify-center pt-7px">
<van-button class="w-213px !h-38px" type="primary">
<span class="text-#fff text-14px">去支付 RMB10,000</span>
</van-button>
</div>
<div
class="w-108px h-137px absolute cursor-move"
:style="{
left: position.x + 'px',
top: position.y + 'px'
}"
@mousedown="startDrag"
@touchstart.prevent="startDrag"
>
<img src="@/static/images/zd5530@2x.png" class="w-full h-full" alt="">
<div
class="flex flex-col items-center absolute bottom-25px text-14px text-#B58047 left-1/2 transform translate-x--1/2 whitespace-nowrap">
<div>恭喜您</div>
<div>竞拍成功</div>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.cursor-move {
touch-action: none;
user-select: none;
}
</style>

View File

@ -1,6 +1,10 @@
<script setup>
import XImage from "@/components/x-image/index.vue";
import {useRuntimeConfig} from "#app";
import QRCode from 'qrcode'
import { showImagePreview } from 'vant';
const statusLabel=[
{label:'已付款',value:2,color:'#18A058'}, {label:'未付款',value:1,color:'#CF3050'}, {label:'已部分付款',value:4,color:'#F09F1F'}
]
@ -15,6 +19,23 @@ const props = defineProps({
const itemLabel=(data)=>{
return statusLabel.find(x=>x.value===data.payStatus)
}
const config = useRuntimeConfig()
const getQRBase64 = async () => {
try {
return await QRCode.toDataURL(`${config.public.NUXT_PUBLIC_API_BASE}/collectCode/payment`, {
width: 200,
margin: 4,
errorCorrectionLevel: 'H'
})
} catch (err) {
console.error('生成二维码失败:', err)
return null
}
}
const openQrCode=async ()=>{
const base64=await getQRBase64()
showImagePreview([base64])
}
</script>
<template>
@ -34,7 +55,7 @@ const itemLabel=(data)=>{
</div>
<div class="flex flex-col justify-end ml-auto ">
<div class="flex w-55px h-26px bg-#2B53AC rounded-4px justify-center items-center">
<div class="text-12px text-#fff line-height-none mt-0.5px mr-5px">查看</div>
<div @click="openQrCode" class="text-12px text-#fff line-height-none mt-0.5px mr-5px">查看</div>
<div>
<img class="w-12px h-12px" src="@/static/images/icon-design-42@3x.png" alt="">
</div>

View File

@ -1,12 +1,16 @@
<script setup>
import { userArtworks } from "@/api/goods/index.js";
import { codeAuthStore } from "@/stores-collect-code/auth/index.js";
import { showImagePreview } from 'vant';
import XImage from '@/components/x-image/index.vue'
import {useRouter} from "#vue-router";
import {goodStore} from "~/stores-collect-code/goods/index.js";
import {ref} from "vue";
import {offlineQrcodeCreate} from "~/api-collect-code/goods/index.js";
import {offlineQrcodeCreate, offlineQrcodeList} from "~/api-collect-code/goods/index.js";
import codeCard from './components/codeCard/index.vue'
import {message} from "~/components/x-message/useMessage.js";
definePageMeta({
layout: 'default',
i18n: 'menu.profile',
@ -26,8 +30,8 @@ const initData = async () => {
}
const show=ref(false)
const close=()=>{
console.log('show',show.value)
show.value=false
}
const logOut=()=>{
localStorage.clear()
@ -38,7 +42,14 @@ const createForm=ref({
price:'',
})
const confirm=async ()=>{
const res=await offlineQrcodeCreate(createForm.value)
if (!createForm.value.price){
message.warning('请输入金额')
return false
}else if (!createForm.value.lotNo){
message.warning('请输入Lot号')
return false
}
const res=await offlineQrcodeCreate({...createForm.value,price:String(createForm.value.price)})
if (res.status===0){
show.value=false
}
@ -59,23 +70,17 @@ const loadMore = async () => {
const { finished } = await getOfflineQrcodeList()
localState.value.finished = finished
}
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 abnormal=ref(false)
const abnormalRow=ref({})
const inputLotNo=async (data)=>{
const res=await offlineQrcodeList({
lotNo:createForm.value.lotNo
})
if (res.status===0){
if (res.data.Data?.length>0){
abnormal.value=true
abnormalRow.value=res.data.Data?.[0]
}
}
}
initData()
@ -134,7 +139,7 @@ initData()
新增
</div>
</div>
<van-dialog v-model:show="show" show-cancel-button @close="close" @confirm="confirm">
<van-dialog v-model:show="show">
<div class="pt-18px pb-24px px-24px">
<div class="text-16px text-#000 font-bold text-center mb-26px">新增收款二维码</div>
<div class="">
@ -144,7 +149,7 @@ initData()
<div class="text-#939393 text-12px">RMB</div>
</div>
<div>
<input v-model="createForm.price" @keydown="validateInput"
<input v-model="createForm.price" type="number"
class="w-214px h-48px bg-#F3F3F3 rounded-4px px-11px text-16px" placeholder="请输入金额">
</div>
</div>
@ -153,14 +158,14 @@ initData()
<div class="text-#1A1A1A text-16px">Lot号</div>
</div>
<div>
<input type="number" v-model="createForm.lotNo" class="w-214px h-48px bg-#F3F3F3 rounded-4px px-11px text-16px" placeholder="请输入拍品序号">
<input type="number" v-model="createForm.lotNo" @input="inputLotNo" class="w-214px h-48px bg-#F3F3F3 rounded-4px px-11px text-16px" placeholder="请输入拍品序号">
</div>
</div>
</div>
<div class="flex flex-col items-center">
<div class="flex flex-col items-center" v-if="abnormal">
<div class="text-#CF3050 text-12px mb-8px mt-4px">*该拍品号当前已存在收款二维码确定要创建吗</div>
<div>
<XImage class="w-116px h-116px rounded-4px mb-9px" src=""></XImage>
<XImage class="w-116px h-116px rounded-4px mb-9px" :src="abnormalRow.hdPic"></XImage>
<div class="text-12px text-#575757 flex flex-col items-center">
<div>日出而作日落而息</div>
<div>张天赐</div>
@ -168,6 +173,16 @@ initData()
</div>
</div>
</div>
<template #footer>
<div class="border-t flex">
<van-button class="w-50% h-56px" style="border: none;border-radius: 0;border-right: 1.5px solid #E7E7E7" @click="show=false">
<span class="text-#000 text-16px text-center">取消</span>
</van-button>
<van-button class="w-50% h-56px !rounded-0" style="border: none;border-radius: 0" @click="confirm">
<span class="text-#000 text-16px text-center text-#2B53AC">确定</span>
</van-button>
</div>
</template>
</van-dialog>
</div>
</template>

View File

@ -1,56 +1,28 @@
<script setup>
import { ref, onMounted, onUnmounted, nextTick } from 'vue';
import {liveStore} from "@/stores/live/index.js";
import {authStore} from "~/stores/auth/index.js";
const {auctionData} = liveStore()
const {userInfo}= authStore()
const list = ref([
const headList=[
{
a: '领先',
b: '现场竞价',
c: '10:12:12',
d: 'RMB5,500',
e: '我'
label:'领先',
color:'#D03050',
value:'head'
},
{
label:'出局',
color:'#939393',
value:'out'
},
{
label:'成交',
color:'#34B633',
value:'success'
}
]);
let intervalId = null;
const addItem = () => {
list.value.push({
a: '领先',
b: '现场竞价',
c: '10:12:12',
d: 'RMB5,500',
e: ''
});
nextTick(() => {
scrollToBottom();
});
};
const scrollToBottom = () => {
const container = document.getElementById('list-container');
if (container) {
setTimeout(() => {
container.scrollTop = container.scrollHeight;
}, 100);
}
};
onMounted(() => {
//
/* intervalId = setInterval(() => {
addItem();
}, 1000);*/
});
onUnmounted(() => {
//
if (intervalId) {
clearInterval(intervalId);
}
});
]
const headItem=(statusCode)=>{
return headList.find(x=>x.value===statusCode)
}
</script>
<template>
@ -64,11 +36,11 @@ onUnmounted(() => {
</template>
<template v-else-if="auctionData.auctionPriceList?.buys?.length>0">
<div v-for="(item, index) in auctionData.auctionPriceList?.buys" :key="index" class="flex flex-shrink-0 h-25px">
<div class="flex-grow-1 text-start" :style="`color: ${item.statusCode==='head'?'#D03050':'#939393'}`" >{{ item.statusCode==='head'?'领先':'出局' }}</div>
<div class="flex-grow-1 text-center">{{ item.auctionType==='local'?'现场竞价':'网络竞价' }}</div>
<div class="flex-grow-1 text-center">{{ item.createdAt }}</div>
<div class="flex-grow-1 text-center">{{item.baseCurrency}}{{ item.baseMoney }}</div>
<div class="flex-grow-1 text-center text-#2B53AC">{{ item.userId===userInfo.ID?'我':'' }}</div>
<div class="flex-grow-1 text-start shrink-0" :style="`color: ${headItem(item.statusCode).color}`" >{{ headItem(item.statusCode).label }}</div>
<div class="flex-grow-1 text-center shrink-0">{{ item.auctionType==='local'?'现场竞价':'网络竞价' }}</div>
<div class="flex-grow-1 text-center shrink-0">{{ item.createdAt }}</div>
<div class="flex-grow-1 text-center shrink-0">{{item.baseCurrency}}{{ item.baseMoney }}</div>
<div class="flex-grow-1 text-center text-#2B53AC shrink-0 w-20px">{{ item.userId===userInfo.ID?'我':'' }}</div>
</div>
</template>
<template v-if="auctionData.wsType==='newArtwork'">

View File

@ -91,9 +91,12 @@ const goBuy=async ()=>{
buyMoney:String(auctionData.value?.nowAuctionPrice?.nextPrice??0)
})
if (res.status===0){
message.success('出价成功')
}
}
const tipOpen=()=>{
message.warning('出价状态未开启')
}
</script>
<template>
@ -127,12 +130,17 @@ const goBuy=async ()=>{
下口价{{auctionData?.nowAuctionPrice?.currency}}
<van-rolling-text class="my-rolling-text1" :start-num="0" :duration="0.5" :target-num="auctionData?.nowAuctionPrice?.nextPrice??0" direction="up"/>
</div>
<x-button @click="goBuy">
<div
:class="`w-344px h-[40px] ${quoteStatus ? 'bg-#FFB25F' : 'bg-#D6D6D8'} rounded-4px ${quoteStatus ? 'text-#fff' : 'text-#7D7D7F'} text-14px flex justify-center items-center mt-10px mb-10px`">
{{ quoteStatus ? `确认出价 ${auctionData?.nowAuctionPrice?.currency} ${auctionData?.nowAuctionPrice?.nextPrice??0}` : '点击"开启出价",即刻参与竞拍 ' }}
</div>
</x-button>
<div v-if="quoteStatus" class="mt-10px mb-10px">
<van-button @click="goBuy" color="#FFB25F" class="w-344px !h-[40px]">
<div>{{`确认出价 ${auctionData?.nowAuctionPrice?.currency} ${auctionData?.nowAuctionPrice?.nextPrice??0}`}}</div>
</van-button>
</div>
<div v-else class="mt-10px mb-10px">
<van-button @click="tipOpen" color="#D6D6D8" class=" w-344px !h-[40px]" v-if="!quoteStatus">
<div class="text-#7D7D7F text-14px">点击"开启出价"即刻参与竞拍</div>
</van-button>
</div>
<broadcast></broadcast>
</div>
<paymentInput v-model:show="show"/>

View File

@ -4,7 +4,6 @@ import XVanSelect from '@/components/x-van-select/index.vue'
import XVanDate from '@/components/x-van-date/index.vue'
definePageMeta({
name: 'personal-info',
})
const {t} = useI18n()
const showPicker = ref(false)

View File

@ -68,7 +68,6 @@ export const goodStore = createGlobalState(() => {
// 状态
actionDetails,
fullLive,
currentItem,
myArtWorks,
pageRef,

View File

@ -86,8 +86,7 @@ export const liveStore = createGlobalState(() => {
text: '本拍品已结束',
color: '#575757',
align: 'center',
backgroundColor: '#fff',
borderColor:'#fff'
},
icon:false,
subTitle:{
@ -97,7 +96,9 @@ export const liveStore = createGlobalState(() => {
},
style: {
width: '151px',
bottom: '230px'
bottom: '230px',
backgroundColor: '#fff',
borderColor:'#fff'
},
})
}else if (data.data?.tip?.tipType === 'failBid'){
@ -128,13 +129,14 @@ export const liveStore = createGlobalState(() => {
text: '竞拍结束,谢谢参与',
color: '#575757',
align: 'center',
backgroundColor: '#fff',
borderColor:'#fff'
},
icon:false,
style: {
width: '195px',
bottom: '230px'
bottom: '230px',
backgroundColor: '#fff',
borderColor:'#fff'
},
})
}

3
env/.env.test vendored
View File

@ -1,7 +1,6 @@
# 测试环境配置
NUXT_PUBLIC_API_BASE=http://172.16.100.99:8005
NUXT_PUBLIC_API_BASE=https://auction-test.szjixun.cn
NUXT_PUBLIC_API_COLLECT_CODE=https://auction-test.szjixun.cn
NUXT_PUBLIC_WS_URL=ws://test-ws.example.com
NUXT_API_SECRET=test-secret
NUXT_PUBLIC_SOCKET_URL=ws://172.16.100.99:8005
# 阿里云播放器配置

View File

@ -27,6 +27,7 @@
"dotenv": "^16.4.7",
"nuxt": "^3.15.0",
"pinyin": "4.0.0-alpha.2",
"qrcode": "^1.5.4",
"segmentit": "^2.0.3",
"vconsole": "^3.15.1",
"vue": "^3.5.13",

View File

@ -41,6 +41,9 @@ importers:
pinyin:
specifier: 4.0.0-alpha.2
version: 4.0.0-alpha.2(segmentit@2.0.3)
qrcode:
specifier: ^1.5.4
version: 1.5.4
segmentit:
specifier: ^2.0.3
version: 2.0.3
@ -784,8 +787,8 @@ packages:
resolution: {integrity: sha512-8tR1xe7ZEbkabTuE/tNhzpolygUn9OaYp9yuYAF4MgDNZg06C3Qny80bes2/e9/Wm3aVkPUlCw6WgU7mQd0yEg==}
engines: {node: '>= 16'}
'@intlify/shared@11.1.0':
resolution: {integrity: sha512-DvpNSxiMrFqYMaGSRDDnQgO/L0MqNH4KWw9CUx8LRHHIdWp08En9DpmSRNpauUOxKpHAhyJJxx92BHZk9J84EQ==}
'@intlify/shared@11.1.1':
resolution: {integrity: sha512-2kGiWoXaeV8HZlhU/Nml12oTbhv7j2ufsJ5vQaa0VTjzUmZVdd/nmKFRAOJ/FtjO90Qba5AnZDwsrY7ZND5udA==}
engines: {node: '>= 16'}
'@intlify/unplugin-vue-i18n@6.0.3':
@ -1819,6 +1822,10 @@ packages:
resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
engines: {node: '>=6'}
camelcase@5.3.1:
resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
engines: {node: '>=6'}
caniuse-api@3.0.0:
resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==}
@ -1862,6 +1869,9 @@ packages:
resolution: {integrity: sha512-5mOlNS0mhX0707P2I0aZ2V/cmHUEO/fL7VFLqszkhUsxt7RwnmrInf/eEQKlf5GzvYeHIjT+Ov1HRfNmymlG0w==}
engines: {node: '>=18'}
cliui@6.0.0:
resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==}
cliui@8.0.1:
resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
engines: {node: '>=12'}
@ -2090,6 +2100,10 @@ packages:
supports-color:
optional: true
decamelize@1.2.0:
resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==}
engines: {node: '>=0.10.0'}
decompress-response@6.0.0:
resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==}
engines: {node: '>=10'}
@ -2159,6 +2173,9 @@ packages:
resolution: {integrity: sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==}
engines: {node: '>=0.3.1'}
dijkstrajs@1.0.3:
resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==}
dom-serializer@2.0.0:
resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==}
@ -2395,6 +2412,10 @@ packages:
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
engines: {node: '>=8'}
find-up@4.1.0:
resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
engines: {node: '>=8'}
find-up@5.0.0:
resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
engines: {node: '>=10'}
@ -2863,6 +2884,10 @@ packages:
resolution: {integrity: sha512-bbgPw/wmroJsil/GgL4qjDzs5YLTBMQ99weRsok1XCDccQeehbHA/I1oRvk2NPtr7KGZgT/Y5tPRnAtMqeG2Kg==}
engines: {node: '>=14'}
locate-path@5.0.0:
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
engines: {node: '>=8'}
locate-path@6.0.0:
resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
engines: {node: '>=10'}
@ -3176,14 +3201,26 @@ packages:
resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==}
engines: {node: '>= 0.8.0'}
p-limit@2.3.0:
resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
engines: {node: '>=6'}
p-limit@3.1.0:
resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
engines: {node: '>=10'}
p-locate@4.1.0:
resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
engines: {node: '>=8'}
p-locate@5.0.0:
resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
engines: {node: '>=10'}
p-try@2.2.0:
resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
engines: {node: '>=6'}
package-json-from-dist@1.0.1:
resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==}
@ -3298,6 +3335,10 @@ packages:
resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==}
engines: {node: '>=4'}
pngjs@5.0.0:
resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==}
engines: {node: '>=10.13.0'}
postcss-calc@10.1.0:
resolution: {integrity: sha512-uQ/LDGsf3mgsSUEXmAt3VsCSHR3aKqtEIkmB+4PhzYwRYOW5MZs/GhCCFpsOtJJkP6EC6uGipbrnaTjqaJZcJw==}
engines: {node: ^18.12 || ^20.9 || >=22.0}
@ -3520,6 +3561,11 @@ packages:
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
engines: {node: '>=6'}
qrcode@1.5.4:
resolution: {integrity: sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==}
engines: {node: '>=10.13.0'}
hasBin: true
queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
@ -3584,6 +3630,9 @@ packages:
resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
engines: {node: '>=0.10.0'}
require-main-filename@2.0.0:
resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==}
resolve-from@4.0.0:
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
engines: {node: '>=4'}
@ -3705,6 +3754,9 @@ packages:
resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==}
engines: {node: '>= 0.8.0'}
set-blocking@2.0.0:
resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==}
setprototypeof@1.2.0:
resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==}
@ -4344,6 +4396,9 @@ packages:
whatwg-url@5.0.0:
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
which-module@2.0.1:
resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==}
which@2.0.2:
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
engines: {node: '>= 8'}
@ -4358,6 +4413,10 @@ packages:
resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
engines: {node: '>=0.10.0'}
wrap-ansi@6.2.0:
resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==}
engines: {node: '>=8'}
wrap-ansi@7.0.0:
resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
engines: {node: '>=10'}
@ -4386,6 +4445,9 @@ packages:
engines: {node: '>= 0.10.0'}
hasBin: true
y18n@4.0.3:
resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==}
y18n@5.0.8:
resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
engines: {node: '>=10'}
@ -4416,10 +4478,18 @@ packages:
engines: {node: '>= 14'}
hasBin: true
yargs-parser@18.1.3:
resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==}
engines: {node: '>=6'}
yargs-parser@21.1.1:
resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
engines: {node: '>=12'}
yargs@15.4.1:
resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==}
engines: {node: '>=8'}
yargs@17.7.2:
resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
engines: {node: '>=12'}
@ -5000,14 +5070,14 @@ snapshots:
'@intlify/shared@11.0.0-rc.1': {}
'@intlify/shared@11.1.0': {}
'@intlify/shared@11.1.1': {}
'@intlify/unplugin-vue-i18n@6.0.3(@vue/compiler-dom@3.5.13)(eslint@9.18.0(jiti@2.4.2))(rollup@4.31.0)(typescript@5.7.3)(vue-i18n@10.0.5(vue@3.5.13(typescript@5.7.3)))(vue@3.5.13(typescript@5.7.3))':
dependencies:
'@eslint-community/eslint-utils': 4.4.1(eslint@9.18.0(jiti@2.4.2))
'@intlify/bundle-utils': 10.0.0(vue-i18n@10.0.5(vue@3.5.13(typescript@5.7.3)))
'@intlify/shared': 11.1.0
'@intlify/vue-i18n-extensions': 8.0.0(@intlify/shared@11.1.0)(@vue/compiler-dom@3.5.13)(vue-i18n@10.0.5(vue@3.5.13(typescript@5.7.3)))(vue@3.5.13(typescript@5.7.3))
'@intlify/shared': 11.1.1
'@intlify/vue-i18n-extensions': 8.0.0(@intlify/shared@11.1.1)(@vue/compiler-dom@3.5.13)(vue-i18n@10.0.5(vue@3.5.13(typescript@5.7.3)))(vue@3.5.13(typescript@5.7.3))
'@rollup/pluginutils': 5.1.4(rollup@4.31.0)
'@typescript-eslint/scope-manager': 8.21.0
'@typescript-eslint/typescript-estree': 8.21.0(typescript@5.7.3)
@ -5031,11 +5101,11 @@ snapshots:
'@intlify/utils@0.13.0': {}
'@intlify/vue-i18n-extensions@8.0.0(@intlify/shared@11.1.0)(@vue/compiler-dom@3.5.13)(vue-i18n@10.0.5(vue@3.5.13(typescript@5.7.3)))(vue@3.5.13(typescript@5.7.3))':
'@intlify/vue-i18n-extensions@8.0.0(@intlify/shared@11.1.1)(@vue/compiler-dom@3.5.13)(vue-i18n@10.0.5(vue@3.5.13(typescript@5.7.3)))(vue@3.5.13(typescript@5.7.3))':
dependencies:
'@babel/parser': 7.26.5
optionalDependencies:
'@intlify/shared': 11.1.0
'@intlify/shared': 11.1.1
'@vue/compiler-dom': 3.5.13
vue: 3.5.13(typescript@5.7.3)
vue-i18n: 10.0.5(vue@3.5.13(typescript@5.7.3))
@ -6476,6 +6546,8 @@ snapshots:
callsites@3.1.0: {}
camelcase@5.3.1: {}
caniuse-api@3.0.0:
dependencies:
browserslist: 4.24.4
@ -6527,6 +6599,12 @@ snapshots:
is-wsl: 3.1.0
is64bit: 2.0.0
cliui@6.0.0:
dependencies:
string-width: 4.2.3
strip-ansi: 6.0.1
wrap-ansi: 6.2.0
cliui@8.0.1:
dependencies:
string-width: 4.2.3
@ -6737,6 +6815,8 @@ snapshots:
optionalDependencies:
supports-color: 9.4.0
decamelize@1.2.0: {}
decompress-response@6.0.0:
dependencies:
mimic-response: 3.1.0
@ -6780,6 +6860,8 @@ snapshots:
diff@7.0.0: {}
dijkstrajs@1.0.3: {}
dom-serializer@2.0.0:
dependencies:
domelementtype: 2.3.0
@ -7080,6 +7162,11 @@ snapshots:
dependencies:
to-regex-range: 5.0.1
find-up@4.1.0:
dependencies:
locate-path: 5.0.0
path-exists: 4.0.0
find-up@5.0.0:
dependencies:
locate-path: 6.0.0
@ -7609,6 +7696,10 @@ snapshots:
mlly: 1.7.4
pkg-types: 1.3.1
locate-path@5.0.0:
dependencies:
p-locate: 4.1.0
locate-path@6.0.0:
dependencies:
p-locate: 5.0.0
@ -8091,14 +8182,24 @@ snapshots:
type-check: 0.4.0
word-wrap: 1.2.5
p-limit@2.3.0:
dependencies:
p-try: 2.2.0
p-limit@3.1.0:
dependencies:
yocto-queue: 0.1.0
p-locate@4.1.0:
dependencies:
p-limit: 2.3.0
p-locate@5.0.0:
dependencies:
p-limit: 3.1.0
p-try@2.2.0: {}
package-json-from-dist@1.0.1: {}
package-manager-detector@0.2.8: {}
@ -8185,6 +8286,8 @@ snapshots:
pluralize@8.0.0: {}
pngjs@5.0.0: {}
postcss-calc@10.1.0(postcss@8.5.1):
dependencies:
postcss: 8.5.1
@ -8401,6 +8504,12 @@ snapshots:
punycode@2.3.1: {}
qrcode@1.5.4:
dependencies:
dijkstrajs: 1.0.3
pngjs: 5.0.0
yargs: 15.4.1
queue-microtask@1.2.3: {}
queue-tick@1.0.1: {}
@ -8473,6 +8582,8 @@ snapshots:
require-from-string@2.0.2: {}
require-main-filename@2.0.0: {}
resolve-from@4.0.0: {}
resolve-from@5.0.0: {}
@ -8610,6 +8721,8 @@ snapshots:
transitivePeerDependencies:
- supports-color
set-blocking@2.0.0: {}
setprototypeof@1.2.0: {}
sharp@0.32.6:
@ -9344,6 +9457,8 @@ snapshots:
tr46: 0.0.3
webidl-conversions: 3.0.1
which-module@2.0.1: {}
which@2.0.2:
dependencies:
isexe: 2.0.0
@ -9354,6 +9469,12 @@ snapshots:
word-wrap@1.2.5: {}
wrap-ansi@6.2.0:
dependencies:
ansi-styles: 4.3.0
string-width: 4.2.3
strip-ansi: 6.0.1
wrap-ansi@7.0.0:
dependencies:
ansi-styles: 4.3.0
@ -9375,6 +9496,8 @@ snapshots:
commander: 2.20.3
cssfilter: 0.0.10
y18n@4.0.3: {}
y18n@5.0.8: {}
yallist@3.1.1: {}
@ -9395,8 +9518,27 @@ snapshots:
yaml@2.7.0: {}
yargs-parser@18.1.3:
dependencies:
camelcase: 5.3.1
decamelize: 1.2.0
yargs-parser@21.1.1: {}
yargs@15.4.1:
dependencies:
cliui: 6.0.0
decamelize: 1.2.0
find-up: 4.1.0
get-caller-file: 2.0.5
require-directory: 2.1.1
require-main-filename: 2.0.0
set-blocking: 2.0.0
string-width: 4.2.3
which-module: 2.0.1
y18n: 4.0.3
yargs-parser: 18.1.3
yargs@17.7.2:
dependencies:
cliui: 8.0.1