HomeLease/pages/requestWithdrawal/addCard.vue

523 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view v-if="visible" class="modal-overlay" @click="handleClose">
<view class="modal-content" @click.stop>
<view class="modal-header">
<text class="modal-title">添加账号</text>
<text class="modal-close" @click="handleClose">×</text>
</view>
<view class="modal-body">
<view class="form-item">
<text class="form-label">账户类型</text>
<picker :range="typeOptions" :value="typeIndex" range-key="label" @change="onTypeChange">
<view class="picker-value">{{ typeOptions[typeIndex].label }}</view>
</picker>
</view>
<view class="form-item">
<text class="form-label">{{ typeOptions[typeIndex].noLabel }}</text>
<view class="input-group">
<textarea
v-if="typeOptions[typeIndex].value === 'QR'"
v-model="bankForm.no"
:placeholder="typeOptions[typeIndex].noPlaceholder"
class="form-input qr-input"
:maxlength="500"
auto-height
/>
<input
v-else
v-model="bankForm.no"
:placeholder="typeOptions[typeIndex].noPlaceholder"
class="form-input"
maxlength="30"
/>
<!-- 收款二维码类型时显示上传按钮 -->
<view v-if="typeOptions[typeIndex].value === 'QR'" class="upload-btn" @click="goToImageUpload">
<text class="upload-text">上传</text>
</view>
</view>
</view>
<view class="form-item">
<text class="form-label">收款人姓名</text>
<input
v-model="bankForm.name"
class="form-input"
maxlength="20"
placeholder="请输入收款人姓名"
/>
</view>
<view class="form-item">
<text class="form-label">身份证号</text>
<input
v-model="bankForm.idCard"
class="form-input"
maxlength="18"
placeholder="请输入身份证号"
/>
</view>
<view class="form-item">
<text class="form-label">手机号</text>
<input
v-model="bankForm.mobile"
class="form-input"
maxlength="11"
placeholder="请输入手机号"
type="number"
/>
</view>
</view>
<view class="modal-footer">
<view class="modal-btn cancel-btn" @click="handleClose">取消</view>
<view
:class="{ 'loading-btn': loading }"
class="modal-btn confirm-btn"
@click="handleSubmit"
>
{{ loading ? '添加中...' : '确认添加' }}
</view>
</view>
</view>
</view>
</template>
<script>
import { addBankAccount } from '@/api/account.js'
export default {
name: 'AddCard',
props: {
visible: {
type: Boolean,
default: false,
},
},
data() {
return {
loading: false,
typeIndex: 0,
typeOptions: [
{
label: '银行卡',
value: 'BANK',
noLabel: '银行卡号',
noPlaceholder: '请输入银行卡号',
},
{
label: '收款二维码',
value: 'QR',
noLabel: '收款码图片',
noPlaceholder: '请输入收款码图片URL',
},
],
bankForm: {
type: 'BANK',
no: '',
name: '',
idCard: '',
mobile: '',
},
}
},
watch: {
visible(newVal) {
if (newVal) {
this.resetForm()
}
},
},
created() {
// 在组件创建时就开始监听事件
console.log('AddCard组件创建开始监听图片上传事件')
uni.$on('image-upload-success', this.onImageUploadSuccess)
},
onLoad() {
// 监听图片上传成功事件
uni.$on('image-upload-success', this.onImageUploadSuccess)
},
onUnload() {
// 移除事件监听
console.log('AddCard组件卸载移除图片上传事件监听')
uni.$off('image-upload-success', this.onImageUploadSuccess)
},
beforeDestroy() {
// 组件销毁前也移除事件监听
console.log('AddCard组件销毁移除图片上传事件监听')
uni.$off('image-upload-success', this.onImageUploadSuccess)
},
methods: {
// 重置表单
resetForm() {
this.bankForm = {
type: 'BANK',
no: '',
name: '',
idCard: '',
mobile: '',
}
this.typeIndex = 0
},
// 关闭弹窗
handleClose() {
this.$emit('close')
},
// 类型选择变化
onTypeChange(e) {
this.typeIndex = e.detail.value
this.bankForm.type = this.typeOptions[this.typeIndex].value
},
// 验证表单
validateForm() {
if (!this.bankForm.no.trim()) {
uni.showToast({
title: '请输入' + this.typeOptions[this.typeIndex].noLabel,
icon: 'none',
})
return false
}
if (!this.bankForm.name.trim()) {
uni.showToast({
title: '请输入收款人姓名',
icon: 'none',
})
return false
}
if (!this.bankForm.idCard.trim()) {
uni.showToast({
title: '请输入身份证号',
icon: 'none',
})
return false
}
if (!this.bankForm.mobile.trim()) {
uni.showToast({
title: '请输入手机号',
icon: 'none',
})
return false
}
// 验证身份证号格式
const idCardRegex = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/
if (!idCardRegex.test(this.bankForm.idCard)) {
uni.showToast({
title: '身份证号格式不正确',
icon: 'none',
})
return false
}
// 验证手机号格式
const mobileRegex = /^1[3-9]\d{9}$/
if (!mobileRegex.test(this.bankForm.mobile)) {
uni.showToast({
title: '手机号格式不正确',
icon: 'none',
})
return false
}
return true
},
// 跳转到图片上传页面
goToImageUpload() {
console.log('准备跳转到图片上传页面')
uni.navigateTo({
url: '/pages/image-upload/image-upload',
success: () => {
console.log('成功跳转到图片上传页面')
},
fail: (err) => {
console.error('跳转到图片上传页面失败:', err)
}
})
},
// 处理图片上传成功
onImageUploadSuccess(imageUrl) {
console.log('接收到图片上传成功事件:', imageUrl)
console.log('当前表单状态:', this.bankForm)
if (imageUrl && typeof imageUrl === 'string') {
this.bankForm.no = imageUrl
console.log('URL已设置到表单:', this.bankForm.no)
uni.showToast({
title: '图片上传成功',
icon: 'success'
})
} else {
console.error('接收到的imageUrl无效:', imageUrl)
uni.showToast({
title: '图片URL无效',
icon: 'none'
})
}
},
// 提交表单
async handleSubmit() {
if (!this.validateForm()) {
return
}
this.loading = true
try {
const response = await addBankAccount(this.bankForm)
if (response.code === 200) {
uni.showToast({
title: '银行卡添加成功',
icon: 'success',
})
this.$emit('success')
this.handleClose()
} else {
uni.showToast({
title: response.msg || '添加失败',
icon: 'none',
})
}
} catch (error) {
console.error('添加银行卡失败:', error)
uni.showToast({
title: '添加失败,请重试',
icon: 'none',
})
} finally {
this.loading = false
}
},
},
}
</script>
<style lang="scss" scoped>
/* 模态框样式 */
.modal-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 10000;
animation: fadeIn 0.3s ease-out;
}
.modal-content {
padding: 30rpx;
width: 90%;
max-width: 600rpx;
background: #fff;
border-radius: 20rpx;
overflow: hidden;
animation: slideUp 0.3s ease-out;
}
.modal-header {
padding: 30rpx;
text-align: center;
border-bottom: 1rpx solid #f0f0f0;
position: relative;
.modal-title {
font-size: 32rpx;
color: #333;
font-weight: 500;
}
.modal-close {
position: absolute;
right: 30rpx;
top: 50%;
transform: translateY(-50%);
font-size: 40rpx;
color: #999;
cursor: pointer;
}
}
.modal-body {
.form-item {
margin-bottom: 30rpx;
.form-label {
display: block;
font-size: 28rpx;
color: #333;
margin-bottom: 15rpx;
font-weight: 500;
}
.form-input {
height: 80rpx;
border: 1rpx solid #e0e0e0;
border-radius: 10rpx;
padding: 0 20rpx;
font-size: 28rpx;
color: #333;
background: #fafafa;
word-break: break-all;
overflow: hidden;
text-overflow: ellipsis;
&:focus {
border-color: #ff803a;
background: #fff;
}
&.qr-input {
font-size: 24rpx;
line-height: 1.4;
padding: 15rpx 20rpx;
min-height: 80rpx;
height: auto;
max-height: 200rpx;
resize: none;
word-wrap: break-word;
white-space: pre-wrap;
}
}
.picker-value {
height: 80rpx;
border: 1rpx solid #e0e0e0;
border-radius: 10rpx;
padding: 0 20rpx;
font-size: 28rpx;
color: #333;
background: #fafafa;
display: flex;
align-items: center;
}
.input-group {
display: flex;
align-items: center;
gap: 15rpx;
.form-input {
flex: 1;
}
.upload-btn {
width: 120rpx;
height: 80rpx;
background: #ff803a;
border-radius: 10rpx;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all 0.3s ease;
&:active {
background: #e67333;
transform: scale(0.95);
}
.upload-text {
color: #fff;
font-size: 26rpx;
font-weight: 500;
}
}
}
}
}
.modal-footer {
display: flex;
border-top: 1rpx solid #f0f0f0;
.modal-btn {
flex: 1;
padding: 30rpx;
text-align: center;
font-size: 30rpx;
font-weight: 500;
&.cancel-btn {
color: #666;
border-right: 1rpx solid #f0f0f0;
}
&.confirm-btn {
color: #ff803a;
}
&.loading-btn {
position: relative;
color: transparent !important;
&::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
width: 30rpx;
height: 30rpx;
margin: -15rpx 0 0 -15rpx;
border: 3rpx solid transparent;
border-top: 3rpx solid #ff803a;
border-radius: 50%;
animation: spin 1s linear infinite;
}
}
}
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes slideUp {
from {
transform: translateY(100rpx);
opacity: 0;
}
to {
transform: translateY(0);
opacity: 1;
}
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
/* 响应式设计 */
@media (max-width: 750rpx) {
.modal-content {
width: 95%;
margin: 20rpx;
}
}
</style>