<template>
|
<!-- 企业发票抬头信息弹窗 -->
|
<el-dialog v-model="dialogVisible" title="客户银行账号配置" width="60%" destroy-on-close @close="handleClose"
|
:close-on-click-modal="false">
|
<!-- 表单主体 -->
|
<el-form ref="formRef" :model="form" :rules="formRules" label-width="140px" size="default"
|
class="form-container">
|
<!-- 关联客户(带搜索图标) -->
|
<el-form-item label="关联客户" v-if="ishowBank" prop="customerName">
|
<!-- <el-input v-model="form.customerName" placeholder="请选择关联客户" readonly suffix-icon="Search"
|
@click="openCustomerSelectDialog" class="search-input" /> -->
|
<el-input v-model="form.customerName" placeholder="请选择关联客户" readonly class="search-input"
|
@click="openCustomerSelectDialog">
|
<template #suffix>
|
<el-icon class="el-input__icon" style="cursor: pointer;" @click="openCustomerSelectDialog">
|
<Search />
|
</el-icon>
|
</template>
|
</el-input>
|
</el-form-item>
|
|
<el-form-item label="关联主体" v-if="!ishowBank" prop="customerName">
|
<el-input v-model="form.customerName" placeholder="请选择关联主体" readonly class="search-input"
|
@click="subjectPerationSelectDialog">
|
<template #suffix>
|
<el-icon class="el-input__icon" style="cursor: pointer;" @click="subjectPerationSelectDialog">
|
<Search />
|
</el-icon>
|
</template>
|
</el-input>
|
</el-form-item>
|
|
<!-- 抬头公司 -->
|
<el-form-item label="账号编号" v-if="ishowBank" prop="accountNo">
|
<el-input v-model="form.accountNo" placeholder="请输入账号编号" />
|
</el-form-item>
|
|
<el-form-item label="银行账号" v-if="!ishowBank" prop="accountNo">
|
<el-input v-model="form.accountNo" placeholder="请输入银行账号" />
|
</el-form-item>
|
|
<!-- 统一社会信用代码 -->
|
<el-form-item label="户名" prop="accountName">
|
<el-input v-model="form.accountName" placeholder="请输入户名" maxlength="18" />
|
</el-form-item>
|
|
<!-- 开户银行名称 -->
|
<el-form-item label="银行名称" prop="bankName">
|
<el-input v-model="form.bankName" placeholder="请输入开户银行名称" />
|
</el-form-item>
|
|
<el-form-item label="支行名称" prop="branchName">
|
<el-input v-model="form.branchName" placeholder="请输入支行名称" />
|
</el-form-item>
|
|
<el-form-item label="账号类型" v-if="ishowBank" prop="accountType">
|
<el-select v-model="form.accountType" placeholder="请选账号类型" clearable>
|
<el-option v-for="dict in sys_invoice_type" :key="dict.value" :label="dict.label"
|
:value="dict.value" />
|
</el-select>
|
</el-form-item>
|
|
<el-form-item label="账号类型" v-if="!ishowBank" prop="accountType">
|
<el-select v-model="form.accountType" placeholder="请选账号类型" clearable>
|
<el-option v-for="dict in sys_internal_type" :key="dict.value" :label="dict.label"
|
:value="dict.value" />
|
</el-select>
|
</el-form-item>
|
|
<el-form-item label="币种" prop="currency">
|
<el-select v-model="form.currency" placeholder="请选币种" clearable>
|
<el-option v-for="dict in sys_currency" :key="dict.value" :label="dict.label" :value="dict.value" />
|
</el-select>
|
</el-form-item>
|
|
|
<el-form-item label="账户状态" prop="status">
|
<el-select v-model="form.status" placeholder="请选账户状态" clearable>
|
<el-option v-for="dict in sys_bank_type" :key="dict.value" :label="dict.label"
|
:value="dict.value" />
|
</el-select>
|
</el-form-item>
|
|
|
|
|
|
|
</el-form>
|
|
<!-- 底部按钮 -->
|
<template #footer>
|
<div class="dialog-footer">
|
<el-button @click="handleClose">取消</el-button>
|
<el-button type="primary" @click="handleSubmit">确定</el-button>
|
</div>
|
</template>
|
</el-dialog>
|
|
<!-- 关联客户选择弹窗 -->
|
<CustomerSelectDialog :visible="isCustomerSelectVisibleIshow" :default-selected-id="form.customerId"
|
@confirm="handleCustomerSelect" @close="isCustomerSelectVisibleIshow = false" />
|
<subjectPeration :visible="subjectPerationShow" :default-selected-id="form.customerId"
|
@confirm="subjectPerationSelect" @close="subjectPerationShow = false" />
|
</template>
|
|
<script setup lang="ts">
|
import { ref, reactive, nextTick } from 'vue';
|
import type { FormInstance, FormRules } from 'element-plus';
|
import { ElMessage } from 'element-plus';
|
// 引入客户选择弹窗组件
|
import CustomerSelectDialog from '../CustomerSelectDialog/index';
|
import subjectPeration from '../subjectPeration/index';
|
|
|
import useCurrentInstance from "@/utils/useCurrentInstance";
|
const { proxy } = useCurrentInstance();
|
const { sys_invoice_type, sys_currency, sys_bank_type,sys_internal_type } = proxy.useDict('sys_invoice_type', 'sys_currency', 'sys_bank_type',
|
'sys_internal_type'
|
);
|
const props = defineProps({
|
ishowBank: {
|
type: Boolean,
|
default: true
|
},
|
|
});
|
// 定义表单数据类型(新增customerId字段,避免赋值时报错)
|
interface InvoiceForm {
|
customerId?: string | number; // 新增:客户ID(用于回显选中)
|
customerName: string; // 关联客户
|
accountNo: string; // 抬头公司
|
accountName: string; // 统一社会信用代码
|
accountType: string; // 发票类型
|
bankName: string; // 开户银行名称
|
branchName: string; // 基本开户账号
|
invoiceOperatingLicenseAddress: string; // 注册场所地址
|
invoiceOperatingLicensePhone: string; // 注册固定电话
|
invoiceOperatingLicenseEmail: string; // 邮箱
|
currency?: string; // 币种
|
status?: string; // 账户状态
|
}
|
|
// 弹窗控制
|
const dialogVisible = ref(false);
|
const isCustomerSelectVisibleIshow = ref(false);
|
|
// Emits
|
const emit = defineEmits(['close', 'submit']);
|
|
// 表单数据(reactive声明,只能修改属性,不能整体赋值)
|
const form = reactive<InvoiceForm>({
|
customerId: '', // 初始化customerId
|
customerName: '',
|
accountNo: '',
|
accountName: '',
|
accountType: '',
|
bankName: '',
|
branchName: '',
|
id: '',
|
invoiceOperatingLicenseAddress: '',
|
invoiceOperatingLicensePhone: '',
|
invoiceOperatingLicenseEmail: '',
|
currency: '',
|
status: '',
|
});
|
|
// 表单校验规则
|
const formRules = reactive<FormRules>({
|
customerName: [
|
{ required: true, message: '请选择关联客户', trigger: 'blur' }
|
],
|
accountNo: [
|
{ required: true, message: '请输入账户编号', trigger: 'blur' }
|
],
|
accountName: [
|
{ required: true, message: '请输入户名', trigger: 'blur' }
|
],
|
// invoiceType: [
|
// { required: true, message: '请选择发票类型', trigger: 'change' }
|
// ],
|
invoiceOperatingLicensePhone: [
|
{ required: true, message: '请输入注册固定电话', trigger: 'blur' },
|
{ pattern: /^1[3-9]\d{9}$|^0\d{2,3}-\d{7,8}$/, message: '请输入正确的手机号或固定电话', trigger: 'blur' }
|
],
|
invoiceOperatingLicenseEmail: [
|
{ required: true, message: '请输入邮箱', trigger: 'blur' },
|
{ type: 'email', message: '请输入正确的邮箱格式', trigger: 'blur' }
|
]
|
});
|
|
// 表单实例
|
const formRef = ref<FormInstance>();
|
|
// 打开弹窗(供父组件调用,修复回显逻辑)
|
const openDialog = (data?: Partial<InvoiceForm>) => {
|
dialogVisible.value = true;
|
|
// 先重置表单,避免旧数据残留
|
nextTick(() => {
|
formRef.value?.resetFields();
|
|
// 有回显数据时,逐个赋值(核心修复:避免整体赋值form = data)
|
if (data && Object.keys(data).length > 0) {
|
// 遍历data的所有字段,赋值到form(仅覆盖对应字段)
|
Object.assign(form, data);
|
// 清空表单校验状态
|
formRef.value?.clearValidate();
|
} else {
|
// 无回显数据时,清空表单
|
Object.assign(form, {
|
customerId: '',
|
customerName: '',
|
accountNo: '',
|
accountName: '',
|
accountType: '',
|
bankName: '',
|
branchName: '',
|
id: '',
|
invoiceOperatingLicenseAddress: '',
|
invoiceOperatingLicensePhone: '',
|
invoiceOperatingLicenseEmail: '',
|
currency: '',
|
status: ''
|
});
|
}
|
});
|
};
|
|
// 打开关联客户选择弹窗
|
const openCustomerSelectDialog = () => {
|
isCustomerSelectVisibleIshow.value = true;
|
};
|
|
// 选择客户回调
|
const handleCustomerSelect = (selectedCustomer) => {
|
form.customerName = selectedCustomer.customerFullName;
|
form.customerId = selectedCustomer.id; // 现在字段已声明,赋值有效
|
isCustomerSelectVisibleIshow.value = false;
|
};
|
const subjectPerationShow = ref(false);
|
const subjectPerationSelectDialog = () => {
|
subjectPerationShow.value = true;
|
|
};
|
const subjectPerationSelect = (selectedCustomer) => {
|
form.customerName = selectedCustomer.customerFullName;
|
form.customerId = selectedCustomer.id; // 现在字段已声明,赋值有效
|
isCustomerSelectVisibleIshow.value = false;
|
};
|
// 提交表单(修复校验逻辑 + 关闭弹窗)
|
const handleSubmit = async () => {
|
if (!formRef.value) return;
|
|
try {
|
// 表单校验
|
const valid = await formRef.value.validate();
|
if (!valid) return;
|
// 校验通过,提交数据给父组件
|
emit('submit', { ...form });
|
// ElMessage.success('提交成功!');
|
} catch (error) {
|
console.error('表单校验失败:', error);
|
// 定位具体失败字段
|
const invalidFields = (error as any).invalidFields;
|
if (invalidFields) {
|
const firstKey = Object.keys(invalidFields)[0];
|
const firstMsg = invalidFields[firstKey][0].message;
|
ElMessage.warning(`校验失败:${firstMsg}`);
|
} else {
|
// ElMessage.warning('请完善必填项后提交');
|
}
|
}
|
};
|
|
// 关闭弹窗
|
const handleClose = () => {
|
dialogVisible.value = false;
|
formRef.value?.resetFields();
|
emit('close');
|
};
|
|
// 暴露方法给父组件
|
defineExpose({ openDialog, handleClose });
|
</script>
|
|
<style scoped lang="scss">
|
.form-container {
|
padding: 10px 0;
|
|
:deep(.el-form-item) {
|
margin-bottom: 18px;
|
}
|
}
|
|
.search-input {
|
:deep(.el-input__inner) {
|
cursor: pointer;
|
background-color: #f8f9fa;
|
}
|
|
:deep(.el-icon-search) {
|
color: #409eff;
|
}
|
}
|
|
.dialog-footer {
|
text-align: right;
|
}
|
/* */
|
/* 使用 :deep() 穿透组件样式 */
|
:deep(.search-input .el-input__wrapper) {
|
background-color: #ffffff !important; /* 强制背景为白色 */
|
box-shadow: 0 0 0 1px var(--el-input-border-color, #dcdfe6) inset; /* 保持边框 */
|
}
|
|
/* 针对 readonly 状态下的特定处理(如果需要更精确控制) */
|
:deep(.search-input .el-input__inner[readonly]) {
|
background-color: #ffffff !important;
|
cursor: pointer; /* 既然是点击弹出,建议鼠标手势设为 pointer */
|
}
|
|
/* 如果你还想去掉鼠标滑过时的灰色感(如果有的话) */
|
:deep(.search-input .el-input__wrapper:hover) {
|
background-color: #ffffff !important;
|
}
|
</style>
|