Commit 125778df authored by qd01's avatar qd01

代码更新 缴费

parent 025fa3cb
...@@ -21,10 +21,7 @@ const keepAliveRouteNames = computed(() => { ...@@ -21,10 +21,7 @@ const keepAliveRouteNames = computed(() => {
</template> </template>
<style> <style>
@font-face {
font-family: pingfang;
src: url('./static/PingFangSC-Regular.otf');
}
.fade-enter-active, .fade-enter-active,
.fade-leave-active { .fade-leave-active {
......
<template> <template>
<div class="container"> <var-popup v-model:show="showPopup" position="bottom" @closed="handleClose">
<!-- <var-popup :show="props.show" position="bottom" close-on-click-overlay
@update:show="(val) => emit('update:show', val)" @closed="handleClose">
<div class="pop"> <div class="pop">
<!-- 付款金额 -->
<div class="top"> <div class="top">
<span class="title">付款金额</span> <span class="title">付款金额</span>
<span class="money">{{ props.mony }}{{ props.dw }}</span> <span class="money">{{ paymentConfig.mony }}{{ paymentConfig.dw }}</span>
</div> </div>
<!-- 支付方式 -->
<div class="pays"> <div class="pays">
<var-radio-group :model-value="selectedPayment" @update:model-value="handlePaymentChange"> <van-radio-group v-model="selectedPayment">
<var-card class="payment-methods"> <var-card class="payment-methods">
<var-cell v-for="method in visiblePaymentMethods" :key="method.name" <van-cell clickable @click="selectedPayment = method.name" v-for="method in visiblePaymentMethods"
:class="['payment-item', { active: selectedPayment === method.name }]"> :key="method.name" :class="['payment-item', { active: selectedPayment === method.name }]">
<template #left> <template #title>
<div class="payment-left"> <div class="item1">
<img :src="method.icon" :alt="method.label" class="payment-icon"> <img :src="method.icon" mode="" class="payment-icon">
<span class="payment-label">{{ method.label }}</span> <div class="paywarp">
<div class="title">{{ method.label }}</div>
<div class="sub">银行单笔限额200000.00元</div>
</div>
</div> </div>
</template> </template>
<template #right> <template #right-icon>
<var-radio :name="method.name" /> <van-radio :name="method.name" />
</template> </template>
</var-cell> </van-cell>
</var-card> </var-card>
</var-radio-group> </van-radio-group>
</div> </div>
<var-notice-bar v-if="props.isBindc" :content="text1" /> <!-- 提示信息 -->
<var-notice-bar v-if="props.isBindpay" :content="text2" /> <div v-if="paymentConfig.zfsm" class="note-text">注:{{ paymentConfig.zfsm }}</div>
<div v-if="props.zfsm" class="note-text">注:{{ props.zfsm }}</div>
<!-- 提交按钮 -->
<var-button block type="primary" class="submit-btn" :loading="isSubmitting" :disabled="isSubmitting" <var-button block type="primary" class="submit-btn" :loading="isSubmitting" :disabled="isSubmitting"
@click="handleSubmit"> @click="handleSubmit">
{{ isSubmitting ? `提交确认,请勿退出${countdown}` : props.btn }} {{ isSubmitting ? `提交确认,请勿退出${countdown}` : paymentConfig.btn }}
</var-button> </var-button>
</div> </div>
</var-popup> --> </var-popup>
1111
<!-- 密码输入弹窗 --> <!-- 密码输入弹窗 -->
<!-- <var-popup :show="showPasswordInput" @update:show="(val) => showPasswordInput = val" position="center"> <var-popup v-model:show="showPasswordInput" position="center">
<div class="password-popup"> <div class="password-popup">
<span class="password-title">请输入支付密码</span> <span class="password-title">请输入支付密码</span>
<var-input v-model="password" type="password" maxlength="6" :focused="showPasswordInput" <var-input v-model="password" type="password" maxlength="6" :focused="showPasswordInput"
@change="handlePasswordChange" @keyup.enter="handlePasswordFinish" /> @keyup.enter="handlePasswordFinish" />
<span class="password-hint">默认支付密码:123456</span> <span class="password-hint">默认支付密码:123456</span>
</div> </div>
</var-popup> --> </var-popup>
</div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed } from 'vue' import { ref, computed, watch } from 'vue';
import { Snackbar } from '@varlet/ui' import { post } from '@/utils/request';
import { post } from '@/utils/request' import type { PaymentProps, PaymentMethod } from '@/types/payment';
import type { PaymentProps, PaymentMethod } from '@/types/payment' import { useDebounceFn } from '@vueuse/core';
import { useDebounceFn } from '@vueuse/core'
// 支付方式图标 // 支付方式图标
import wxIcon from '@/static/payup/wx.svg' import wxIcon from '@/static/payup/wx.svg';
import zfbIcon from '@/static/payup/zfb.svg' import zfbIcon from '@/static/payup/zfb.svg';
import ylIcon from '@/static/payup/yinlian.svg' import ylIcon from '@/static/payup/yinlian.svg';
import jljIcon from '@/static/payup/jlj.svg' import jljIcon from '@/static/payup/jlj.svg';
import fhIcon from '@/static/payup/fh.svg' import fhIcon from '@/static/payup/fh.svg';
import yjIcon from '@/static/payup/yj.svg' import yjIcon from '@/static/payup/yj.svg';
const props = withDefaults(defineProps<PaymentProps>(), { // 定义默认值
show: false, const defaultConfig = {
mony: 0,
dw: '', dw: '',
btn: '确认支付' btn: '确认支付',
}) url: '/ops/daybook',
password: false,
needCheck: false,
payway: 0,
wechat: 1,
zfb: 1,
ysf: 1,
tzj: 0,
jtqb: 0,
dtqb: 0,
zfsm: '',
isBindc: true,
isBindpay: false
};
// props 只接收必要的属性,移除 show
const props = defineProps<{
paymentInfo: {
mony: number
productId: string
type: number
}
}>();
// 内部状态,包含 show
const paymentConfig = ref({
show: false, // show 移到内部维护
...defaultConfig,
...props.paymentInfo
});
// 监听 props 变化
watch(() => props.paymentInfo, (newVal) => {
paymentConfig.value = {
...paymentConfig.value, // 保持当前的 show 状态
...defaultConfig,
...newVal
};
}, { deep: true });
// 定义事件,移除 update:show
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'update:show', value: boolean): void (e: 'close'): void;
(e: 'close'): void (e: 'beforeClick', key: string): void;
(e: 'beforeClick', key: string): void }>();
}>()
// 修改 showPopup 计算属性
const showPopup = computed({
get: () => paymentConfig.value.show,
set: (val) => {
paymentConfig.value.show = val;
if (!val) emit('close');
},
});
// 提供打开方法给父组件
const open = () => {
paymentConfig.value.show = true;
};
// 暴露方法给父组件
defineExpose({
open
});
// 状态管理 // 状态管理
const selectedPayment = ref('ali') const selectedPayment = ref('ali');
const isSubmitting = ref(false) const isSubmitting = ref(false);
const countdown = ref(6) const countdown = ref(6);
const showPasswordInput = ref(false) const showPasswordInput = ref(false);
const password = ref('') const password = ref('');
// 提示文本
const text1 = '该笔费用为开通国际银行卡跨国转账至中国境内银行卡手续费,该费用由中国银保监会收取'
const text2 = '该笔款项是一带一路银行卡绑定第三方支付手续费,费用由第三方收取'
// 支付方式列表 // 支付方式列表
const paymentMethods = computed<PaymentMethod[]>(() => [ const paymentMethods = computed<PaymentMethod[]>(() => [
{ name: 'wechat', label: '微信支付', icon: wxIcon, visible: props.wechat === 1 }, { name: 'wechat', label: '微信支付', icon: wxIcon, visible: paymentConfig.value.wechat === 1 },
{ name: 'ali', label: '支付宝支付', icon: zfbIcon, visible: props.zfb === 1 }, { name: 'ali', label: '支付宝支付', icon: zfbIcon, visible: paymentConfig.value.zfb === 1 },
{ name: 'yl', label: '云闪付', icon: ylIcon, visible: props.ysf === 1 }, { name: 'yl', label: '云闪付', icon: ylIcon, visible: paymentConfig.value.ysf === 1 },
{ name: 'tzj', label: '保额', icon: jljIcon, visible: props.tzj === 1 }, { name: 'tzj', label: '保额', icon: jljIcon, visible: paymentConfig.value.tzj === 1 },
{ name: 'jtqb', label: '体验金', icon: fhIcon, visible: props.jtqb === 1 }, { name: 'jtqb', label: '体验金', icon: fhIcon, visible: paymentConfig.value.jtqb === 1 },
{ name: 'dtqb', label: '动态钱包', icon: yjIcon, visible: props.dtqb === 1 } { name: 'dtqb', label: '动态钱包', icon: yjIcon, visible: paymentConfig.value.dtqb === 1 },
]) ]);
const visiblePaymentMethods = computed(() => const visiblePaymentMethods = computed(() =>
paymentMethods.value.filter(method => method.visible) paymentMethods.value.filter((method) => method.visible)
) );
// 处理支付方式变更 // 提交处理(带防抖)
const handlePaymentChange = (value: string) => { const handleSubmit = useDebounceFn(async () => {
selectedPayment.value = value if (paymentConfig.value.password) {
} showPasswordInput.value = true;
return;
}
const uniqueKey = paymentConfig.value.needCheck ? generateUniqueKey() : undefined;
if (paymentConfig.value.needCheck && uniqueKey) {
emit('beforeClick', uniqueKey);
}
startCountdown();
await handlePayment(uniqueKey);
}, 1000);
// 关闭弹窗
const handleClose = () => {
paymentConfig.value.show = false;
};
// 密码处理
const handlePasswordFinish = () => {
if (password.value === '123456') {
showPasswordInput.value = false;
handlePayment();
} else {
showFailToast('密码错误');
}
password.value = '';
};
// 生成唯一标识 // 生成唯一标识
const generateUniqueKey = () => { const generateUniqueKey = () => {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
return Array.from({ length: 99 }, () => return Array.from({ length: 99 }, () => chars[Math.floor(Math.random() * chars.length)]).join('');
chars[Math.floor(Math.random() * chars.length)] };
).join('')
}
// 倒计时处理 // 倒计时处理
const startCountdown = () => { const startCountdown = () => {
isSubmitting.value = true isSubmitting.value = true;
const timer = setInterval(() => { const timer = setInterval(() => {
countdown.value-- countdown.value--;
if (countdown.value <= 0) { if (countdown.value <= 0) {
clearInterval(timer) clearInterval(timer);
isSubmitting.value = false isSubmitting.value = false;
countdown.value = 6 countdown.value = 6;
} }
}, 1000) }, 1000);
} };
// 支付处理 // 支付处理
const handlePayment = async (uniqueKey?: string) => { const handlePayment = async (uniqueKey?: string) => {
if (!selectedPayment.value) { if (!selectedPayment.value) {
Snackbar.error('请选择支付方式') showFailToast('请选择支付方式');
return return;
} }
const paymentData = { const paymentData = {
productId: props.productId, productId: paymentConfig.value.productId,
remark: selectedPayment.value, remark: selectedPayment.value,
balance: props.mony, balance: paymentConfig.value.mony,
type: props.type, type: paymentConfig.value.type,
...(uniqueKey && { bakCol3: uniqueKey }) ...(uniqueKey && { bakCol3: uniqueKey }),
} };
try { try {
const res = await post(props.url || '', paymentData) const res = await post(paymentConfig.value.url || '', paymentData);
if (res.code === 200) { if (res.code === 200) {
if (props.payway === 0) { let script = res.msg
window.location.href = res.msg location.href = script
handleClose();
} else { } else {
Snackbar.success(res.msg) showFailToast(res.msg);
setTimeout(() => {
window.location.href = '/pages/product/product'
}, 1000)
}
handleClose()
} else {
Snackbar.error(res.msg)
} }
} catch (error) { } catch (error) {
console.error('Payment error:', error) console.error('Payment error:', error);
Snackbar.error('支付失败,请稍后重试') showFailToast('支付失败,请稍后重试');
} }
} };
// 提交处理(带防抖)
const handleSubmit = useDebounceFn(async () => {
if (props.password) {
showPasswordInput.value = true
return
}
const uniqueKey = props.needCheck ? generateUniqueKey() : undefined
if (props.needCheck) {
emit('beforeClick', uniqueKey)
}
startCountdown()
await handlePayment(uniqueKey)
}, 1000)
// 密码处理
const handlePasswordFinish = (value: string) => {
if (value === '123456') {
showPasswordInput.value = false
handlePayment()
} else {
Snackbar.error('密码错误')
}
password.value = ''
}
const handleClose = () => {
emit('update:show', false)
emit('close')
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.container {
font-family: pingfang;
}
.pop { .pop {
background: #f5f6f7; background: #ffffff;
border-radius: 12px 12px 0 0; border-radius: 16px 16px 0 0;
padding: 20px; padding: 12px;
box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.1);
}
.top { .top {
text-align: center; text-align: center;
margin-bottom: 20px; display: flex;
flex-direction: column;
.title { .title {
font-size: 22px; font-size: 18px;
display: block; color: #333;
margin-bottom: 10px; font-weight: 500;
} }
.money { .money {
font-size: 28px; font-size: 28px;
color: #fa7307; color: #fa7307;
} font-weight: bold;
} }
} }
.payment-methods { .payment-methods {
margin: 20px 0; margin: 16px 0;
} border-radius: 12px;
overflow: hidden;
.payment-item { box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
padding: 12px;
.payment-left { .item1 {
display: flex; display: flex;
align-items: center; align-items: center;
gap: 10px;
img {
width: 30px;
height: 30px;
margin-right: 8px;
} }
.payment-icon { .title {
width: 20px; font-weight: 500;
height: 20px; font-size: 14px;
color: #0E0E0E;
}
.sub {
font-weight: 400;
font-size: 12px;
color: #999999;
}
} }
} }
.payment-item {
transition: background-color 0.2s;
&.active {
background-color: #f5f6f7;
}
}
.note-text { .note-text {
color: red; color: #ff4d4f;
padding: 10px 0; font-size: 14px;
margin-top: 16px;
text-align: center;
} }
.submit-btn { .submit-btn {
margin-top: 20px; margin-top: 24px;
border-radius: 8px;
font-size: 16px;
font-weight: 500;
} }
.password-popup { .password-popup {
padding: 20px; padding: 24px;
background: #ffffff;
border-radius: 12px;
text-align: center; text-align: center;
.password-title { .password-title {
font-size: 18px; font-size: 18px;
margin-bottom: 20px; color: #333;
display: block; margin-bottom: 16px;
} }
.password-hint { .password-hint {
color: #999;
font-size: 14px; font-size: 14px;
margin-top: 10px; color: #999;
display: block; margin-top: 12px;
} }
} }
</style> </style>
\ No newline at end of file
...@@ -25,6 +25,14 @@ const handleClick = (item) => { ...@@ -25,6 +25,14 @@ const handleClick = (item) => {
navigateTo("/user/singIn"); navigateTo("/user/singIn");
} }
} }
const show = ref(false)
const getuserinfo = async () => {
const res = await get('/system/user/', {})
if(res.dld == 2){
show.value = true
}
}
getuserinfo()
const showGuide = ref(false) const showGuide = ref(false)
const content = ref([]) const content = ref([])
const content3 = ref([]) const content3 = ref([])
...@@ -42,6 +50,9 @@ const getNotices = async () => { ...@@ -42,6 +50,9 @@ const getNotices = async () => {
console.error('Failed to fetch notices:', error) console.error('Failed to fetch notices:', error)
} }
} }
const handleConfirm = () => {
navigateTo('/product')
}
getNotices() getNotices()
const handleNewsItemClick = (item) => { const handleNewsItemClick = (item) => {
navigateTo(`/newsDetail/${item.noticeId}`) navigateTo(`/newsDetail/${item.noticeId}`)
...@@ -50,6 +61,8 @@ const handleNewsItemClick = (item) => { ...@@ -50,6 +61,8 @@ const handleNewsItemClick = (item) => {
<template> <template>
<div class="container"> <div class="container">
<van-dialog v-model:show="show" @confirm="handleConfirm" confirmButtonColor="red" confirmButtonText="前往会场认购" cancelButtonText="先不前往认购" title="恭喜您获得债券认购资格,您的购买意向申请已经通过,现在可以认购债权了,您要前往认购吗?" show-cancel-button>
</van-dialog>
<GuideModal v-model="showGuide" :guide-list="content" /> <GuideModal v-model="showGuide" :guide-list="content" />
<div class="imgwarp"> <div class="imgwarp">
<img src="/static/pages/home/14.png"> <img src="/static/pages/home/14.png">
...@@ -79,11 +92,7 @@ const handleNewsItemClick = (item) => { ...@@ -79,11 +92,7 @@ const handleNewsItemClick = (item) => {
</div> </div>
<NewsCard :content3="content3" @itemClick="handleNewsItemClick" /> <NewsCard :content3="content3" @itemClick="handleNewsItemClick" />
</div> </div>
<!-- 恭喜您获得债券认购资格,您的购买意向申请已经通过,现在可以认购债权了,您要前往认购吗
两个按钮
(前往会场认购)
(先不前往认购) -->
</div> </div>
</template> </template>
......
...@@ -187,6 +187,17 @@ fetchData() ...@@ -187,6 +187,17 @@ fetchData()
</div> </div>
</div> </div>
</div> </div>
<var-divider />
<div class="assets-grid">
<div class="asset-item" v-ripple>
<div class="amount">{{ userData.q6 || 0 }}</div>
<div class="label">分销奖励</div>
<div class="actions">
<button class="action-btn primary" @click="gotx(userData.q6 || 0, 6, '分销奖励')">提现</button>
<button class="action-btn secondary" @click="gomx(6)">明细</button>
</div>
</div>
</div>
</div> </div>
<!-- 广告横幅 --> <!-- 广告横幅 -->
...@@ -350,7 +361,7 @@ fetchData() ...@@ -350,7 +361,7 @@ fetchData()
.asset-item { .asset-item {
text-align: center; text-align: center;
flex: 1; width: 25%;
.amount { .amount {
font-size: 18px; font-size: 18px;
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
import { ref, onMounted } from 'vue' import { ref, onMounted } from 'vue'
import { get } from '@/utils/request' import { get } from '@/utils/request'
import ExpandableText from '@/components/ExpandableText.vue' import ExpandableText from '@/components/ExpandableText.vue'
import PayUp from '~/components/PayUp.vue'
definePageMeta({ definePageMeta({
layout: 'default', layout: 'default',
title: '产品详情', title: '产品详情',
...@@ -63,33 +63,48 @@ const fetchData = async () => { ...@@ -63,33 +63,48 @@ const fetchData = async () => {
loading.value = false loading.value = false
} }
} }
const showBuy = ref(false)
const handleBuy = () => { const paymentInfo = ref({
showBuy.value = true mony: 200,
productId: '',
type: 0
});
const payupRef = ref();
const handleBuy = (item) => {
paymentInfo.value.productId = item.productId
paymentInfo.value.mony = item.price
payupRef.value?.open();
} }
const handleBuy1 = () => { const handleClose = () => {
if(!subForm.value.a7 || !subForm.value.a8){ paymentInfo.value.show = false;
showFailToast('请填写完整信息')
return false
}
subForm.value.a3 = productArr.value.productName
subForm.value.a4 = productArr.value.productId
subForm.value.a5 = 1
post(`/yw3/add`, subForm.value).then(res => {
if (res?.code == 200) {
subForm.value = {}
showSuccessToast('提交成功')
}else{
showBuy.value = false
showFailToast(res.msg)
}
})
} }
const others = ref(false)
// const handleBuy1 = () => {
// if (!subForm.value.a7 || !subForm.value.a8) {
// showFailToast('请填写完整信息')
// return false
// }
// subForm.value.a3 = productArr.value.productName
// subForm.value.a4 = productArr.value.productId
// subForm.value.a5 = 1
// post(`/yw3/add`, subForm.value).then(res => {
// if (res?.code == 200) {
// subForm.value = {}
// showSuccessToast('提交成功')
// } else {
// showBuy.value = false
// showFailToast(res.msg)
// }
// })
// }
fetchData() fetchData()
</script> </script>
<template> <template>
<div class="container"> <div class="container">
<PayUp ref="payupRef" :payment-info="paymentInfo" @close="handleClose" />
<var-loading description="加载中..." :loading="loading"> <var-loading description="加载中..." :loading="loading">
<div style="margin-bottom: 50px"> <div style="margin-bottom: 50px">
<div class="company-title">{{ companyInfo.a1 }}</div> <div class="company-title">{{ companyInfo.a1 }}</div>
...@@ -127,7 +142,7 @@ fetchData() ...@@ -127,7 +142,7 @@ fetchData()
</var-card> </var-card>
</div> </div>
<van-submit-bar :price="productArr.price * 100" @click="handleBuy" label="总价" button-text="立即购买" <van-submit-bar :price="productArr.price * 100" @click="handleBuy(productArr)" label="总价" button-text="立即购买"
safe-area-inset-bottom> safe-area-inset-bottom>
<template #default> <template #default>
<div> <div>
...@@ -138,18 +153,20 @@ fetchData() ...@@ -138,18 +153,20 @@ fetchData()
</template> </template>
</van-submit-bar> </van-submit-bar>
</var-loading> </var-loading>
<var-popup position="bottom" v-model:show="showBuy"> <var-popup position="bottom" v-model:show="others">
<div class="popup-example-block"> <div class="popup-example-block">
<div class="title">您暂时没有购买资格</div> <div class="title">您暂时没有购买资格</div>
<div class="title"> 如您有意向购买 请登记您的信息</div> <div class="title"> 如您有意向购买 请登记您的信息</div>
<var-form ref="form" scroll-to-error="start"> <var-form ref="form" scroll-to-error="start">
<var-space direction="column" :size="[14, 0]"> <var-space direction="column" :size="[14, 0]">
<var-input placeholder="姓名" :rules="v => !!v || '姓名不能为空'" v-model="subForm.a7" /> <var-input placeholder="姓名" :rules="v => !!v || '姓名不能为空'" v-model="subForm.a7" />
<var-input placeholder="电话" type="number" maxlength="11" :rules="v => !!v || '电话不能为空'" v-model="subForm.a8" /> <var-input placeholder="电话" type="number" maxlength="11" :rules="v => !!v || '电话不能为空'"
v-model="subForm.a8" />
</var-space> </var-space>
</var-form> </var-form>
<var-button size="large" style="margin-top: 16px;" block type="danger" @click="handleBuy1">确认提交信息</var-button> <var-button size="large" style="margin-top: 16px;" block type="danger" @click="handleBuy1">确认提交信息</var-button>
<var-button size="large" style="margin-top: 16px;" block type="info" @click="showBuy = false">我没有购买意向,误点</var-button> <var-button size="large" style="margin-top: 16px;" block type="info"
@click="others = false">我没有购买意向,误点</var-button>
</div> </div>
</var-popup> </var-popup>
</div> </div>
...@@ -225,10 +242,12 @@ fetchData() ...@@ -225,10 +242,12 @@ fetchData()
} }
} }
} }
.popup-example-block{
.popup-example-block {
height: 400px; height: 400px;
padding: 16px; padding: 16px;
.title{
.title {
font-size: 16px; font-size: 16px;
font-weight: 600; font-weight: 600;
color: red; color: red;
......
<template> <template>
<div class="container"> <div class="container">
<div class="empty-tips">暂未购买过产品</div> <div class="empty-tips" v-if="productList.length === 0">暂未购买过产品</div>
<template v-else>
<div class="card" v-for="item in productList" :key="item?.productData?.productId" @click="navigateTo('/product/company/' + item?.productData?.productId)">
<div class="leftbox">
<div class="title">
{{ item.productData.productName }}
</div>
<div>
购买时间:{{ item.createTime }}
</div>
<div>订单号:{{ item.orderId }}</div>
<div style="margin: 6px;">
<span style="font-size: 12px;color: red;border: 1px solid red;border-radius: 5px;padding: 5px;">央企送拍</span>
<span
style="font-size: 12px;margin: 0 10px;color: red;border: 1px solid red;border-radius: 5px;padding: 5px;">国有资产</span>
<span style="font-size: 12px;color: red;border: 1px solid red;border-radius: 5px;padding: 5px;">放心付</span>
</div>
<div class="content">
<div v-for="(info, index) in [
{ title: '售价', value: item.productData.price + '元' },
{ title: '每日收益', value: item.productData.productType + '元' },
{ title: '收益周期', value: item.productData.buttonStyle }
]" :key="index" class="item">
<div class="item-title">{{ info.title }}</div>
<div class="item-value">{{ info.value }}</div>
</div>
</div>
<div>赠送公司分红<span style="color: red;">{{ item.productData.productTitle }}</span></div>
</div>
</div>
</template>
</div> </div>
</template> </template>
<script setup> <script setup>
...@@ -11,6 +42,12 @@ definePageMeta({ ...@@ -11,6 +42,12 @@ definePageMeta({
keepalive: true keepalive: true
}) })
const productList = ref([])
const getProductList = async () => {
const res = await get('/api/api/transfer/listUser?orderType=0')
productList.value = res.data
}
getProductList()
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.container { .container {
...@@ -25,5 +62,79 @@ definePageMeta({ ...@@ -25,5 +62,79 @@ definePageMeta({
color: #999; color: #999;
font-size: 14px; font-size: 14px;
} }
.card {
margin: 16px 6px;
display: flex;
justify-content: space-between;
align-items: stretch;
background-color: #fff;
border-radius: 12px;
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
overflow: hidden;
transition: all 0.3s ease;
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
}
&-active {
transform: scale(0.98);
opacity: 0.8;
}
}
.leftbox {
padding: 16px;
flex: 1;
.title {
font-size: 16px;
font-weight: bold;
color: #333;
margin-bottom: 12px;
}
.content {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 2px;
.item {
text-align: center;
.item-title {
font-size: 14px;
color: #666;
margin-bottom: 4px;
}
.item-value {
font-size: 14px;
color: #e62129;
font-weight: 500;
}
}
}
}
.rightbox {
width: 60px;
background-color: #e62129;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.3s ease;
.title {
writing-mode: vertical-lr;
text-orientation: upright;
font-weight: 500;
}
}
} }
</style> </style>
\ No newline at end of file
<script setup> <script setup>
import { ref, watch, onMounted } from 'vue' import { ref, watch } from 'vue'
import { get, post } from '~/utils/request' import { post } from '~/utils/request'
const route = useRoute() const route = useRoute()
...@@ -26,6 +26,7 @@ const range = ref([ ...@@ -26,6 +26,7 @@ const range = ref([
{ text: "生活补贴", value: 1 }, { text: "生活补贴", value: 1 },
{ text: "产品收益", value: 2 }, { text: "产品收益", value: 2 },
{ text: "公司分红", value: 5 }, { text: "公司分红", value: 5 },
{ text: "分销奖励", value: 6 },
]) ])
// 获取路由参数中的tab // 获取路由参数中的tab
...@@ -36,16 +37,21 @@ const resetList = () => { ...@@ -36,16 +37,21 @@ const resetList = () => {
list.value = [] list.value = []
pageNum.value = 1 pageNum.value = 1
finished.value = false finished.value = false
loading.value = false loading.value = true // 改为 true,避免 van-list 立即触发 load
total.value = 0 total.value = 0
emptyTipsShow.value = false emptyTipsShow.value = false
getList()
} }
watch(active, () => { // Tab 点击处理
const handleClick = (item) => {
if (active.value === item.value) return
active.value = item.value
resetList() resetList()
}) }
const getList = async () => { const getList = async () => {
if (loading.value) { // 添加loading检查,避免重复请求
try { try {
const data = { const data = {
balanceType: active.value, balanceType: active.value,
...@@ -62,9 +68,6 @@ const getList = async () => { ...@@ -62,9 +68,6 @@ const getList = async () => {
} else { } else {
pageNum.value++ pageNum.value++
} }
if (list.value.length >= total.value) {
finished.value = true
}
} else { } else {
showFailToast(res.msg || '加载失败') showFailToast(res.msg || '加载失败')
finished.value = true finished.value = true
...@@ -75,15 +78,13 @@ const getList = async () => { ...@@ -75,15 +78,13 @@ const getList = async () => {
} finally { } finally {
loading.value = false loading.value = false
} }
}
} }
// Tab 点击处理 // 初始加载
const handleClick = (item) => { onMounted(() => {
if (active.value === item.value) return
active.value = item.value
resetList() resetList()
} })
</script> </script>
<template> <template>
...@@ -94,9 +95,15 @@ const handleClick = (item) => { ...@@ -94,9 +95,15 @@ const handleClick = (item) => {
{{ item.text }} {{ item.text }}
</var-tab> </var-tab>
</var-tabs> </var-tabs>
<!-- List --> <!-- List -->
<van-list class="list-container" v-model:loading="loading" :finished="finished" finished-text="没有更多了" <van-list
@load="getList"> class="list-container"
v-model:loading="loading"
:finished="finished"
finished-text="没有更多了"
@load="getList"
>
<div v-for="(item, index) in list" :key="index" class="detail-item"> <div v-for="(item, index) in list" :key="index" class="detail-item">
<!-- 头部信息 --> <!-- 头部信息 -->
<div class="item-header"> <div class="item-header">
...@@ -106,7 +113,8 @@ const handleClick = (item) => { ...@@ -106,7 +113,8 @@ const handleClick = (item) => {
item.balanceType == 0 ? '信用分' : item.balanceType == 0 ? '信用分' :
item.balanceType == 1 ? '生活补贴' : item.balanceType == 1 ? '生活补贴' :
item.balanceType == 2 ? '产品收益' : item.balanceType == 2 ? '产品收益' :
item.balanceType == 5 ? '公司分红' : '' item.balanceType == 5 ? '公司分红' :
item.balanceType == 6 ? '分销奖励' : ''
}} }}
</span> </span>
</div> </div>
...@@ -140,6 +148,7 @@ const handleClick = (item) => { ...@@ -140,6 +148,7 @@ const handleClick = (item) => {
剩余:{{ item.amount }}{{ item.balanceType === 2 || item.balanceType === 1 ? '元' : '' }} 剩余:{{ item.amount }}{{ item.balanceType === 2 || item.balanceType === 1 ? '元' : '' }}
</div> </div>
</div> </div>
<div class="item-footer"> <div class="item-footer">
<time>{{ item.time }}</time> <time>{{ item.time }}</time>
</div> </div>
...@@ -153,6 +162,7 @@ const handleClick = (item) => { ...@@ -153,6 +162,7 @@ const handleClick = (item) => {
min-height: calc(100vh - 54px); min-height: calc(100vh - 54px);
background: #fff; background: #fff;
font-family: pingfang; font-family: pingfang;
.fixed-tabs { .fixed-tabs {
position: fixed; position: fixed;
top: 52px; top: 52px;
......
export interface PaymentProps {
show: boolean; // 是否显示弹窗
mony: number; // 金额
dw: string; // 单位
btn: string; // 按钮文字
productId: string; // 产品 ID
type: number; // 支付类型
url: string; // 支付接口地址
password: boolean; // 是否需要密码
needCheck: boolean; // 是否需要校验
payway: number; // 支付方式
wechat: number; // 是否显示微信支付
zfb: number; // 是否显示支付宝支付
ysf: number; // 是否显示云闪付
tzj: number; // 是否显示保额
jtqb: number; // 是否显示体验金
dtqb: number; // 是否显示动态钱包
zfsm?: string; // 支付说明
isBindc?: boolean; // 是否绑定银行卡
isBindpay?: boolean; // 是否绑定支付
}
export interface PaymentMethod {
name: string; // 支付方式名称
label: string; // 显示名称
icon: string; // 图标路径
visible: boolean; // 是否显示
}
\ No newline at end of file
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