企业信息补全页面开发
This commit is contained in:
632
pages/complete-info/company-info.vue
Normal file
632
pages/complete-info/company-info.vue
Normal file
@@ -0,0 +1,632 @@
|
||||
<template>
|
||||
<AppLayout title="企业信息">
|
||||
<view class="company-info-container">
|
||||
<!-- 头部信息 -->
|
||||
<view class="header-info">
|
||||
<view class="progress-text">企业信息完善度</view>
|
||||
<view class="progress-value">{{ completionPercentage }}%</view>
|
||||
</view>
|
||||
|
||||
<!-- 表单内容 -->
|
||||
<view class="form-content">
|
||||
<!-- 企业名称 -->
|
||||
<view class="form-item">
|
||||
<view class="label">企业名称</view>
|
||||
<input
|
||||
class="input-field"
|
||||
v-model="formData.companyName"
|
||||
placeholder="请输入企业名称"
|
||||
@input="updateCompletion"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 统一社会信用代码 -->
|
||||
<view class="form-item">
|
||||
<view class="label">统一社会信用代码</view>
|
||||
<input
|
||||
class="input-field"
|
||||
v-model="formData.socialCreditCode"
|
||||
placeholder="请输入统一社会信用代码"
|
||||
maxlength="18"
|
||||
@input="updateCompletion"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 企业注册地点 -->
|
||||
<view class="form-item clickable" @click="selectLocation">
|
||||
<view class="label">企业注册地点</view>
|
||||
<view class="input-content">
|
||||
<text class="input-text" :class="{ placeholder: !formData.registeredAddress }">
|
||||
{{ formData.registeredAddress || '请选择注册地点' }}
|
||||
</text>
|
||||
<uni-icons type="arrowright" size="16" color="#999"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 企业信息介绍 -->
|
||||
<view class="form-item clickable" @click="editCompanyIntro">
|
||||
<view class="label">企业信息介绍</view>
|
||||
<view class="input-content">
|
||||
<text class="input-text intro-text" :class="{ placeholder: !formData.companyIntro }">
|
||||
{{ formData.companyIntro || '请输入企业介绍' }}
|
||||
</text>
|
||||
<uni-icons type="arrowright" size="16" color="#999"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 企业法人姓名 -->
|
||||
<view class="form-item">
|
||||
<view class="label">企业法人姓名</view>
|
||||
<input
|
||||
class="input-field"
|
||||
v-model="formData.legalPersonName"
|
||||
placeholder="请输入法人姓名"
|
||||
@input="updateCompletion"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<!-- 本地重点发展产业 -->
|
||||
<view class="form-item clickable" @click="selectIndustry">
|
||||
<view class="label">本地重点发展产业</view>
|
||||
<view class="input-content">
|
||||
<text class="input-text" :class="{ placeholder: !formData.industryType }">
|
||||
{{ formData.industryType || '请选择产业类型' }}
|
||||
</text>
|
||||
<uni-icons type="arrowright" size="16" color="#999"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 是否是本地企业 -->
|
||||
<view class="form-item clickable" @click="selectLocalCompany">
|
||||
<view class="label">是否是本地企业</view>
|
||||
<view class="input-content">
|
||||
<text class="input-text" :class="{ placeholder: formData.isLocalCompany === null }">
|
||||
{{ formData.isLocalCompany === null ? '请选择' : (formData.isLocalCompany ? '是' : '否') }}
|
||||
</text>
|
||||
<uni-icons type="arrowright" size="16" color="#999"></uni-icons>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 联系人信息列表 -->
|
||||
<view class="contact-section">
|
||||
<view class="section-title">联系人信息</view>
|
||||
|
||||
<!-- 每个联系人作为一个分组 -->
|
||||
<view
|
||||
class="contact-group"
|
||||
v-for="(contact, index) in formData.contacts"
|
||||
:key="index"
|
||||
>
|
||||
<view class="group-header">联系人{{ index + 1 }}</view>
|
||||
<view class="form-item">
|
||||
<view class="label">联系人姓名</view>
|
||||
<input
|
||||
class="input-field"
|
||||
v-model="contact.name"
|
||||
placeholder="请输入联系人姓名"
|
||||
@input="updateCompletion"
|
||||
/>
|
||||
</view>
|
||||
<view class="form-item">
|
||||
<view class="label">联系人电话</view>
|
||||
<input
|
||||
class="input-field"
|
||||
v-model="contact.phone"
|
||||
placeholder="请输入联系人电话"
|
||||
@input="updateCompletion"
|
||||
/>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 添加联系人按钮 -->
|
||||
<view class="add-contact-btn" @click="addContact" v-if="formData.contacts.length < 3">
|
||||
<uni-icons type="plus" size="20" color="#256BFA"></uni-icons>
|
||||
<text>添加联系人</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 底部按钮 -->
|
||||
<view class="bottom-actions">
|
||||
<button class="cancel-btn" @click="cancel">取消</button>
|
||||
<button class="confirm-btn" @click="confirm">确认</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 弹窗组件 -->
|
||||
<uni-popup ref="popup" type="center">
|
||||
<view class="popup-content">
|
||||
<view class="popup-title">{{ popupTitle }}</view>
|
||||
<input
|
||||
v-if="popupType === 'text'"
|
||||
class="popup-input"
|
||||
v-model="popupValue"
|
||||
:placeholder="popupPlaceholder"
|
||||
/>
|
||||
<textarea
|
||||
v-if="popupType === 'textarea'"
|
||||
class="popup-textarea"
|
||||
v-model="popupValue"
|
||||
:placeholder="popupPlaceholder"
|
||||
maxlength="500"
|
||||
></textarea>
|
||||
<view class="popup-actions">
|
||||
<button class="popup-cancel" @click="closePopup">取消</button>
|
||||
<button class="popup-confirm" @click="confirmPopup">确定</button>
|
||||
</view>
|
||||
</view>
|
||||
</uni-popup>
|
||||
|
||||
<!-- 地址选择器 -->
|
||||
<area-cascade-picker ref="areaPicker"></area-cascade-picker>
|
||||
</AppLayout>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, computed, inject } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import AreaCascadePicker from '@/components/area-cascade-picker/area-cascade-picker.vue'
|
||||
|
||||
const { $api } = inject('globalFunction')
|
||||
|
||||
// 表单数据
|
||||
const formData = reactive({
|
||||
companyName: '',
|
||||
socialCreditCode: '',
|
||||
registeredAddress: '',
|
||||
registeredAddressName: '',
|
||||
longitude: null,
|
||||
latitude: null,
|
||||
companyIntro: '',
|
||||
legalPersonName: '',
|
||||
industryType: '', // 是否是本地重点发展产业
|
||||
isLocalCompany: null, // 是否是本地企业 (true/false/null)
|
||||
contacts: [
|
||||
{ name: '', phone: '' }
|
||||
]
|
||||
})
|
||||
|
||||
// 弹窗相关
|
||||
const popup = ref(null)
|
||||
const popupTitle = ref('')
|
||||
const popupType = ref('text') // text | textarea
|
||||
const popupValue = ref('')
|
||||
const popupPlaceholder = ref('')
|
||||
const currentEditField = ref('')
|
||||
|
||||
// 地址选择器引用
|
||||
const areaPicker = ref(null)
|
||||
|
||||
// 产业类型选项数据
|
||||
const industryOptions = [
|
||||
'人工智能',
|
||||
'生物医药',
|
||||
'新能源',
|
||||
'高端装备制造',
|
||||
'其他'
|
||||
]
|
||||
|
||||
// 完成度计算
|
||||
const completionPercentage = computed(() => {
|
||||
const fields = [
|
||||
formData.companyName,
|
||||
formData.socialCreditCode,
|
||||
formData.registeredAddress,
|
||||
formData.companyIntro,
|
||||
formData.legalPersonName,
|
||||
formData.industryType,
|
||||
formData.isLocalCompany !== null ? 'filled' : ''
|
||||
]
|
||||
|
||||
// 检查联系人信息
|
||||
const hasContact = formData.contacts.some(contact => contact.name && contact.phone)
|
||||
|
||||
const filledFields = fields.filter(field => field && field.trim()).length + (hasContact ? 1 : 0)
|
||||
const totalFields = fields.length + 1
|
||||
|
||||
return Math.round((filledFields / totalFields) * 100)
|
||||
})
|
||||
|
||||
// 更新完成度
|
||||
const updateCompletion = () => {
|
||||
// 完成度会自动通过computed更新
|
||||
}
|
||||
|
||||
// 选择注册地点
|
||||
const selectLocation = () => {
|
||||
// 打开五级联动地址选择器
|
||||
areaPicker.value?.open({
|
||||
title: '选择企业注册地点',
|
||||
maskClick: true,
|
||||
success: (addressData) => {
|
||||
// addressData 包含: address, province, city, district, street, community
|
||||
formData.registeredAddress = addressData.address
|
||||
formData.registeredAddressName = addressData.address
|
||||
|
||||
// 可以保存详细的地址信息
|
||||
formData.provinceCode = addressData.province?.code
|
||||
formData.provinceName = addressData.province?.name
|
||||
formData.cityCode = addressData.city?.code
|
||||
formData.cityName = addressData.city?.name
|
||||
formData.districtCode = addressData.district?.code
|
||||
formData.districtName = addressData.district?.name
|
||||
formData.streetCode = addressData.street?.code
|
||||
formData.streetName = addressData.street?.name
|
||||
formData.communityCode = addressData.community?.code
|
||||
formData.communityName = addressData.community?.name
|
||||
|
||||
updateCompletion()
|
||||
|
||||
$api.msg('地址选择成功')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 处理地图选择返回的地址
|
||||
const handleLocationSelected = (locationData) => {
|
||||
formData.registeredAddress = locationData.address
|
||||
formData.registeredAddressName = locationData.name
|
||||
formData.longitude = locationData.longitude
|
||||
formData.latitude = locationData.latitude
|
||||
updateCompletion()
|
||||
}
|
||||
|
||||
// 编辑企业介绍
|
||||
const editCompanyIntro = () => {
|
||||
currentEditField.value = 'companyIntro'
|
||||
popupTitle.value = '企业信息介绍'
|
||||
popupType.value = 'textarea'
|
||||
popupValue.value = formData.companyIntro
|
||||
popupPlaceholder.value = '请输入企业介绍'
|
||||
popup.value?.open()
|
||||
}
|
||||
|
||||
|
||||
// 选择产业类型
|
||||
const selectIndustry = () => {
|
||||
uni.showActionSheet({
|
||||
itemList: industryOptions,
|
||||
success: (res) => {
|
||||
formData.industryType = industryOptions[res.tapIndex]
|
||||
updateCompletion()
|
||||
$api.msg('产业类型选择成功')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 选择是否是本地企业
|
||||
const selectLocalCompany = () => {
|
||||
uni.showActionSheet({
|
||||
itemList: ['是', '否'],
|
||||
success: (res) => {
|
||||
formData.isLocalCompany = res.tapIndex === 0
|
||||
updateCompletion()
|
||||
$api.msg('选择成功')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
// 添加联系人
|
||||
const addContact = () => {
|
||||
if (formData.contacts.length < 3) {
|
||||
formData.contacts.push({ name: '', phone: '' })
|
||||
}
|
||||
}
|
||||
|
||||
// 关闭弹窗
|
||||
const closePopup = () => {
|
||||
popup.value?.close()
|
||||
popupValue.value = ''
|
||||
}
|
||||
|
||||
// 确认弹窗
|
||||
const confirmPopup = () => {
|
||||
const field = currentEditField.value
|
||||
|
||||
if (field === 'companyIntro') {
|
||||
formData.companyIntro = popupValue.value
|
||||
}
|
||||
|
||||
updateCompletion()
|
||||
closePopup()
|
||||
}
|
||||
|
||||
// 取消
|
||||
const cancel = () => {
|
||||
uni.navigateBack()
|
||||
}
|
||||
|
||||
// 确认提交
|
||||
const confirm = () => {
|
||||
// 验证必填字段
|
||||
if (!formData.companyName.trim()) {
|
||||
$api.msg('请输入企业名称')
|
||||
return
|
||||
}
|
||||
|
||||
if (!formData.socialCreditCode.trim()) {
|
||||
$api.msg('请输入统一社会信用代码')
|
||||
return
|
||||
}
|
||||
|
||||
if (!formData.registeredAddress.trim()) {
|
||||
$api.msg('请选择注册地点')
|
||||
return
|
||||
}
|
||||
|
||||
if (!formData.companyIntro.trim()) {
|
||||
$api.msg('请输入企业介绍')
|
||||
return
|
||||
}
|
||||
|
||||
if (!formData.legalPersonName.trim()) {
|
||||
$api.msg('请输入法人姓名')
|
||||
return
|
||||
}
|
||||
|
||||
if (!formData.industryType.trim()) {
|
||||
$api.msg('请选择产业类型')
|
||||
return
|
||||
}
|
||||
|
||||
if (formData.isLocalCompany === null) {
|
||||
$api.msg('请选择是否是本地企业')
|
||||
return
|
||||
}
|
||||
|
||||
// 验证至少有一个联系人
|
||||
const hasValidContact = formData.contacts.some(contact =>
|
||||
contact.name.trim() && contact.phone.trim()
|
||||
)
|
||||
|
||||
if (!hasValidContact) {
|
||||
$api.msg('请至少添加一个联系人信息')
|
||||
return
|
||||
}
|
||||
|
||||
// 验证联系人电话格式
|
||||
const phoneRegex = /^1[3-9]\d{9}$/
|
||||
for (let contact of formData.contacts) {
|
||||
if (contact.name.trim() && contact.phone.trim()) {
|
||||
if (!phoneRegex.test(contact.phone)) {
|
||||
$api.msg('请输入正确的手机号码')
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 提交数据
|
||||
uni.showLoading({ title: '保存中...' })
|
||||
|
||||
// 这里调用后端接口保存企业信息
|
||||
const submitData = {
|
||||
...formData,
|
||||
contacts: formData.contacts.filter(contact => contact.name.trim() && contact.phone.trim())
|
||||
}
|
||||
|
||||
$api.createRequest('/app/company/complete-info', submitData, 'post')
|
||||
.then((resData) => {
|
||||
uni.hideLoading()
|
||||
$api.msg('企业信息保存成功')
|
||||
|
||||
// 跳转到首页或企业相关页面
|
||||
uni.reLaunch({
|
||||
url: '/pages/index/index'
|
||||
})
|
||||
})
|
||||
.catch((err) => {
|
||||
uni.hideLoading()
|
||||
$api.msg(err.msg || '保存失败,请重试')
|
||||
})
|
||||
}
|
||||
|
||||
onLoad((options) => {
|
||||
// 可以在这里加载已有的企业信息
|
||||
console.log('企业信息补全页面加载')
|
||||
})
|
||||
|
||||
// 暴露方法给其他页面调用
|
||||
defineExpose({
|
||||
handleLocationSelected
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="stylus" scoped>
|
||||
.company-info-container
|
||||
min-height: 100vh
|
||||
background: #f5f5f5
|
||||
padding-bottom: 120rpx
|
||||
|
||||
.header-info
|
||||
background: #fff
|
||||
padding: 40rpx 32rpx
|
||||
display: flex
|
||||
justify-content: space-between
|
||||
align-items: center
|
||||
margin-bottom: 20rpx
|
||||
|
||||
.progress-text
|
||||
font-size: 32rpx
|
||||
color: #000000
|
||||
font-weight: 500
|
||||
|
||||
.progress-value
|
||||
font-size: 32rpx
|
||||
color: #256BFA
|
||||
font-weight: 600
|
||||
|
||||
.form-content
|
||||
background: #fff
|
||||
margin-bottom: 20rpx
|
||||
|
||||
.form-item
|
||||
padding: 32rpx
|
||||
border-bottom: 1rpx solid #f0f0f0
|
||||
display: flex
|
||||
justify-content: space-between
|
||||
align-items: center
|
||||
|
||||
&:last-child
|
||||
border-bottom: none
|
||||
|
||||
&.clickable
|
||||
cursor: pointer
|
||||
|
||||
.label
|
||||
font-size: 28rpx
|
||||
color: #000000
|
||||
min-width: 200rpx
|
||||
|
||||
.input-field
|
||||
flex: 1
|
||||
font-size: 28rpx
|
||||
color: #333
|
||||
text-align: right
|
||||
|
||||
&::placeholder
|
||||
color: #999
|
||||
font-size: 26rpx
|
||||
|
||||
.input-content
|
||||
flex: 1
|
||||
display: flex
|
||||
justify-content: space-between
|
||||
align-items: center
|
||||
|
||||
.input-text
|
||||
font-size: 28rpx
|
||||
color: #333
|
||||
flex: 1
|
||||
text-align: right
|
||||
|
||||
&.placeholder
|
||||
color: #999
|
||||
font-size: 26rpx
|
||||
|
||||
&.intro-text
|
||||
max-height: 80rpx
|
||||
overflow: hidden
|
||||
text-overflow: ellipsis
|
||||
white-space: nowrap
|
||||
|
||||
.contact-section
|
||||
margin-top: 20rpx
|
||||
|
||||
.section-title
|
||||
padding: 32rpx
|
||||
font-size: 32rpx
|
||||
color: #333
|
||||
font-weight: 500
|
||||
background: #fff
|
||||
border-bottom: 1rpx solid #f0f0f0
|
||||
|
||||
.contact-group
|
||||
background: #fff
|
||||
margin-bottom: 20rpx
|
||||
border-radius: 16rpx
|
||||
overflow: hidden
|
||||
|
||||
.group-header
|
||||
padding: 24rpx 32rpx
|
||||
font-size: 28rpx
|
||||
color: #000000
|
||||
background: #f8f9fa
|
||||
font-weight: 500
|
||||
border-bottom: 1rpx solid #e8e8e8
|
||||
|
||||
.form-item
|
||||
border-bottom: 1rpx solid #f0f0f0
|
||||
|
||||
&:last-child
|
||||
border-bottom: none
|
||||
|
||||
.add-contact-btn
|
||||
padding: 32rpx
|
||||
display: flex
|
||||
align-items: center
|
||||
justify-content: center
|
||||
color: #256BFA
|
||||
font-size: 28rpx
|
||||
background: #fff
|
||||
border-top: 1rpx solid #f0f0f0
|
||||
|
||||
text
|
||||
margin-left: 12rpx
|
||||
|
||||
.bottom-actions
|
||||
position: fixed
|
||||
bottom: 0
|
||||
left: 0
|
||||
right: 0
|
||||
background: #fff
|
||||
padding: 20rpx 32rpx
|
||||
display: flex
|
||||
gap: 20rpx
|
||||
box-shadow: 0 -2rpx 10rpx rgba(0,0,0,0.1)
|
||||
|
||||
.cancel-btn, .confirm-btn
|
||||
flex: 1
|
||||
height: 80rpx
|
||||
border-radius: 40rpx
|
||||
font-size: 32rpx
|
||||
border: none
|
||||
|
||||
.cancel-btn
|
||||
background: #f5f5f5
|
||||
color: #666
|
||||
|
||||
.confirm-btn
|
||||
background: #256BFA
|
||||
color: #fff
|
||||
|
||||
// 弹窗样式
|
||||
.popup-content
|
||||
width: 600rpx
|
||||
background: #fff
|
||||
border-radius: 20rpx
|
||||
padding: 40rpx
|
||||
|
||||
.popup-title
|
||||
font-size: 36rpx
|
||||
color: #333
|
||||
font-weight: 500
|
||||
margin-bottom: 30rpx
|
||||
text-align: center
|
||||
|
||||
.popup-input, .popup-textarea
|
||||
width: 100%
|
||||
padding: 20rpx
|
||||
border: 1rpx solid #e0e0e0
|
||||
border-radius: 10rpx
|
||||
font-size: 28rpx
|
||||
margin-bottom: 30rpx
|
||||
box-sizing: border-box
|
||||
text-align: center
|
||||
|
||||
.popup-textarea
|
||||
height: 200rpx
|
||||
|
||||
.popup-actions
|
||||
display: flex
|
||||
gap: 20rpx
|
||||
|
||||
.popup-cancel, .popup-confirm
|
||||
flex: 1
|
||||
height: 70rpx
|
||||
border-radius: 35rpx
|
||||
font-size: 28rpx
|
||||
border: none
|
||||
|
||||
.popup-cancel
|
||||
background: #f5f5f5
|
||||
color: #666
|
||||
|
||||
.popup-confirm
|
||||
background: #256BFA
|
||||
color: #fff
|
||||
|
||||
// 按钮重置样式
|
||||
button::after
|
||||
border: none
|
||||
</style>
|
Reference in New Issue
Block a user