Commit ba473afe authored by zhangsan's avatar zhangsan

1

parent db43353d
This diff is collapsed.
......@@ -19,9 +19,12 @@ declare module 'vue' {
VanButton: typeof import('vant/es')['Button']
VanCell: typeof import('vant/es')['Cell']
VanEmpty: typeof import('vant/es')['Empty']
VanIcon: typeof import('vant/es')['Icon']
VanList: typeof import('vant/es')['List']
VanLoading: typeof import('vant/es')['Loading']
VanNavBar: typeof import('vant/es')['NavBar']
VanStep: typeof import('vant/es')['Step']
VanSteps: typeof import('vant/es')['Steps']
VanSwipe: typeof import('vant/es')['Swipe']
VanSwipeItem: typeof import('vant/es')['SwipeItem']
VanTag: typeof import('vant/es')['Tag']
......
......@@ -7,7 +7,7 @@
<!-- 使用插槽或v-html展示内容 -->
<div class="guide-content">
<slot :index="currentIndex">
<div v-html="guideList[currentIndex]?.notictBody"></div>
<div v-html="guideList[currentIndex]?.noticeContent"></div>
</slot>
</div>
......
......@@ -31,7 +31,9 @@ router.beforeEach(async (to, from, next) => {
const res = await request.get('/system/config/configKeys?code=appVersion');
if (res.code === 200 && res?.data?.appVersion !== sessionStorage.getItem('appVersion')) {
sessionStorage.setItem('appVersion', res.data.appVersion);
if(to.path !== '/login'){
window.location.reload();
}
return;
}
} catch (error) {
......
......@@ -37,6 +37,7 @@ const titleMap: Record<string, string> = {
ddownload: "APP下载",
newsdetail: "新闻详情",
modify: "修改资料",
myapple: "提现记录",
};
// 处理路径转换为路由配置
......
/**
* 身份证号码验证接口
*/
import router from '@/router' // 直接导入路由实例
/**
* 验证用户是否已实名认证
* @returns boolean
*/
export const isEealNameAuthentication = () => {
const userInfo = JSON.parse(sessionStorage.getItem('userInfo') || '{}')
if(userInfo.data === 'true'){
return true
}
showFailToast('请先进行实名认证')
setTimeout(() => {
router.push('/user/shiming')
}, 1000)
return false
}
interface IDCardValidationResult {
isValid: boolean
message?: string
......@@ -11,21 +31,27 @@ interface IDCardValidationResult {
* @param id 身份证号码
* @returns boolean
*/
export const isValidIDCard = (id: string): boolean => {
if (!id) return false
const idCardRegex = /^(?:\d{15}|\d{17}[\dXx])$/;
// 15 位身份证验证
if (id.length === 15) {
return isValidIDCard15(id)
// 测试函数
export const isValidIDCard = (id: string): boolean => {
return idCardRegex.test(id);
}
// export const isValidIDCard = (id: string): boolean => {
// if (!id) return false
// 18 位身份证验证
if (id.length === 18) {
return isValidIDCard18(id)
}
// // 15 位身份证验证
// if (id.length === 15) {
// return isValidIDCard15(id)
// }
return false
}
// // 18 位身份证验证
// if (id.length === 18) {
// return isValidIDCard18(id)
// }
// return false
// }
/**
* 验证银行卡号
......@@ -70,6 +96,7 @@ interface IDCardValidationResult {
* @param id 18位身份证号码
* @returns boolean
*/
function isValidIDCard18(id: string): boolean {
// 只检查是否为 18 位的数字或X结尾
const regex = /^\d{17}(\d|X)$/
......
<template>
<div class="container">
<GuideModal v-model="visible" :guideList="guideList" />
<!-- 顶部红色背景区域 -->
<div class="header-bg">
<van-swipe class="my-swipe" :autoplay="3000" lazy-render indicator-color="white">
......@@ -19,7 +20,7 @@
<div class="video-placeholder">
<!-- 视频占位,可以用背景色或图片代替 -->
<div class="video-box">
<video src="@/static/home.mp4" controls></video>
<video poster="@/static/poster.jpg" src="@/static/home.mp4" controls></video>
</div>
</div>
</div>
......@@ -65,17 +66,19 @@
</template>
<script setup lang="ts">
import { ref, onMounted } from "vue";
import { ref } from "vue";
import { useRouter } from "vue-router";
import request from "@/utils/request";
import { onPageShow } from "@/composables";
import "viplayer/dist/index.css";
import newsIcon from '@/static/home/8.png';
import GuideModal from '@/components/GuideModal.vue';
const router = useRouter();
const newsList = ref([]);
const bannerList = ref([]);
const kfurl = ref(sessionStorage.getItem("kfurl") || "");
const visible = ref(false);
const guideList = ref([]);
const openKf = () => {
window.location.href = kfurl.value;
};
......@@ -91,6 +94,18 @@ const getNewsList = async () => {
showToast("获取新闻列表失败");
}
};
const getGuideList = async () => {
try {
const res = await request.get('/system/notice/list');
guideList.value = res.rows.filter(item => item.noticeType == 0 || item.noticeType == 1 || item.noticeType == 2);
if (guideList.value.length > 0) {
visible.value = true;
}
} catch (error) {
console.error('Failed to fetch notices:', error);
showFailToast(error.msg || '获取通知信息失败'); // 提示用户获取通知信息失败
}
};
const getBannerList = async () => {
try {
const res = await request.get("/ops/banner/appList");
......@@ -102,6 +117,7 @@ const getBannerList = async () => {
onPageShow(() => {
getBannerList();
getNewsList();
getGuideList();
});
</script>
......
<template>
<div class="login-container">
<div class="logo">
<div class="logo-icon"></div>
<div class="logo-icon">
<img src="@/static/logo.jpg" alt="">
</div>
</div>
<div class="form-container">
......@@ -102,20 +104,24 @@ const onLineService = () => {
<style lang="scss" scoped>
// 样式代码保持不变
.login-container {
min-height: 100vh;
height: 100vh;
background: #fff;
padding: 20px;
box-sizing: border-box;
.logo {
padding: 40px 0 20px;
padding: 80px 0 20px;
display: flex;
justify-content: center;
.logo-icon {
width: 60px;
height: 60px;
background: #ff6b35;
width: 120px;
height: 120px;
border-radius: 16px;
img{
width: 100%;
height: 100%;
}
}
}
......
<template>
<div class="register-container">
<div class="logo">
<div class="logo-icon"></div>
<div class="logo-icon">
<img src="@/static/logo.jpg" alt="">
</div>
</div>
<div class="form-container">
......@@ -115,20 +117,24 @@ const handleRegister = async () => {
<style lang="scss" scoped>
.register-container {
min-height: 100vh;
height: 100vh;
background: #fff;
padding: 20px;
box-sizing: border-box;
.logo {
padding: 40px 0 20px;
padding: 80px 0 20px;
display: flex;
justify-content: center;
.logo-icon {
width: 60px;
height: 60px;
background: #ff6b35;
width: 120px;
height: 120px;
border-radius: 16px;
img{
width: 100%;
height: 100%;
}
}
}
......
......@@ -11,76 +11,46 @@
<div class="form-title">申请人基本资料</div>
<div class="form-group">
<var-form ref="form" scroll-to-error="start">
<var-form ref="form" :disabled="isEdit" scroll-to-error="start">
<var-input v-model="formData.a3" placeholder="请输入姓名" />
<var-select
v-model="formData.a4"
:rules="[(v) => !!v || '请选择性别']"
placeholder="性别"
>
<var-select v-model="formData.a4" :rules="[(v) => !!v || '请选择性别']" placeholder="性别">
<var-option label="男" />
<var-option label="女" />
</var-select>
<var-input
v-model="formData.a5"
:rules="[
<var-input v-model="formData.a5" :rules="[
(v) => !!v || '请输入年龄',
(v) => /^\d+$/.test(v) || '年龄必须为数字',
(v) =>
(Number(v) >= 18 && Number(v) <= 100) ||
'年龄必须在18-100岁之间',
]"
placeholder="请输入年龄"
/>
<var-input
v-model="formData.a6"
:rules="[
]" placeholder="请输入年龄" />
<var-input v-model="formData.a6" :rules="[
(v) => !!v || '请输入身份证号',
(v) =>
/^[1-9]\d{5}(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dX]$/.test(
v
) || '请输入正确的身份证号',
]"
placeholder="请输入身份证号"
/>
<var-input
v-model="formData.a7"
:rules="[
]" placeholder="请输入身份证号" />
<var-input v-model="formData.a7" :rules="[
(v) => !!v || '请输入民族',
(v) =>
/^[\u4e00-\u9fa5]{1,10}族$/.test(v) || '请输入正确的民族名称',
]"
placeholder="请输入民族"
/>
<var-input
v-model="formData.a9"
:rules="[
]" placeholder="请输入民族" />
<var-input v-model="formData.a9" :rules="[
(v) => !!v || '请输入联系电话',
(v) => /^1[3-9]\d{9}$/.test(v) || '请输入正确的手机号',
]"
placeholder="请输入联系电话"
/>
<var-input
textarea
v-model="formData.a8"
placeholder="请输入家庭住址"
/>
]" placeholder="请输入联系电话" />
<var-input textarea v-model="formData.a8" placeholder="请输入家庭住址" :rows="3" />
</var-form>
</div>
<!-- 提交按钮 -->
<div class="button-group">
<var-button
v-if="!isModify"
block
type="primary"
class="submit-btn"
@click="handleSubmit"
>
点击申领
<var-button block type="primary" :class="record.a1 == 1 ? 'submit-btn-disabled' : record.a1 == 2 ? 'submit-btn-success' : 'submit-btn'" @click="handleSubmit">
{{ record.a1 == 1 ? "申领中" : record.a1 == 2 ? "申领成功" : "点击申领" }}
</var-button>
<var-button v-else block @click="handleModify" class="modify-btn">
修改资料
<var-button v-if="isModify" block @click="handleModify" class="modify-btn">
{{ isModify && isEdit ? "修改资料" : "提交资料" }}
</var-button>
</div>
</div>
......@@ -88,10 +58,11 @@
</template>
<script setup lang="ts">
import { reactive, onMounted } from "vue";
import { reactive } from "vue";
import { usePageHook } from "@/hooks/usePageHook";
import { addApply, editApply, getApplyList } from "@/api/czwj";
import { ref } from "vue";
import { isEealNameAuthentication } from "@/utils/userInfoCheck";
const form = ref();
const formData = reactive({
a3: "",
......@@ -103,21 +74,24 @@ const formData = reactive({
a9: "",
});
let isModify = ref(false);
const isEdit = ref(false);
const record = ref({});
// 获取申请记录
const getApplyRecord = async () => {
try {
const res = await getApplyList();
if (res.data?.length > 0) {
isModify.value = true;
const record = res.data[0];
isEdit.value = true;
record.value = res.data[0];
Object.assign(formData, {
a3: record.a3,
a4: record.a4,
a5: record.a5,
a6: record.a6,
a7: record.a7,
a8: record.a8,
a9: record.a9,
a3: record.value.a3,
a4: record.value.a4,
a5: record.value.a5,
a6: record.value.a6,
a7: record.value.a7,
a8: record.value.a8,
a9: record.value.a9,
});
}
} catch (error) {
......@@ -128,12 +102,19 @@ const getApplyRecord = async () => {
// 提交申请
const handleSubmit = async () => {
try {
// 表单验证
const validateRes = await form.value.validate();
if (!validateRes) {
showToast("请填写正确信息!");
return;
}
if (isModify.value) {
return false
}
if (!isEealNameAuthentication()) {
return false
}
const res = await addApply(formData);
if (res?.code === 200) {
showToast("申请提交成功");
......@@ -149,10 +130,14 @@ const handleSubmit = async () => {
// 修改资料
const handleModify = () => {
if (isModify.value && isEdit.value) {
isEdit.value = false;
}
else {
showConfirmDialog({
title: "确认修改资料吗?",
})
.then(async() => {
.then(async () => {
try {
const listRes = await getApplyList();
if (listRes?.data?.length > 0) {
......@@ -178,6 +163,8 @@ const handleModify = () => {
.catch(() => {
// on cancel
});
}
};
usePageHook({
......@@ -227,6 +214,14 @@ usePageHook({
background: #ff4444;
}
.submit-btn-disabled {
background: #ccc;
}
.submit-btn-success {
background: #00c49f;
}
.modify-btn {
background: #ff6b35;
color: #fff;
......
......@@ -4,10 +4,11 @@
<div class="user-header">
<div class="user-info">
<div class="avatar">
<img src="@/static/user/avatar.jpg" alt="">
</div>
<div class="info">
<div class="name">
{{ userInfo?.data == "true" ? userInfo?.pName : "未实名" }}
{{ userInfo?.data == "true" ? userInfo?.nickName : "未实名" }}
<span class="already">{{
userInfo?.data == "true" ? "已实名" : "未实名"
}}</span>
......@@ -43,12 +44,7 @@
<!-- 功能按钮组 -->
<div class="function-grid">
<div
v-for="(item, index) in renderList"
:key="index"
class="grid-item"
@click="router.push(item.path)"
>
<div v-for="(item, index) in renderList" :key="index" class="grid-item" @click="handleClick(item)">
<div class="icon">
<img :src="item.icon" alt="icon" />
</div>
......@@ -66,7 +62,7 @@ import { ref } from "vue";
import { useRouter } from "vue-router";
import { usePageHook } from "@/hooks/usePageHook";
import handleCopy from "@/utils/handleCopy";
import { isEealNameAuthentication } from "@/utils/userInfoCheck";
// 导入图标
import a2 from "@/static/user/2.png";
import a3 from "@/static/user/3.png";
......@@ -74,6 +70,7 @@ import a4 from "@/static/user/4.png";
import a5 from "@/static/user/5.png";
import a6 from "@/static/user/6.png";
import a7 from "@/static/user/7.png";
import a8 from "@/static/user/8.png";
const router = useRouter();
......@@ -84,8 +81,19 @@ const renderList = [
{ title: "邀请好友", icon: a5, path: "/user/invite" },
{ title: "修改资料", icon: a6, path: "/user/modify" },
{ title: "APP下载", icon: a7, path: "/user/ddownload" },
{ title: "提现记录", icon: a8, path: "/user/myapple" },
];
const handleClick = (item: any) => {
if (item.title == "实名认证" || item.title == "邀请好友" || item.title == "APP下载" || item.title == "我的团队") {
router.push(item.path);
} else {
if (!isEealNameAuthentication()) {
return false
}
router.push(item.path);
}
};
// 格式化手机号
const formatPhone = (phone: string) => {
if (!phone) return "";
......@@ -94,11 +102,21 @@ const formatPhone = (phone: string) => {
// 提现
const tixian = (q1: string, type: number, title: string) => {
if (!isEealNameAuthentication()) {
return false
}
if (q1 == null || isNaN(Number(q1)) || Number(q1) < 1) {
showToast("余额不足");
return false;
}
router.push(`/user/tixian?balance=${q1}&type=${type}&title=${title}`);
};
// 明细
const goZjmx = (type: number) => {
if (!isEealNameAuthentication()) {
return false
}
router.push(`/user/zjmx?type=${type}`);
};
......@@ -154,6 +172,7 @@ usePageHook({
.info {
flex: 1;
.name {
font-size: 18px;
margin-bottom: 15px;
......@@ -166,6 +185,7 @@ usePageHook({
margin-left: 8px;
}
}
.warpinfo {
display: flex;
font-size: 12px;
......@@ -241,6 +261,7 @@ usePageHook({
height: 100%;
object-fit: cover;
}
.banner-text {
position: absolute;
bottom: 10px;
......@@ -261,7 +282,7 @@ usePageHook({
border-radius: 10px;
padding: 20px;
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-template-columns: repeat(4, 1fr);
gap: 20px;
.grid-item {
......@@ -275,6 +296,7 @@ usePageHook({
border-radius: 20px;
margin-bottom: 8px;
background: #ff6b6b;
img {
width: 100%;
height: 100%;
......
<template>
<div class="myapple-container">
<van-nav-bar title="提现记录" left-arrow @click-left="$router.back()" fixed />
<div class="content">
<van-list
v-model:loading="loading"
:finished="finished"
finished-text="没有更多了"
@load="getList"
>
<div v-for="(item, index) in list" :key="index" class="record-card">
<div class="card-header">
<div class="amount-info">
<span class="label">提现金额</span>
<span class="amount">¥{{ item.withdrawAmount }}</span>
</div>
<van-tag :type="getStatusType(item.status)" round class="status-tag">
{{ getStatusText(item.status) }}
</van-tag>
</div>
<div class="progress-section">
<van-steps :active="getStepByStatus(item.status)" active-color="#07c160">
<van-step>申请提现</van-step>
<van-step>缴纳手续费</van-step>
<van-step>解除风控</van-step>
<van-step>缴纳税费</van-step>
<van-step>到账成功</van-step>
</van-steps>
</div>
<div class="card-footer">
<div class="info-item">
<van-icon name="clock-o" />
<span>{{ item.createTime }}</span>
</div>
<div class="info-item">
<van-icon name="credit-pay" />
<span>{{ item.bankName }} {{ item.bankNum }} </span>
</div>
</div>
</div>
</van-list>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import request from '@/utils/request'
const list = ref([])
const pageSize = ref(10)
const pageNum = ref(1)
const total = ref(0)
const finished = ref(false)
const loading = ref(false)
const getList = async () => {
try {
const data = {
withdrawType: 1,
beginDate: ""
}
const res = await request.post(`/ops/withdraw/list?pageNum=${pageNum.value}&pageSize=${pageSize.value}`, data)
if (res.code === 200) {
list.value = [...list.value, ...(res.rows || [])]
total.value = res.total || 0
if (list.value.length >= total.value) {
finished.value = true
} else {
pageNum.value++
}
} else {
showFailToast(res.msg || '加载失败')
finished.value = true
}
} catch (error) {
console.error('获取列表失败:', error)
showFailToast('加载失败,请重试')
finished.value = true
} finally {
loading.value = false
}
}
const getStatusText = (status: string) => {
switch (status) {
case '0':
case '1':
return '审核中'
case '2':
return '已到账'
case '3':
return '已驳回'
default:
return '未知状态'
}
}
const getStatusType = (status: string) => {
switch (status) {
case '0':
case '1':
return 'warning'
case '2':
return 'success'
case '3':
return 'danger'
default:
return 'default'
}
}
const getStepByStatus = (status: string) => {
switch (status) {
case '0':
return 1
case '1':
return 2
case '2':
return 4
case '3':
return 0
default:
return 0
}
}
</script>
<style lang="scss" scoped>
.myapple-container {
min-height: 100vh;
background: #f7f8fa;
.content {
padding: 16px;
}
.record-card {
border-radius: 12px;
padding: 16px;
margin-bottom: 16px;
box-shadow: 0 2px 12px rgba(100, 101, 102, 0.08);
background: #fff;
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
.amount-info {
display: flex;
flex-direction: column;
.label {
font-size: 14px;
color: #666;
margin-bottom: 4px;
}
.amount {
font-size: 24px;
font-weight: bold;
color: #333;
}
}
.status-tag {
padding: 6px 12px;
}
}
.progress-section {
margin: 20px 0;
:deep(.van-step) {
.van-step__title {
font-size: 12px;
}
}
}
.card-footer {
display: flex;
flex-direction: column;
gap: 8px;
margin-top: 16px;
padding-top: 16px;
border-top: 1px solid #f5f5f5;
.info-item {
display: flex;
align-items: center;
color: #666;
font-size: 13px;
.van-icon {
margin-right: 6px;
font-size: 16px;
}
}
}
}
}
:deep(.van-steps--horizontal) {
padding: 0;
}
</style>
......@@ -93,7 +93,7 @@ getTeam()
<van-list class="user-list" v-model:loading="loading" :finished="finished" finished-text="没有更多了" @load="getTeam">
<div class="item" v-for="(item, index) in list" :key="index">
<div class="userphone">
<img src="@/static/pages/my/1.png" alt="用户头像">
<img src="@/static/user/avatar.jpg" alt="用户头像">
</div>
<div class="usermsg">
<div class="username">
......@@ -119,7 +119,7 @@ getTeam()
<style lang="scss" scoped>
.container {
width: 100%;
min-height: 100vh;
height: calc(100vh - 48px);
background: #f5f6f8;
padding: 10px;
overflow:hidden;
......
......@@ -155,6 +155,7 @@ const goToAddBank = () => {
>
立即提现
</var-button>
</div>
</template>
......
......@@ -14,7 +14,7 @@ export default defineConfig({
vue(),
// 添加 legacy 插件支持旧版浏览器
legacy({
targets: ['ie >= 11', 'chrome >= 49', 'ios >= 8'],
targets: ['ie >= 11', 'chrome >= 49', 'ios >= 8', 'android >= 4.4'],
additionalLegacyPolyfills: ['regenerator-runtime/runtime'],
modernPolyfills: true
}),
......
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