HomeLease/pages/requestWithdrawal/deleteCar.vue
2025-08-20 15:32:16 +08:00

427 lines
9.1 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="delete-tip">请选择要删除的银行卡:</view>
<!-- 加载状态 -->
<view v-if="loading" class="loading-container">
<view class="loading-spinner"></view>
<text class="loading-text">加载中...</text>
</view>
<!-- 银行卡列表 -->
<view v-else-if="bankList.length > 0" class="bank-list">
<view
v-for="bank in bankList"
:key="bank.id"
:class="{ selected: selectedIds.includes(bank.id) }"
class="bank-item"
@click="toggleSelection(bank.id)"
>
<view class="bank-info">
<view class="bank-header">
<text class="bank-name">{{ bank.name }}</text>
<text class="bank-type">{{ getBankTypeText(bank.type) }}</text>
</view>
<text class="bank-number">{{ maskCardNumber(bank.no) }}</text>
</view>
<view :class="{ checked: selectedIds.includes(bank.id) }" class="checkbox">
<text v-if="selectedIds.includes(bank.id)" class="check-icon">✓</text>
</view>
</view>
</view>
<!-- 空状态 -->
<view v-else class="empty-state">
<text class="empty-icon">💳</text>
<text class="empty-text">暂无银行卡</text>
</view>
</view>
<view class="modal-footer">
<view class="modal-btn cancel-btn" @click="handleClose">取消</view>
<view
:class="{ disabled: selectedIds.length === 0 || loading }"
class="modal-btn confirm-btn"
@click="handleDelete"
>
{{ loading ? '删除中...' : `确认删除 (${selectedIds.length})` }}
</view>
</view>
</view>
</view>
</template>
<script>
import { deleteBankAccount, getBankAccountList } from '@/api/account.js'
export default {
name: 'DeleteCard',
props: {
visible: {
type: Boolean,
default: false
}
},
data() {
return {
loading: false,
bankList: [],
selectedIds: [],
}
},
watch: {
visible(newVal) {
if (newVal) {
this.fetchBankList()
this.selectedIds = []
}
}
},
methods: {
// 获取银行卡列表
async fetchBankList() {
this.loading = true
try {
const response = await getBankAccountList()
if (response.code === 200 && response.data) {
this.bankList = response.data
console.log('银行卡列表获取成功:', this.bankList)
}
} catch (error) {
console.error('获取银行卡列表失败:', error)
uni.showToast({
title: '获取银行卡列表失败',
icon: 'none',
})
} finally {
this.loading = false
}
},
// 关闭弹窗
handleClose() {
this.$emit('close')
},
// 切换选择状态
toggleSelection(bankId) {
const index = this.selectedIds.indexOf(bankId)
if (index > -1) {
this.selectedIds.splice(index, 1)
} else {
this.selectedIds.push(bankId)
}
},
// 掩码银行卡号
maskCardNumber(cardNumber) {
if (!cardNumber) return ''
if (cardNumber.length <= 8) return cardNumber
return '**** **** **** ' + cardNumber.slice(-4)
},
// 获取银行类型文本
getBankTypeText(type) {
const typeMap = {
'BANK': '银行卡',
'QR': '收款二维码'
}
return typeMap[type] || '未知类型'
},
// 删除银行卡
async handleDelete() {
if (this.selectedIds.length === 0) {
uni.showToast({
title: '请选择要删除的银行卡',
icon: 'none',
})
return
}
uni.showModal({
title: '确认删除',
content: `确认删除选中的${this.selectedIds.length}张银行卡吗?`,
success: async res => {
if (res.confirm) {
this.loading = true
try {
const response = await deleteBankAccount(this.selectedIds)
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 {
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 {
padding: 30rpx;
max-height: 600rpx;
overflow-y: auto;
.delete-tip {
font-size: 28rpx;
color: #666;
margin-bottom: 30rpx;
}
.loading-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 60rpx 0;
.loading-spinner {
width: 60rpx;
height: 60rpx;
border: 4rpx solid #f3f3f3;
border-top: 4rpx solid #ff803a;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-bottom: 20rpx;
}
.loading-text {
font-size: 28rpx;
color: #666;
}
}
.bank-list {
.bank-item {
display: flex;
align-items: center;
padding: 30rpx;
border: 2rpx solid #f0f0f0;
border-radius: 15rpx;
margin-bottom: 20rpx;
transition: all 0.3s ease;
&:last-child {
margin-bottom: 0;
}
&.selected {
border-color: #ff803a;
background: #fff5f0;
}
.bank-info {
flex: 1;
.bank-header {
display: flex;
align-items: center;
margin-bottom: 10rpx;
.bank-name {
font-size: 30rpx;
color: #333;
font-weight: 500;
margin-right: 15rpx;
}
.bank-type {
font-size: 22rpx;
color: #ff803a;
background: #fff5f0;
padding: 4rpx 12rpx;
border-radius: 20rpx;
}
}
.bank-number {
font-size: 26rpx;
color: #666;
}
}
.checkbox {
width: 40rpx;
height: 40rpx;
border: 2rpx solid #e0e0e0;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
&.checked {
border-color: #ff803a;
background: #ff803a;
.check-icon {
color: #fff;
font-size: 24rpx;
font-weight: bold;
}
}
}
}
}
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 80rpx 0;
.empty-icon {
font-size: 80rpx;
margin-bottom: 20rpx;
}
.empty-text {
font-size: 28rpx;
color: #999;
}
}
}
.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;
&.disabled {
color: #ccc;
background: #f5f5f5;
}
}
}
}
@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>