refactor: 重构多个组件以支持 Vue 3 语法和功能

- 将多个组件转换为 `<script setup>` 语法,提升可读性和性能
- 优化状态管理和事件处理逻辑,简化代码结构
- 更新样式和布局以适应新组件结构
- 添加新功能和修复已知问题,提升用户体验
This commit is contained in:
Yer11214
2026-07-08 18:37:11 +08:00
parent 4d0b0fb5e4
commit 349ffa4f34
189 changed files with 18278 additions and 20758 deletions

View File

@@ -1,5 +1,5 @@
<template>
<div>
<div class="seller-control" :style="themeStyle">
<u-navbar
:border="false"
:fixed="true"
@@ -18,56 +18,71 @@
</div>
</template>
<script>
import { getCompanyDetail } from "@/api/entry";
import step1 from "./step1";
import step2 from "./step2";
import step3 from "./step3";
export default {
data() {
return {
companyData: "",
current: 1,
};
},
components: {
step1,
step2,
step3,
},
mounted() {
this.init();
},
methods: {
back() {
if (this.current > 1) {
this.current--;
return;
}
uni.navigateBack({
delta: 1,
fail: () => {
uni.switchTab({ url: "/pages/tabbar/home/index" });
},
});
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { useStore } from '@/store'
import { getCompanyDetail } from '@/api/entry'
import step1 from './step1.vue'
import step2 from './step2.vue'
import step3 from './step3.vue'
import { getThemeStyle } from '@/utils/theme'
const store = useStore()
const themeStyle = computed(() => getThemeStyle(store.state.theme))
const companyData = ref<any>('')
const current = ref(1)
onMounted(() => {
init()
})
function back() {
if (current.value > 1) {
current.value--
return
}
uni.navigateBack({
delta: 1,
fail: () => {
uni.switchTab({ url: '/pages/tabbar/home/index' })
},
async init(next) {
const res = await getCompanyDetail();
if (res.data.success) {
this.companyData = res.data.result;
next ? this.current++ : "";
}
},
next() {
this.init("next");
},
finished() {
uni.navigateTo({
url: "/pages/passport/entry/seller/index",
});
},
},
};
})
}
async function init(next?: string) {
const res = await getCompanyDetail()
if (res.data.success) {
companyData.value = res.data.result
if (next) {
current.value++
}
}
}
function next() {
init('next')
}
function finished() {
uni.navigateTo({
url: '/pages/passport/entry/seller/index',
})
}
</script>
<style lang="scss" scoped></style>
<style lang="scss">
page {
background: #f7f7f7;
}
</style>
<style lang="scss" scoped>
@import "./entry.scss";
.seller-control {
min-height: 100vh;
background: #f7f7f7;
}
</style>

View File

@@ -0,0 +1,92 @@
@mixin seller-entry-form {
:deep(.u-form-item) {
padding: 0;
margin-top: 24rpx;
}
:deep(.u-form-item__body) {
flex-direction: column !important;
align-items: stretch !important;
padding: 0;
}
:deep(.u-form-item__body__left) {
width: 100% !important;
margin-bottom: 16rpx;
}
:deep(.u-form-item__body__left__content__label) {
display: block;
font-size: 30rpx;
font-weight: 600;
color: #333;
line-height: 1.4;
white-space: normal;
}
:deep(.u-form-item__body__right),
:deep(.u-form-item__body__right__content),
:deep(.u-form-item__body__right__content__slot) {
width: 100%;
flex: none;
min-width: 0;
}
:deep(.u-form-item__body__right__content__slot) {
display: block;
}
.field-input {
width: 100%;
margin-top: 0;
}
.field-row {
display: flex;
align-items: center;
gap: 16rpx;
width: 100%;
}
.field-row .field-input {
flex: 1;
min-width: 0;
}
.field-textarea {
width: 100%;
:deep(.u-textarea) {
background: #fafafa !important;
border-radius: 12rpx;
padding: 20rpx;
box-sizing: border-box;
}
:deep(.u-textarea__field) {
width: 100%;
font-size: 28rpx;
line-height: 1.6;
color: #333;
}
}
}
@mixin seller-entry-submit {
text-align: center;
background: var(--theme-light, #ff6b35);
height: 88rpx;
line-height: 88rpx;
color: #fff;
width: 92%;
margin: 40rpx auto 60rpx;
border-radius: 100px;
font-size: 30rpx;
}
.picker-action {
flex-shrink: 0;
color: var(--theme-light, #ff6b35);
font-size: 28rpx;
white-space: nowrap;
}

View File

@@ -1,18 +1,28 @@
.flag-title {
font-size: 42rpx;
font-weight: bold;
font-size: 30rpx;
font-weight: 600;
color: #333;
line-height: 1.4;
margin-bottom: 8rpx;
}
.submit,
.notice {
font-weight: bold;
font-size: 28rpx;
height: 92rpx;
text-align: center;
letter-spacing: 4rpx;
line-height: 92rpx;
.wrapper {
box-sizing: border-box;
min-height: 100vh;
padding: 20rpx 24rpx 40rpx;
background: #f8f8f8;
}
.column {
padding: 32rpx;
margin-bottom: 20rpx;
background: #fff;
border-radius: 20rpx;
}
.wrapper {
padding:16rpx;
}
.tips {
color: #999;
font-size: 24rpx;
line-height: 1.4;
margin-top: 12rpx;
}

View File

@@ -1,12 +1,12 @@
<template>
<div class="wrapper">
<u-navbar
:border="false"
:fixed="true"
:placeholder="true"
:auto-back="true"
></u-navbar>
<div>
<div class="wrapper" :style="themeStyle">
<u-navbar
:border="false"
:fixed="true"
:placeholder="true"
:auto-back="true"
></u-navbar>
<div class="entry-content">
<div class="title">店铺入驻</div>
<div class="step-list">
<div
@@ -24,144 +24,164 @@
</div>
</template>
<script>
import { getCompanyDetail } from "@/api/entry";
export default {
components: {},
<script setup lang="ts">
import { ref, computed } from 'vue'
import { onLoad, onShow } from '@dcloudio/uni-app'
import { useStore } from '@/store'
import { tipsToLogin } from '@/utils/filters.js'
import { getCompanyDetail } from '@/api/entry'
import { getThemeStyle } from '@/utils/theme'
data() {
return {
current: 999,
entrySteps: [
{
title: "填写资质信息",
value: "APPLY",
},
{
title: "提交审核",
value: "APPLYING",
},
],
const store = useStore()
storeStatusWay: [
{
title: "申请已通过,请联系管理员",
value: "OPEN",
},
{
title: "店铺已关闭,重申请联系管理员",
value: "CLOSED",
},
{
title: "审核未通过,请修改资质信息",
value: "REFUSED",
},
],
const themeStyle = computed(() => getThemeStyle(store.state.theme))
companyData: "", // 公司信息
};
const current = ref(999)
const companyData = ref<any>('')
const entrySteps = ref([
{
title: '填写资质信息',
value: 'APPLY',
},
onShow() {
if(this.tipsToLogin()){
this.init();
}
{
title: '提交审核',
value: 'APPLYING',
},
])
mounted() {},
const storeStatusWay = [
{
title: '申请已通过,请联系管理员',
value: 'OPEN',
},
{
title: '店铺已关闭,重申请联系管理员',
value: 'CLOSED',
},
{
title: '审核未通过,请修改资质信息',
value: 'REFUSED',
},
]
onLoad(options) {},
methods: {
getEntryNotice() {
uni.navigateTo({
url: "/pages/mine/help/tips?type=STORE_REGISTER",
});
onShow(() => {
if (tipsToLogin()) {
init()
}
})
onLoad(() => {})
function getEntryNotice() {
uni.navigateTo({
url: '/pages/mine/help/tips?type=STORE_REGISTER',
})
}
function keepOn() {
if (companyData.value && companyData.value.storeDisable == 'OPEN') {
uni.showToast({
title: '审核已通过',
icon: 'none',
})
} else {
uni.navigateTo({
url: '/pages/passport/entry/seller/control',
})
}
}
async function init() {
entrySteps.value = [
{
title: '填写资质信息',
value: 'APPLY',
},
keepOn() {
if (this.companyData && this.companyData.storeDisable == "OPEN") {
uni.showToast({
title:"审核已通过",
icon:"none"
})
} else {
uni.navigateTo({
url: "/pages/passport/entry/seller/control",
});
}
{
title: '提交审核',
value: 'APPLYING',
},
async init() {
this.entrySteps = [
{
title: "填写资质信息",
value: "APPLY",
},
{
title: "提交审核",
value: "APPLYING",
},
];
const res = await getCompanyDetail();
if (res.data.success) {
this.companyData = res.data.result;
]
const res = await getCompanyDetail()
if (res.data.success) {
companyData.value = res.data.result
if (this.companyData) {
this.storeStatusWay.forEach((item) => {
if (item.value == this.companyData.storeDisable) {
this.entrySteps.push(item);
}
});
this.current =
this.entrySteps.findIndex(
(item) => item.value == this.companyData.storeDisable
) || 0;
} else {
this.current = 0;
if (companyData.value) {
storeStatusWay.forEach((item) => {
if (item.value == companyData.value.storeDisable) {
entrySteps.value.push(item)
}
}
},
},
};
})
current.value =
entrySteps.value.findIndex(
(item) => item.value == companyData.value.storeDisable
) || 0
} else {
current.value = 0
}
}
}
</script>
<style>
<style lang="scss">
page {
background: #fff;
}
</style>
<style lang="scss" scoped>
@import url("./entry.scss");
.wrapper {
padding: 0 80rpx;
min-height: 100vh;
background: #fff;
box-sizing: border-box;
}
.entry-content {
padding: 32rpx 80rpx calc(40rpx + env(safe-area-inset-bottom));
box-sizing: border-box;
}
.title {
padding-top: calc(104rpx);
font-style: normal;
line-height: 1;
line-height: 1.2;
font-weight: 500;
font-size: 56rpx;
color: #333;
padding-left: 20rpx;
}
.step-list {
margin: 80rpx 0;
}
.step-item {
padding: 30rpx 20rpx;
font-size: 40rpx;
font-weight: bold;
color: #666;
}
.step-list {
margin: 80rpx 0;
overflow: hidden;
}
.active {
color: $light-color;
background: rgba($color: $light-color, $alpha: 0.1);
.step-item.active {
color: var(--theme-light, #ff6b35);
background: var(--theme-light-10, rgba(255, 107, 53, 0.1));
border-radius: 20rpx;
}
.submit,
.notice {
font-weight: bold;
font-size: 28rpx;
height: 92rpx;
text-align: center;
letter-spacing: 4rpx;
line-height: 92rpx;
border-radius: 20rpx;
}
.submit {
color: #fff;
margin-top: 120rpx;
background: rgba($light-color, 0.8);
background: var(--theme-light, #ff6b35);
}
.notice {
margin-top: 40rpx;
color: #333;

View File

@@ -1,113 +1,118 @@
<template>
<div class="wrapper">
<u-form label-width="200" :model="form" ref="uForm">
<div class="wrapper" :style="themeStyle">
<up-form label-position="top" :model="form" ref="uForm">
<div class="column">
<div class="flag-title light-color">基础信息</div>
<u-form-item
<up-form-item
required
:border-bottom="false"
prop="companyName"
label="公司名称"
><u-input
><u-input border="none" class="field-input"
v-model="form.companyName"
:custom-style="defaultInputStyle"
/></u-form-item>
<u-form-item
:custom-style="fieldInputStyle"
/></up-form-item>
<up-form-item
required
:border-bottom="false"
prop="companyAddressPath"
label="公司所在地"
>
<div @click="showPicker()" style="margin-right: 30rpx;">选择</div>
<u-input
disabled
:custom-style="defaultInputStyle"
v-model="form.companyAddressPath"
/></u-form-item>
<u-form-item
<view class="field-row">
<u-input
disabled
border="none"
class="field-input"
:custom-style="fieldInputStyle"
v-model="form.companyAddressPath"
/>
<view class="picker-action" @click="showPicker()">选择</view>
</view>
</up-form-item>
<up-form-item
required
:border-bottom="false"
prop="companyAddress"
label="公司详细地址"
><u-input
:custom-style="defaultInputStyle"
><u-input border="none" class="field-input"
:custom-style="fieldInputStyle"
v-model="form.companyAddress"
/></u-form-item>
<u-form-item
/></up-form-item>
<up-form-item
required
:border-bottom="false"
prop="employeeNum"
label="员工人数"
><u-input
><u-input border="none" class="field-input"
type="number"
:custom-style="defaultInputStyle"
:custom-style="fieldInputStyle"
v-model="form.employeeNum"
/></u-form-item>
/></up-form-item>
<u-form-item
<up-form-item
required
:border-bottom="false"
prop="companyPhone"
label="公司电话"
><u-input
><u-input border="none" class="field-input"
type="number"
:custom-style="defaultInputStyle"
:custom-style="fieldInputStyle"
v-model="form.companyPhone"
/></u-form-item>
<u-form-item
/></up-form-item>
<up-form-item
:border-bottom="false"
prop="registeredCapital"
label="注册资金"
required
><u-input
><u-input border="none" class="field-input"
type="number"
:custom-style="defaultInputStyle"
:custom-style="fieldInputStyle"
v-model="form.registeredCapital"
/></u-form-item>
<u-form-item
/></up-form-item>
<up-form-item
required
:border-bottom="false"
prop="linkName"
label="联系人姓名"
><u-input :custom-style="defaultInputStyle" v-model="form.linkName"
/></u-form-item>
<u-form-item
><u-input border="none" class="field-input" :custom-style="fieldInputStyle" v-model="form.linkName"
/></up-form-item>
<up-form-item
required
:border-bottom="false"
prop="linkPhone"
label="联系人电话"
><u-input
><u-input border="none" class="field-input"
type="number"
:custom-style="defaultInputStyle"
:custom-style="fieldInputStyle"
v-model="form.linkPhone"
/></u-form-item>
<u-form-item
/></up-form-item>
<up-form-item
required
:border-bottom="false"
prop="companyEmail"
label="电子邮箱"
><u-input
:custom-style="defaultInputStyle"
><u-input border="none" class="field-input"
:custom-style="fieldInputStyle"
v-model="form.companyEmail"
/></u-form-item>
/></up-form-item>
</div>
<div class="column">
<div class="flag-title light-color">营业执照信息</div>
<u-form-item
<up-form-item
required
:border-bottom="false"
prop="licenseNum"
label="营业执照号"
><u-input :custom-style="defaultInputStyle" v-model="form.licenseNum"
/></u-form-item>
<u-form-item
><u-input border="none" class="field-input" :custom-style="fieldInputStyle" v-model="form.licenseNum"
/></up-form-item>
<up-form-item
required
:border-bottom="false"
prop="scope"
label="法定经营范围"
><u-input :custom-style="defaultInputStyle" v-model="form.scope"
/></u-form-item>
<u-form-item
><u-input border="none" class="field-input" :custom-style="fieldInputStyle" v-model="form.scope"
/></up-form-item>
<up-form-item
:border-bottom="false"
prop="licencePhoto"
label="营业执照电子版"
@@ -126,25 +131,25 @@
请压缩图片在2M以内确保文字清晰以免上传或审核失败
</div>
</div>
</u-form-item>
</up-form-item>
</div>
<div class="column">
<div class="flag-title light-color">法人信息</div>
<u-form-item
<up-form-item
required
:border-bottom="false"
prop="legalName"
label="法人姓名"
><u-input :custom-style="defaultInputStyle" v-model="form.legalName"
/></u-form-item>
<u-form-item
><u-input border="none" class="field-input" :custom-style="fieldInputStyle" v-model="form.legalName"
/></up-form-item>
<up-form-item
required
:border-bottom="false"
prop="legalId"
label="法人证件号"
><u-input :custom-style="defaultInputStyle" v-model="form.legalId"
/></u-form-item>
<u-form-item
><u-input border="none" class="field-input" :custom-style="fieldInputStyle" v-model="form.legalId"
/></up-form-item>
<up-form-item
required
:border-bottom="false"
prop="legalPhoto"
@@ -166,11 +171,10 @@
:max-count="1"
></u-upload>
</div>
</u-form-item>
{{form}}
</up-form-item>
</div>
</u-form>
<div class="submit" @click="validatorStep1Form">提交/下一步</div>
</up-form>
<view class="submit" @click="validatorStep1Form">提交/下一步</view>
<m-city
:provinceData="list"
headTitle="区域选择"
@@ -182,234 +186,222 @@
</div>
</template>
<script>
import { applyFirst } from "@/api/entry";
import city from "@/components/m-city/m-city.vue";
import storage from "@/utils/storage.js";
import { handleUploadAfterRead, getUploadedUrls } from "@/utils/uploadHelper.js";
import * as RegExp from "@/utils/RegExp.js";
export default {
components: { "m-city": city },
data() {
return {
storage,
defaultInputStyle: {
background: "#f7f7f7",
padding: "0 20rpx",
"border-radius": "10rpx",
},
legalPhotoFileList: [],
legalPhotoBackFileList: [],
licencePhotoFileList: [],
form: {
companyName: "",
companyAddressIdPath: [],
companyAddressPath: "",
companyAddress: "",
employeeNum: "",
registeredCapital: "",
linkName: "",
linkPhone: "",
companyPhone: "",
companyEmail: "",
licenseNum: "",
scope: "",
legalPhoto: "",
licencePhoto: "",
legalName: "",
legalId: "",
},
list: [
{
id: "",
localName: "请选择",
children: [],
},
],
rules: {
// 验证规则
companyName: [{ required: true, message: "请填写公司信息" }],
companyAddressPath: [{ required: true, message: "请选择公司所在地" }],
companyAddress: [{ required: true, message: "请填写公司详细地址" }],
employeeNum: [{ required: true, message: "请填写公司员工总数" }],
registeredCapital: [{ required: true, message: "请填写公司注册资金" }],
linkName: [{ required: true, message: "请填写联系人姓名" }],
linkPhone: [
{ required: true, message: "请填写联系人电话" },
{
// 自定义验证函数,见上说明
validator: (rule, value, callback) => {
// 上面有说返回true表示校验通过返回false表示不通过
// this.$u.test.mobile()就是返回true或者false的
return this.$u.test.mobile(value);
},
message: "手机号码不正确",
// 触发器可以同时用blur和change
trigger: ["change", "blur"],
},
],
companyPhone: [
{ required: true, message: "请填写公司电话" },
{
// 自定义验证函数,见上说明
validator: (rule, value, callback) => {
// 上面有说返回true表示校验通过返回false表示不通过
// this.$u.test.mobile()就是返回true或者false的
return this.$u.test.mobile(value);
},
message: "请填写正确的号码",
// 触发器可以同时用blur和change
trigger: ["change", "blur"],
},
],
companyEmail: [
{ required: true, message: "请填写电子邮箱" },
{
// 自定义验证函数,见上说明
validator: (rule, value, callback) => {
// 上面有说返回true表示校验通过返回false表示不通过
// this.$u.test.mobile()就是返回true或者false的
return this.$u.test.email(value);
},
message: "请填写正确的电子邮箱",
// 触发器可以同时用blur和change
trigger: ["change", "blur"],
},
],
licenseNum: [
{ required: true, message: "请填写营业执照号" },
{ pattern: RegExp.licenseNum, message: "请输入正确的营业执照号" },
],
scope: [{ required: true, message: "请填写营业执照所示经营范围" }],
legalPhoto: [{ required: true, message: "请上传法人身份证照片" },
{
// 自定义验证函数,见上说明
validator: (rule, value, callback) => {
// 上面有说返回true表示校验通过返回false表示不通过
// this.$u.test.mobile()就是返回true或者false的
return value.length === 2;
},
message: "请上传法人身份证正反照片",
// 触发器可以同时用blur和change
trigger: ["change", "blur"],
}],
licencePhoto: [{ required: true, message: "请上传营业执照" }],
legalName: [{ required: true, message: "请输入法人姓名" }],
legalId: [
{ required: true, message: "请输入法人证件号" },
{ pattern: RegExp.IDCard, message: "请输入正确的证件号" },
],
},
};
<script setup lang="ts">
import { ref, reactive, computed, watch, getCurrentInstance } from 'vue'
import { onReady } from '@dcloudio/uni-app'
import { useStore } from '@/store'
import { applyFirst } from '@/api/entry'
import MCity from '@/components/m-city/m-city.vue'
import { handleUploadAfterRead, getUploadedUrls } from '@/utils/uploadHelper.js'
import * as RegExp from '@/utils/RegExp.js'
import { getThemeStyle } from '@/utils/theme'
import { fieldInputStyle } from '@/utils/form-style.js'
const props = defineProps<{ companyData?: any }>()
const emit = defineEmits<{ callback: [] }>()
const store = useStore()
const { proxy } = getCurrentInstance()!
const themeStyle = computed(() => getThemeStyle(store.state.theme))
const uForm = ref<any>(null)
const cityPicker = ref<any>(null)
const legalPhotoFileList = ref<any[]>([])
const legalPhotoBackFileList = ref<any[]>([])
const licencePhotoFileList = ref<any[]>([])
const form = reactive<Record<string, any>>({
companyName: '',
companyAddressIdPath: [],
companyAddressPath: '',
companyAddress: '',
employeeNum: '',
registeredCapital: '',
linkName: '',
linkPhone: '',
companyPhone: '',
companyEmail: '',
licenseNum: '',
scope: '',
legalPhoto: '',
licencePhoto: '',
legalName: '',
legalId: '',
})
const list = ref([
{
id: '',
localName: '请选择',
children: [],
},
mounted() {
this.$refs.uForm.setRules(this.rules);
},
props: ["companyData"],
watch: {
companyData: {
handler(val) {
if (val) {
this["form"] = val;
// 给图片赋值
const judgeDeepPhoto = ["legalPhoto", "licencePhoto"];
judgeDeepPhoto.forEach((key) => {
if (this.form[key]) {
this.form[key].split(",").forEach((item) => {
this[`${key}FileList`].push({ url: item });
});
}
});
}
},
deep: true,
])
const rules = {
companyName: [{ required: true, message: '请填写公司信息' }],
companyAddressPath: [{ required: true, message: '请选择公司所在地' }],
companyAddress: [{ required: true, message: '请填写公司详细地址' }],
employeeNum: [{ required: true, message: '请填写公司员工总数' }],
registeredCapital: [{ required: true, message: '请填写公司注册资金' }],
linkName: [{ required: true, message: '请填写联系人姓名' }],
linkPhone: [
{ required: true, message: '请填写联系人电话' },
{
validator: (_rule: unknown, value: string) => proxy.$u.test.mobile(value),
message: '手机号码不正确',
trigger: ['change', 'blur'],
},
},
methods: {
onUploadAfterRead(event, key, fileListKey) {
if (!Array.isArray(this.form[key])) {
this.form[key] = [];
],
companyPhone: [
{ required: true, message: '请填写公司电话' },
{
validator: (_rule: unknown, value: string) => proxy.$u.test.mobile(value),
message: '请填写正确的号码',
trigger: ['change', 'blur'],
},
],
companyEmail: [
{ required: true, message: '请填写电子邮箱' },
{
validator: (_rule: unknown, value: string) => proxy.$u.test.email(value),
message: '请填写正确的电子邮箱',
trigger: ['change', 'blur'],
},
],
licenseNum: [
{ required: true, message: '请填写营业执照号' },
{ pattern: RegExp.licenseNum, message: '请输入正确的营业执照号' },
],
scope: [{ required: true, message: '请填写营业执照所示经营范围' }],
legalPhoto: [
{ required: true, message: '请上传法人身份证照片' },
{
validator: (_rule: unknown, value: string | string[]) =>
Array.isArray(value) ? value.length === 2 : false,
message: '请上传法人身份证正反照片',
trigger: ['change', 'blur'],
},
],
licencePhoto: [{ required: true, message: '请上传营业执照' }],
legalName: [{ required: true, message: '请输入法人姓名' }],
legalId: [
{ required: true, message: '请输入法人证件号' },
{ pattern: RegExp.IDCard, message: '请输入正确的证件号' },
],
}
watch(
() => props.companyData,
(val) => {
if (val) {
Object.assign(form, val)
const judgeDeepPhoto = ['legalPhoto', 'licencePhoto'] as const
const fileListMap = {
legalPhoto: legalPhotoFileList,
licencePhoto: licencePhotoFileList,
}
handleUploadAfterRead(event, this[fileListKey], () => {
if (key === "legalPhoto") {
this.form[key] = [
...getUploadedUrls(this.legalPhotoFileList),
...getUploadedUrls(this.legalPhotoBackFileList),
];
} else {
this.form[key] = getUploadedUrls(this[fileListKey]);
judgeDeepPhoto.forEach((key) => {
if (form[key]) {
form[key].split(',').forEach((item: string) => {
fileListMap[key].value.push({ url: item })
})
}
});
},
getPickerParentValue(e) {
this.form.companyAddressIdPath = [];
let name = "";
e.forEach((item, index) => {
if (item.id) {
// 遍历数据
this.form.companyAddressIdPath.push(item.id);
if (index == e.length - 1) {
name += item.localName;
} else {
name += item.localName + ",";
}
this.form.companyAddressPath = name;
}
});
},
// 显示三级地址联动
showPicker() {
console.log(this.$refs)
this.$refs.cityPicker.show();
},
validatorStep1Form() {
this.$refs.uForm.validate(async (valid) => {
console.log(valid);
if (valid) {
const params = { ...this.form };
params.legalPhoto = params.legalPhoto.toString();
params.licencePhoto = params.licencePhoto.toString();
params.companyAddressIdPath = params.companyAddressIdPath.toString();
delete params.complexAddress;
const res = await applyFirst(params);
if (res.data.success) {
uni.showToast({
title: "提交成功!",
icon: "none",
});
this.$emit("callback");
}
}
});
},
})
}
},
};
{ deep: true }
)
onReady(() => {
uForm.value?.setRules(rules)
})
function onUploadAfterRead(
event: any,
key: string,
fileListKey: 'licencePhotoFileList' | 'legalPhotoFileList' | 'legalPhotoBackFileList'
) {
const fileListMap = {
licencePhotoFileList,
legalPhotoFileList,
legalPhotoBackFileList,
}
if (!Array.isArray(form[key])) {
form[key] = []
}
handleUploadAfterRead(event, fileListMap[fileListKey].value, () => {
if (key === 'legalPhoto') {
form[key] = [
...getUploadedUrls(legalPhotoFileList.value),
...getUploadedUrls(legalPhotoBackFileList.value),
]
} else {
form[key] = getUploadedUrls(fileListMap[fileListKey].value)
}
})
}
function getPickerParentValue(e: any[]) {
form.companyAddressIdPath = []
let name = ''
e.forEach((item, index) => {
if (item.id) {
form.companyAddressIdPath.push(item.id)
if (index == e.length - 1) {
name += item.localName
} else {
name += item.localName + ','
}
form.companyAddressPath = name
}
})
}
function showPicker() {
cityPicker.value?.show()
}
function validatorStep1Form() {
uForm.value?.validate(async (valid: boolean) => {
if (valid) {
const params = { ...form }
params.legalPhoto = params.legalPhoto.toString()
params.licencePhoto = params.licencePhoto.toString()
params.companyAddressIdPath = params.companyAddressIdPath.toString()
delete params.complexAddress
const res = await applyFirst(params)
if (res.data.success) {
uni.showToast({
title: '提交成功!',
icon: 'none',
})
emit('callback')
}
}
})
}
</script>
<style>
/* page {
background: #fff;
} */
<style lang="scss">
page {
background: #f8f8f8;
}
</style>
<style lang="scss" scoped>
@import url("./entry.scss");
@import "./entry.scss";
@import "./entry-form.scss";
.column {
padding: 32rpx;
margin-bottom: 20rpx;
background: #fff;
.wrapper {
@include seller-entry-form;
}
.submit {
color: #fff;
margin-top: 120rpx;
background: rgba($light-color, 0.8);
}
.tips {
color: #999;
font-size: 24rpx;
line-height: 1.2;
margin-top: 10rpx;
@include seller-entry-submit;
}
</style>

View File

@@ -1,144 +1,135 @@
<template>
<div class="wrapper">
<u-form label-width="250" :model="form" ref="uForm">
<div class="wrapper" :style="themeStyle">
<up-form label-position="top" :model="form" ref="uForm">
<div class="column">
<div class="flag-title light-color">基础信息</div>
<u-form-item
<up-form-item
required
:border-bottom="false"
prop="settlementBankAccountName"
label="银行开户名"
><u-input
><u-input border="none" class="field-input"
v-model="form.settlementBankAccountName"
:custom-style="defaultInputStyle"
/></u-form-item>
:custom-style="fieldInputStyle"
/></up-form-item>
<u-form-item
<up-form-item
required
:border-bottom="false"
prop="settlementBankAccountNum"
label="银行账号"
><u-input
:custom-style="defaultInputStyle"
><u-input border="none" class="field-input"
:custom-style="fieldInputStyle"
v-model="form.settlementBankAccountNum"
/></u-form-item>
<u-form-item
/></up-form-item>
<up-form-item
required
:border-bottom="false"
prop="settlementBankBranchName"
label="开户银行支行名称"
><u-input
:custom-style="defaultInputStyle"
><u-input border="none" class="field-input"
:custom-style="fieldInputStyle"
v-model="form.settlementBankBranchName"
/></u-form-item>
/></up-form-item>
<u-form-item
<up-form-item
required
:border-bottom="false"
prop="settlementBankJointName"
label="支行联行号"
><u-input
:custom-style="defaultInputStyle"
><u-input border="none" class="field-input"
:custom-style="fieldInputStyle"
v-model="form.settlementBankJointName"
/></u-form-item>
/></up-form-item>
</div>
</u-form>
<div class="submit" @click="validatorStep2Form">提交/下一步</div>
</up-form>
<view class="submit" @click="validatorStep2Form">提交/下一步</view>
</div>
</template>
<script>
import { applySecond } from "@/api/entry";
<script setup lang="ts">
import { ref, reactive, computed, watch } from 'vue'
import { onReady } from '@dcloudio/uni-app'
import { useStore } from '@/store'
import { applySecond } from '@/api/entry'
import { getThemeStyle } from '@/utils/theme'
import { fieldInputStyle } from '@/utils/form-style.js'
export default {
data() {
return {
defaultInputStyle: {
background: "#f7f7f7",
padding: "0 20rpx",
"border-radius": "10rpx",
},
form: {
settlementBankAccountName: "",
settlementBankAccountNum: "",
settlementBankBranchName: "",
settlementBankJointName: "",
},
const props = defineProps<{ companyData?: any }>()
const emit = defineEmits<{ callback: [] }>()
rules: {
// 验证规则
settlementBankAccountName: [
{ required: true, message: "请填写银行开户名称" },
],
settlementBankAccountNum: [
{ required: true, message: "请填写银行账号" },
],
settlementBankBranchName: [
{ required: true, message: "请填写开户银行支行名称" },
],
settlementBankJointName: [
{ required: true, message: "请填写支行联行号" },
],
},
};
const store = useStore()
const themeStyle = computed(() => getThemeStyle(store.state.theme))
const uForm = ref<any>(null)
const form = reactive({
settlementBankAccountName: '',
settlementBankAccountNum: '',
settlementBankBranchName: '',
settlementBankJointName: '',
})
const rules = {
settlementBankAccountName: [
{ required: true, message: '请填写银行开户名称' },
],
settlementBankAccountNum: [
{ required: true, message: '请填写银行账号' },
],
settlementBankBranchName: [
{ required: true, message: '请填写开户银行支行名称' },
],
settlementBankJointName: [
{ required: true, message: '请填写支行联行号' },
],
}
watch(
() => props.companyData,
(val) => {
if (val) {
Object.assign(form, val)
}
},
mounted() {
this.$refs.uForm.setRules(this.rules);
},
props: ["companyData"],
watch: {
companyData: {
handler(val) {
this["form"] = val;
console.log(this.form)
},
deep: true,
immediate:true
},
},
methods: {
validatorStep2Form() {
this.$refs.uForm.validate(async (valid) => {
if (valid) {
const params = { ...this.form };
const res = await applySecond(params);
if (res.data.success) {
uni.showToast({
title: "提交成功!",
icon: "none",
});
this.$emit("callback");
}
}
});
},
},
};
{ deep: true, immediate: true }
)
onReady(() => {
uForm.value?.setRules(rules)
})
function validatorStep2Form() {
uForm.value?.validate(async (valid: boolean) => {
if (valid) {
const params = { ...form }
const res = await applySecond(params)
if (res.data.success) {
uni.showToast({
title: '提交成功!',
icon: 'none',
})
emit('callback')
}
}
})
}
</script>
<style>
/* page {
background: #fff;
} */
<style lang="scss">
page {
background: #f8f8f8;
}
</style>
<style lang="scss" scoped>
@import url("./entry.scss");
@import "./entry.scss";
@import "./entry-form.scss";
.wrapper {
// padding: 50rpx 32rpx 16rpx 32rpx;
}
.column {
padding: 32rpx;
margin-bottom: 20rpx;
background: #fff;
@include seller-entry-form;
}
.submit {
color: #fff;
margin-top: 120rpx;
background: rgba($light-color, 0.8);
}
.tips {
color: #999;
font-size: 24rpx;
line-height: 1.2;
margin-top: 10rpx;
@include seller-entry-submit;
}
</style>

View File

@@ -1,16 +1,16 @@
<template>
<div class="wrapper">
<u-form label-width="200" :model="form" ref="uForm">
<div class="wrapper" :style="themeStyle">
<up-form label-position="top" :model="form" ref="uForm">
<div class="column">
<div class="flag-title light-color">基础信息</div>
<u-form-item
<up-form-item
required
:border-bottom="false"
prop="storeName"
label="店铺名称"
><u-input v-model="form.storeName" :custom-style="defaultInputStyle"
/></u-form-item>
<u-form-item
><u-input border="none" class="field-input" v-model="form.storeName" :custom-style="fieldInputStyle"
/></up-form-item>
<up-form-item
required
:border-bottom="false"
prop="storeLogo"
@@ -25,39 +25,45 @@
:max-count="1"
></u-upload>
</div>
</u-form-item>
<u-form-item
</up-form-item>
<up-form-item
required
:border-bottom="false"
prop="goodsManagementCategory"
label="店铺经营类目"
>
<div @click="showCategory()" style="margin-right: 30rpx;">选择</div>
<u-input
:custom-style="defaultInputStyle"
v-model="goodsManagementCategory"
disabled
@click="showCategory()"
/></u-form-item>
>
<view class="field-row">
<u-input
border="none"
class="field-input"
:custom-style="fieldInputStyle"
v-model="goodsManagementCategory"
disabled
@click="showCategory()"
/>
<view class="picker-action" @click="showCategory()">选择</view>
</view>
</up-form-item>
<u-form-item
<up-form-item
required
:border-bottom="false"
prop="storeAddressPath"
label="店铺所在地"
>
<div @click="showPicker()" style="margin-right: 30rpx;">选择</div>
<u-input
:custom-style="defaultInputStyle"
v-model="form.storeAddressPath"
disabled
/>
</u-form-item>
<view class="field-row">
<u-input
border="none"
class="field-input"
:custom-style="fieldInputStyle"
v-model="form.storeAddressPath"
disabled
/>
<view class="picker-action" @click="showPicker()">选择</view>
</view>
</up-form-item>
<!-- <u-form-item
<!-- <up-form-item
required
:border-bottom="false"
prop="storeAddressPath"
@@ -65,30 +71,35 @@
>
<div class="get-center" @click="clickUniMap()">开始定位</div>
<div class="tips-success" v-if="form.storeCenter">已成功定位</div>
</u-form-item> -->
</up-form-item> -->
<u-form-item
<up-form-item
required
:border-bottom="false"
prop="storeAddressDetail"
label="店铺详细地址"
><u-input
:custom-style="defaultInputStyle"
><u-input border="none" class="field-input"
:custom-style="fieldInputStyle"
v-model="form.storeAddressDetail"
/></u-form-item>
<u-form-item
/></up-form-item>
<up-form-item
required
:border-bottom="false"
prop="storeDesc"
label="店铺简介"
><u-input
type="textarea"
:custom-style="defaultInputStyle"
>
<u-textarea
class="field-textarea"
border="none"
height="240"
maxlength="500"
v-model="form.storeDesc"
/></u-form-item>
placeholder="请输入店铺简介"
/>
</up-form-item>
</div>
</u-form>
<div class="submit" @click="validatorStep1Form">提交平台审核</div>
</up-form>
<view class="submit" @click="validatorStep3Form">提交平台审核</view>
<m-city
:provinceData="list"
headTitle="区域选择"
@@ -108,261 +119,256 @@
</div>
</template>
<script>
import { applyThird } from "@/api/entry";
import { getCategoryList } from "@/api/goods";
import city from "@/components/m-city/m-city.vue";
import storage from "@/utils/storage.js";
import { handleUploadAfterRead } from "@/utils/uploadHelper.js";
import uniMap from "@/components/uniMap";
import permision from "@/js_sdk/wa-permission/permission.js";
export default {
components: { "m-city": city, uniMap },
data() {
return {
storage,
mapFlag: false,
defaultInputStyle: {
background: "#f7f7f7",
padding: "0 20rpx",
"border-radius": "10rpx",
},
goodsManagementCategory: "",
storeLogoFileList: [],
categoryList: [],
form: {
storeName: "",
storeLogo: "",
goodsManagementCategory: "",
storeAddressPath: "",
storeAddressDetail: "",
storeDesc: "",
},
list: [
{
id: "",
localName: "请选择",
children: [],
},
],
rules: {
// 验证规则
goodsManagementCategory: [
{ required: true, message: "请选择店铺经营类目" },
],
storeName: [{ required: true, message: "请填写店铺名称" }],
storeLogo: [{ required: true, message: "请上传店铺logo" }],
storeDesc: [{ required: true, message: "请填写店铺简介" }],
storeCenter: [{ required: true, message: "请选择店铺位置" }],
storeAddressIdPath: [{ required: true, message: "请选择店铺位置" }],
storeAddressDetail: [{ required: true, message: "请输入店铺详细地址" }],
},
enableCategory: false,
};
<script setup lang="ts">
import { ref, reactive, computed, watch, onMounted } from 'vue'
import { onReady } from '@dcloudio/uni-app'
import { useStore } from '@/store'
import { applyThird } from '@/api/entry'
import { getCategoryList } from '@/api/goods'
import MCity from '@/components/m-city/m-city.vue'
import uniMap from '@/components/uniMap'
import permision from '@/js_sdk/wa-permission/permission.js'
import { handleUploadAfterRead } from '@/utils/uploadHelper.js'
import { getThemeStyle } from '@/utils/theme'
import { fieldInputStyle } from '@/utils/form-style.js'
const props = defineProps<{ companyData?: any }>()
const emit = defineEmits<{ callback: [] }>()
const store = useStore()
const themeStyle = computed(() => getThemeStyle(store.state.theme))
const uForm = ref<any>(null)
const cityPicker = ref<any>(null)
const mapFlag = ref(false)
const enableCategory = ref(false)
const goodsManagementCategory = ref('')
const storeLogoFileList = ref<any[]>([])
const categoryList = ref<any[]>([])
const form = reactive<Record<string, any>>({
storeName: '',
storeLogo: '',
goodsManagementCategory: '',
storeAddressPath: '',
storeAddressDetail: '',
storeDesc: '',
})
const list = ref([
{
id: '',
localName: '请选择',
children: [],
},
mounted() {
this.$refs.uForm.setRules(this.rules);
this.fetchCategoryList();
])
const rules = {
goodsManagementCategory: [
{ required: true, message: '请选择店铺经营类目' },
],
storeName: [{ required: true, message: '请填写店铺名称' }],
storeLogo: [{ required: true, message: '请上传店铺logo' }],
storeDesc: [{ required: true, message: '请填写店铺简介' }],
storeCenter: [{ required: true, message: '请选择店铺位置' }],
storeAddressIdPath: [{ required: true, message: '请选择店铺位置' }],
storeAddressDetail: [{ required: true, message: '请输入店铺详细地址' }],
}
watch(
() => props.companyData,
(val) => {
if (val) {
Object.assign(form, val)
const judgeDeepPhoto = ['storeLogo']
judgeDeepPhoto.forEach((key) => {
if (form[key]) {
storeLogoFileList.value = []
form[key].split(',').forEach((item: string) => {
storeLogoFileList.value.push({ url: item })
})
}
})
}
},
props: ["companyData"],
watch: {
companyData: {
handler(val) {
this["form"] = val;
// 给图片赋值
const judgeDeepPhoto = ["storeLogo"];
{ deep: true, immediate: true }
)
judgeDeepPhoto.forEach((key) => {
if (this.form[key]) {
this.form[key].split(",").forEach((item) => {
this[`${key}FileList`].push({ url: item });
});
}
});
},
deep: true,
immediate: true,
},
},
onReady(() => {
uForm.value?.setRules(rules)
})
methods: {
callBackAddress(val) {
console.log(val);
this.form.storeAddressDetail = val.address;
this.form.storeCenter = `${val.longitude},${val.latitude}`;
},
// 关闭地图
closeMap() {
this.mapFlag = false;
},
// 打开地图并访问权限
clickUniMap() {
console.log("click");
// #ifdef APP-PLUS
if (plus.os.name == "iOS") {
// ios系统
permision.judgeIosPermission("location")
? (this.mapFlag = true)
: this.refuseMap();
} else {
// 安卓
this.requestAndroidPermission(
"android.permission.ACCESS_FINE_LOCATION"
);
}
// #endif
onMounted(() => {
fetchCategoryList()
})
// #ifndef APP-PLUS
this.mapFlag = true;
// #endif
},
function callBackAddress(val: any) {
form.storeAddressDetail = val.address
form.storeCenter = `${val.longitude},${val.latitude}`
}
// 如果拒绝权限 提示区设置
refuseMap() {
uni.showModal({
title: "温馨提示",
content: "您已拒绝定位,请开启",
confirmText: "去设置",
success(res) {
if (res.confirm) {
//打开授权设置
// #ifndef MP-WEIXIN
uni.getSystemInfo({
success(res) {
if (res.platform == "ios") {
//IOS
plus.runtime.openURL("app-settings://");
} else if (res.platform == "android") {
//安卓
let main = plus.android.runtimeMainActivity();
let Intent = plus.android.importClass(
"android.content.Intent"
);
let mIntent = new Intent("android.settings.ACTION_SETTINGS");
main.startActivity(mIntent);
}
},
});
// #endif
}
},
});
},
// 获取安卓是否拥有地址权限
async requestAndroidPermission(permisionID) {
var result = await permision.requestAndroidPermission(permisionID);
function closeMap() {
mapFlag.value = false
}
if (result == 1) {
this.mapFlag = true;
} else {
this.refuseMap();
function clickUniMap() {
// #ifdef APP-PLUS
if (plus.os.name == 'iOS') {
permision.judgeIosPermission('location')
? (mapFlag.value = true)
: refuseMap()
} else {
requestAndroidPermission('android.permission.ACCESS_FINE_LOCATION')
}
// #endif
// #ifndef APP-PLUS
mapFlag.value = true
// #endif
}
function refuseMap() {
uni.showModal({
title: '温馨提示',
content: '您已拒绝定位,请开启',
confirmText: '去设置',
success(res) {
if (res.confirm) {
// #ifndef MP-WEIXIN
uni.getSystemInfo({
success(sysRes) {
if (sysRes.platform == 'ios') {
plus.runtime.openURL('app-settings://')
} else if (sysRes.platform == 'android') {
const main = plus.android.runtimeMainActivity()
const Intent = plus.android.importClass('android.content.Intent')
const mIntent = new Intent('android.settings.ACTION_SETTINGS')
main.startActivity(mIntent)
}
},
})
// #endif
}
},
})
}
confirmCategory(val) {
this.form.goodsManagementCategory = val[0].value;
this.goodsManagementCategory = val[0].label;
},
async fetchCategoryList() {
const res = await getCategoryList(0);
async function requestAndroidPermission(permisionID: string) {
const result = await permision.requestAndroidPermission(permisionID)
if (result == 1) {
mapFlag.value = true
} else {
refuseMap()
}
}
function confirmCategory(val: any[]) {
form.goodsManagementCategory = val[0].value
goodsManagementCategory.value = val[0].label
}
async function fetchCategoryList() {
const res = await getCategoryList(0)
if (res.data.success) {
if (res.data.result.length) {
categoryList.value = res.data.result.map((item: any) => {
return { label: item.name, value: item.id }
})
if (form.goodsManagementCategory) {
goodsManagementCategory.value = categoryList.value.find(
(item) => form.goodsManagementCategory == item.value
)?.label || ''
}
}
}
}
function onUploadAfterRead(
event: any,
key: string,
fileListKey: 'storeLogoFileList'
) {
handleUploadAfterRead(event, storeLogoFileList.value, (urls) => {
form[key] = urls
})
}
function getPickerParentValue(e: any[]) {
form.storeAddressIdPath = []
let name = ''
e.forEach((item, index) => {
if (item.id) {
form.storeAddressIdPath.push(item.id)
if (index == e.length - 1) {
name += item.localName
} else {
name += item.localName + ','
}
form.storeAddressPath = name
}
})
form.storeCenter = e[e.length - 1].center
}
function showPicker() {
cityPicker.value?.show()
}
function showCategory() {
enableCategory.value = true
}
function validatorStep3Form() {
uForm.value?.validate(async (valid: boolean) => {
if (valid) {
const params = { ...form }
params.storeLogo = params.storeLogo.toString()
params.storeAddressIdPath = params.storeAddressIdPath.toString()
const res = await applyThird(params)
if (res.data.success) {
if (res.data.result.length) {
this.categoryList = res.data.result.map((item) => {
return { label: item.name, value: item.id };
});
if (this.form.goodsManagementCategory) {
this.goodsManagementCategory = this.categoryList.find(
(item) => this.form.goodsManagementCategory == item.value
).label;
}
}
uni.showToast({
title: '提交成功!',
icon: 'none',
})
emit('callback')
}
},
onUploadAfterRead(event, key, fileListKey) {
handleUploadAfterRead(event, this[fileListKey], (urls) => {
this.form[key] = urls;
});
},
getPickerParentValue(e) {
this.form.storeAddressIdPath = [];
console.log(e)
let name = "";
e.forEach((item, index) => {
if (item.id) {
// 遍历数据
this.form.storeAddressIdPath.push(item.id);
if (index == e.length - 1) {
name += item.localName;
} else {
name += item.localName + ",";
}
this.form['storeAddressPath'] = name
}
});
this.form.storeCenter = e[e.length-1].center
},
// 显示三级地址联动
showPicker() {
this.$refs.cityPicker.show();
},
showCategory() {
this.enableCategory = true;
},
validatorStep1Form() {
this.$refs.uForm.validate(async (valid) => {
console.log(valid);
if (valid) {
const params = { ...this.form };
params.storeLogo = params.storeLogo.toString();
params.storeAddressIdPath = params.storeAddressIdPath.toString();
const res = await applyThird(params);
if (res.data.success) {
uni.showToast({
title: "提交成功!",
icon: "none",
});
this.$emit("callback");
}
}
});
},
},
};
}
})
}
</script>
<style>
/* page {
background: #fff;
} */
<style lang="scss">
page {
background: #f8f8f8;
}
</style>
<style lang="scss" scoped>
@import url("./entry.scss");
@import "./entry.scss";
@import "./entry-form.scss";
.wrapper {
@include seller-entry-form;
}
.get-center {
padding: 12rpx 30rpx;
background: $light-color;
background: var(--theme-light, #ff6b35);
border-radius: 10rpx;
font-size: 24rpx;
color: #fff;
font-weight: bold;
display: inline;
}
.column {
padding: 32rpx;
margin-bottom: 20rpx;
background: #fff;
display: inline-block;
}
.submit {
color: #fff;
margin-top: 120rpx;
background: rgba($light-color, 0.8);
}
.tips {
color: #999;
font-size: 24rpx;
line-height: 1.2;
margin-top: 10rpx;
@include seller-entry-submit;
}
.tips-success {
color: $weChat-color;
font-size: 24rpx;