web-base-pc/src/components/WithdrawalDialog.vue

421 lines
13 KiB
Vue
Raw Normal View History

2025-04-30 17:43:18 +08:00
<template>
<el-dialog
:title="'提现'"
:close-on-click-modal="false"
:visible.sync="dialogVisible"
width="40%"
2025-04-30 17:43:18 +08:00
center
custom-class="withdrawal-dialog"
@close="handleClose"
>
<div class="withdrawal-dialog-content">
<el-form
:model="txform"
:rules="txrules"
label-width="100px"
ref="txform"
>
<el-form-item :label="'银行卡号'" prop="pkBank">
<el-input
v-if="bankData.cardNumber"
v-model="bankData.cardNumber"
disabled
></el-input>
<div v-else @click="goToBindCard" class="bind-card-prompt">
请先绑定银行卡
</div>
</el-form-item>
<el-form-item :label="'提现金额'" prop="cashAmount">
<el-input
v-model="txform.cashAmount"
:placeholder="'请输入提现金额'"
type="number"
clearable
@input="fetchWithdrawalInfo"
></el-input>
</el-form-item>
<el-form-item :label="'二级密码'" prop="payPwd">
<el-input
v-model="txform.payPwd"
type="password"
:placeholder="'请输入二级密码'"
show-password
clearable
></el-input>
</el-form-item>
<el-form-item :label="'备注'" prop="remarks">
<el-input
v-model="txform.remarks"
:placeholder="'请输入备注(可选)'"
type="textarea"
:rows="2"
></el-input>
</el-form-item>
<el-form-item :label="'提现账户'" prop="pkAccount">
<el-select
clearable
v-model="txform.pkAccount"
:placeholder="'请选择提现账户'"
@change="fetchWithdrawalInfo"
style="width: 100%"
>
<el-option
v-for="(item, index) in pkBdAccountList"
:key="index"
:label="item.pkTransactionKeyVal"
:value="item.pkId"
></el-option>
</el-select>
</el-form-item>
<el-form-item
label="提现信息"
label-width="100px"
class="withdrawal-info-section"
>
<div class="info-line">
<span>{{ `${"可提现金额"}(${currencyIcon})` }}</span>
<span>{{ widthDrwaData.amount || "0.00" }}</span>
</div>
<div class="info-line">
<span>{{ `${"账户余额"}(${currencyIcon})` }}</span>
<span>{{ widthDrwaData.balance || "0.00" }}</span>
</div>
<div class="info-line">
<span>{{ `${"提现手续费"}(${currencyIcon})` }}</span>
<span>{{ widthDrwaData.srviceCharge || "0.00" }}</span>
</div>
<div class="info-line">
<span>{{ `${"最低提现额度"}(${currencyIcon})` }}</span>
<span>{{ widthDrwaData.minAmount || "0.00" }}</span>
</div>
</el-form-item>
</el-form>
<div class="dialog-footer">
<el-button @click="handleClose">取消</el-button>
<el-button
:disabled="canbind"
type="primary"
class="confirm-button"
@click="saveTx"
>
确认提现
</el-button>
</div>
</div>
</el-dialog>
</template>
<script>
import * as wal from "@/api/wallet.js";
export default {
name: "WithdrawalDialog",
props: {
visible: {
type: Boolean,
default: false,
},
userInfo: {
type: Object,
required: true,
},
},
data() {
return {
txform: {
pkBank: "",
cashAmount: "",
remarks: "",
payPwd: "",
pkAccount: "",
},
txrules: {
// Basic rules, enhance as needed
pkBank: [
{ required: true, message: "请绑定银行卡", trigger: "change" },
],
cashAmount: [
{ required: true, message: "请输入提现金额", trigger: "blur" },
{ type: "number", message: "金额必须为数字值" },
{
validator: (rule, value, callback) => {
if (value <= 0) {
callback(new Error("提现金额必须大于0"));
} else {
callback();
}
},
trigger: "blur",
},
],
payPwd: [
{ required: true, message: "请输入二级密码", trigger: "blur" },
],
pkAccount: [
{ required: true, message: "请选择提现账户", trigger: "change" },
],
},
pkBdAccountList: [],
bankData: {},
widthDrwaData: {},
canbind: false,
dialogVisible: this.visible,
};
},
computed: {
currencyIcon() {
return this.userInfo?.currencyIcon || "";
},
},
watch: {
visible(newVal) {
this.dialogVisible = newVal;
if (newVal) {
this.fetchInitialData(); // Fetch data when dialog opens
}
},
dialogVisible(newVal) {
if (!newVal) {
this.$emit("update:visible", false);
}
},
},
methods: {
async fetchInitialData() {
await this.getDefaultBank();
await this.getPkBdAccountList();
await this.checkIsbindBank();
this.fetchWithdrawalInfo(); // Fetch initial withdrawal info
},
async getDefaultBank() {
try {
const res = await wal.getDefaultBank();
this.bankData = res.data || {};
this.txform.pkBank = this.bankData.pkId || "";
// Update rule based on whether bank is bound
this.txrules.pkBank[0].required = !this.bankData.pkId;
} catch (error) {
console.error("获取默认银行卡失败:", error);
this.$message.error("获取默认银行卡信息失败");
}
},
async getPkBdAccountList() {
try {
const res = await wal.getPkBdAccountList({ accountProperty: 3 });
this.pkBdAccountList = res.data || [];
if (this.pkBdAccountList.length > 0 && !this.txform.pkAccount) {
this.txform.pkAccount = this.pkBdAccountList[0].pkId;
}
} catch (error) {
console.error("获取提现账户列表失败:", error);
this.$message.error("获取提现账户列表失败");
}
},
async checkIsbindBank() {
try {
const res = await wal.checkIsbindBank();
this.canbind = res.flag === "N"; // Disable button if not bound ('N')
} catch (error) {
console.error("检查银行卡绑定状态失败:", error);
this.$message.error("检查银行卡绑定状态失败");
}
},
async fetchWithdrawalInfo() {
if (!this.txform.pkAccount) {
// If no account selected, reset withdrawal info
this.widthDrwaData = {};
return;
}
try {
const res = await wal.getWidthdrawShow({
pkAccount: this.txform.pkAccount,
cashAmount: Number(this.txform.cashAmount) || 0,
});
this.widthDrwaData = res.data || {};
} catch (error) {
console.error("获取提现信息失败:", error);
this.widthDrwaData = {}; // Reset on error
// Optionally show an error message to the user
// this.$message.error("获取提现详细信息失败");
}
},
saveTx() {
this.$refs.txform.validate(async (valid) => {
if (valid) {
if (this.canbind) {
this.$message.warning("请先绑定银行卡");
return;
}
if (!this.txform.cashAmount || this.txform.cashAmount <= 0) {
this.$message.warning("请输入正确的提现金额");
return;
}
try {
const res = await wal.addWithdraw(this.txform);
if (res.code == 200) {
this.$message.success(res.msg || "提现申请成功");
this.$emit("success"); // Notify parent on success
this.handleClose(); // Close dialog
} else {
this.$message.error(res.msg || "提现申请失败");
}
} catch (error) {
console.error("提现申请失败:", error);
this.$message.error("提现申请失败");
}
} else {
console.log("提现表单验证失败");
return false;
}
});
},
handleClose() {
this.$refs.txform.resetFields(); // Reset form on close
this.widthDrwaData = {}; // Reset withdrawal info
this.dialogVisible = false; // This will trigger the watch and emit update:visible
this.$emit("close");
},
goToBindCard() {
this.$emit("go-bind-card");
this.handleClose();
},
},
};
</script>
<style lang="scss" scoped>
// Apply styles using the custom dialog class for better scoping
::v-deep .withdrawal-dialog {
.el-dialog__header {
border-bottom: 1px solid #eaeaec; // Slightly lighter border
padding: 20px 28px; // Increase padding more
.el-dialog__title {
font-size: 20px; // Increase title font size again
font-weight: 600;
}
}
.el-dialog__body {
padding: 28px; // Increase body padding more
}
.el-dialog__footer {
padding: 15px 28px; // Increase footer padding more
border-top: 1px solid #eaeaec; // Slightly lighter border
}
}
.withdrawal-dialog-content {
// Renamed class
.el-form-item {
margin-bottom: 22px; // Increase spacing between form items more
}
.el-form-item__label {
font-size: 16px; // Increase label size again
color: #505356; // Darker label color
line-height: 44px; // Align with increased input height
}
.el-input__inner,
.el-textarea__inner,
.el-select .el-input__inner {
// Apply consistent styling to inputs/select
height: 44px; // Increase input height again
line-height: 44px;
font-size: 16px; // Increase input font size again
padding: 0 18px; // Increase padding slightly
width: 100%;
border-radius: 5px; // Slightly rounder corners
}
.el-textarea__inner {
height: auto;
min-height: 44px; // Ensure minimum height matches input
line-height: 1.7; // Adjust line-height for textarea
padding-top: 10px; // Adjust vertical padding
padding-bottom: 10px;
}
// Style for the bind card prompt message
.bind-card-prompt {
line-height: 44px; // Match increased input height
color: #e64e4e; // Slightly adjust danger color
cursor: pointer;
font-size: 16px; // Increase font size again
&:hover {
text-decoration: underline;
}
}
// Section for withdrawal info display
.withdrawal-info-section {
margin-top: 20px; // Increase space above the section more
// Use ::v-deep to target the label generated by el-form-item within this specific section
::v-deep .el-form-item__label {
// Style the label for this section
font-size: 16px; // Consistent label size
font-weight: 600; // Make it bolder
color: #303133;
margin-bottom: 8px; // Add space below label
line-height: normal; // Reset line-height if needed
float: none; // Ensure label is block display
text-align: left; // Align label text left
}
// Use ::v-deep to target the content wrapper generated by el-form-item
::v-deep .el-form-item__content {
// Target the content area
line-height: normal;
background-color: #f0f2f5; // Darker background color
padding: 20px 25px; // Increase padding more
border-radius: 8px; // Larger border radius
border: 1px solid #d1d5db; // Slightly darker border
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.05); // Subtle inset shadow for depth
font-size: 16px; // Keep font size consistent
color: #333; // Ensure good contrast
margin-left: 0 !important; // Override default margin if necessary
}
}
// Style for each info line (replaces linetx)
.info-line {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 12px; // Increase spacing between lines more
&:last-child {
margin-bottom: 0;
}
span:first-child {
color: #777; // Adjust label color
}
span:last-child {
font-weight: 600;
color: #222; // Darker value color
}
}
.dialog-footer {
// Styles for the footer button area
text-align: right;
margin-top: 30px; // Increase space above buttons more
.el-button {
width: auto;
padding: 12px 25px; // Increase button padding more
font-size: 16px; // Increase button font size again
margin-left: 14px; // Increase button margin more
border-radius: 6px; // Rounder corners
}
.confirm-button {
// Specific style for confirm (replaces saveBtn)
}
}
}
// Adjust styles for disabled input if needed
::v-deep .el-input.is-disabled .el-input__inner {
background-color: #f5f7fa;
border-color: #e4e7ed; // Consistent border color
color: #c0c4cc; // Standard disabled text color
cursor: not-allowed;
}
</style>