Commit 18d65930 authored by zhangsan's avatar zhangsan

1

parent accf05f8
......@@ -17,6 +17,7 @@ declare module 'vue' {
Progress: typeof import('./components/progress.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
Sall: typeof import('./components/sall.vue')['default']
SignIn: typeof import('./components/signIn.vue')['default']
VanButton: typeof import('vant/es')['Button']
VanCell: typeof import('vant/es')['Cell']
......
<template>
<div class="price-animation-container">
<div v-if="showPopup" class="red-packet-container">
<div v-for="packet in redPackets" :key="packet.id" class="red-packet" :class="packet.swing" :style="{
left: packet.left + 'px',
top: packet.top + 'px',
animationDelay: packet.delay + 's'
}">
<van-icon name="gift-o" color="#ff4400" size="24" />
</div>
</div>
<van-popup v-model:show="showPopup" round closeable position="center"
:overlay-style="{ background: 'rgba(0, 0, 0, 0.3)' }" class="custom-popup" @close="handleClose">
<div class="popup-content">
<img src="@/static/home/logo.png" alt="">
<div class="header">
<div class="title">限时抵扣</div>
</div>
<div class="price-section">
<div class="price-info">
<div class="original-price">原入仓价 ¥{{ originalPrice }}</div>
</div>
<div class="save-price">预存款抵扣¥{{ (originalPrice - finalPrice).toFixed(2) }}</div>
<div class="current-price">
<span class="currency">¥</span>
<span class="number animate-price">{{ displayPrice }}</span>
</div>
</div>
<div class="benefits">
<div class="benefit-item">
<van-icon name="certificate" color="#ff4400" />
<span>投资无忧</span>
</div>
<div class="benefit-item">
<van-icon name="shield-o" color="#ff4400" />
<span>资金安全</span>
</div>
<div class="benefit-item">
<van-icon name="balance-o" color="#ff4400" />
<span>收益稳定</span>
</div>
</div>
<div class="finger-hint">
<van-icon name="arrow-down" class="finger-icon" />
</div>
<div class="action-button" @click="handlePurchase">
我要入仓
</div>
</div>
</van-popup>
</div>
</template>
<script setup>
import { ref, onMounted, watch } from 'vue'
import { showToast } from 'vant'
const props = defineProps({
originalPrice: {
type: Number,
required: true
},
finalPrice: {
type: Number,
required: true
}
})
// 定义事件
const emit = defineEmits(['on-purchase', 'on-close'])
const showPopup = ref(false)
const displayPrice = ref(props.originalPrice)
const isAnimating = ref(false)
const redPackets = ref([])
let rainInterval = null
const animatePrice = () => {
isAnimating.value = true
const duration = 800
const steps = 25
const priceDiff = props.originalPrice - props.finalPrice
const stepValue = priceDiff / steps
let currentStep = 0
const interval = setInterval(() => {
if (currentStep < steps) {
displayPrice.value = Math.round((props.originalPrice - stepValue * currentStep) * 100) / 100
currentStep++
} else {
displayPrice.value = props.finalPrice
clearInterval(interval)
isAnimating.value = false
}
}, duration / steps)
}
// 提供给外部的打开方法
const open = () => {
showPopup.value = true
animatePrice()
}
// 处理弹窗关闭
const handleClose = () => {
stopRedPacketRain()
emit('on-close') // 触发关闭回调
}
// 处理购买点击
const handlePurchase = () => {
emit('on-purchase') // 触发购买回调
}
// 停止红包雨
const stopRedPacketRain = () => {
if (rainInterval) {
clearTimeout(rainInterval)
rainInterval = null
}
redPackets.value = []
}
// 创建红包的逻辑保持不变
const createRedPacket = () => {
const packet = {
id: Date.now() + Math.random(),
left: Math.random() * window.innerWidth,
delay: Math.random() * 3,
top: -50,
swing: Math.random() > 0.5 ? 'swing-left' : 'swing-right'
}
redPackets.value.push(packet)
setTimeout(() => {
const index = redPackets.value.findIndex(p => p.id === packet.id)
if (index > -1) {
redPackets.value[index] = {
...packet,
top: -50,
left: Math.random() * window.innerWidth,
delay: Math.random() * 3,
swing: Math.random() > 0.5 ? 'swing-left' : 'swing-right'
}
}
}, 3000)
}
const createRandomPacket = () => {
const randomDelay = Math.random() * 500 + 100
rainInterval = setTimeout(() => {
if (redPackets.value.length < 10) {
createRedPacket()
}
createRandomPacket()
}, randomDelay)
}
const startRedPacketRain = () => {
redPackets.value = []
for (let i = 0; i < 5; i++) {
createRedPacket()
}
createRandomPacket()
}
// 监听弹窗状态
watch(() => showPopup.value, (newVal) => {
if (newVal) {
startRedPacketRain()
} else {
stopRedPacketRain()
}
})
// 暴露方法给外部使用
defineExpose({
open
})
// 移除自动打开的逻辑
onMounted(() => {
// 不再自动打开弹窗
})
</script>
<style scoped lang="scss">
.custom-popup {
width: 90%;
border-radius: 12px;
z-index: 2001;
background: url('@/static/other/noticebg.png') no-repeat center center;
background-size: 100% 100%;
padding: 30px 0;
}
.popup-content {
padding: 20px;
img {
width: 140px;
margin-bottom: 10px;
margin-left: 20px;
}
}
.header {
text-align: center;
margin-bottom: 15px;
}
.title {
font-size: 18px;
font-weight: bold;
color: red;
}
.subtitle {
font-size: 14px;
color: #ff4400;
margin-top: 5px;
}
.price-section {
text-align: center;
margin: 20px 0;
}
.current-price {
margin-bottom: 10px;
}
.currency {
font-size: 20px;
color: #ff4400;
font-weight: bold;
}
.number {
font-size: 36px;
color: #ff4400;
font-weight: bold;
display: inline-block;
}
.number.animate-price {
animation: priceAnimation 2s infinite;
}
.price-info {
display: flex;
justify-content: center;
gap: 15px;
font-size: 14px;
}
.original-price {
color: #999;
text-decoration: line-through;
}
.save-price {
font-size: 14px;
color: #ff4400;
}
.benefits {
display: flex;
justify-content: space-around;
padding: 15px 0;
}
.benefit-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 5px;
i {
font-size: 30px;
}
}
.benefit-item span {
font-size: 12px;
color: #666;
}
.finger-hint {
text-align: center;
margin: 0 0 -5px;
}
.finger-icon {
color: #ff4400;
font-size: 24px;
animation: fingerAnimation 1s infinite;
}
.action-button {
background: #ff4400;
color: white;
width: 70%;
padding: 12px;
border-radius: 25px;
text-align: center;
margin: 0 auto;
font-size: 16px;
font-weight: bold;
margin-top: 15px;
}
@keyframes priceAnimation {
0% {
transform: scale(1);
}
50% {
transform: scale(1.2);
}
100% {
transform: scale(1);
}
}
@keyframes fingerAnimation {
0% {
transform: translateY(0);
opacity: 1;
}
50% {
transform: translateY(8px);
opacity: 0.5;
}
100% {
transform: translateY(0);
opacity: 1;
}
}
.red-packet-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 3000;
overflow: hidden;
}
.red-packet {
position: absolute;
animation: falling 3s linear infinite;
display: flex;
align-items: center;
justify-content: center;
&.swing-left {
animation: falling-left 3s linear infinite;
}
&.swing-right {
animation: falling-right 3s linear infinite;
}
i {
filter: drop-shadow(0 0 5px rgba(255, 68, 0, 0.5));
transform: scale(1.2);
opacity: 0.9;
}
}
@keyframes falling-left {
0% {
transform: translateY(0) translateX(0) rotate(0deg);
opacity: 0.8;
}
25% {
transform: translateY(30vh) translateX(-100px) rotate(90deg);
}
50% {
transform: translateY(60vh) translateX(-50px) rotate(180deg);
opacity: 1;
}
75% {
transform: translateY(90vh) translateX(-100px) rotate(270deg);
}
100% {
transform: translateY(120vh) translateX(0) rotate(360deg);
opacity: 0.8;
}
}
@keyframes falling-right {
0% {
transform: translateY(0) translateX(0) rotate(0deg);
opacity: 0.8;
}
25% {
transform: translateY(30vh) translateX(100px) rotate(-90deg);
}
50% {
transform: translateY(60vh) translateX(50px) rotate(-180deg);
opacity: 1;
}
75% {
transform: translateY(90vh) translateX(100px) rotate(-270deg);
}
100% {
transform: translateY(120vh) translateX(0) rotate(-360deg);
opacity: 0.8;
}
}
</style>
src/static/home/logo.png

2.81 KB | W: | H:

src/static/home/logo.png

13.7 KB | W: | H:

src/static/home/logo.png
src/static/home/logo.png
src/static/home/logo.png
src/static/home/logo.png
  • 2-up
  • Swipe
  • Onion skin
src/static/other/logo.png

3.2 KB | W: | H:

src/static/other/logo.png

13.6 KB | W: | H:

src/static/other/logo.png
src/static/other/logo.png
src/static/other/logo.png
src/static/other/logo.png
  • 2-up
  • Swipe
  • Onion skin
src/static/user/logo.png

2.81 KB | W: | H:

src/static/user/logo.png

13.7 KB | W: | H:

src/static/user/logo.png
src/static/user/logo.png
src/static/user/logo.png
src/static/user/logo.png
  • 2-up
  • Swipe
  • Onion skin
src/static/xbgz/logo.png

2.81 KB | W: | H:

src/static/xbgz/logo.png

13.7 KB | W: | H:

src/static/xbgz/logo.png
src/static/xbgz/logo.png
src/static/xbgz/logo.png
src/static/xbgz/logo.png
  • 2-up
  • Swipe
  • Onion skin
......@@ -172,7 +172,7 @@ const submitPay = async () => {
} catch (error) {
showToast({
message: error.message || '支付失败',
message: error.msg || '支付失败',
type: 'error'
})
} finally {
......
......@@ -21,7 +21,7 @@ const active = ref(Number(route.query.type) || 5);
const resetList = () => {
list.value = []
pageNum.value = 1
finished.value = true
finished.value = false
loading.value = false
total.value = 0
emptyTipsShow.value = false
......@@ -31,6 +31,7 @@ watch(active, () => {
resetList();
});
const getList = async () => {
try {
const data = {
......@@ -42,22 +43,22 @@ const getList = async () => {
data
);
if (res.code === 200) {
if (pageNum.value === 1) {
list.value = res.rows || []
} else {
list.value = [...list.value, ...(res.rows || [])]
}
total.value = res.total || 0
if (list.value.length >= total.value) {
finished.value = true
} else {
pageNum.value++
}
if (list.value.length >= total.value) {
finished.value = true
}
} else {
showFailToast(res.msg || '加载失败')
finished.value = true
}
} catch (error) {
console.error('获取列表失败:', error)
showFailToast('加载失败,请重试')
finished.value = true
} finally {
......
<template>
<sall :original-price="1500" ref="sallRef" @on-purchase="jiaoqian1000" @on-close="handleClose" :final-price="1000" />
<div class="trading_wrap_bg">
<div class="trading_header">
<img class="trading_header_title" src="@/static/home/logo.png" alt="" />
......@@ -37,7 +38,29 @@
</van-cell-group>
</div>
</div>
<div class="trading_content_blk trading_content_blk1" style="margin-bottom: 25px;">
<div class="bonus_info">
<div class="bonus_items">
<div class="bonus_item">
<div class="bonus_item_title">每日分红</div>
<div class="bonus_item_value">50元</div>
</div>
<div class="bonus_item">
<div class="bonus_item_title">单购下发习币</div>
<div class="bonus_item_value">习币2000个</div>
</div>
<div class="bonus_item">
<div class="bonus_item_title">每人限购仓</div>
<div class="bonus_item_value">5次</div>
</div>
<div class="bonus_item">
<div class="bonus_item_title">分红时间至</div>
<div class="bonus_item_value">2035年</div>
</div>
</div>
</div>
<div class="join_btn" @click="openjiaoqian">立即入仓</div>
</div>
<!-- 红普通仓模块 -->
<div class="trading_content_blk trading_content_blk1">
<div class="bonus_info">
......@@ -85,11 +108,12 @@ import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { usePageHook } from '@/hooks/usePageHook'
import request from '@/utils/request'
import sall from '@/components/sall.vue'
const router = useRouter()
const popup = ref(null)
const popupType = ref('app')
const userInfo = ref({})
const sallRef = ref(null)
const handleTrading = () => {
if(calculateTimeDifference(userInfo.extend3, 10)){
showToast('安全监管完毕后即可抛售')
......@@ -140,6 +164,20 @@ const gotx = (balance, type, title) => {
}
})
}
const jiaoqian1000 = () => {
router.push({
path: '/user/payUp',
query: {
amount: 1000,
paytitle: '持币储分红理财仓',
paytype: 0,
productId: 2
}
})
}
const openjiaoqian = () => {
sallRef.value.open()
}
const handleJoin = () => {
if (userInfo.value.extend2 == 2) {
showToast('您已入仓')
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment