Files
cashier_app/entryManager/add/add.vue
2026-01-09 18:52:40 +08:00

512 lines
11 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<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>