@@ -84,3 +84,15 @@ export function getCentralSubjects(query) { | |||
params: query | |||
}) | |||
} | |||
//检索 | |||
export function realtimeBankList(data, dump = true) { | |||
return request({ | |||
url: '/yinnong/deposit/realtimeList', | |||
method: 'post', | |||
data: data, | |||
params: { | |||
dump, | |||
} | |||
}) | |||
} |
@@ -0,0 +1,216 @@ | |||
<!-- 下拉列表表单组件 zhao --> | |||
<template> | |||
<div> | |||
<van-field | |||
:readonly="true" | |||
:clickable="!readonly" | |||
:name="name" | |||
:value="visibleValue" | |||
:label="label" | |||
:placeholder="placeholder" | |||
@click="openPopup" | |||
input-align="right" | |||
right-icon="arrow-down" | |||
:rules="rules" | |||
:required="required" | |||
:label-width="labelWidth || 'auto'" | |||
> | |||
</van-field> | |||
<van-popup v-model="popupVisible" position="bottom"> | |||
<van-picker | |||
ref="picker" | |||
:title="label" | |||
show-toolbar | |||
:columns="columns ? columns : remoteColumns" | |||
:readonly="readonly" | |||
:value-key="valueKey" | |||
:loading="loading" | |||
@confirm="onConfirm" | |||
@cancel="onCancel" | |||
@change="onChanged" | |||
/> | |||
</van-popup> | |||
</div> | |||
</template> | |||
<script> | |||
import request from "@/utils/request"; | |||
export default { | |||
name: "fieldCascadeSelect", | |||
props: [ | |||
'name', 'readonly', 'value', 'label', 'placeholder', 'required', 'rules', 'labelWidth', | |||
'columns', // 列表数据 Array | |||
'valueKey', // 名称键名 String | |||
'dataKey', // 值键名 String | |||
'remoteUrl', // 远程列表加载地址 String | |||
'onRemoteResponse', // 远程获取到结果的处理回调 String|Function 如果是函数需返回数组, 如果是字符串支持.分割 | |||
'clearable', // 点击取消时清空绑定值 | |||
], | |||
watch: { | |||
value: function (newVal, oldVal) { | |||
this.internalValue = newVal; | |||
this.visibleValue = newVal ? newVal.join(' / ') : ''; | |||
this.syncIndex(); | |||
}, | |||
columns: function (newVal, oldVal) { | |||
this.syncIndex(); | |||
}, | |||
remoteUrl: function (newVal, oldVal) { | |||
this.requestRemote(); | |||
}, | |||
onRemoteResponse: function (newVal, oldVal) { | |||
this.parseRemote(); | |||
} | |||
}, | |||
created() { | |||
if(this.remoteUrl) | |||
this.requestRemote(); | |||
}, | |||
data() { | |||
return { | |||
popupVisible: false, | |||
internalValue: this.value, | |||
visibleValue: '', | |||
defaultIndex: [], | |||
remoteColumns: null, | |||
loading: false, | |||
remoteResponse: null, | |||
}; | |||
}, | |||
methods: { | |||
openPopup() { | |||
if(!this.readonly) | |||
{ | |||
this.popupVisible = true; | |||
this.$nextTick(() => { | |||
this.$refs.picker.setIndexes(this.defaultIndex); | |||
}) | |||
} | |||
}, | |||
closePopup() { | |||
this.popupVisible = false; | |||
}, | |||
onChanged(data) { | |||
this.$emit('change', data); | |||
}, | |||
onConfirm(data) { | |||
this.syncValue(data); | |||
this.$emit('input', this.internalValue); | |||
this.$emit('confirm', this.internalValue); | |||
this.closePopup(); | |||
}, | |||
onCancel() { | |||
this.closePopup(); | |||
this.$emit('cancel'); | |||
if(this.clearable) | |||
{ | |||
this.visibleValue = ''; | |||
this.internalValue = []; | |||
this.$emit('input', this.internalValue); | |||
} | |||
}, | |||
getValue(data) { | |||
return typeof(data) === 'object' && this.dataKey ? data[this.dataKey] : data; | |||
}, | |||
getLabel(data) { | |||
return typeof(data) === 'object' && this.valueKey ? data[this.valueKey] : data; | |||
}, | |||
syncValue(data) { | |||
let res = []; | |||
for(let a of data) | |||
{ | |||
res.push(this.getValue(a)); | |||
} | |||
this.internalValue = res; | |||
res = []; | |||
for(let a of data) | |||
{ | |||
res.push(this.getLabel(a)); | |||
} | |||
this.visibleValue = res.join(' / '); | |||
}, | |||
syncIndex() { | |||
let columns = this.getColumns(); | |||
if(!columns) | |||
return -1; | |||
let arr = []; | |||
let dataArr = []; | |||
let ptr = columns; | |||
for(let i = 0; i < this.internalValue.length; i++) | |||
{ | |||
if(!ptr) | |||
break; | |||
let p = null; | |||
for(let m = 0; m < ptr.length; m++) | |||
{ | |||
if(this.getValue(ptr[m]) == this.internalValue[i]) { | |||
arr.push(m); | |||
dataArr.push(ptr[m]); | |||
p = ptr[m]; | |||
break; | |||
} | |||
} | |||
if(p) | |||
ptr = p.children; | |||
} | |||
if(arr.length) | |||
{ | |||
this.defaultIndex = arr; | |||
this.visibleValue = dataArr.map((x) => this.getLabel(x)).join(' / '); | |||
this.onChanged(dataArr); | |||
return dataArr; | |||
} | |||
if(1) // 不存在 | |||
{ | |||
this.defaultIndex = []; | |||
this.visibleValue = (this.internalValue || []).join(' / '); | |||
this.onChanged([]); | |||
} | |||
return -1; | |||
}, | |||
getColumns() { | |||
return this.columns ? this.columns : this.remoteColumns; | |||
}, | |||
requestRemote() { | |||
if(!this.remoteUrl) | |||
return; | |||
this.loading = true; | |||
this.remoteColumns = []; | |||
let promise = typeof(this.remoteUrl) === 'function' ? this.remoteUrl() : (this.remoteUrl instanceof Promise ? this.remoteUrl : request(this.remoteUrl)); | |||
promise.then((resp) => { | |||
this.remoteResponse = resp; | |||
this.parseRemote(); | |||
this.syncIndex(); | |||
}).catch((e) => { | |||
console.error(e); | |||
}).finally(() => { | |||
this.loading = false; | |||
}) | |||
}, | |||
parseRemote() { | |||
if(!this.remoteResponse) | |||
return; | |||
let type = typeof(this.onRemoteResponse); | |||
if(type === 'function') | |||
this.remoteColumns = this.onRemoteResponse(this.remoteResponse); | |||
else if(type === 'string') | |||
{ | |||
let arr = this.onRemoteResponse.split('.'); | |||
let ptr = this.remoteResponse; | |||
for(let i in arr) | |||
{ | |||
ptr = this.remoteResponse[arr[i]]; | |||
} | |||
this.remoteColumns = ptr; | |||
} | |||
else | |||
this.remoteColumns = this.remoteResponse; | |||
}, | |||
}, | |||
} | |||
</script> | |||
<style scoped> | |||
</style> |
@@ -18,32 +18,34 @@ | |||
<van-form @submit="goModify" @failed="getError" :show-error-message="false" scroll-to-error validate-first> | |||
<div class="main_box"> | |||
<van-field label="省" required :rules="[{ required: true , message:'请输入省' }]" v-model="form.sheng" placeholder="请输入省" input-align="right" label-width="auto"/> | |||
<van-field label="市" required :rules="[{ required: true , message:'请输入市' }]" v-model="form.shi" placeholder="请输入市" input-align="right" label-width="auto"/> | |||
<van-field | |||
readonly | |||
clickable | |||
<FieldCascadeSelect :required="true" :rules="[{ required: true , message:'请选择省市' }]" data-key="value" value-key="label" :columns="regionOptions" v-model="form.region" placeholder="请选择开户省市" label="开户省市" label-width="auto" @input="onRegionChanged"/> | |||
<FieldSelect | |||
label="所属银行" | |||
placeholder="请选择" | |||
v-model="bankType" | |||
@click="showBankType = true" | |||
input-align="right" | |||
right-icon="arrow-down" | |||
v-model="form.bankType" | |||
label-width="auto" | |||
required | |||
:required="true" | |||
:rules="[{ required: true , message:'请选择所属银行' }]" | |||
:columns="bankTypeOptions" | |||
data-key="dictValue" | |||
value-key="dictLabel" | |||
/> | |||
<van-popup v-model="showBankType" position="bottom"> | |||
<van-field label="开户行" required :rules="[{ required: true , message:'请输入开户行' }]" v-model="form.bankDeposit" placeholder="请输入开户行" input-align="right" label-width="auto"> | |||
<template #button> | |||
<van-button :disabled="!canFetch" size="small" type="primary" native-type="button" @click="searchBankAddress">手动检索</van-button> | |||
</template> | |||
</van-field> | |||
<van-popup v-model:show="showBankAddress" position="bottom"> | |||
<van-picker | |||
show-toolbar | |||
:columns="bankTypeOptions" | |||
@confirm="onConfirmBankType" | |||
@cancel="showBankType = false" | |||
value-key="bankDeposit" | |||
:columns="bankAddressOption" | |||
@confirm="onConfirmBankAddress" | |||
@cancel="showBankAddress = false" | |||
/> | |||
</van-popup> | |||
<van-field label="开户行" required :rules="[{ required: true , message:'请输入开户行' }]" v-model="form.bankDeposit" placeholder="请输入开户行" input-align="right" label-width="auto"/> | |||
<van-field label="联行号" required :rules="[{ required: true , message:'请输入联行号' }]" v-model="form.payeePaymentLines" placeholder="请输入联行号" input-align="right" label-width="auto"/> | |||
<van-field label="机构号" v-model="form.institutionNumber" placeholder="请输入机构号" input-align="right" label-width="auto"/> | |||
@@ -62,21 +64,29 @@ | |||
<script> | |||
import { addDeposit } from "@/api/onlineHome/bankAgriculture/bankOfDeposit"; | |||
import {options} from "@/api/user"; | |||
import FieldCascadeSelect from "@/components/form/FieldCascadeSelect"; | |||
import {listDeposit, realtimeBankList} from "@/api/onlineHome/bankAgriculture/paymentAccount"; | |||
import FieldSelect from "@/components/form/FieldSelect"; | |||
export default { | |||
name: "paymentAccountAdd", | |||
components: {FieldSelect, FieldCascadeSelect}, | |||
data() { | |||
return { | |||
showBankType:false, | |||
bankType:'', | |||
// 所属银行字典 | |||
bankTypeOptions: [], | |||
showBankAddress: false, | |||
bankAddressOption: [], | |||
form:{ | |||
sheng: "", //省 必填 | |||
shi: "", //市 必填 | |||
bankType: "", //所属银行 必填 | |||
bankDeposit: "", //开户行 必填 | |||
payeePaymentLines: "", //联行号 //必填 | |||
} | |||
region: [], | |||
}, | |||
}; | |||
}, | |||
created() { | |||
@@ -89,9 +99,7 @@ | |||
getDetail(){ | |||
// 所属银行 | |||
this.getDicts("bank_type_all").then(res => { | |||
for (var i = 0; i < res.data.length; i++) { | |||
this.bankTypeOptions.push({text: res.data[i].dictLabel, value: res.data[i].dictValue}); | |||
} | |||
this.bankTypeOptions = res.data; | |||
}); | |||
}, | |||
getError(e){ | |||
@@ -114,7 +122,61 @@ | |||
}, | |||
goBack(){ | |||
window.history.go(-1) | |||
} | |||
}, | |||
onRegionChanged(val) { | |||
val = val || []; | |||
this.form.sheng = val.length > 0 ? val[0] : null; | |||
this.form.shi = val.length > 1 ? val[1] : null; | |||
}, | |||
onConfirmBankAddress(value){ | |||
this.form.bankAddress = value.bankDeposit; | |||
this.form.payeePaymentLines = value.payeePaymentLines; | |||
this.form.bankDeposit = value.bankDeposit; | |||
this.showBankAddress = false; | |||
}, | |||
checkFormField(what, desc) { | |||
if(!this.form[what]) | |||
{ | |||
this.$toast({ | |||
icon: 'fail', | |||
message: '请选择' + desc, | |||
duration:"1000", | |||
}); | |||
return false; | |||
} | |||
return true; | |||
}, | |||
searchBankAddress(){ | |||
if(!this.checkFormField('sheng', '省')) return; | |||
if(!this.checkFormField('shi', '市')) return; | |||
if(!this.checkFormField('bankType', '所属银行')) return; | |||
if(!this.checkFormField('bankDeposit', '关键词')) return; | |||
let data = { | |||
sheng: this.form.sheng, | |||
shi: this.form.shi, | |||
bankType: this.form.bankType, | |||
bankDeposit: this.form.bankDeposit, | |||
} | |||
listDeposit(data).then(response => { | |||
if (response.rows.length<1){ | |||
realtimeBankList(data, false).then(response2 => { | |||
this.bankAddressOption = response2.data; | |||
this.showBankAddress = true; | |||
}); | |||
}else{ | |||
this.bankAddressOption = response.rows; | |||
this.showBankAddress = true; | |||
} | |||
}); | |||
}, | |||
}, | |||
computed: { | |||
regionOptions() { | |||
return options; | |||
}, | |||
canFetch() { | |||
return this.form.sheng && this.form.shi && this.form.bankType && this.form.bankDeposit; | |||
}, | |||
}, | |||
} | |||
</script> | |||