mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp.git
synced 2026-09-20 11:52:02 +08:00
refactor: 更新表单组件以增强上传功能和验证逻辑
- 在 step1.vue、step2.vue 和 step3.vue 中添加上传规则和删除功能 - 优化照片上传的处理逻辑,确保上传后能正确恢复表单状态 - 更新表单验证逻辑,使用 async/await 处理验证过程 - 修改样式以提升用户体验,确保上传组件的可用性和一致性
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="wrapper" :style="themeStyle">
|
<div class="wrapper" :style="themeStyle">
|
||||||
<up-form label-position="top" :model="form" ref="uForm">
|
<up-form label-position="top" :model="form" :rules="rules" ref="uForm">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="flag-title light-color">基础信息</div>
|
<div class="flag-title light-color">基础信息</div>
|
||||||
<up-form-item
|
<up-form-item
|
||||||
@@ -124,6 +124,7 @@
|
|||||||
:auto-upload="false"
|
:auto-upload="false"
|
||||||
width="200"
|
width="200"
|
||||||
@afterRead="onUploadAfterRead($event, 'licencePhoto', 'licencePhotoFileList')"
|
@afterRead="onUploadAfterRead($event, 'licencePhoto', 'licencePhotoFileList')"
|
||||||
|
@delete="onUploadDelete($event, 'licencePhoto', 'licencePhotoFileList')"
|
||||||
:max-count="1"
|
:max-count="1"
|
||||||
></u-upload>
|
></u-upload>
|
||||||
|
|
||||||
@@ -161,6 +162,7 @@
|
|||||||
:auto-upload="false"
|
:auto-upload="false"
|
||||||
width="200"
|
width="200"
|
||||||
@afterRead="onUploadAfterRead($event, 'legalPhoto', 'legalPhotoFileList')"
|
@afterRead="onUploadAfterRead($event, 'legalPhoto', 'legalPhotoFileList')"
|
||||||
|
@delete="onUploadDelete($event, 'legalPhoto', 'legalPhotoFileList')"
|
||||||
:max-count="1"
|
:max-count="1"
|
||||||
></u-upload>
|
></u-upload>
|
||||||
<u-upload
|
<u-upload
|
||||||
@@ -168,6 +170,7 @@
|
|||||||
:auto-upload="false"
|
:auto-upload="false"
|
||||||
width="200"
|
width="200"
|
||||||
@afterRead="onUploadAfterRead($event, 'legalPhoto', 'legalPhotoBackFileList')"
|
@afterRead="onUploadAfterRead($event, 'legalPhoto', 'legalPhotoBackFileList')"
|
||||||
|
@delete="onUploadDelete($event, 'legalPhoto', 'legalPhotoBackFileList')"
|
||||||
:max-count="1"
|
:max-count="1"
|
||||||
></u-upload>
|
></u-upload>
|
||||||
</div>
|
</div>
|
||||||
@@ -187,8 +190,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, computed, watch, getCurrentInstance } from 'vue'
|
import { ref, reactive, computed, watch, getCurrentInstance, onMounted } from 'vue'
|
||||||
import { onReady } from '@dcloudio/uni-app'
|
|
||||||
import { useStore } from '@/store'
|
import { useStore } from '@/store'
|
||||||
import { applyFirst } from '@/api/entry'
|
import { applyFirst } from '@/api/entry'
|
||||||
import MCity from '@/components/m-city/m-city.vue'
|
import MCity from '@/components/m-city/m-city.vue'
|
||||||
@@ -278,8 +280,10 @@ const rules = {
|
|||||||
legalPhoto: [
|
legalPhoto: [
|
||||||
{ required: true, message: '请上传法人身份证照片' },
|
{ required: true, message: '请上传法人身份证照片' },
|
||||||
{
|
{
|
||||||
validator: (_rule: unknown, value: string | string[]) =>
|
validator: (_rule: unknown, value: string | string[]) => {
|
||||||
Array.isArray(value) ? value.length === 2 : false,
|
const urls = normalizePhotoUrls(value)
|
||||||
|
return urls.length === 2
|
||||||
|
},
|
||||||
message: '请上传法人身份证正反照片',
|
message: '请上传法人身份证正反照片',
|
||||||
trigger: ['change', 'blur'],
|
trigger: ['change', 'blur'],
|
||||||
},
|
},
|
||||||
@@ -297,24 +301,53 @@ watch(
|
|||||||
(val) => {
|
(val) => {
|
||||||
if (val) {
|
if (val) {
|
||||||
Object.assign(form, val)
|
Object.assign(form, val)
|
||||||
const judgeDeepPhoto = ['legalPhoto', 'licencePhoto'] as const
|
restorePhotoFields(val)
|
||||||
const fileListMap = {
|
|
||||||
legalPhoto: legalPhotoFileList,
|
|
||||||
licencePhoto: licencePhotoFileList,
|
|
||||||
}
|
|
||||||
judgeDeepPhoto.forEach((key) => {
|
|
||||||
if (form[key]) {
|
|
||||||
form[key].split(',').forEach((item: string) => {
|
|
||||||
fileListMap[key].value.push({ url: item })
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
onReady(() => {
|
function normalizePhotoUrls(value: string | string[] | undefined) {
|
||||||
|
if (Array.isArray(value)) {
|
||||||
|
return value.filter(Boolean)
|
||||||
|
}
|
||||||
|
if (typeof value === 'string' && value) {
|
||||||
|
return value.split(',').map((item) => item.trim()).filter(Boolean)
|
||||||
|
}
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
function createUploadedFileItem(url: string) {
|
||||||
|
return {
|
||||||
|
url,
|
||||||
|
status: 'success',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function restorePhotoFields(data: Record<string, any>) {
|
||||||
|
licencePhotoFileList.value = []
|
||||||
|
legalPhotoFileList.value = []
|
||||||
|
legalPhotoBackFileList.value = []
|
||||||
|
|
||||||
|
const licenceUrls = normalizePhotoUrls(data.licencePhoto)
|
||||||
|
if (licenceUrls.length) {
|
||||||
|
licencePhotoFileList.value = licenceUrls.map(createUploadedFileItem)
|
||||||
|
form.licencePhoto = licenceUrls
|
||||||
|
}
|
||||||
|
|
||||||
|
const legalUrls = normalizePhotoUrls(data.legalPhoto)
|
||||||
|
if (legalUrls.length) {
|
||||||
|
legalPhotoFileList.value = legalUrls[0]
|
||||||
|
? [createUploadedFileItem(legalUrls[0])]
|
||||||
|
: []
|
||||||
|
legalPhotoBackFileList.value = legalUrls[1]
|
||||||
|
? [createUploadedFileItem(legalUrls[1])]
|
||||||
|
: []
|
||||||
|
form.legalPhoto = legalUrls
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
uForm.value?.setRules(rules)
|
uForm.value?.setRules(rules)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -334,17 +367,40 @@ function onUploadAfterRead(
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleUploadAfterRead(event, fileListMap[fileListKey].value, () => {
|
handleUploadAfterRead(event, fileListMap[fileListKey].value, () => {
|
||||||
if (key === 'legalPhoto') {
|
syncUploadFormValue(key)
|
||||||
form[key] = [
|
|
||||||
...getUploadedUrls(legalPhotoFileList.value),
|
|
||||||
...getUploadedUrls(legalPhotoBackFileList.value),
|
|
||||||
]
|
|
||||||
} else {
|
|
||||||
form[key] = getUploadedUrls(fileListMap[fileListKey].value)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onUploadDelete(
|
||||||
|
event: { index: number },
|
||||||
|
key: string,
|
||||||
|
fileListKey: 'licencePhotoFileList' | 'legalPhotoFileList' | 'legalPhotoBackFileList'
|
||||||
|
) {
|
||||||
|
const fileListMap = {
|
||||||
|
licencePhotoFileList,
|
||||||
|
legalPhotoFileList,
|
||||||
|
legalPhotoBackFileList,
|
||||||
|
}
|
||||||
|
const list = fileListMap[fileListKey].value
|
||||||
|
if (event.index >= 0 && event.index < list.length) {
|
||||||
|
list.splice(event.index, 1)
|
||||||
|
}
|
||||||
|
syncUploadFormValue(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncUploadFormValue(key: string) {
|
||||||
|
if (key === 'legalPhoto') {
|
||||||
|
form[key] = [
|
||||||
|
...getUploadedUrls(legalPhotoFileList.value),
|
||||||
|
...getUploadedUrls(legalPhotoBackFileList.value),
|
||||||
|
]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (key === 'licencePhoto') {
|
||||||
|
form[key] = getUploadedUrls(licencePhotoFileList.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function getPickerParentValue(e: any[]) {
|
function getPickerParentValue(e: any[]) {
|
||||||
form.companyAddressIdPath = []
|
form.companyAddressIdPath = []
|
||||||
|
|
||||||
@@ -366,26 +422,28 @@ function showPicker() {
|
|||||||
cityPicker.value?.show()
|
cityPicker.value?.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
function validatorStep1Form() {
|
async function validatorStep1Form() {
|
||||||
uForm.value?.validate(async (valid: boolean) => {
|
try {
|
||||||
if (valid) {
|
await uForm.value?.validate()
|
||||||
const params = { ...form }
|
} catch {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
params.legalPhoto = params.legalPhoto.toString()
|
const params = { ...form }
|
||||||
params.licencePhoto = params.licencePhoto.toString()
|
|
||||||
params.companyAddressIdPath = params.companyAddressIdPath.toString()
|
|
||||||
delete params.complexAddress
|
|
||||||
|
|
||||||
const res = await applyFirst(params)
|
params.legalPhoto = params.legalPhoto.toString()
|
||||||
if (res.data.success) {
|
params.licencePhoto = params.licencePhoto.toString()
|
||||||
uni.showToast({
|
params.companyAddressIdPath = params.companyAddressIdPath.toString()
|
||||||
title: '提交成功!',
|
delete params.complexAddress
|
||||||
icon: 'none',
|
|
||||||
})
|
const res = await applyFirst(params)
|
||||||
emit('callback')
|
if (res.data.success) {
|
||||||
}
|
uni.showToast({
|
||||||
}
|
title: '提交成功!',
|
||||||
})
|
icon: 'none',
|
||||||
|
})
|
||||||
|
emit('callback')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@@ -399,6 +457,21 @@ page {
|
|||||||
|
|
||||||
.wrapper {
|
.wrapper {
|
||||||
@include seller-entry-form;
|
@include seller-entry-form;
|
||||||
|
|
||||||
|
:deep(.u-upload__deletable) {
|
||||||
|
width: 24rpx;
|
||||||
|
height: 24rpx;
|
||||||
|
border-bottom-left-radius: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.u-upload__deletable__icon) {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.u-upload__deletable .u-icon__icon) {
|
||||||
|
font-size: 16rpx !important;
|
||||||
|
line-height: 16rpx !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.submit {
|
.submit {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="wrapper" :style="themeStyle">
|
<div class="wrapper" :style="themeStyle">
|
||||||
<up-form label-position="top" :model="form" ref="uForm">
|
<up-form label-position="top" :model="form" :rules="rules" ref="uForm">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="flag-title light-color">基础信息</div>
|
<div class="flag-title light-color">基础信息</div>
|
||||||
<up-form-item
|
<up-form-item
|
||||||
@@ -48,8 +48,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, computed, watch } from 'vue'
|
import { ref, reactive, computed, watch, onMounted } from 'vue'
|
||||||
import { onReady } from '@dcloudio/uni-app'
|
|
||||||
import { useStore } from '@/store'
|
import { useStore } from '@/store'
|
||||||
import { applySecond } from '@/api/entry'
|
import { applySecond } from '@/api/entry'
|
||||||
import { getThemeStyle } from '@/utils/theme'
|
import { getThemeStyle } from '@/utils/theme'
|
||||||
@@ -96,24 +95,25 @@ watch(
|
|||||||
{ deep: true, immediate: true }
|
{ deep: true, immediate: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
onReady(() => {
|
onMounted(() => {
|
||||||
uForm.value?.setRules(rules)
|
uForm.value?.setRules(rules)
|
||||||
})
|
})
|
||||||
|
|
||||||
function validatorStep2Form() {
|
async function validatorStep2Form() {
|
||||||
uForm.value?.validate(async (valid: boolean) => {
|
try {
|
||||||
if (valid) {
|
await uForm.value?.validate()
|
||||||
const params = { ...form }
|
} catch {
|
||||||
const res = await applySecond(params)
|
return
|
||||||
if (res.data.success) {
|
}
|
||||||
uni.showToast({
|
const params = { ...form }
|
||||||
title: '提交成功!',
|
const res = await applySecond(params)
|
||||||
icon: 'none',
|
if (res.data.success) {
|
||||||
})
|
uni.showToast({
|
||||||
emit('callback')
|
title: '提交成功!',
|
||||||
}
|
icon: 'none',
|
||||||
}
|
})
|
||||||
})
|
emit('callback')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="wrapper" :style="themeStyle">
|
<div class="wrapper" :style="themeStyle">
|
||||||
<up-form label-position="top" :model="form" ref="uForm">
|
<up-form label-position="top" :model="form" :rules="rules" ref="uForm">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<div class="flag-title light-color">基础信息</div>
|
<div class="flag-title light-color">基础信息</div>
|
||||||
<up-form-item
|
<up-form-item
|
||||||
@@ -109,11 +109,14 @@
|
|||||||
>
|
>
|
||||||
</m-city>
|
</m-city>
|
||||||
|
|
||||||
<u-select
|
<u-picker
|
||||||
v-model:show="enableCategory"
|
v-model:show="enableCategory"
|
||||||
|
:columns="[categoryList]"
|
||||||
|
keyName="label"
|
||||||
|
valueName="value"
|
||||||
|
title="店铺经营类目"
|
||||||
@confirm="confirmCategory"
|
@confirm="confirmCategory"
|
||||||
:list="categoryList"
|
></u-picker>
|
||||||
></u-select>
|
|
||||||
|
|
||||||
<uniMap v-if="mapFlag" @close="closeMap" @callback="callBackAddress" />
|
<uniMap v-if="mapFlag" @close="closeMap" @callback="callBackAddress" />
|
||||||
</div>
|
</div>
|
||||||
@@ -121,7 +124,6 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, reactive, computed, watch, onMounted } from 'vue'
|
import { ref, reactive, computed, watch, onMounted } from 'vue'
|
||||||
import { onReady } from '@dcloudio/uni-app'
|
|
||||||
import { useStore } from '@/store'
|
import { useStore } from '@/store'
|
||||||
import { applyThird } from '@/api/entry'
|
import { applyThird } from '@/api/entry'
|
||||||
import { getCategoryList } from '@/api/goods'
|
import { getCategoryList } from '@/api/goods'
|
||||||
@@ -197,11 +199,8 @@ watch(
|
|||||||
{ deep: true, immediate: true }
|
{ deep: true, immediate: true }
|
||||||
)
|
)
|
||||||
|
|
||||||
onReady(() => {
|
|
||||||
uForm.value?.setRules(rules)
|
|
||||||
})
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
uForm.value?.setRules(rules)
|
||||||
fetchCategoryList()
|
fetchCategoryList()
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -266,9 +265,13 @@ async function requestAndroidPermission(permisionID: string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function confirmCategory(val: any[]) {
|
function confirmCategory(val: any) {
|
||||||
form.goodsManagementCategory = val[0].value
|
const selected = val?.value?.[0] || val?.[0]
|
||||||
goodsManagementCategory.value = val[0].label
|
if (!selected) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
form.goodsManagementCategory = selected.value
|
||||||
|
goodsManagementCategory.value = selected.label
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchCategoryList() {
|
async function fetchCategoryList() {
|
||||||
@@ -324,22 +327,23 @@ function showCategory() {
|
|||||||
enableCategory.value = true
|
enableCategory.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
function validatorStep3Form() {
|
async function validatorStep3Form() {
|
||||||
uForm.value?.validate(async (valid: boolean) => {
|
try {
|
||||||
if (valid) {
|
await uForm.value?.validate()
|
||||||
const params = { ...form }
|
} catch {
|
||||||
params.storeLogo = params.storeLogo.toString()
|
return
|
||||||
params.storeAddressIdPath = params.storeAddressIdPath.toString()
|
}
|
||||||
const res = await applyThird(params)
|
const params = { ...form }
|
||||||
if (res.data.success) {
|
params.storeLogo = params.storeLogo.toString()
|
||||||
uni.showToast({
|
params.storeAddressIdPath = params.storeAddressIdPath.toString()
|
||||||
title: '提交成功!',
|
const res = await applyThird(params)
|
||||||
icon: 'none',
|
if (res.data.success) {
|
||||||
})
|
uni.showToast({
|
||||||
emit('callback')
|
title: '提交成功!',
|
||||||
}
|
icon: 'none',
|
||||||
}
|
})
|
||||||
})
|
emit('callback')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|||||||
Reference in New Issue
Block a user