440 lines
12 KiB
Vue
440 lines
12 KiB
Vue
<template>
|
||
<view class="page">
|
||
<view class="box">
|
||
<!-- 商户类型 渠道信息 进件信息 -->
|
||
<!-- 微信小程序不能用动态组件!!! -->
|
||
<shengpay
|
||
:ref="refHandle"
|
||
@applyHandle="applyHandle"
|
||
v-if="showRef('shengpay')"
|
||
/>
|
||
<alipay
|
||
:ref="refHandle"
|
||
@applyHandle="applyHandle"
|
||
v-if="showRef('alipay')"
|
||
/>
|
||
<wxpay
|
||
:ref="refHandle"
|
||
@applyHandle="applyHandle"
|
||
v-if="showRef('wxpay')"
|
||
/>
|
||
<zftpay
|
||
:ref="refHandle"
|
||
@applyHandle="applyHandle"
|
||
v-if="showRef('zftpay')"
|
||
/>
|
||
<sftpay
|
||
:ref="refHandle"
|
||
@applyHandle="applyHandle"
|
||
v-if="showRef('sftpay')"
|
||
/>
|
||
<lklpay
|
||
:ref="refHandle"
|
||
@applyHandle="applyHandle"
|
||
v-if="showRef('lklpay')"
|
||
/>
|
||
<ysfpay
|
||
:ref="refHandle"
|
||
@applyHandle="applyHandle"
|
||
v-if="showRef('ysfpay')"
|
||
/>
|
||
<dgpay
|
||
:ref="refHandle"
|
||
@applyHandle="applyHandle"
|
||
v-if="showRef('dgpay')"
|
||
/>
|
||
<yspay
|
||
:ref="refHandle"
|
||
@applyHandle="applyHandle"
|
||
v-if="showRef('yspay')"
|
||
/>
|
||
<utmpay
|
||
:ref="refHandle"
|
||
@applyHandle="applyHandle"
|
||
v-if="showRef('utmpay')"
|
||
/>
|
||
<fuioupay
|
||
:ref="refHandle"
|
||
@applyHandle="applyHandle"
|
||
v-if="showRef('fuioupay')"
|
||
/>
|
||
<lklspay
|
||
:ref="refHandle"
|
||
@applyHandle="applyHandle"
|
||
v-if="showRef('lklspay')"
|
||
/>
|
||
|
||
<view class="notes" v-if="['0', '3', '8'].includes(channelInfo.state)">
|
||
<image
|
||
src="@/static/img/exclamation.svg"
|
||
style="height: 22rpx; width: 22rpx"
|
||
></image>
|
||
<text>请确保信息的真实性和准确性,否则将影响通道申请成功率</text>
|
||
</view>
|
||
|
||
<!-- 错误信息 -->
|
||
<view class="result-fail" v-if="channelInfo.state == 3 && applyErrorInfo">
|
||
<text style="width: 83%">驳回原因:{{ applyErrorInfo }} </text>
|
||
<image src="@/static/img/passerror.svg"></image>
|
||
</view>
|
||
|
||
<view class="result-wait" v-if="channelInfo.state == 1">
|
||
<text style="width: 83%">信息审核中:请耐心等待</text>
|
||
<image src="@/static/img/passwait.svg"></image>
|
||
</view>
|
||
<!-- channelInfo.state -->
|
||
<view class="result-success" v-if="channelInfo.state == 2">
|
||
<text style="width: 83%">恭喜你:通道已开通</text>
|
||
<image src="@/static/img/passok.svg"></image>
|
||
</view>
|
||
|
||
<!-- 状态: 0-未发起、 1-审核中、 2-进件成功、 3-驳回待修改、 4-待验证、 5-待签约
|
||
状态为 1,2,4,5 开启disable (也就是状态不为 0 3) -->
|
||
<template v-if="['0', '3', '8'].includes(channelInfo.state)">
|
||
<view class="btn-area">
|
||
<view @click.stop="read" class="read">智能读取</view>
|
||
<view @click.stop="draft" style="margin-left: 30rpx" class="read">保存草稿</view>
|
||
</view>
|
||
|
||
<button @click.stop="submit(false)" class="submit">提交</button>
|
||
</template>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, reactive, onMounted, toRaw, provide, nextTick } from "vue";
|
||
import shengpay from "./channel/shengft/shengft.vue"; // 盛付通
|
||
import alipay from "./channel/zfbpay.vue"; // 支付宝官方
|
||
import wxpay from "./channel/wxpay.vue"; // 微信官方
|
||
import zftpay from "./channel/zftpay.vue"; // 支付宝直付通
|
||
import sftpay from "./channel/sftpay.vue"; // 微信收付通
|
||
import lklpay from "./channel/lklpay.vue"; // 拉卡拉
|
||
import ysfpay from "./channel/ysfpay.vue"; // 云闪付
|
||
import fuioupay from "./channel/fuiou/fuioupay.vue"; // 富友
|
||
import dgpay from "./channel/dgpay/dgpay.vue"; // 斗拱
|
||
import utmpay from "./channel/utmpay/utmpay.vue"; // 银联前置
|
||
import yspay from "./channel/yspay/yspay.vue"; // 银盛
|
||
import lklspay from "./channel/lklspay/lklspay.vue"; // lklsass
|
||
|
||
import { onLoad, onShow } from "@dcloudio/uni-app";
|
||
import {
|
||
$mchApplymentsInfo,
|
||
$mergeApplyDetailInfos,
|
||
$mchApplyments,
|
||
$updateApply,
|
||
} from "@/http/apiManager.js";
|
||
import { debounce } from "@/util/tool.js";
|
||
import rules from "./components/rules.js"; //引入表单校验规则
|
||
import graceChecker from "@/util/graceChecker.js"; //引入表单校验工具函数
|
||
|
||
// 进件渠道信息,包含 支付接口代码 名称 状态 进件ID
|
||
const channelInfo = reactive({});
|
||
|
||
const vdata = reactive({
|
||
channelRef: "",
|
||
});
|
||
|
||
// 动态ref
|
||
const refHandle = (el) => {
|
||
if (el) vdata.channelRef = el;
|
||
};
|
||
|
||
// 动态展示隐藏
|
||
const showRef = (code) => code === channelInfo.code;
|
||
|
||
onLoad((option) => {
|
||
for (let key in option) {
|
||
if (option[key] === "undefined") {
|
||
option[key] = undefined;
|
||
continue;
|
||
}
|
||
if (key == "codeUrl") {
|
||
channelInfo.codeUrl = decodeURIComponent(option.codeUrl);
|
||
continue;
|
||
}
|
||
channelInfo[key] = option[key];
|
||
}
|
||
});
|
||
|
||
provide("channelInfo", channelInfo);
|
||
|
||
onMounted(() => {
|
||
if (channelInfo.applyId) mchApplyInfoHandle(); // 调用查询进件信息函数,只有进件完之后才有该ID
|
||
});
|
||
|
||
// 查询进件信息
|
||
let mchApplyInfo = ref({}); // 进件信息
|
||
let applyErrorInfo = ref(false); // 错误信息
|
||
const mchApplyInfoHandle = () => {
|
||
let originData = ""; // 进件资料回显 是否查询原始数据 状态1原始, 状态0不填加密数据
|
||
if (["0", "3", "8"].includes(channelInfo.state)) originData = 1;
|
||
|
||
$mchApplymentsInfo(channelInfo.applyId, originData).then(({ bizData }) => {
|
||
// 错误信息
|
||
if (bizData) {
|
||
bizData.applyErrorInfo
|
||
? (applyErrorInfo.value = bizData.applyErrorInfo)
|
||
: (applyErrorInfo.value = false);
|
||
// 获取进件信息对象后,为子页码赋值
|
||
assignment(JSON.parse(bizData.applyDetailInfo));
|
||
}
|
||
});
|
||
};
|
||
|
||
// 智能读取按钮
|
||
const read = () => {
|
||
uni.showLoading({ title: "读取中", icon: "none" });
|
||
$mergeApplyDetailInfos(channelInfo.mchNo)
|
||
.then((res) => {
|
||
uni.hideLoading();
|
||
|
||
// 非空校验,然后剔除为空属性, 再将读取到的信息放到子组件进行合并
|
||
if (res.bizData && Object.keys(res.bizData).length !== 0) {
|
||
let obj = {};
|
||
|
||
for (let item in res.bizData) {
|
||
if (res.bizData[item]) obj[item] = res.bizData[item];
|
||
}
|
||
|
||
assignment(obj);
|
||
|
||
uni.showToast({ title: "读取成功", icon: "none" });
|
||
} else {
|
||
uni.showToast({ title: "读取信息为空", icon: "none" });
|
||
}
|
||
})
|
||
.catch((err) => {});
|
||
};
|
||
|
||
// 保存草稿 (接口一致,传参为true)
|
||
const draft = () => submit(true);
|
||
|
||
// 为子页面赋值,通过code值来判断为谁赋值
|
||
const assignment = (obj) => {
|
||
vdata.channelRef.assignObj(obj);
|
||
};
|
||
|
||
// 发起按钮
|
||
const isLoad = ref(false);
|
||
|
||
let timer; // 定时器
|
||
const submit = (isTempData) => {
|
||
if (timer) clearTimeout(timer);
|
||
timer = setTimeout(() => {
|
||
timer = null;
|
||
vdata.channelRef.launchApply(isTempData);
|
||
}, 500);
|
||
};
|
||
|
||
// 受益人前置校验函数
|
||
const ownerCheck = (index, val) => {
|
||
let errText = "";
|
||
switch (val) {
|
||
case "idcard1Img":
|
||
errText = `请上传第${index + 1}项受益人身份证人像面照`;
|
||
break;
|
||
1;
|
||
case "idcardNo":
|
||
errText = `请输入第${index + 1}项受益人身份证号`;
|
||
break;
|
||
case "idcardName":
|
||
errText = `请输入第${index + 1}项受益人身份证名称`;
|
||
break;
|
||
case "idcardAddress":
|
||
errText = `请输入第${index + 1}项受益人身份证地址`;
|
||
break;
|
||
case "idcard2Img":
|
||
errText = `请上传第${index + 1}项受益人身份证国徽面照`;
|
||
break;
|
||
case "idcardEffectEnd":
|
||
errText = `请选择第${index + 1}项受益人身份证起始有效期`;
|
||
break;
|
||
case "idcardEffectBegin":
|
||
errText = `请选择第${index + 1}项受益人身份证结束有效期`;
|
||
}
|
||
uni.showToast({ title: errText, icon: "none" });
|
||
};
|
||
|
||
// 最终版,发起进件
|
||
const applyHandle = (objData, ownerFlag = false) => {
|
||
const { name, isTempData, applyDetailInfo } = objData;
|
||
|
||
// 从reactive中拿回被代理的对象 (商户进件详细消息)
|
||
const rowApplyDetailInfo = toRaw(applyDetailInfo);
|
||
|
||
// 每次进来都要重置一次进件规则 需要深拷贝,因为下方会动态添加很多东西
|
||
let check = JSON.parse(JSON.stringify(rules[name + "Rule"]));
|
||
|
||
// 添加额外的进件规则
|
||
objData.formCheck ? rules[name + "Fun"](check, ...objData.formCheck) : null;
|
||
|
||
let checkRes = graceChecker.check(rowApplyDetailInfo, check);
|
||
if (!checkRes && !isTempData)
|
||
return uni.showToast({ title: graceChecker.error, icon: "none" });
|
||
|
||
// 受益人校验,比较特殊,放在最后手动校验
|
||
if (
|
||
ownerFlag &&
|
||
!isTempData &&
|
||
applyDetailInfo.companyBeneficiaryList.length > 0
|
||
) {
|
||
let ownerList = applyDetailInfo.companyBeneficiaryList;
|
||
|
||
for (let ownerIndex = 0; ownerIndex < ownerList.length; ownerIndex++) {
|
||
for (let key in ownerList[ownerIndex]) {
|
||
if (!ownerList[ownerIndex][key]) return ownerCheck(ownerIndex, key);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 传参对象
|
||
let params = {
|
||
ifCode: channelInfo.code, // 支付接口代码
|
||
productType: applyDetailInfo.productType, //产品类型
|
||
address: applyDetailInfo.address,
|
||
contactName: applyDetailInfo.contactName,
|
||
mchFullName: applyDetailInfo.mchFullName || applyDetailInfo.mchShortName,
|
||
areaCode: applyDetailInfo.areaCode ? applyDetailInfo.areaCode[2] : "", // 只要区县码即可
|
||
contactPhone: applyDetailInfo.contactPhone,
|
||
applyDetailInfo: JSON.stringify(rowApplyDetailInfo),
|
||
mchNo: channelInfo.mchNo,
|
||
};
|
||
let applyId;
|
||
channelInfo.applyId ? (applyId = channelInfo.applyId) : (applyId = undefined);
|
||
|
||
if (applyId) params.applyId = applyId; // 有就传
|
||
|
||
if (isTempData && channelInfo.applyId) {
|
||
uni.showLoading({ title: "保存中...", icon: "none" }); // 开启loading
|
||
params.isTempData = true;
|
||
// 保存草稿调用update方法进行提交
|
||
$updateApply(params.applyId, params)
|
||
.then((res) => {
|
||
uni.hideLoading();
|
||
uni.showToast({ title: "保存成功", icon: "none" });
|
||
if (channelInfo.applyId) {
|
||
uni.navigateBack();
|
||
} else {
|
||
uni.navigateBack({ delta: 2 });
|
||
}
|
||
})
|
||
.catch((err) => {});
|
||
return;
|
||
}
|
||
|
||
if (isTempData) params.isTempData = true;
|
||
uni.showLoading({
|
||
title: isTempData ? "保存中..." : "发送中...",
|
||
icon: "none",
|
||
});
|
||
|
||
// 存在applyid情况下的发起进件也走更新接口
|
||
if (channelInfo.applyId) {
|
||
$updateApply(params.applyId, params)
|
||
.then((res) => {
|
||
uni.hideLoading();
|
||
uni.showToast({ title: "发送成功", icon: "none" });
|
||
if (channelInfo.applyId) {
|
||
uni.navigateBack();
|
||
} else {
|
||
uni.navigateBack({ delta: 2 });
|
||
}
|
||
})
|
||
.catch((err) => {});
|
||
return;
|
||
}
|
||
|
||
// 发起进件函数
|
||
$mchApplyments(params)
|
||
.then((res) => {
|
||
uni.hideLoading();
|
||
uni.showToast({
|
||
title: isTempData ? "保存成功" : "发送成功",
|
||
icon: "none",
|
||
});
|
||
if (channelInfo.applyId) {
|
||
uni.navigateBack();
|
||
} else {
|
||
uni.navigateBack({ delta: 2 });
|
||
}
|
||
})
|
||
.catch((err) => {});
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
@import "./static/information.scss";
|
||
.page {
|
||
padding: 30rpx;
|
||
box-sizing: border-box;
|
||
padding-bottom: 150rpx;
|
||
background-color: #f5f6fd;
|
||
min-height: calc(100vh - 0px);
|
||
}
|
||
.box {
|
||
border-radius: 10px;
|
||
overflow: hidden;
|
||
padding-bottom: 10px;
|
||
background-color: #fff;
|
||
}
|
||
.mch-title {
|
||
font-weight: bold;
|
||
font-size: 28rpx;
|
||
color: #3981ff;
|
||
}
|
||
.mch-type {
|
||
display: flex;
|
||
align-items: center;
|
||
image {
|
||
margin-left: 10px;
|
||
height: 20rpx;
|
||
width: 20rpx;
|
||
}
|
||
}
|
||
|
||
.btn-area {
|
||
position: relative;
|
||
z-index: 20;
|
||
box-sizing: border-box;
|
||
width: 100%;
|
||
background: #fff;
|
||
// background: linear-gradient(transparent,#fff 85%);
|
||
padding: 10rpx 30rpx 30rpx;
|
||
display: flex;
|
||
position: fixed;
|
||
bottom: 1rpx;
|
||
left: 0;
|
||
justify-content: space-between;
|
||
|
||
.read {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
flex-grow: 1;
|
||
height: 90rpx;
|
||
border: 1rpx solid #c5c7cc;
|
||
border-radius: 10rpx;
|
||
background: #fff;
|
||
font-weight: 500;
|
||
font-size: 30rpx;
|
||
letter-spacing: 0.07em;
|
||
color: #808080;
|
||
}
|
||
}
|
||
.submit {
|
||
display: flex;
|
||
justify-content: center;
|
||
margin: 0 auto;
|
||
margin-bottom: 150rpx;
|
||
width: 380rpx;
|
||
height: 90rpx;
|
||
line-height: 90rpx;
|
||
border-radius: 10rpx;
|
||
background: #3981ff;
|
||
font-weight: 500;
|
||
font-size: 30rpx;
|
||
color: #fff;
|
||
}
|
||
</style>
|