512 lines
11 KiB
Vue
512 lines
11 KiB
Vue
<template>
|
||
<view class="min-page bg-f7 u-font-28 color-333">
|
||
<steps v-model="step" />
|
||
<view class="u-m-t-32">
|
||
<basicInfo v-if="step==0" :data="form.merchantBaseInfo" :maxSize="maxSize"
|
||
@update="update($event,'merchantBaseInfo')">
|
||
</basicInfo>
|
||
<legalPerpoleInfo v-if="step==1" :maxSize="maxSize" :data="form.legalPersonInfo"
|
||
@update="update($event,'legalPersonInfo')">
|
||
</legalPerpoleInfo>
|
||
<businessLicenceInfo v-if="step==2" :maxSize="maxSize" :data="form.businessLicenceInfo"
|
||
@update="update($event,'businessLicenceInfo')"></businessLicenceInfo>
|
||
<storeInfo v-if="step==3" :maxSize="maxSize" :data="form.storeInfo" @update="update($event,'storeInfo')">
|
||
</storeInfo>
|
||
<settlementInfo v-if="step==4" :maxSize="maxSize" :data="form.settlementInfo"
|
||
@update="update($event,'settlementInfo')">
|
||
</settlementInfo>
|
||
</view>
|
||
<bottomBtnGroup @save="saveClick" @cancel="cancelClick" :cancelText="cancelText" :confirmText="confirmText">
|
||
</bottomBtnGroup>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import steps from './components/steps.vue'
|
||
import basicInfo from './components/basic-info.vue'
|
||
import legalPerpoleInfo from './components/legalPerpole-info.vue'
|
||
import businessLicenceInfo from './components/business-licence-info.vue'
|
||
import storeInfo from './components/store-info.vue'
|
||
import settlementInfo from './components/settlement-info.vue'
|
||
import bottomBtnGroup from './components/bottom-btn-group.vue'
|
||
import dayjs from 'dayjs'
|
||
import {
|
||
reactive,
|
||
ref,
|
||
watch,
|
||
onMounted,
|
||
computed
|
||
} from 'vue';
|
||
const form = reactive({
|
||
"shopId": 0,
|
||
"merchantCode": "",
|
||
"merchantBaseInfo": {
|
||
"userType": "0",
|
||
"shortName": "",
|
||
"mccCode": "",
|
||
"alipayAccount": "",
|
||
"contactPersonType": "LEGAL",
|
||
"contactName": "",
|
||
"certType": "0",
|
||
"contactPersonId": "",
|
||
"contactPersonIdStartDate": dayjs().valueOf(),
|
||
"contactPersonIdEndDate": dayjs().add(10, 'year').valueOf(),
|
||
"contactIdCardBackPic": {
|
||
"url": "",
|
||
"wechatId": "",
|
||
"alipayId": ""
|
||
},
|
||
"contactIdCardFrontPic": {
|
||
"url": "",
|
||
"wechatId": "",
|
||
"alipayId": ""
|
||
},
|
||
"contactPhone": "",
|
||
"contactAddr": "",
|
||
"contactEmail": "",
|
||
"companyChildType": "1"
|
||
},
|
||
"legalPersonInfo": {
|
||
"legalPersonName": "",
|
||
"legalPersonId": "",
|
||
"legalIdPersonStartDate": dayjs().valueOf(),
|
||
"legalPersonIdEndDate": dayjs().add(10, 'year').valueOf(),
|
||
"legalPersonPhone": "",
|
||
"legalPersonEmail": "",
|
||
"legalGender": "",
|
||
"legalAddress": "",
|
||
"idCardHandPic": {
|
||
"url": "",
|
||
"wechatId": "",
|
||
"alipayId": ""
|
||
},
|
||
"idCardFrontPic": {
|
||
"url": "",
|
||
"wechatId": "",
|
||
"alipayId": ""
|
||
},
|
||
"idCardBackPic": {
|
||
"url": "",
|
||
"wechatId": "",
|
||
"alipayId": ""
|
||
}
|
||
},
|
||
"businessLicenceInfo": {
|
||
"licenceName": "",
|
||
"licenceNo": "",
|
||
"licenceStartDate": dayjs().valueOf(),
|
||
"licenceEndDate": dayjs().add(10, 'year').valueOf(),
|
||
"registeredAddress": "",
|
||
"licensePic": {
|
||
"url": "",
|
||
"wechatId": "",
|
||
"alipayId": ""
|
||
}
|
||
},
|
||
"storeInfo": {
|
||
"mercProvCode": "",
|
||
"mercCityCode": "",
|
||
"mercAreaCode": "",
|
||
"mercProv": "",
|
||
"mercCity": "",
|
||
"mercArea": "",
|
||
"businessAddress": "",
|
||
"insidePic": {
|
||
"url": "",
|
||
"wechatId": "",
|
||
"alipayId": ""
|
||
},
|
||
"doorPic": {
|
||
"url": "",
|
||
"wechatId": "",
|
||
"alipayId": ""
|
||
},
|
||
"cashierDeskPic": {
|
||
"url": "",
|
||
"wechatId": "",
|
||
"alipayId": ""
|
||
}
|
||
},
|
||
"settlementInfo": {
|
||
"settlementType": "",
|
||
"noLegalName": "",
|
||
"noLegalId": "",
|
||
"settlementCardType": "",
|
||
"settlementCardNo": "",
|
||
"settlementName": "",
|
||
"bankMobile": "",
|
||
"openAccProvinceId": "",
|
||
"openAccCityId": "",
|
||
"openAccAreaId": "",
|
||
"openAccProvince": "",
|
||
"openAccCity": "",
|
||
"openAccArea": "",
|
||
"bankName": "",
|
||
"bankInstId": "",
|
||
"bankType": "",
|
||
"bankBranchName": "",
|
||
"bankBranchCode": "",
|
||
"bankCardFrontPic": {
|
||
"url": "",
|
||
"wechatId": "",
|
||
"alipayId": ""
|
||
},
|
||
"bankCardBackPic": {
|
||
"url": "",
|
||
"wechatId": "",
|
||
"alipayId": ""
|
||
},
|
||
"openAccountLicencePic": {
|
||
"url": "",
|
||
"wechatId": "",
|
||
"alipayId": ""
|
||
},
|
||
"noLegalHandSettleAuthPic": {
|
||
"url": "",
|
||
"wechatId": "",
|
||
"alipayId": ""
|
||
},
|
||
"noLegalSettleAuthPic": {
|
||
"url": "",
|
||
"wechatId": "",
|
||
"alipayId": ""
|
||
},
|
||
"noLegalIdCardFrontPic": {
|
||
"url": "",
|
||
"wechatId": "",
|
||
"alipayId": ""
|
||
},
|
||
"noLegalIdCardBackPic": {
|
||
"url": "",
|
||
"wechatId": "",
|
||
"alipayId": ""
|
||
}
|
||
}
|
||
})
|
||
const maxSize = ref(2)
|
||
const step = ref(1)
|
||
|
||
|
||
import {
|
||
addEntryManager
|
||
} from '@/http/api/order/entryManager.js'
|
||
|
||
const rules = {
|
||
merchantBaseInfo: {
|
||
userType: {
|
||
required: true,
|
||
errorMsg: '请选择商户类型',
|
||
},
|
||
shortName: {
|
||
required: true,
|
||
errorMsg: '请填写商户简称',
|
||
},
|
||
mccCode: {
|
||
required: true,
|
||
errorMsg: '请选择行业类目',
|
||
},
|
||
alipayAccount: {
|
||
required: true,
|
||
errorMsg: '请填写支付宝账号',
|
||
}
|
||
},
|
||
legalPersonInfo: {
|
||
'idCardHandPic.url': {
|
||
required: true,
|
||
errorMsg: '请上传身份证手持图片',
|
||
},
|
||
'idCardFrontPic.url': {
|
||
required: true,
|
||
errorMsg: '请上传身份证正面图片',
|
||
},
|
||
'idCardBackPic.url': {
|
||
required: true,
|
||
errorMsg: '请上传身份证反面图片',
|
||
},
|
||
legalPersonName: {
|
||
required: true,
|
||
errorMsg: '请填写法人姓名',
|
||
},
|
||
legalPersonId: {
|
||
required: true,
|
||
errorMsg: '请填写法人身份证号',
|
||
},
|
||
legalIdPersonStartDate: {
|
||
required: true,
|
||
errorMsg: '请填写法人身份证开始日期',
|
||
},
|
||
legalPersonIdEndDate: {
|
||
required: true,
|
||
errorMsg: '请填写法人身份证到期日期',
|
||
},
|
||
legalPersonPhone: {
|
||
required: true,
|
||
errorMsg: '请填写法人电话',
|
||
},
|
||
legalPersonEmail: {
|
||
required: true,
|
||
errorMsg: '请填写法人邮箱',
|
||
},
|
||
legalGender: {
|
||
required: true,
|
||
errorMsg: '请填写法人性别',
|
||
},
|
||
legalAddress: {
|
||
required: true,
|
||
errorMsg: '请填写法人地址',
|
||
},
|
||
|
||
},
|
||
storeInfo: {
|
||
mercProvCode: {
|
||
required: true,
|
||
errorMsg: '请选择归属地',
|
||
},
|
||
mercCityCode: {
|
||
required: true,
|
||
errorMsg: '请选择归属地',
|
||
},
|
||
mercAreaCode: {
|
||
required: true,
|
||
errorMsg: '请选择归属地',
|
||
},
|
||
mercProv: {
|
||
required: true,
|
||
errorMsg: '请选择归属地',
|
||
},
|
||
mercCity: {
|
||
required: true,
|
||
errorMsg: '请选择归属地',
|
||
},
|
||
mercArea: {
|
||
required: true,
|
||
errorMsg: '请选择归属地',
|
||
},
|
||
businessAddress: {
|
||
required: true,
|
||
errorMsg: '请填写营业地址',
|
||
},
|
||
'insidePic.url': {
|
||
required: true,
|
||
errorMsg: '请上传经营场所内设照片',
|
||
},
|
||
'doorPic.url': {
|
||
required: true,
|
||
errorMsg: '请上传门头照',
|
||
},
|
||
'cashierDeskPic.url': {
|
||
required: true,
|
||
errorMsg: '请上传收银台照片',
|
||
}
|
||
}
|
||
|
||
}
|
||
|
||
function isEmptyValue(val) {
|
||
if (val === '' || val === undefined || val === null) {
|
||
return true
|
||
}
|
||
return false
|
||
}
|
||
|
||
/**
|
||
* 解析属性路径,返回数组格式的路径片段
|
||
* @param {string} str - 属性路径(如 'userType' 或 'idCardHandPic.url')
|
||
* @returns {Array<string>} 属性路径片段数组(如 ['userType'] 或 ['idCardHandPic', 'url'])
|
||
*/
|
||
function returnKey(str) {
|
||
// 无论是否包含'.',都返回数组,方便后续统一处理
|
||
return str.includes('.') ? str.split('.') : [str];
|
||
}
|
||
|
||
/**
|
||
* 根据属性路径数组,安全获取对象的嵌套属性值
|
||
* @param {Object} obj - 目标对象(如 form.legalPersonInfo)
|
||
* @param {Array<string>} keyPath - 属性路径数组(如 ['idCardHandPic', 'url'])
|
||
* @returns {*} 嵌套属性的值(若路径不存在,返回 undefined)
|
||
*/
|
||
function getNestedValue(obj, keyPath) {
|
||
// 边界处理:obj不是对象,直接返回undefined
|
||
if (typeof obj !== 'object' || obj === null) {
|
||
return undefined;
|
||
}
|
||
|
||
// 逐层遍历属性路径,获取最终值
|
||
return keyPath.reduce((currentObj, key) => {
|
||
// 中间层级不存在,直接返回undefined,避免报错
|
||
if (currentObj === undefined || currentObj === null) {
|
||
return undefined;
|
||
}
|
||
return currentObj[key];
|
||
}, obj);
|
||
}
|
||
|
||
|
||
|
||
function verifyValue(val, ruleItem) {
|
||
const isEmpty = isEmptyValue(val)
|
||
let result = {
|
||
ispas: true,
|
||
errorMsg: ''
|
||
}
|
||
if (ruleItem.required) {
|
||
|
||
if (isEmpty) {
|
||
result.ispas = false
|
||
result.errorMsg = ruleItem.errorMsg
|
||
return result
|
||
}
|
||
}
|
||
return result
|
||
}
|
||
|
||
function verifyData(data, rule) {
|
||
// 边界处理:data不是对象,直接返回校验失败(若有必填规则)
|
||
if (typeof data !== 'object' || data === null) {
|
||
// 遍历规则,返回第一个必填项的错误信息
|
||
for (let ruleKey in rule) {
|
||
const ruleItem = rule[ruleKey];
|
||
if (ruleItem.required) {
|
||
return {
|
||
ispas: false,
|
||
errorMsg: ruleItem.errorMsg || '数据格式错误,无法校验'
|
||
};
|
||
}
|
||
}
|
||
return {
|
||
ispas: true,
|
||
errorMsg: ''
|
||
};
|
||
}
|
||
|
||
for (let ruleKey in rule) {
|
||
const ruleItem = rule[ruleKey];
|
||
// 1. 获取属性路径数组(如 ['idCardHandPic', 'url'])
|
||
const keyPath = returnKey(ruleKey);
|
||
// 2. 安全获取嵌套属性值(核心:支持深层级属性)
|
||
const targetValue = getNestedValue(data, keyPath);
|
||
// 3. 校验属性值
|
||
const result = verifyValue(targetValue, ruleItem);
|
||
|
||
// 4. 校验失败,直接返回结果
|
||
if (!result.ispas) {
|
||
return result;
|
||
}
|
||
}
|
||
|
||
return {
|
||
ispas: true,
|
||
errorMsg: ''
|
||
}
|
||
}
|
||
|
||
function saveClick() {
|
||
if (step.value == 0) {
|
||
const {
|
||
ispas,
|
||
errorMsg
|
||
} = verifyData(form.merchantBaseInfo, rules.merchantBaseInfo)
|
||
if (!ispas) {
|
||
uni.showToast({
|
||
title: errorMsg || '请完善必填内容',
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
}
|
||
if (step.value == 1) {
|
||
const {
|
||
ispas,
|
||
errorMsg
|
||
} = verifyData(form.legalPersonInfo, rules.legalPersonInfo)
|
||
if (!ispas) {
|
||
uni.showToast({
|
||
title: errorMsg || '请完善必填内容',
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
}
|
||
if (step.value == 2) {
|
||
const {
|
||
ispas,
|
||
errorMsg
|
||
} = verifyData(form.businessLicenceInfo, rules.businessLicenceInfo)
|
||
if (!ispas) {
|
||
uni.showToast({
|
||
title: errorMsg || '请完善必填内容',
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
}
|
||
if (step.value == 3) {
|
||
const {
|
||
ispas,
|
||
errorMsg
|
||
} = verifyData(form.storeInfo, rules.storeInfo)
|
||
if (!ispas) {
|
||
uni.showToast({
|
||
title: errorMsg || '请完善必填内容',
|
||
icon: 'none'
|
||
})
|
||
return
|
||
}
|
||
}
|
||
if (step.value != 4) {
|
||
step.value++
|
||
return
|
||
}
|
||
addEntryManager(form)
|
||
|
||
return
|
||
}
|
||
|
||
function cancelClick() {
|
||
step.value--;
|
||
}
|
||
|
||
function update(value, key) {
|
||
if (form.hasOwnProperty(key)) {
|
||
form[key] = value
|
||
}
|
||
}
|
||
|
||
watch(() => form, (newval) => {
|
||
uni.setStorageSync('entryManager_submit_data', form)
|
||
}, {
|
||
deep: true,
|
||
immediate: true
|
||
})
|
||
const cancelText = computed(() => {
|
||
if (step.value == 0) {
|
||
return '返回'
|
||
}
|
||
return '上一步'
|
||
})
|
||
const confirmText = computed(() => {
|
||
if (step.value == 4) {
|
||
return '提交'
|
||
}
|
||
return '下一步'
|
||
})
|
||
onMounted(() => {
|
||
// const data=uni.getStorageSync('entryManager_submit_data')
|
||
// if(data){
|
||
// Object.assign(form,data)
|
||
// }
|
||
})
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.min-page {
|
||
padding: 32rpx 28rpx;
|
||
}
|
||
|
||
.container {
|
||
padding: 32rpx 28rpx;
|
||
border-radius: 16rpx;
|
||
margin-bottom: 32rpx;
|
||
background-color: #fff;
|
||
}
|
||
</style> |