Commit 3e692e42 authored by zhangsan's avatar zhangsan

1

parent 2d01666c
......@@ -19,7 +19,6 @@ declare module 'vue' {
SignIn: typeof import('./components/signIn.vue')['default']
VanButton: typeof import('vant/es')['Button']
VanDivider: typeof import('vant/es')['Divider']
VanEmpty: typeof import('vant/es')['Empty']
VanList: typeof import('vant/es')['List']
VanLoading: typeof import('vant/es')['Loading']
VanNavBar: typeof import('vant/es')['NavBar']
......
src/static/invitebg.png

992 KB

import router from "@/router";
export const isEealNameAuthentication = () => {
const userInfo = JSON.parse(sessionStorage.getItem("userInfo") || "{}");
console.log(userInfo);
if (userInfo.data === "true") {
return true;
}
showConfirmDialog({
title: "请先进行实名认证",
message: "实名认证将获得50万元财政结算余额进行提现,并获取30万元贴现国债,进行每日免费收益提现,并且可以出售贴现国债期货",
confirmButtonText: "立即前往",
confirmButtonColor: "#ff0000",
showCancelButton: true,
})
.then(() => {
router.push("/user/shiming");
})
.catch(() => {
// on cancel
});
return false;
};
/**
* 身份证号码验证接口
*/
interface IDCardValidationResult {
isValid: boolean
message?: string
}
isValid: boolean;
message?: string;
}
/**
/**
* 验证身份证号码
* @param id 身份证号码
* @returns boolean
*/
export const isValidIDCard = (id: string): boolean => {
if (!id) return false
export const isValidIDCard = (id: string): boolean => {
if (!id) return false;
// 15 位身份证验证
if (id.length === 15) {
return isValidIDCard15(id)
return isValidIDCard15(id);
}
// 18 位身份证验证
if (id.length === 18) {
return isValidIDCard18(id)
return isValidIDCard18(id);
}
return false
}
return false;
};
/**
/**
* 验证银行卡号
* @param cardNumber 银行卡号
* @returns boolean
*/
export const isValidBankCard = (cardNumber: string): boolean => {
export const isValidBankCard = (cardNumber: string): boolean => {
// 银行卡号只检查长度和是否为数字
return /^\d{16,19}$/.test(cardNumber)
}
return /^\d{16,19}$/.test(cardNumber);
};
/**
/**
* 验证15位身份证号码
* @param id 15位身份证号码
* @returns boolean
*/
function isValidIDCard15(id: string): boolean {
function isValidIDCard15(id: string): boolean {
// 只检查是否为 15 位纯数字
const regex = /^\d{15}$/
if (!regex.test(id)) return false
const regex = /^\d{15}$/;
if (!regex.test(id)) return false;
// 校验出生日期
const year = parseInt(id.substr(6, 2))
const month = parseInt(id.substr(8, 2))
const day = parseInt(id.substr(10, 2))
const year = parseInt(id.substr(6, 2));
const month = parseInt(id.substr(8, 2));
const day = parseInt(id.substr(10, 2));
// 使用当前年份来做年份范围的检查
const currentYear = new Date().getFullYear()
const fullYear = year + (year >= 50 ? 1900 : 2000)
const currentYear = new Date().getFullYear();
const fullYear = year + (year >= 50 ? 1900 : 2000);
// 日期校验
const birthDate = new Date(fullYear, month - 1, day)
const birthDate = new Date(fullYear, month - 1, day);
return (
birthDate.getFullYear() === fullYear &&
birthDate.getMonth() === month - 1 &&
birthDate.getDate() === day
)
}
);
}
/**
/**
* 验证18位身份证号码
* @param id 18位身份证号码
* @returns boolean
*/
function isValidIDCard18(id: string): boolean {
function isValidIDCard18(id: string): boolean {
// 只检查是否为 18 位的数字或X结尾
const regex = /^\d{17}(\d|X)$/
if (!regex.test(id)) return false
const regex = /^\d{17}(\d|X)$/;
if (!regex.test(id)) return false;
// 校验出生日期
const year = parseInt(id.substr(6, 4))
const month = parseInt(id.substr(10, 2))
const day = parseInt(id.substr(12, 2))
const birthDate = new Date(year, month - 1, day)
const year = parseInt(id.substr(6, 4));
const month = parseInt(id.substr(10, 2));
const day = parseInt(id.substr(12, 2));
const birthDate = new Date(year, month - 1, day);
return (
birthDate.getFullYear() === year &&
birthDate.getMonth() === month - 1 &&
birthDate.getDate() === day
)
}
);
}
/**
/**
* 掩码处理身份证号码
* @param idNumber 身份证号码
* @returns string 掩码后的身份证号码
*/
export const maskIdNumber = (idNumber: string): string => {
if (!idNumber) return idNumber
export const maskIdNumber = (idNumber: string): string => {
if (!idNumber) return idNumber;
// 处理18位身份证
if (idNumber.length === 18) {
return idNumber.replace(/^(\d{6})(\d{8})(\d{4})$/, '$1********$3')
return idNumber.replace(/^(\d{6})(\d{8})(\d{4})$/, "$1********$3");
}
// 处理15位身份证
if (idNumber.length === 15) {
return idNumber.replace(/^(\d{6})(\d{6})(\d{3})$/, '$1******$3')
return idNumber.replace(/^(\d{6})(\d{6})(\d{3})$/, "$1******$3");
}
return idNumber
}
return idNumber;
};
/**
/**
* 数字转中文大写
* @param num 需要转换的数字
* @returns string 转换后的中文大写
*/
export const convertToChineseUppercase = (num: number): string => {
const units = ['', '', '', '', '', '十万', '百万', '千万', '亿']
const digits = ['', '', '', '', '', '', '', '', '', '']
export const convertToChineseUppercase = (num: number): string => {
const units = ["", "", "", "", "", "十万", "百万", "千万", "亿"];
const digits = ["", "", "", "", "", "", "", "", "", ""];
if (num === 0) return digits[0]
if (num === 0) return digits[0];
let result = ''
let unitIndex = 0
let zeroFlag = false
let result = "";
let unitIndex = 0;
let zeroFlag = false;
while (num > 0) {
const digit = num % 10
const digit = num % 10;
if (digit > 0) {
result = digits[digit] + (units[unitIndex] || '') + result
zeroFlag = false
result = digits[digit] + (units[unitIndex] || "") + result;
zeroFlag = false;
} else if (!zeroFlag) {
result = digits[0] + result
zeroFlag = true
result = digits[0] + result;
zeroFlag = true;
}
num = Math.floor(num / 10)
unitIndex++
num = Math.floor(num / 10);
unitIndex++;
}
return result
.replace(/零+/g, '')
.replace(/零$/, '')
.replace(/个$/, '')
}
return result.replace(/零+/g, "").replace(/零$/, "").replace(/个$/, "");
};
/**
/**
* 验证身份证号码并返回详细信息
* @param id 身份证号码
* @returns IDCardValidationResult
*/
export const validateIDCard = (id: string): IDCardValidationResult => {
export const validateIDCard = (id: string): IDCardValidationResult => {
if (!id) {
return {
isValid: false,
message: '身份证号码不能为空'
}
message: "身份证号码不能为空",
};
}
if (id.length !== 15 && id.length !== 18) {
return {
isValid: false,
message: '身份证号码长度不正确'
}
message: "身份证号码长度不正确",
};
}
const isValid = isValidIDCard(id)
const isValid = isValidIDCard(id);
return {
isValid,
message: isValid ? undefined : '身份证号码格式不正确'
}
}
/**
message: isValid ? undefined : "身份证号码格式不正确",
};
};
/**
* 验证银行名称是否合法
* @param bankName 银行名称
* @returns boolean
*/
export const isValidBankName = (bankName: string): boolean => {
export const isValidBankName = (bankName: string): boolean => {
if (!bankName) return false;
return bankName.includes('银行');
}
return bankName.includes("银行");
};
/**
/**
* 验证银行卡号并返回详细信息
* @param cardNumber 银行卡号
* @returns { isValid: boolean, message?: string }
*/
export const validateBankCard = (cardNumber: string): { isValid: boolean; message?: string } => {
export const validateBankCard = (
cardNumber: string
): { isValid: boolean; message?: string } => {
if (!cardNumber) {
return {
isValid: false,
message: '银行卡号不能为空'
}
message: "银行卡号不能为空",
};
}
const isValid = isValidBankCard(cardNumber)
const isValid = isValidBankCard(cardNumber);
return {
isValid,
message: isValid ? undefined : '银行卡号格式不正确'
}
}
\ No newline at end of file
message: isValid ? undefined : "银行卡号格式不正确",
};
};
......@@ -2,8 +2,12 @@
import { ref } from 'vue'
import request from '@/utils/request'
import NavBar from '@/components/NavBar.vue'
import { useRouter } from 'vue-router'
const router = useRouter()
const extend8 = ref('')
const extend7 = ref('')
const errors = ref({ extend8: '', extend7: '' })
const userInfo = ref({})
function getUserInfo() {
......@@ -14,12 +18,49 @@ function getUserInfo() {
})
}
getUserInfo()
function validateAlipay(value) {
if (!value) {
return '支付宝账号不能为空'
}
// 支持手机号或邮箱格式
const phoneReg = /^1[3-9]\d{9}$/
const emailReg = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
if (!phoneReg.test(value) && !emailReg.test(value)) {
return '请输入正确的手机号或邮箱格式'
}
return ''
}
function validateName(value) {
if (!value) {
return '姓名不能为空'
}
const nameReg = /^[\u4e00-\u9fa5]{2,8}$/
if (!nameReg.test(value)) {
return '请输入2-8个汉字的真实姓名'
}
return ''
}
async function handleBind() {
// 表单验证
errors.value.extend8 = validateAlipay(extend8.value)
errors.value.extend7 = validateName(extend7.value)
if (errors.value.extend8 || errors.value.extend7) {
return
}
if(userInfo.value.dy != 4){
showFailToast('请加入人民结算党员后进行绑定')
return
}
try {
// TODO: 实现绑定支付宝逻辑
await request.post('/system/user/bdwxAndAl', {
extend8: extend8.value,
extend7: extend7.value,
extend8: extend8.value.trim(),
extend7: extend7.value.trim(),
})
showSuccessToast('绑定成功')
router.replace('/bind/card')
......@@ -36,15 +77,29 @@ async function handleBind() {
<div class="form-content">
<var-input
v-model="extend8"
placeholder="请输入支付宝账号"
placeholder="请输入支付宝账号(手机号或邮箱)"
:error="errors.extend8"
:error-message="errors.extend8"
@input="errors.extend8 = validateAlipay(extend8)"
class="input-item"
/>
>
<template #prepend>
<var-icon name="account" :size="20" />
</template>
</var-input>
<var-input
v-model="extend7"
placeholder="请输入真实姓名"
:error="errors.extend7"
:error-message="errors.extend7"
@input="errors.extend7 = validateName(extend7)"
class="input-item"
/>
>
<template #prepend>
<var-icon name="account-circle" :size="20" />
</template>
</var-input>
<var-button
type="primary"
......@@ -97,6 +152,16 @@ async function handleBind() {
height: 48px;
font-size: 15px;
}
:deep(.var-icon) {
color: #1677FF;
margin-right: 8px;
}
:deep(.var-input__error-message) {
padding-left: 12px;
font-size: 12px;
}
}
.submit-btn {
......
......@@ -10,7 +10,7 @@ const showQRCode = ref(false)
const showScanner = ref(false)
const userInfo = ref({})
const qrCodeUrl = ref('')
const kfurl = ref(sessionStorage.getItem('kfurl') || '')
// 获取用户信息
function getUserInfo() {
request.get('/system/user/').then((res) => {
......@@ -18,10 +18,10 @@ function getUserInfo() {
})
}
getUserInfo()
function saoyisao(){
if(userInfo.value.dy != 1){
function saoyisao() {
if (userInfo.value.dy == 4) {
showScanner.value = true
}else{
} else {
showFailToast('请加入人民结算党员后进行扫码付款')
}
}
......@@ -42,7 +42,7 @@ async function generateEncryptedQRCode() {
try {
const { userId, nickName: name, phonenumber: phone } = userInfo.value
// 确保所有必要的字段都存在
if ( !name || !phone) {
if (!name || !phone) {
showFailToast('用户信息不完整')
return
}
......@@ -77,6 +77,7 @@ async function generateEncryptedQRCode() {
// 处理转账按钮点击
function handleTransfer() {
router.push('/transfer')
}
......@@ -98,14 +99,23 @@ function handleScanError(error) {
// 处理绑定支付宝
function bindAlipay() {
router.push('/bind/alipay')
}
// 处理绑定微信支付
function bindWechatPay() {
router.push('/bind/wechat')
}
// 在线客服
function gokf() {
if (!kfurl.value) {
showFailToast('客服链接不存在')
return
}
window.location.href = kfurl.value
}
// 保存二维码
function saveQrCode() {
if (!qrCodeUrl.value) return
......@@ -124,17 +134,13 @@ function saveQrCode() {
<div class="card-container">
<NavBar title="财政结算" />
<!-- 扫码组件 -->
<QrScanner
v-if="showScanner"
@close="showScanner = false"
@scan-success="handleScanSuccess"
@scan-error="handleScanError"
/>
<QrScanner v-if="showScanner" @close="showScanner = false" @scan-success="handleScanSuccess"
@scan-error="handleScanError" />
<div class="topbox">
<div class="left">中华人民共和国财政结算</div>
<div class="right">
<div class="item">
<div class="item" @click="gokf">
<img src="@/static/pages/home/kf2.png" alt="">
<span>在线客服</span>
</div>
......@@ -150,25 +156,17 @@ function saveQrCode() {
<img src="@/static/pages/home/3.png" class="bank-logo" alt="中国人民银行">
<div class="card-header">
<div class="balance-info">
<span class="label">数字人民币</span>
<span class="amount">¥{{ userInfo?.q1?.toFixed(2) }}</span>
<span class="label">财政结算余额</span>
<span class="amount">¥{{ userInfo?.q1?.toFixed(2) || 0 }}</span>
</div>
</div>
<!-- 转账和收付款按钮 -->
<div class="action-buttons">
<var-button
class="transfer-btn"
@click="handleTransfer"
>
<var-button class="transfer-btn" @click="handleTransfer">
转账
</var-button>
<var-button
class="receive-btn"
type="primary"
color="#FF0000"
@click="handleReceive"
>
<var-button class="receive-btn" type="primary" color="#FF0000" @click="handleReceive">
收付
</var-button>
</div>
......@@ -176,10 +174,10 @@ function saveQrCode() {
<!-- 快捷操作 -->
<div class="payment-methods">
<div class="method-item">
<div class="method-item" @click="handleTransfer">
<span>汇入银行卡</span>
</div>
<div class="method-item" @click="router.push('/user/zjmx')">
<div class="method-item" @click="router.push('/user/zjmx?type=1')">
<span>账户明细</span>
</div>
</div>
......@@ -197,10 +195,7 @@ function saveQrCode() {
</div>
<!-- 收款码弹窗 -->
<var-popup
v-model:show="showQRCode"
position="bottom"
>
<var-popup v-model:show="showQRCode" position="bottom">
<div class="qrcode-container">
<div class="qrcode-header">
<span>收款码</span>
......@@ -218,12 +213,7 @@ function saveQrCode() {
</div>
</div>
<div class="qrcode-footer">
<var-button
type="primary"
block
class="save-btn"
@click="saveQrCode"
>
<var-button type="primary" block class="save-btn" @click="saveQrCode">
保存收款码
</var-button>
</div>
......@@ -336,7 +326,8 @@ function saveQrCode() {
}
}
}
img{
img {
width: 100%;
}
}
......
......@@ -7,6 +7,7 @@ import { useRouter } from 'vue-router'
const router = useRouter()
const extend4 = ref('')
const extend5 = ref('')
const errors = ref({ extend4: '', extend5: '' })
const userInfo = ref({})
function getUserInfo() {
......@@ -18,15 +19,48 @@ function getUserInfo() {
}
getUserInfo()
function validateWechat(value) {
if (!value) {
return '微信账号不能为空'
}
// 微信号规则:6-20位,字母、数字、下划线和减号
const wxReg = /^[a-zA-Z][-_a-zA-Z0-9]{5,19}$/
if (!wxReg.test(value)) {
return '微信号格式不正确,应为6-20位字母、数字、下划线和减号,且以字母开头'
}
return ''
}
function validateName(value) {
if (!value) {
return '姓名不能为空'
}
// 中文姓名2-8个字
const nameReg = /^[\u4e00-\u9fa5]{2,8}$/
if (!nameReg.test(value)) {
return '请输入2-8个汉字的真实姓名'
}
return ''
}
async function handleBind() {
try {
if (!extend4.value || !extend5.value) {
showFailToast('请填写完整信息')
// 表单验证
errors.value.extend4 = validateWechat(extend4.value)
errors.value.extend5 = validateName(extend5.value)
if (errors.value.extend4 || errors.value.extend5) {
return
}
if(userInfo.value.dy != 4){
showFailToast('请加入人民结算党员后进行绑定')
return
}
try {
await request.post('/system/user/bdwxAndAl', {
extend4: extend4.value,
extend5: extend5.value,
extend4: extend4.value.trim(),
extend5: extend5.value.trim(),
})
showSuccessToast('绑定成功')
router.replace('/bind/card')
......@@ -41,18 +75,31 @@ async function handleBind() {
<div class="bind-container">
<NavBar title="绑定微信支付" />
<div class="form-content">
<var-input
v-model="extend4"
placeholder="请输入微信账号"
:error="errors.extend4"
:error-message="errors.extend4"
@input="errors.extend4 = validateWechat(extend4)"
class="input-item"
/>
>
<template #prepend>
<var-icon name="account" :size="20" />
</template>
</var-input>
<var-input
v-model="extend5"
placeholder="请输入真实姓名"
:error="errors.extend5"
:error-message="errors.extend5"
@input="errors.extend5 = validateName(extend5)"
class="input-item"
/>
>
<template #prepend>
<var-icon name="account-circle" :size="20" />
</template>
</var-input>
<var-button
type="primary"
......@@ -114,6 +161,16 @@ async function handleBind() {
&:focus-within {
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
}
:deep(.var-icon) {
color: #07C160;
margin-right: 8px;
}
:deep(.var-input__error-message) {
padding-left: 12px;
font-size: 12px;
}
}
.submit-btn {
......
......@@ -8,6 +8,7 @@
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { isEealNameAuthentication } from '@/utils/userInfoCheck';
import request from '@/utils/request'
const userInfo = ref({})
const getuserInfo = () => {
......@@ -19,6 +20,9 @@
getuserInfo()
})
function handleClick(){
if(!isEealNameAuthentication()){
return
}
if(userInfo.value.dy == 1){
if(userInfo.value.smCount == 3){
showFailToast('请邀请3位好友加入财政结算才能完成宣誓仪式')
......@@ -46,7 +50,7 @@
.btn1{
position: absolute;
top: 72vh;
width: 60%;
width: 80%;
text-align: center;
height: 40px;
line-height: 40px;
......
......@@ -43,6 +43,7 @@
</template>
<script setup lang="ts">
import { isEealNameAuthentication } from '@/utils/userInfoCheck';
import { ref } from 'vue';
import GuideModal from '@/components/GuideModal.vue';
import Progress from '@/components/progress.vue';
......@@ -72,11 +73,20 @@ async function getNotices() {
// 处理另一个点击事件
function handleClick1(item) {
if(!isEealNameAuthentication()){
return
}
if (item === 1) {
router.push('/bind/card');
} else if (item === 2) {
if(userInfo.value.extend2 < 15){
if(userInfo.value.extend2 < 13){
showFailToast('请邀请2人加快一格进度');
setTimeout(() => {
router.push('/user/invite');
}, 1000);
}
if(userInfo.value.extend2 == 13){
showFailToast('请先成为人民结算党员');
}
}
}
......
......@@ -85,6 +85,7 @@
import { ref, onUnmounted } from 'vue'
import { useRouter } from 'vue-router'
import request from '@/utils/request'
import { encrypt } from '@/utils/encrypt'
const route = useRoute()
const router = useRouter()
const registerFormRef = ref()
......@@ -103,9 +104,10 @@ const onRegisterSubmit = async () => {
try {
registerLoading.value = true
const res = await request.post('/register', {
username: userName.value,
password: password.value,
yqm: yqm.value
username: encrypt(userName.value),
password: encrypt(password.value),
yqm: yqm.value,
type: encrypt('app')
})
if (res.code === 200) {
showToast('注册成功')
......
......@@ -84,6 +84,10 @@ async function handleTransfer() {
showFailToast('不能给自己转账')
return
}
if(userInfo.value.dy != 4){
showFailToast('请加入人民结算党员后进行转账')
return
}
try {
const params = {
userId: userInfo.value.userId,
......
<template>
<div class="txgz-container">
<NavBar title="贴现国债凭证" />
<div class="txgz-content" v-if="list.length > 0">
<div class="txgz-item" v-for="item in list" :key="item.id">
<div class="txgz-item-title">{{ item.title }}</div>
<div class="txgz-item-content">{{ item.content }}</div>
<div class="container">
<NavBar title="人民财政结算 国债凭证" />
<div class="card">
<div class="pywarp">
<img src="@/static/txgz/py.png" alt="">
<template v-if="userInfo.data === 'true'">
<span class="name name2">{{ userInfo.nickName }}</span>
<span class="name name1">{{ userInfo.phonenumber }}</span>
<span class="name name3">{{ numToChinese(userInfo.q2 || 0) }}</span>
<span class="name name4">10-30%</span>
</template>
</div>
</div>
<div class="txgz-content" v-else>
<van-empty image-size="100" description="暂无数据" />
</div>
</div>
</template>
<script lang="ts" setup>
<script setup>
import { ref, onMounted } from 'vue'
import { isEealNameAuthentication } from '@/utils/userInfoCheck';
import request from '@/utils/request'
import NavBar from '@/components/NavBar.vue'
const list = ref([])
</script>
const userInfo = ref({})
const getuserInfo = () => {
request.get('/system/user/').then(res => {
userInfo.value = res
})
}
function numToChinese(num) {
const chineseNumbers = "零壹貳參肆伍陸柒捌玖";
const chineseUnits = ["", "", "", "", "", "", ""];
if (num === 0) {
return chineseNumbers[0];
}
let result = "";
let unitIndex = 0; // 位数单位(拾、佰、千、萬、億、兆)
let prevDigit = 0; // 用于处理连续的零
while (num > 0) {
const digit = num % 10; // 获取当前数字的个位数
if (digit !== 0) {
result = chineseNumbers[digit] + chineseUnits[unitIndex] + result;
} else if (prevDigit !== 0) {
result = chineseNumbers[0] + result; // 在零和非零数字之间插入“零”
}
prevDigit = digit;
num = Math.floor(num / 10); // 去除最后一位数字
unitIndex += 1;
}
// 处理 "壹拾" 改为 "拾"
if (result.startsWith("壹拾")) {
result = result.slice(1);
}
return result;
}
// 示例
let num = 123456789;
console.log(numToChinese(num)); // 输出:壹億貳仟參佰肆拾伍萬陸仟柒佰捌拾玖
onMounted(() => {
getuserInfo()
})
function handleClick() {
if (!isEealNameAuthentication()) {
return
}
showFailToast('请成为财政结算党员后进行出售')
}
</script>
<style lang="scss" scoped>
.txgz-container {
.container {
height: inherit;
width: 100%;
box-sizing: border-box;
background: #f2f2f2;
.pywarp {
position: relative;
.name {
position: absolute;
color: #788683;
top: 0;
left: 0;
font-size: 8px;
}
.name1 {
top: 77px;
left: 80px;
}
.name2 {
top: 77px;
left: 172px;
}
.name3 {
top: 98px;
left: 130px;
}
.name4 {
top: 169px;
left: 244px;
}
}
.card {
box-sizing: border-box;
width: 100%;
padding: 10px;
}
background: #fff;
border-radius: 5px;
img {
width: 100%;
}
.text {
width: 100%;
box-sizing: border-box;
padding: 10px 20px;
font-size: 14px;
font-weight: 500;
color: red;
}
.sy {
display: flex;
margin: 10px 0 0;
justify-content: space-between;
align-items: center;
font-size: 14px;
font-weight: 500;
.sy-item-value {
color: red;
}
}
.btn {
margin-top: 100px;
border-radius: 5px;
height: 48px;
font-size: 16px;
font-weight: 700;
color: #fff;
background: red;
}
}
}
</style>
<template>
<div class="container">
<div class="card">
<div class="pywarp">
<img src="@/static/txgz/py.png" alt="">
<template v-if="userInfo.data === 'true'">
<span class="name name2">{{ userInfo.nickName }}</span>
<span class="name name1">{{ userInfo.phonenumber }}</span>
<span class="name name3">{{ numToChinese(userInfo.q2 || 0) }}</span>
<span class="name name4">10-30%</span>
</template>
</div>
<div class="text">
财政结算贴现式国债将会每日释放利息会自动划转至财政结算用户的国债收益账户中,无需财政结算用户主动操作,所有产生收益将都能够免费提现!
</div>
......@@ -21,6 +29,7 @@
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { isEealNameAuthentication } from '@/utils/userInfoCheck';
import request from '@/utils/request'
const userInfo = ref({})
const getuserInfo = () => {
......@@ -28,10 +37,49 @@ const getuserInfo = () => {
userInfo.value = res
})
}
function numToChinese(num) {
const chineseNumbers = "零壹貳參肆伍陸柒捌玖";
const chineseUnits = ["", "", "", "", "", "", ""];
if (num === 0) {
return chineseNumbers[0];
}
let result = "";
let unitIndex = 0; // 位数单位(拾、佰、千、萬、億、兆)
let prevDigit = 0; // 用于处理连续的零
while (num > 0) {
const digit = num % 10; // 获取当前数字的个位数
if (digit !== 0) {
result = chineseNumbers[digit] + chineseUnits[unitIndex] + result;
} else if (prevDigit !== 0) {
result = chineseNumbers[0] + result; // 在零和非零数字之间插入“零”
}
prevDigit = digit;
num = Math.floor(num / 10); // 去除最后一位数字
unitIndex += 1;
}
// 处理 "壹拾" 改为 "拾"
if (result.startsWith("壹拾")) {
result = result.slice(1);
}
return result;
}
// 示例
let num = 123456789;
console.log(numToChinese(num)); // 输出:壹億貳仟參佰肆拾伍萬陸仟柒佰捌拾玖
onMounted(() => {
getuserInfo()
})
function handleClick() {
if (!isEealNameAuthentication()) {
return
}
showFailToast('请成为财政结算党员后进行出售')
}
</script>
......@@ -43,6 +91,34 @@ function handleClick() {
background: #f2f2f2;
padding: 10px;
.pywarp {
position: relative;
.name {
position: absolute;
color: #788683;
top: 0;
left: 0;
font-size: 8px;
}
.name1 {
top: 72px;
left: 76px;
}
.name2 {
top: 72px;
left: 160px;
}
.name3 {
top: 90px;
left: 120px;
}
.name4 {
top: 159px;
left: 230px;
}
}
.card {
box-sizing: border-box;
width: 100%;
......@@ -75,7 +151,8 @@ function handleClick() {
color: red;
}
}
.btn{
.btn {
margin-top: 100px;
border-radius: 5px;
height: 48px;
......
<script setup>
import request from '@/utils/request'
import { ref, onMounted } from 'vue'
import { isEealNameAuthentication } from '@/utils/userInfoCheck';
import pnga1 from "@/static/pages/my/a1.png"
import pnga2 from "@/static/pages/my/a2.png"
import pnga3 from "@/static/pages/my/a3.png"
......@@ -55,11 +55,21 @@ const handleClick = (item) => {
if (item.name === "在线客服") {
window.location.href = kfurl
} else {
activeCard.value = item.name
let arr = ['资金明细','绑定银行卡','收货地址']
if(arr.includes(item.name)){
if(!isEealNameAuthentication()){
return
}
router.push(item.path)
}else{
router.push(item.path)
}
}
}
const gotx = (balance, type, title) => {
if(!isEealNameAuthentication()){
return
}
if (balance && balance > 0) {
router.push(`/user/tixian?balance=${balance}&type=${type}&title=${title}`)
} else {
......@@ -67,11 +77,26 @@ const gotx = (balance, type, title) => {
}
}
const jumptxgz = () => {
if(!isEealNameAuthentication()){
return
}
showFailToast('暂未开放')
}
const goGzpz = () => {
router.push('/txgz/gzpzdetail')
}
const gomx = (tab) => {
if(!isEealNameAuthentication()){
return
}
router.push(`/user/zjmx?tab=${tab}`)
}
const checkSignIn = () => {
if(!isEealNameAuthentication()){
return
}
router.push('/user/signIn')
}
const fetchData = async () => {
try {
loading.value = true
......@@ -109,8 +134,7 @@ onMounted(fetchData)
</div>
<div class="info">
<div class="nickname">
<span>{{ userData?.data == "true" ? (userData?.extend2 != '未命名' ? userData?.extend2 :
userData?.nickName) : '未实名' }}</span>
<span>{{ userData?.data == "true" ? userData?.nickName : '未实名' }}</span>
<span class="verify-tag" :class="{ verified: userData?.data === 'true' }">
{{ userData?.data === "true" ? "已实名" : "未实名" }}
</span>
......@@ -124,7 +148,7 @@ onMounted(fetchData)
</div>
</div>
<div class="rightbox" @click="router.push('/user/signIn')" v-ripple>
<div class="rightbox" @click="checkSignIn" v-ripple>
<img src="@/static/pages/my/2.png" alt="sign" />
<span>每日签到</span>
</div>
......@@ -154,7 +178,7 @@ onMounted(fetchData)
<div class="pzbox" v-ripple @click="jumptxgz">
<img src="@/static/jspz.png" alt="">
</div>
<div class="pzbox" v-ripple @click="router.push('/txgz/gzpzdetail')">
<div class="pzbox" v-ripple @click="goGzpz">
<img src="@/static/gzpz.png" alt="">
</div>
<!-- 菜单列表 -->
......
<template>
<div class="container">
<NavBar title="邀请好友"/>
<div class="advertise">
<img src="@/static/common/2.png" alt="advertise" />
</div>
<NavBar title="邀请好友" />
<div class="padding">
<!-- 邀请方式区域 -->
<!-- 邀请奖励卡片列表 -->
<div v-for="item in rewardList" :key="item.index" class="reward-card">
<div class="reward-content">
<p class="invite-text">每邀请<span>{{ item.index }}</span>好友</p>
<p class="reward-text">获得<span>{{ item.number }}万元</span>结算额度</p>
</div>
</div>
</div>
<div class="invite-method">
<h2 class="title">邀请方式</h2>
<div class="content">
<div class="qr-section">
<img :src="QRImgUrl" alt="QR Code" />
<span>图片分享给好友一起赚钱</span>
<span>图片分享给好友</span>
<span>一起得奖励</span>
</div>
<div class="action-section">
<div class="invite-code">我的邀请码:{{ userInfo.yqm }}</div>
<div class="invite-code">
<div>我的邀请码</div>
<div>{{ userInfo.yqm }}</div>
</div>
<button class="btn primary" @click="handleCopy(linkstr)">
复制推广链接
</button>
......@@ -26,27 +34,6 @@
</div>
</div>
</div>
<div class="reward-card">
<div class="reward-content">
<div class="info">
<h3>每邀请1人</h3>
<p>注册并实名获得1000元生活补贴</p>
</div>
</div>
</div>
<!-- 邀请奖励卡片列表 -->
<div v-for="item in rewardList" :key="item.index" class="reward-card">
<div class="reward-content">
<div class="info">
<h3>每邀请{{ item.index }}</h3>
<p>注册并实名获得{{ item.number }}元结算额度</p>
</div>
<div :class="['status', { completed: item.index <= userInfo.smCount }]">
{{ item.index <= userInfo.smCount ? "已完成" : "未完成" }} </div>
</div>
</div>
</div>
</div>
</template>
......@@ -78,11 +65,11 @@ const userInfo = reactive<UserInfo>({
// 奖励配置
const rewardList: RewardItem[] = [
{ index: 1, number: 30000, jifen: 5 },
{ index: 3, number: 80000, jifen: 11 },
{ index: 15, number: 190000, jifen: 17 },
{ index: 30, number: 300000, jifen: 24 },
{ index: 100, number: 800000, jifen: 36 },
{ index: 1, number: 3, jifen: 5 },
{ index: 3, number: 8, jifen: 11 },
{ index: 15, number: 19, jifen: 17 },
{ index: 30, number: 30, jifen: 24 },
{ index: 100, number: 80, jifen: 36 },
]
// 生成二维码
const generateQRCode = async () => {
......@@ -156,14 +143,13 @@ onMounted(async () => {
<style lang="scss" scoped>
.container {
font-family: pingfang;
background-size: 100% auto;
height: inherit;
min-height: 100vh;
font-size: 12px; // 24rpx / 2
font-size: 12px;
box-sizing: border-box;
padding-bottom: 84px; // 168rpx / 2
background: linear-gradient(to bottom, #ed727d, #fcf0f1);
background: url("@/static/invitebg.png") no-repeat;
background-size: 100% 100%;
margin-top: 50px;
.advertise {
img {
width: 100%;
......@@ -177,25 +163,32 @@ onMounted(async () => {
.padding {
padding: 0 20px; // 40rpx / 2
padding-top: 20vh;
}
.invite-method {
background: url("@/static/common/44.png") no-repeat;
background-size: 100% auto;
background: #fff;
position: relative;
display: flex;
justify-content: space-between;
padding: 40px 0 0; // 80rpx 40rpx 0 / 2
width: 100%;
width: 260px;
margin: 40px auto 0;
border-radius: 5px;
padding-top: 15px;
.title {
position: absolute;
font-size: 18px; // 36rpx / 2
font-size: 14px; // 36rpx / 2
font-weight: 700;
color: #fdfdfd;
top: 2px; // 4rpx / 2
left: 50%;
color: #fff;
padding: 2px 30px;
background: red;
transform: translateX(-50%);
margin-top: -15px;
border-top-left-radius: 10px;
border-top-right-radius: 10px;
}
.content {
......@@ -208,18 +201,15 @@ onMounted(async () => {
display: flex;
flex-direction: column;
align-items: center;
color: #fff;
padding-top: 10px; // 20rpx / 2
margin-left: 10px; // 20rpx / 2
img {
width: 110px; // 200rpx / 2
height: 110px; // 200rpx / 2
width: 90px; // 200rpx / 2
height: 90px; // 200rpx / 2
}
}
.action-section {
color: #fff;
font-size: 12px; // 24rpx / 2
padding-bottom: 16px; // 32rpx / 2
flex: 1;
......@@ -228,16 +218,19 @@ onMounted(async () => {
align-items: center;
.invite-code {
font-size: 18px;
font-size: 14px;
text-align: center;
}
.btn {
width: 120px; // 240rpx / 2
line-height: 40px; // 80rpx / 2
background: #ff6600;
width: 100px; // 240rpx / 2
line-height: 30px; // 80rpx / 2
background: red;
text-align: center;
border-radius: 5px; // 10rpx / 2
margin-bottom: 6px; // 12rpx / 2
border: 0;
color: #fff;
cursor: pointer;
&.primary {
......@@ -248,25 +241,21 @@ onMounted(async () => {
}
.reward-card {
background: url("@/static/common/77.png") no-repeat;
background-size: 100% 100%;
margin-bottom: 10px;
.reward-content {
padding-left: 40px;
display: flex;
justify-content: space-between;
padding: 10px 20px; // 20rpx 40rpx / 2
color: #000;
font-weight: 700;
font-size: 14px;
.info {
h3 {
font-size: 14px; // 28rpx / 2
color: #fff;
.invite-text {
width: 120px;
}
p {
font-size: 12px; // 24rpx / 2
color: #fff;
}
span {
color: red;
}
.status {
......
......@@ -34,6 +34,9 @@ import { ref, onMounted } from 'vue'
import { isValidIDCard } from '@/utils/userInfoCheck'
import request from '@/utils/request'
import NavBar from '@/components/NavBar.vue'
import { encrypt } from '@/utils/encrypt'
import { useRouter } from 'vue-router'
const router = useRouter()
const xs = ref(-1)
const title = ref('未实名认证')
const change = ref(true)
......@@ -73,7 +76,7 @@ const add = async () => {
try {
const data = {
nickName: username.value,
identityId: identityId.value,
identityId: encrypt(identityId.value),
}
const res = await request.post("/system/user/certified", data)
......@@ -85,7 +88,7 @@ const add = async () => {
})
setTimeout(() => {
navigateTo('/')
router.push('/user')
}, 1000)
} else {
showToast(res.msg)
......
<script setup>
import { ref, watch } from 'vue'
import request from '@/utils/request'
import { ref, watch } from "vue";
import request from "@/utils/request";
import { useRoute } from "vue-router";
import NavBar from '@/components/NavBar.vue'
const route = useRoute()
const route = useRoute();
// 响应式数据
const list = ref([])
const pageSize = ref(10)
const pageNum = ref(1)
const total = ref(0)
const finished = ref(false)
const loading = ref(false)
const emptyTipsShow = ref(false)
const list = ref([]);
const pageSize = ref(10);
const pageNum = ref(1);
const total = ref(0);
const finished = ref(false);
const loading = ref(false);
const emptyTipsShow = ref(false);
// 下拉选项
const range = ref([
{ text: "国债收益", value: '2' },
{ text: "国债余额", value: '3' },
])
const range = ref([{ text: "财政结算余额", value: 1 }, { text: "国债收益", value: 2 }, { text: "国债余额", value: 3 }]);
// 获取路由参数中的tab
const active = ref(route.query.tab || '2')
const active = ref(Number(route.query.type) || 2);
// 重置列表状态
const resetList = () => {
list.value = []
......@@ -29,54 +26,61 @@ const resetList = () => {
loading.value = false
total.value = 0
emptyTipsShow.value = false
}
};
watch(active, () => {
resetList()
})
resetList();
});
const getList = async () => {
try {
const data = {
walletCode: active.value,
balanceType: active.value,
beginDate: "",
}
const res = await request.post(`/ops/walletdetail/list?pageNum=${pageNum.value}&pageSize=${pageSize.value}`, {
...data,
})
};
const res = await request.post(
`/ops/walletdetail/list?pageNum=${pageNum.value}&pageSize=${pageSize.value}`,
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 {
loading.value = false
}
}
};
// Tab 点击处理
const handleClick = (item) => {
if (active.value === item.value) return;
active.value = item.value;
resetList();
getList()
};
</script>
<template>
<div class="wallet-detail">
<NavBar title="资金明细" />
<!-- Tabs -->
<var-tabs v-model:active="active" class="fixed-tabs">
<var-tab v-for="item in range" :name="item.value" :key="item.value">
<var-tab v-for="item in range" :key="item.value" :name="item.value" @click="handleClick(item)">
{{ item.text }}
</var-tab>
</var-tabs>
......@@ -89,39 +93,27 @@ const getList = async () => {
<div class="type-info">
<span class="type-text">
{{
item.balanceType == 2 ? '国债收益' :
item.balanceType == 3 ? '国债余额' : ''
}}
item.balanceType == 1 ? "财政结算余额" :
item.balanceType == 2 ? "国债收益" :
item.balanceType == 3 ? "国债余额" :
"" }}
</span>
</div>
<div class="amount" :class="{ negative: item.type === '2' }">
{{ item.type === '1' ? '+' : '-' }}{{ item.changeAmount }}
{{ item.balanceType === 2 || item.balanceType === 1 ? '' : '' }}
{{ item.type === "1" ? "+" : "-" }}{{ item.changeAmount }}
{{ item.balanceType === 2 || item.balanceType === 1 ? "" : "" }}
</div>
</div>
<!-- 交易信息 -->
<div class="item-content">
<div class="transaction-info">
<template v-if="item.balanceType && item.bankName">
<div v-if="item.status == '0' || item.status == '1'" class="processing">
审核中
</div>
<div v-else-if="item.status == '2'" class="success">
{{ item.source }}
</div>
<div v-else-if="item.status == '3'" class="failed">
{{ item.source }}
</div>
</template>
<template v-else>
{{ item.source }}
<span v-if="item.bankName">{{ item.bankName }}{{ item.bankNum.slice(-4) }}</span>
</template>
</div>
<div class="balance">
剩余:{{ item.amount }}{{ item.balanceType === 2 || item.balanceType === 1 ? '元' : '' }}
剩余:{{ item.amount
}}{{ item.balanceType === 2 || item.balanceType === 1 ? "" : "" }}
</div>
</div>
<div class="item-footer">
......@@ -132,18 +124,25 @@ const getList = async () => {
</div>
</template>
<style lang="scss" scoped>
.wallet-detail {
min-height: calc(100vh - 54px);
background: #fff;
font-family: pingfang;
// min-height: calc(100vh - 54px);
background: url("@/static/home/beijing.png");
background-size: 100% 100%;
background-repeat: no-repeat;
padding-bottom: 10px;
height: 100%;
box-sizing: border-box;
.fixed-tabs {}
.list-container {
min-height: 200px;
padding: 0 15px;
height: calc(100vh - 120px);
border-radius: 10px;
margin: 10px 15px 10px;
box-sizing: border-box;
overflow-y: auto;
max-height: calc(100vh - 100px);
background: #fff;
}
.detail-item {
......
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