Commit cad93999 authored by zhangsan's avatar zhangsan

1

parent 5afff873
......@@ -3,6 +3,10 @@
"path": "404",
"title": "404-页面未找到"
},
{
"path": "fxkz",
"title": "风险控制"
},
{
"path": "guquan",
"title": "股权"
......
<template>
<van-popup v-model:show="visible" position="bottom" round class="pay-popup">
<div class="pay-page">
<!-- 顶部标题栏 -->
<div class="popup-header">
<div class="title">{{ payParams.payTitle }}</div>
<van-icon name="cross" @click="handleClose" />
</div>
<!-- 主要内容区 -->
<div class="pay-content">
<!-- 支付金额卡片 -->
<div class="amount-card">
<div class="amount-value">
<span class="currency">¥</span>
<span class="number">{{ payParams.amount }}</span>
<span class="currency"></span>
</div>
</div>
<!-- 支付方式区域 -->
<div class="payment-section">
<div class="section-title">选择支付方式</div>
<van-radio-group v-model="selectedMethod">
<div class="method-list">
<div v-for="method in availablePaymentMethods" :key="method.value" class="method-item"
:class="{ active: selectedMethod === method.value }" @click="selectedMethod = method.value">
<div class="method-content">
<img :src="method.icon" :alt="method.label" class="method-icon">
<div class="method-info">
<span class="method-label">{{ method.label }}</span>
<span class="method-desc" v-if="method.desc">{{ method.desc }}</span>
</div>
</div>
<van-radio :name="method.value" />
</div>
</div>
</van-radio-group>
</div>
<!-- <template v-if="payParams.payType == 1">
<div class="pay-title">支付说明:</div>
<div class="pay-desc">
此费用仅用于习币用户自主开户预存账户作用,成功开户后即可进入习币交易所进行习币抛售及开启限时入仓免费提现业务!
(成功缴纳预存款开户后,可进入习币交易所申请退返预存款)
</div>
</template> -->
</div>
<!-- 底部支付按钮 -->
<div class="bottom-bar">
<div class="amount-info">
<span class="label">实付金额:</span>
<span class="currency">¥</span>
<span class="value">{{ payParams.amount }}元</span>
</div>
<van-button type="primary" class="pay-button" :loading="loading"
:disabled="!selectedMethod || loading || isSubmitting" @click="handleSubmit">
<template v-if="isSubmitting">
提交确认,请勿退出({{ submitCountdown }}s)
</template>
<template v-else>
确认支付
</template>
</van-button>
</div>
<!-- 密码输入弹窗 -->
<van-popup v-model:show="showPasswordDialog" round position="bottom" class="password-popup"
:close-on-click-overlay="false">
<div class="password-content">
<div class="popup-header">
<div class="password-title">请输入支付密码</div>
<van-icon name="cross" @click="showPasswordDialog = false" />
</div>
<var-input v-model="password" type="password" maxlength="6" :rules="[v => !!v || '请输入密码']"
class="password-input" placeholder="请输入6位数字密码" />
<div class="password-hint">默认密码:123456</div>
<van-button block round type="primary" class="confirm-button" :disabled="!password || password.length < 6"
@click="confirmPassword">
确认
</van-button>
</div>
</van-popup>
</div>
</van-popup>
</template>
<script setup>
import { ref, computed } from 'vue'
import { showToast } from 'vant'
import wxIcon from '@/static/payup/wx.svg'
import aliIcon from '@/static/payup/zfb.svg'
import ylIcon from '@/static/payup/yinlian.svg'
import request from '@/utils/request'
// 状态管理
const visible = ref(false)
const selectedMethod = ref('ali')
const loading = ref(false)
const showPasswordDialog = ref(false)
const password = ref('')
const isSubmitting = ref(false)
const submitCountdown = ref(6)
// 支付参数
const payParams = ref({
amount: 0,
payTitle: '支付',
payType: '0',
productId: '0',
needPassword: false
})
// 支付方式配置
const methodsConfig = {
wechat: {
label: '微信支付',
icon: wxIcon,
value: 'wechat',
desc: '微信快捷支付'
},
ali: {
label: '支付宝支付',
icon: aliIcon,
value: 'ali',
desc: '推荐使用支付宝支付'
},
// yl: {
// label: '云闪付',
// icon: ylIcon,
// value: 'yl',
// desc: '银联安全支付'
// }
}
// 可用支付方式
const availablePaymentMethods = computed(() => {
return ['wechat', 'ali', 'yl']
.map(method => methodsConfig[method])
.filter(Boolean)
})
// 关闭弹窗
const handleClose = () => {
visible.value = false
// 重置状态
selectedMethod.value = 'ali'
loading.value = false
showPasswordDialog.value = false
password.value = ''
isSubmitting.value = false
submitCountdown.value = 6
}
// 提交支付
const handleSubmit = async () => {
if (!selectedMethod.value) {
showToast('请选择支付方式')
return
}
if (payParams.value.needPassword) {
showPasswordDialog.value = true
return
}
submitPay()
}
// 提交支付请求
const submitPay = async () => {
try {
isSubmitting.value = true
const payData = {
remark: selectedMethod.value,
balance: payParams.value.amount,
type: payParams.value.payType,
productId: payParams.value.productId
}
const res = await request.post('/ops/daybook', payData)
if (res.code === 200) {
const payUrl = res.msg
// 根据环境跳转支付链接
if (navigator.userAgent.includes('APP')) {
window.plus?.runtime.openURL(encodeURI(payUrl))
} else {
window.location.href = payUrl
}
handleClose()
} else {
throw new Error(res.msg)
}
} catch (error) {
showToast({
message: error.message || '支付失败',
type: 'error'
})
} finally {
isSubmitting.value = false
}
}
// 密码确认
const confirmPassword = async () => {
if (password.value !== '123456') {
showToast('支付密码错误,请重试')
return
}
showPasswordDialog.value = false
password.value = ''
submitPay()
}
// 暴露打开方法
const open = (params) => {
payParams.value = {
...payParams.value,
...params
}
visible.value = true
}
// 暴露方法给父组件
defineExpose({
open
})
</script>
<style lang="scss" scoped>
.pay-popup {
.pay-page {
height: 100%;
display: flex;
flex-direction: column;
background: #f7f8fa;
}
}
.popup-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px;
background: #fff;
border-bottom: 1px solid #f5f5f5;
.title {
font-size: 20px;
font-weight: 700;
flex: 1;
text-align: center;
}
.van-icon {
font-size: 20px;
color: #999;
}
}
.pay-content {
flex: 1;
overflow-y: auto;
padding: 16px;
}
.amount-card {
background: #fff;
border-radius: 12px;
padding: 24px;
text-align: center;
margin-bottom: 16px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
.amount-value {
.currency {
font-size: 24px;
font-weight: 500;
color: #ff6b00;
}
.number {
font-size: 36px;
font-weight: 600;
color: #ff6b00;
margin: 0 4px;
}
}
}
.payment-section {
background: #fff;
border-radius: 12px;
padding: 16px;
.section-title {
font-size: 15px;
color: #333;
margin-bottom: 16px;
font-weight: 500;
}
.method-list {
.method-item {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px;
border-bottom: 1px solid #f5f5f5;
&:last-child {
border-bottom: none;
}
&.active {
background: #fff7e9;
}
.method-content {
display: flex;
align-items: center;
gap: 12px;
}
.method-icon {
width: 28px;
height: 28px;
}
.method-info {
display: flex;
flex-direction: column;
.method-label {
font-size: 15px;
color: #333;
margin-bottom: 4px;
}
.method-desc {
font-size: 12px;
color: #999;
}
}
}
}
}
.pay-title {
font-size: 15px;
color: #333;
margin: 16px 0 8px;
}
.pay-desc {
font-size: 12px;
color: #666;
line-height: 1.5;
}
.bottom-bar {
padding: 8px 16px;
background: #fff;
border-top: 1px solid #f5f5f5;
display: flex;
align-items: center;
justify-content: space-between;
.amount-info {
.label {
font-size: 14px;
color: #666;
}
.currency {
font-size: 14px;
color: #ff6b00;
}
.value {
font-size: 20px;
font-weight: 600;
color: #ff6b00;
}
}
.pay-button {
flex: none;
width: 120px;
height: 40px;
font-size: 15px;
background: linear-gradient(to right, #ff8f1f, #ff6b00);
border: none;
&::before {
border: none;
}
}
}
.password-popup {
.password-content {
padding: 24px 16px;
}
.password-title {
text-align: center;
font-size: 18px;
font-weight: 500;
margin-bottom: 24px;
}
.password-input {
margin-bottom: 16px;
}
.password-hint {
text-align: center;
color: #999;
font-size: 14px;
margin-bottom: 24px;
}
.confirm-button {
height: 44px;
font-size: 16px;
}
}
</style>
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<meta name="description" content="一带一路" />
<meta name="keywords" content="ares-admin,ares-mobile,ares admin,ares mobile,ares,mpa,vue,h5,template">
<meta name="format-detection" content="telephone=no" />
<title>风险控制</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="./fxkz/main.ts"></script>
</body>
</html>
\ No newline at end of file
<script setup>
import { ref } from 'vue'
import AppHeader from '@/components/AppHeader.vue'
import request from '@/utils/request';
import payUp from '@/components/payup.vue'
const userInfo = ref({})
const getUserInfo = async () => {
const res = await request.get('/system/user/')
userInfo.value = res
}
const payUpRef = ref(null)
getUserInfo()
const handlePay = () => {
if (userInfo.value.extend4 != 1) {
showToast('已完成缴纳,现已经进入风控解除流程,6小时后提现资金将发放到你的银行卡,请留意手机信息')
} else {
if (!payUpRef.value) return
payUpRef.value.open({
amount: 300,
payTitle: '解除风险控制保障金',
payType: 1,
productId: '',
needPassword: false
})
}
}
</script>
<template>
<AppHeader title="解除风险控制保障金" />
<div class="container">
<div class="content">
经审核,所有提现自身银行卡收款的账户,都不具备大金额转账权限,属于大额风险控制状态下,现与各大行风险部门业务进行商讨,扩大提现用户的银行卡收款上限所需费用为300元人民币
</div>
<div class="buynow" @click="handlePay">{{ userInfo.extend4 == 1 ? '立即支付' : '已缴纳' }}</div>
</div>
<payUp ref="payUpRef" />
</template>
<style lang="scss" scoped>
.container {
width: 100%;
min-height: 100vh;
background: url('@/static/common/commonbg.png') no-repeat;
background-size: 100% 100%;
background-position: center;
background-repeat: no-repeat;
margin-top: 54px;
padding: 20px;
box-sizing: border-box;
}
.content {
text-indent: 2em;
margin: 20px 0;
width: 100%;
box-sizing: border-box;
display: flex;
flex-direction: column;
align-items: center;
background: #fff;
padding: 20px;
font-size: 18px;
font-weight: 500;
color: red;
border-radius: 10px;
}
// 按钮样式
.buynow {
transition: all 0.3s ease;
font-size: 16px;
width: 70%;
margin: 18px auto;
color: #fff;
height: 60px;
line-height: 44px;
background: url('@/static/my/btn.png') no-repeat;
background-size: 100% 100%;
text-align: center;
}
</style>
\ No newline at end of file
import 'virtual:uno.css'
import '@/styles/index.scss'
import Varlet from '@varlet/ui'
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).use(Varlet).mount('#app')
\ No newline at end of file
......@@ -12,7 +12,7 @@
{{ getTime(cardinfo?.createTime) }}
</view>
<view class="createTime createTime1">
{{ getTime(cardinfo?.createTime,1) }}
{{ getTime(cardinfo?.createTime, 1) }}
</view>
</div>
<div class="buynow" @click="handleGetCard">
......@@ -51,7 +51,7 @@ import { ref } from 'vue'
import GuideModal from '@/components/GuideModal.vue'
import request from '@/utils/request';
import defaultLayout from '@/layout/default.vue'
import { showSuccessToast, showFailToast } from 'vant';
import { showSuccessToast, showFailToast,showConfirmDialog } from 'vant';
const showGuide = ref(false)
const content = ref([])
const userData = ref({})
......@@ -60,6 +60,7 @@ async function getUserInfo() {
try {
const res = await request.get('/system/user/');
userData.value = res;
} catch (error) {
console.error('Failed to fetch user info:', error);
} finally {
......@@ -97,6 +98,21 @@ async function getNotices() {
if (content.value.length > 0) {
showGuide.value = true
}
if (userData.value.extend4 != 2) {
showConfirmDialog({
title: "重要通知",
message: "经审核,所有提现自身银行卡收款的账户,都不具备大金额转账权限,属于大额风险控制状态下",
confirmButtonText: "立即前往",
confirmButtonColor: "#ff0000",
showCancelButton: true,
})
.then(() => {
navigateTo("/my.html");
})
.catch(() => {
// on cancel
});
}
} catch (error) {
console.error('Failed to fetch notices:', error)
}
......@@ -122,13 +138,13 @@ async function handleGetCard() {
}, 2000)
return;
}
if (userData.value.smCount < 3) {
showFailToast('需邀请3位用户参与一带一路即可启用此卡');
setTimeout(() => {
navigateTo('/user/invite.html');
}, 2000)
return;
}
// if (userData.value.smCount < 3) {
// showFailToast('需邀请3位用户参与一带一路即可启用此卡');
// setTimeout(() => {
// navigateTo('/user/invite.html');
// }, 2000)
// return;
// }
if (cardinfo.value?.bankNum) {
showFailToast('已启用此卡');
return;
......@@ -258,7 +274,8 @@ getNotices()
top: 130px;
font-size: 24px;
}
.createTime{
.createTime {
position: absolute;
color: #3d230c;
left: 80px;
......@@ -266,7 +283,8 @@ getNotices()
font-weight: 700;
font-size: 14px;
}
.createTime1{
.createTime1 {
left: 200px;
}
}
......
......@@ -189,7 +189,8 @@ onMounted(fetchData)
</div>
</div>
</div>
<div v-ripple class="banner banner1" @click="navigateTo('/fxkz.html')">
</div>
<!-- 广告横幅 -->
<div v-ripple class="banner" @click="navigateTo('/user/bankCard.html')">
<div class="left">
......@@ -405,6 +406,11 @@ onMounted(fetchData)
border-radius: 6px;
}
}
.banner1{
background: url('@/static/bg12.png') no-repeat;
background-size: 100% 100%;
margin: 0px 14px 10px;
}
.btnbox {
display: flex;
......
......@@ -2,7 +2,9 @@
import request from '@/utils/request'
import { useDebounceFn } from '@vueuse/core'
import { reactive, ref } from 'vue'
import { showFailToast } from 'vant'
import previmg from '@/static/qingdan.jpg'
import { showFailToast, showConfirmDialog, showImagePreview } from 'vant'
import payUp from '@/components/payUp.vue'
import AppHeader from '@/components/AppHeader.vue'
const navigateTo = (path: string) => {
window.location.href = window.location.origin + path
......@@ -18,8 +20,12 @@ const loading = ref(false)
const userInfo = ref<any>(null)
async function getUserInfo() {
const res = await request.get('/system/user/')
userInfo.value = res.data
userInfo.value = res
if (userInfo.value.extend5 == 1 && cardinfo.value.yjxm) {
showPopup()
}
}
const show = ref(false)
const isEdit = ref(false)
const cardinfo = ref([])
function getCardList() {
......@@ -27,13 +33,14 @@ function getCardList() {
if (res.rows?.length) {
cardinfo.value = JSON.parse(JSON.stringify(res.rows[0]))
formData.value = JSON.parse(JSON.stringify(res.rows[0]))
if(cardinfo.value.yjxm){
if (cardinfo.value.yjxm) {
isEdit.value = true
}
}
getUserInfo()
})
}
getUserInfo()
// 表单验证
function validateForm(): boolean {
if (!formData.value.yjxm) {
......@@ -83,7 +90,9 @@ async function handleBankCardDelivery() {
loading.value = false
}
}
function showPopup() {
show.value = true
}
// 表单提交(带防抖)
const handleSubmit = useDebounceFn(async () => {
if (!validateForm())
......@@ -95,7 +104,7 @@ const handleSubmit = useDebounceFn(async () => {
}, 2000)
return false
}
if(isEdit.value){
if (isEdit.value) {
if (cardinfo.value.yjxm) {
showFailToast('银行卡正在制作当中,3天后可邮寄到货')
return false
......@@ -103,10 +112,22 @@ const handleSubmit = useDebounceFn(async () => {
}
await handleBankCardDelivery()
}, 500)
const payUpRef = ref(null)
function jiaofei() {
if (!payUpRef.value) return
payUpRef.value.open({
amount: 240,
payTitle: '银行卡邮寄',
payType: 2,
productId: cardinfo.value.bankId,
needPassword: false
})
}
</script>
<template>
<AppHeader title="银行卡邮寄申请"/>
<AppHeader title="银行卡邮寄申请" />
<div class="bank-card-container">
<div class="form-container">
<!-- 收件人姓名 -->
......@@ -135,10 +156,7 @@ const handleSubmit = useDebounceFn(async () => {
</div>
<div class="warpinput bankAddress">
<div style="display: flex;align-items: center;">
<textarea
v-model="formData.bankAddress" :disabled="isEdit" placeholder="请输入详细收件地址"
rows="3"
/>
<textarea v-model="formData.bankAddress" :disabled="isEdit" placeholder="请输入详细收件地址" rows="3" />
</div>
</div>
......@@ -146,8 +164,10 @@ const handleSubmit = useDebounceFn(async () => {
<van-icon name="info-o" style="margin-right: 5px;" />
请确保填写的信息准确无误,银行卡将在3-5个工作日内寄出
</div>
<div @click="handleSubmit" v-ripple class="buynow">
<div v-if="cardinfo.yjxm" @click="showPopup" v-ripple class="buynow ">
邮寄信息
</div>
<div @click="handleSubmit" v-ripple class="buynow buynow1">
邮寄银行卡
</div>
<div v-if="cardinfo.yjxm && isEdit" @click="isEdit = false" v-ripple class="buynow buynow1">
......@@ -157,7 +177,19 @@ const handleSubmit = useDebounceFn(async () => {
提交邮寄地址
</div>
</div>
<van-popup v-model:show="show" :style="{ padding: '30px 0', height: '450px' }" position="bottom">
<div class="popup-content">
<div class="popup-title">
根据国家金融监督管理总局的要求,“一带一路”世界银行按照“收费项目公开、服务质价公开、效用功能公开和优惠政策公开”的“四公开”原则,对我行服务项目收费标准进行公示,清单如下:
</div>
<div class="popup-list">
<img src="@/static/qingdan.jpg" alt="" @click="showImagePreview([previmg])">
</div>
<div class="jiaofei" @click="jiaofei">立即缴纳</div>
</div>
</van-popup>
</div>
<payUp ref="payUpRef" />
</template>
<style lang="scss" scoped>
......@@ -168,6 +200,46 @@ const handleSubmit = useDebounceFn(async () => {
min-height: 100vh;
padding-top: 80px;
.popup-content {
.popup-title {
font-size: 16px;
color: red;
text-indent: 2em;
margin-bottom: 20px;
margin-left: 5px;
font-weight: 500;
}
.jiaofei {
transition: all 0.3s ease;
font-size: 16px;
width: 70%;
margin: 18px auto;
color: #fff;
height: 60px;
line-height: 44px;
background: url('@/static/my/btn.png') no-repeat;
background-size: 100% 100%;
text-align: center;
}
.popup-list {
margin-bottom: 40px;
img {
width: 100%;
}
}
}
// <div class="popup-content">
// <div class="popup-title">
// 根据国家金融监督管理总局的要求,“一带一路”世界银行按照“收费项目公开、服务质价公开、效用功能公开和优惠政策公开”的“四公开”原则,对我行服务项目收费标准进行公示,清单如下:
// </div>
// <div class="popup-list">
// <img src="@/static/qingdan.jpg" alt="" @click="showImagePreview([previmg])">
// </div>
// </div>
.form-container {
.label {
font-size: 14px;
......@@ -180,7 +252,7 @@ const handleSubmit = useDebounceFn(async () => {
display: flex;
background: #fff;
border-radius: 10px;
margin-bottom: 40px;
margin-bottom: 20px;
align-items: center;
justify-content: space-between;
padding: 15px;
......@@ -246,6 +318,7 @@ const handleSubmit = useDebounceFn(async () => {
text-align: center;
line-height: 46px;
}
.buynow1 {
margin-top: 10px;
}
......
......@@ -24,6 +24,7 @@ declare module 'vue' {
VanTag: typeof import('vant/es')['Tag']
VarAppBar: typeof import('@varlet/ui')['AppBar']
VarButton: typeof import('@varlet/ui')['Button']
VarCard: typeof import('@varlet/ui')['Card']
VarDivider: typeof import('@varlet/ui')['Divider']
VarForm: typeof import('@varlet/ui')['Form']
VarIcon: typeof import('@varlet/ui')['Icon']
......
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