chuangte_bike_newxcx/page_shanghu/upload_license.vue

1449 lines
43 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="page">
<u-navbar :title="isViewMode ? '企业认证信息' : '营业执照'" :border-bottom="false" :background="bgc" title-color='#fff' back-icon-color="#fff"
title-size='36' height='45'></u-navbar>
<view class="content">
<!-- 状态卡片 -->
<view class="status-card" v-if="isViewMode && status" :class="statusClass" :style="statusCardStyle">
<view class="status-header">
<view class="status-icon">
<u-icon :name="getStatusIcon()" :size="48" :color="getStatusIconColor()"></u-icon>
</view>
<view class="status-content">
<view class="status-title">{{getStatusText()}}</view>
<view class="status-desc">{{getStatusDesc()}}</view>
</view>
</view>
<view class="reject-reason" v-if="normalizedStatus === 'REJECT' && auditRemark">
<view class="reason-label">驳回原因:</view>
<view class="reason-text">{{auditRemark}}</view>
</view>
</view>
<view class="upload-section">
<view class="section-title">上传营业执照</view>
<view class="upload-box" @click="chooseLicenseImage" v-if="!licenseImage && (!isViewMode || normalizedStatus === 'REJECT')">
<image class="upload-icon" src="https://api.ccttiot.com/smartmeter/img/static/udgL6KzisrZlMrk9AZb2" mode=""></image>
<text class="upload-tip">点击上传营业执照照片</text>
<text class="upload-desc">支持 JPG、PNG 格式,大小不超过 5MB</text>
</view>
<view class="upload-preview" v-else-if="licenseImage">
<image :src="licenseImage" mode="aspectFit" class="preview-img"></image>
<view class="preview-actions" v-if="!isViewMode || normalizedStatus === 'REJECT'">
<view class="action-btn" @click="chooseLicenseImage">重新上传</view>
<view class="action-btn delete" @click="removeLicenseImage" v-if="!isViewMode || normalizedStatus === 'REJECT'">删除</view>
</view>
</view>
<view class="upload-preview" v-else-if="isViewMode && !licenseImage">
<view class="empty-img">
<text>暂无营业执照图片</text>
</view>
</view>
</view>
<view class="form-section">
<view class="section-title">企业信息</view>
<view class="form-item">
<view class="form-label">公司名称 <text class="required" v-if="!isViewMode || normalizedStatus === 'REJECT'">*</text></view>
<input v-if="!isViewMode || normalizedStatus === 'REJECT'" class="form-input" v-model="licenseName" placeholder="请输入公司名称" maxlength="100" />
<view v-else class="form-text">{{licenseName || '未填写'}}</view>
</view>
<view class="form-item">
<view class="form-label">企业简称</view>
<input v-if="!isViewMode || normalizedStatus === 'REJECT'" class="form-input" v-model="licenseAlias" placeholder="请输入企业简称" maxlength="50" />
<view v-else class="form-text">{{licenseAlias || '未填写'}}</view>
</view>
<view class="form-item">
<view class="form-label">统一社会信用代码 <text class="required" v-if="!isViewMode || normalizedStatus === 'REJECT'">*</text></view>
<input v-if="!isViewMode || normalizedStatus === 'REJECT'" class="form-input" v-model="licenseNo" placeholder="请输入统一社会信用代码" maxlength="50" />
<view v-else class="form-text">{{licenseNo || '未填写'}}</view>
</view>
<view class="form-item">
<view class="form-label">企业地址</view>
<input v-if="!isViewMode || normalizedStatus === 'REJECT'" class="form-input" v-model="licenseAddress" placeholder="请输入企业地址" maxlength="200" />
<view v-else class="form-text">{{licenseAddress || '未填写'}}</view>
</view>
<view class="form-item">
<view class="form-label">有效期起始</view>
<picker v-if="!isViewMode || normalizedStatus === 'REJECT'" mode="date" :value="licenseStartTime" @change="onLicenseStartTimeChange">
<view class="picker-input">
<text :class="licenseStartTime ? '' : 'placeholder-text'">{{licenseStartTime || '请选择有效期起始日期'}}</text>
<u-icon name="arrow-right" size="28" color="#999"></u-icon>
</view>
</picker>
<view v-else class="form-text">{{licenseStartTime || '未填写'}}</view>
</view>
<view class="form-item">
<view class="form-label">有效期结束</view>
<picker v-if="!isViewMode || normalizedStatus === 'REJECT'" mode="date" :value="licenseEndTime" @change="onLicenseEndTimeChange">
<view class="picker-input">
<text :class="licenseEndTime ? '' : 'placeholder-text'">{{licenseEndTime || '请选择有效期结束日期'}}</text>
<u-icon name="arrow-right" size="28" color="#999"></u-icon>
</view>
</picker>
<view v-else class="form-text">{{licenseEndTime || '未填写'}}</view>
</view>
<view class="form-item">
<view class="form-label">是否长期</view>
<u-switch v-if="!isViewMode || normalizedStatus === 'REJECT'" v-model="licenseIsLongTime" size="24"></u-switch>
<view v-else class="form-text">{{licenseIsLongTime ? '是' : '否'}}</view>
</view>
</view>
<view class="upload-section">
<view class="section-title">法人身份证照片</view>
<view class="idcard-upload-row">
<view class="idcard-upload-item">
<view class="upload-label">身份证人像面</view>
<view class="upload-box-small" @click="chooseIdCardFace" v-if="!legalIdCardFace && (!isViewMode || normalizedStatus === 'REJECT')">
<image class="upload-icon-small" src="https://api.ccttiot.com/smartmeter/img/static/udgL6KzisrZlMrk9AZb2" mode=""></image>
<text class="upload-tip-small">点击上传</text>
</view>
<view class="upload-preview-small" v-else-if="legalIdCardFace">
<image :src="legalIdCardFace" mode="aspectFit" class="preview-img-small"></image>
<view class="preview-actions-small" v-if="!isViewMode || normalizedStatus === 'REJECT'">
<view class="action-btn-small" @click="chooseIdCardFace">重新上传</view>
<view class="action-btn-small delete" @click="removeIdCardFace">删除</view>
</view>
</view>
<view class="upload-preview-small" v-else-if="isViewMode && !legalIdCardFace">
<view class="empty-img-small">
<text>暂无图片</text>
</view>
</view>
</view>
<view class="idcard-upload-item">
<view class="upload-label">身份证国徽面</view>
<view class="upload-box-small" @click="chooseIdCardNational" v-if="!legalIdCardNational && (!isViewMode || normalizedStatus === 'REJECT')">
<image class="upload-icon-small" src="https://api.ccttiot.com/smartmeter/img/static/udgL6KzisrZlMrk9AZb2" mode=""></image>
<text class="upload-tip-small">点击上传</text>
</view>
<view class="upload-preview-small" v-else-if="legalIdCardNational">
<image :src="legalIdCardNational" mode="aspectFit" class="preview-img-small"></image>
<view class="preview-actions-small" v-if="!isViewMode || normalizedStatus === 'REJECT'">
<view class="action-btn-small" @click="chooseIdCardNational">重新上传</view>
<view class="action-btn-small delete" @click="removeIdCardNational">删除</view>
</view>
</view>
<view class="upload-preview-small" v-else-if="isViewMode && !legalIdCardNational">
<view class="empty-img-small">
<text>暂无图片</text>
</view>
</view>
</view>
</view>
</view>
<view class="form-section">
<view class="section-title">法人信息</view>
<view class="form-item">
<view class="form-label">法人姓名 <text class="required" v-if="!isViewMode || normalizedStatus === 'REJECT'">*</text></view>
<input v-if="!isViewMode || normalizedStatus === 'REJECT'" class="form-input" v-model="legalName" placeholder="请输入法人姓名" maxlength="20" />
<view v-else class="form-text">{{legalName || '未填写'}}</view>
</view>
<view class="form-item">
<view class="form-label">法人身份证 <text class="required" v-if="!isViewMode || normalizedStatus === 'REJECT'">*</text></view>
<input v-if="!isViewMode || normalizedStatus === 'REJECT'" class="form-input" v-model="legalIdCard" placeholder="请输入法人身份证号码" maxlength="18" type="idcard" />
<view v-else class="form-text">{{legalIdCard || '未填写'}}</view>
</view>
<view class="form-item">
<view class="form-label">法人手机号</view>
<input v-if="!isViewMode || normalizedStatus === 'REJECT'" class="form-input" v-model="legalMobile" placeholder="请输入法人手机号" maxlength="11" type="number" />
<view v-else class="form-text">{{legalMobile || '未填写'}}</view>
</view>
<view class="form-item">
<view class="form-label">法人身份证有效期起始</view>
<picker v-if="!isViewMode || normalizedStatus === 'REJECT'" mode="date" :value="legalStartTime" @change="onLegalStartTimeChange">
<view class="picker-input">
<text :class="legalStartTime ? '' : 'placeholder-text'">{{legalStartTime || '请选择身份证有效期起始日期'}}</text>
<u-icon name="arrow-right" size="28" color="#999"></u-icon>
</view>
</picker>
<view v-else class="form-text">{{legalStartTime || '未填写'}}</view>
</view>
<view class="form-item">
<view class="form-label">法人身份证有效期结束</view>
<picker v-if="!isViewMode || normalizedStatus === 'REJECT'" mode="date" :value="legalEndTime" @change="onLegalEndTimeChange">
<view class="picker-input">
<text :class="legalEndTime ? '' : 'placeholder-text'">{{legalEndTime || '请选择身份证有效期结束日期'}}</text>
<u-icon name="arrow-right" size="28" color="#999"></u-icon>
</view>
</picker>
<view v-else class="form-text">{{legalEndTime || '未填写'}}</view>
</view>
<view class="form-item">
<view class="form-label">是否长期身份证</view>
<u-switch v-if="!isViewMode || normalizedStatus === 'REJECT'" v-model="legalIsLongTime" size="24"></u-switch>
<view v-else class="form-text">{{legalIsLongTime ? '是' : '否'}}</view>
</view>
</view>
<view class="tips-section">
<view class="tips-title">温馨提示:</view>
<view class="tips-item">1. 请确保营业执照信息清晰可见</view>
<view class="tips-item">2. 营业执照需在有效期内</view>
<view class="tips-item">3. 请如实填写企业信息,信息需与营业执照一致</view>
<view class="tips-item">4. 上传后请等待审核,审核通过后方可使用</view>
</view>
</view>
<view class="bottom-btn"
:class="bottomBtnClass"
@click="handleBottomBtnClick()"
v-if="!isViewMode || normalizedStatus === 'REJECT' || (isViewMode && status)">
<text>{{getBottomBtnText()}}</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
bgc: {
backgroundColor: "#4886F1",
},
licenseImage: '',
token: '',
licenseId: null, // 编辑时的ID
submitting: false,
licenseName: '', // 公司名称
licenseNo: '', // 统一社会信用代码
legalName: '', // 法人姓名
legalIdCard: '', // 法人身份证
isViewMode: false, // 是否为查看模式
status: '', // 审核状态WAIT_AUDIT(待审核)、SUCCESS(通过)、REJECT(驳回)
auditRemark: '', // 驳回原因
// 新增字段
licenseStartTime: '', // 有效期起始
licenseEndTime: '', // 有效期结束
licenseIsLongTime: false, // 是否长期
licenseAlias: '', // 企业简称
licenseAddress: '', // 企业地址
legalMobile: '', // 法人手机号
legalIdCardNational: '', // 法人身份证国徽面
legalIdCardFace: '', // 法人身份证人像面
legalStartTime: '', // 法人身份证有效期起始
legalEndTime: '', // 法人身份证有效期结束
legalIsLongTime: false // 是否长期身份证
}
},
computed: {
// 标准化状态值(计算属性)
normalizedStatus() {
if(!this.status) return ''
const statusUpper = String(this.status).toUpperCase()
// 支持多种可能的格式
if(statusUpper.includes('WAIT') || statusUpper.includes('AUDIT')){
return 'WAIT_AUDIT'
}
if(statusUpper.includes('SUCCESS') || statusUpper.includes('PASS') || statusUpper.includes('APPROVE')){
return 'SUCCESS'
}
if(statusUpper.includes('REJECT') || statusUpper.includes('REFUSE') || statusUpper.includes('FAIL')){
return 'REJECT'
}
return statusUpper
},
// 状态样式类(用于 :class
statusClass() {
const classMap = {
'WAIT_AUDIT': 'status-wait',
'SUCCESS': 'status-success',
'REJECT': 'status-reject'
}
return classMap[this.normalizedStatus] || ''
},
// 状态卡片样式(用于 :style
statusCardStyle() {
const styleMap = {
'WAIT_AUDIT': {
background: 'linear-gradient(135deg, #FFF7E6 0%, #FFFFFF 100%)',
'border-left': '6rpx solid #FF9500'
},
'SUCCESS': {
background: 'linear-gradient(135deg, #F6FFED 0%, #FFFFFF 100%)',
'border-left': '6rpx solid #52C41A'
},
'REJECT': {
background: 'linear-gradient(135deg, #FFF1F0 0%, #FFFFFF 100%)',
'border-left': '6rpx solid #FF4D4F'
}
}
return styleMap[this.normalizedStatus] || {}
},
// 底部按钮样式类(用于 :class
bottomBtnClass() {
if(this.isViewMode && this.normalizedStatus === 'REJECT'){
return 'btn-resubmit'
}
return ''
}
},
onLoad(option) {
// 获取userId
let userId = option.userId || ''
if(!userId){
// 如果没有userId尝试从存储中获取
let user = uni.getStorageSync('user')
userId = user ? user.userId : ''
}
if(!userId){
// 如果还是没有通过getInfo获取
this.$u.get("/getInfo").then((resp) => {
if(resp.code == 200 && resp.user && resp.user.userId){
this.checkEnterpriseAuth(resp.user.userId)
} else {
// 没有userId直接显示提交界面
this.isViewMode = false
this.getQiniuToken()
}
}).catch(() => {
// 获取失败,直接显示提交界面
this.isViewMode = false
this.getQiniuToken()
})
} else {
// 有userId检查是否有认证数据
this.checkEnterpriseAuth(userId)
}
// 如果有ID说明是编辑模式先获取已有数据
if(option.id){
this.licenseId = option.id
this.getLicenseInfo()
}
},
methods: {
// OCR识别
recognizeImage(type, url) {
let apiUrl = ''
if (type === 'license') {
apiUrl = '/common/ocr/businessLicense'
} else if (type === 'face') {
apiUrl = '/common/ocr/idCardFace'
} else if (type === 'national') {
apiUrl = '/common/ocr/idCardBack'
}
if (!apiUrl) {
uni.hideLoading()
return
}
// uploadImage 已经开启了 loading这里更新文字即可
uni.showLoading({
title: '智能识别中...',
mask: true
})
this.$u.get(apiUrl, {
url: url
}).then(res => {
uni.hideLoading()
console.log('OCR识别结果:', res)
if (res.code == 200 && res.data) {
this.fillFormData(type, res.data)
uni.showToast({
title: '识别成功',
icon: 'success'
})
} else {
uni.showToast({
title: '识别信息不全,请手动填写',
icon: 'none'
})
}
}).catch(err => {
uni.hideLoading()
console.error('OCR识别错误:', err)
uni.showToast({
title: '识别服务异常,请手动填写',
icon: 'none'
})
})
},
// 填充OCR数据
fillFormData(type, data) {
if (type === 'license') {
// 营业执照
// 兼容多种 OCR 返回格式,优先匹配用户提供的格式
this.licenseName = data.companyName || data.name || this.licenseName
this.licenseNo = data.creditCode || data.regNum || this.licenseNo
this.legalName = data.legalPerson || data.person || this.legalName
this.licenseAddress = data.businessAddress || data.address || this.licenseAddress
// 有效期起始
const startDate = data.validFromDate || data.registrationDate || data.establishDate
if (startDate) {
this.licenseStartTime = this.formatOCRDate(startDate)
}
// 有效期结束
// 检查 validToDate
if (data.validToDate) {
if (data.validToDate.includes('长期')) {
this.licenseIsLongTime = true
this.licenseEndTime = ''
} else {
this.licenseEndTime = this.formatOCRDate(data.validToDate)
this.licenseIsLongTime = false
}
}
// 检查 validPeriod (例如 "2023-05-24至长期")
else if (data.validPeriod) {
if (data.validPeriod.includes('长期')) {
this.licenseIsLongTime = true
this.licenseEndTime = ''
} else {
// 尝试解析范围字符串
// ... 简单的逻辑,如果不是长期,可能需要用户手动填
}
}
} else if (type === 'face') {
// 身份证人像面
if (data.name) this.legalName = data.name
// 兼容 idNumber 和 idNum
if (data.idNumber) this.legalIdCard = data.idNumber
else if (data.idNum) this.legalIdCard = data.idNum
} else if (type === 'national') {
// 身份证国徽面
// 优先使用 validStartDate / validEndDate
if (data.validStartDate) {
this.legalStartTime = this.formatOCRDate(data.validStartDate)
}
if (data.validEndDate) {
if (data.validEndDate === '长期' || data.validEndDate.includes('长期')) {
this.legalIsLongTime = true
this.legalEndTime = ''
} else {
this.legalEndTime = this.formatOCRDate(data.validEndDate)
this.legalIsLongTime = false
}
} else if (data.validDate) {
// 旧格式兼容 "20200101-20400101"
const dates = data.validDate.split('-')
if (dates.length >= 1 && !this.legalStartTime) {
this.legalStartTime = this.formatOCRDate(dates[0])
}
if (dates.length >= 2 && !this.legalEndTime && !this.legalIsLongTime) {
if (dates[1] === '长期') {
this.legalIsLongTime = true
this.legalEndTime = ''
} else {
this.legalEndTime = this.formatOCRDate(dates[1])
this.legalIsLongTime = false
}
}
}
}
},
// 辅助格式化OCR日期 (例如 YYYYMMDD -> YYYY-MM-DD)
formatOCRDate(dateStr) {
if (!dateStr) return ''
// 移除可能存在的点或横杠,统一处理
let cleanStr = String(dateStr).replace(/\./g, '').replace(/-/g, '')
if (cleanStr.length === 8) {
return `${cleanStr.substring(0, 4)}-${cleanStr.substring(4, 6)}-${cleanStr.substring(6, 8)}`
}
return dateStr // 无法处理则原样返回
},
// 获取七牛云上传token
getQiniuToken() {
this.$u.get("/common/qiniuToken").then((res) => {
if (res.code == 200) {
this.token = res.data
}
})
},
// 检查企业认证信息(判断是否有数据)
checkEnterpriseAuth(userId) {
this.$u.get(`/bst/enterpriseAuth/last?userId=${userId}`).then((res) => {
if(res.code == 200 && res.data && res.data.id){
// 有数据,显示查看模式
this.isViewMode = true
// 填充表单字段(基础字段)
this.licenseImage = res.data.licenseUrl || res.data.licenseImage || ''
this.licenseName = res.data.licenseName || ''
this.licenseNo = res.data.licenseNo || ''
this.legalName = res.data.legalName || ''
this.legalIdCard = res.data.legalIdCard || ''
this.status = res.data.status || ''
this.auditRemark = res.data.auditRemark || res.data.rejectReason || ''
// 填充新增字段(企业信息)
this.licenseStartTime = this.formatDate(res.data.licenseStartTime)
this.licenseEndTime = this.formatDate(res.data.licenseEndTime)
this.licenseIsLongTime = res.data.licenseIsLongTime === true || res.data.licenseIsLongTime === 1 || res.data.licenseIsLongTime === '1'
this.licenseAlias = res.data.licenseAlias || ''
this.licenseAddress = res.data.licenseAddress || ''
// 填充新增字段(法人信息)
this.legalMobile = res.data.legalMobile || ''
this.legalIdCardNational = res.data.legalIdCardNational || res.data.legalIdCardBack || ''
this.legalIdCardFace = res.data.legalIdCardFace || res.data.legalIdCardFront || ''
this.legalStartTime = this.formatDate(res.data.legalStartTime)
this.legalEndTime = this.formatDate(res.data.legalEndTime)
this.legalIsLongTime = res.data.legalIsLongTime === true || res.data.legalIsLongTime === 1 || res.data.legalIsLongTime === '1'
// 调试:打印完整数据
console.log('企业认证数据:', JSON.stringify(res.data))
// 如果是驳回状态需要获取token以便重新提交
// 使用 $nextTick 确保 computed 属性已更新
this.$nextTick(() => {
if(this.normalizedStatus === 'REJECT'){
this.getQiniuToken()
}
// 调试:打印状态值
console.log('认证状态:', this.status, '标准化后:', this.normalizedStatus)
})
} else {
// 没有数据或数据为空,显示提交界面
this.isViewMode = false
this.getQiniuToken()
}
}).catch(() => {
// 请求失败,显示提交界面
this.isViewMode = false
this.getQiniuToken()
})
},
// 获取营业执照信息(编辑模式)
getLicenseInfo() {
this.$u.get("/app/userLicense/byType?licenseType=1").then((res) => {
if(res.code == 200 && res.data && res.data.id){
// 兼容多种可能的字段名
this.licenseImage = res.data.licenseUrl || res.data.businessLicenseUrl || res.data.url || ''
this.licenseId = res.data.id
// 填充表单字段
this.licenseName = res.data.licenseName || ''
this.licenseNo = res.data.licenseNo || ''
this.legalName = res.data.legalName || ''
this.legalIdCard = res.data.legalIdCard || ''
// 填充新增字段
this.licenseStartTime = res.data.licenseStartTime ? this.formatDate(res.data.licenseStartTime) : ''
this.licenseEndTime = res.data.licenseEndTime ? this.formatDate(res.data.licenseEndTime) : ''
this.licenseIsLongTime = res.data.licenseIsLongTime || false
this.licenseAlias = res.data.licenseAlias || ''
this.licenseAddress = res.data.licenseAddress || ''
this.legalMobile = res.data.legalMobile || ''
this.legalIdCardNational = res.data.legalIdCardNational || ''
this.legalIdCardFace = res.data.legalIdCardFace || ''
this.legalStartTime = res.data.legalStartTime ? this.formatDate(res.data.legalStartTime) : ''
this.legalEndTime = res.data.legalEndTime ? this.formatDate(res.data.legalEndTime) : ''
this.legalIsLongTime = res.data.legalIsLongTime || false
}
}).catch(() => {
// 如果获取失败,可能是新增模式
})
},
// 选择营业执照图片
chooseLicenseImage() {
this.uploadImage('license')
},
// 删除图片
removeLicenseImage() {
uni.showModal({
title: '提示',
content: '确定要删除已上传的营业执照吗?',
success: (res) => {
if(res.confirm){
this.licenseImage = ''
}
}
})
},
// 提交营业执照
submitLicense() {
if(!this.licenseImage){
uni.showToast({
title: '请先上传营业执照',
icon: 'none',
duration:3000
})
return
}
if(!this.licenseName || !this.licenseName.trim()){
uni.showToast({
title: '请输入公司名称',
icon: 'none',
duration:3000
})
return
}
if(!this.licenseNo || !this.licenseNo.trim()){
uni.showToast({
title: '请输入统一社会信用代码',
icon: 'none',
duration:3000
})
return
}
if(!this.legalName || !this.legalName.trim()){
uni.showToast({
title: '请输入法人姓名',
icon: 'none',
duration:3000
})
return
}
if(!this.legalIdCard || !this.legalIdCard.trim()){
uni.showToast({
title: '请输入法人身份证号码',
icon: 'none',
duration:3000
})
return
}
// 验证身份证格式(简单验证)
if(this.legalIdCard.length !== 15 && this.legalIdCard.length !== 18){
uni.showToast({
title: '请输入正确的身份证号码',
icon: 'none',
duration:3000
})
return
}
if(this.submitting){
return
}
this.submitting = true
let user = uni.getStorageSync('user')
let userId = user ? user.userId : ''
if(!userId){
// 如果没有userId尝试从getInfo获取
this.$u.get("/getInfo").then((resp) => {
if(resp.code == 200 && resp.user && resp.user.userId){
this.submitData(resp.user.userId)
} else {
this.submitting = false
uni.showToast({
title: '获取用户信息失败,请重新登录',
icon: 'none',
duration:3000
})
}
}).catch(() => {
this.submitting = false
uni.showToast({
title: '获取用户信息失败,请重新登录',
icon: 'none',
duration:3000
})
})
} else {
this.submitData(userId)
}
},
// 获取状态文本
getStatusText() {
const statusMap = {
'WAIT_AUDIT': '审核中',
'SUCCESS': '已审核',
'REJECT': '已驳回'
}
return statusMap[this.normalizedStatus] || '未知状态'
},
// 获取状态描述
getStatusDesc() {
const descMap = {
'WAIT_AUDIT': '您的企业认证信息正在审核中,请耐心等待',
'SUCCESS': '恭喜!您的企业认证已通过审核',
'REJECT': '您的企业认证未通过审核,请根据驳回原因修改后重新提交'
}
return descMap[this.normalizedStatus] || ''
},
// 获取状态图标
getStatusIcon() {
const iconMap = {
'WAIT_AUDIT': 'clock',
'SUCCESS': 'checkmark-circle',
'REJECT': 'close-circle'
}
return iconMap[this.normalizedStatus] || 'info-circle'
},
// 获取状态图标颜色
getStatusIconColor() {
const colorMap = {
'WAIT_AUDIT': '#FF9500',
'SUCCESS': '#52C41A',
'REJECT': '#FF4D4F'
}
return colorMap[this.normalizedStatus] || '#999'
},
// 获取底部按钮文字
getBottomBtnText() {
if(this.isViewMode){
if(this.normalizedStatus === 'REJECT'){
return '重新提交'
} else {
return '返回'
}
} else {
return '提交'
}
},
// 处理底部按钮点击
handleBottomBtnClick() {
if(this.isViewMode){
if(this.normalizedStatus === 'REJECT'){
// 驳回状态,允许重新提交
this.submitLicense()
} else {
// 其他状态,返回
this.goBack()
}
} else {
// 非查看模式,提交
this.submitLicense()
}
},
// 返回
goBack() {
uni.navigateBack()
},
// 日期选择器变化事件
onLicenseStartTimeChange(e) {
this.licenseStartTime = e.detail.value
},
onLicenseEndTimeChange(e) {
this.licenseEndTime = e.detail.value
},
onLegalStartTimeChange(e) {
this.legalStartTime = e.detail.value
},
onLegalEndTimeChange(e) {
this.legalEndTime = e.detail.value
},
// 格式化日期(从后端格式转换为前端显示格式)
formatDate(dateStr) {
if(!dateStr) return ''
// 处理各种可能的日期格式
let date = String(dateStr)
// 如果是 "yyyy-MM-dd HH:mm:ss" 或 "yyyy-MM-ddTHH:mm:ss" 格式,只取日期部分
if(date.includes(' ')){
return date.split(' ')[0]
}
if(date.includes('T')){
return date.split('T')[0]
}
// 如果已经是 yyyy-MM-dd 格式,直接返回
if(date.match(/^\d{4}-\d{2}-\d{2}$/)){
return date
}
return date
},
// 格式化日期时间为后端格式(只返回日期部分,不包含时分秒)
formatDateTime(dateStr) {
if(!dateStr) return null
// 只取日期部分,去掉时分秒
let date = String(dateStr)
// 如果包含空格,只取日期部分
if(date.includes(' ')){
return date.split(' ')[0]
}
// 如果包含T只取日期部分
if(date.includes('T')){
return date.split('T')[0]
}
// 如果已经是 yyyy-MM-dd 格式,直接返回
if(date.length === 10 && date.match(/^\d{4}-\d{2}-\d{2}$/)){
return date
}
// 其他情况,尝试提取日期部分
return date.substring(0, 10)
},
// 选择身份证人像面
chooseIdCardFace() {
if(!this.token){
uni.showToast({
title: '上传token获取失败请重试',
icon: 'none',
duration:3000
})
return
}
this.uploadImage('face')
},
// 选择身份证国徽面
chooseIdCardNational() {
if(!this.token){
uni.showToast({
title: '上传token获取失败请重试',
icon: 'none',
duration:3000
})
return
}
this.uploadImage('national')
},
// 删除身份证人像面
removeIdCardFace() {
uni.showModal({
title: '提示',
content: '确定要删除已上传的身份证人像面吗?',
success: (res) => {
if(res.confirm){
this.legalIdCardFace = ''
}
}
})
},
// 删除身份证国徽面
removeIdCardNational() {
uni.showModal({
title: '提示',
content: '确定要删除已上传的身份证国徽面吗?',
success: (res) => {
if(res.confirm){
this.legalIdCardNational = ''
}
}
})
},
// 上传图片(通用方法,支持类型参数)
uploadImage(type) {
if(!this.token){
uni.showToast({
title: '上传token获取失败请重试',
icon: 'none',
duration:3000
})
return
}
let _this = this
let math = 'static/' + _this.$u.guid(20)
uni.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success(res) {
const tempFilePaths = res.tempFilePaths[0]
// 检查文件大小5MB
uni.getFileInfo({
filePath: tempFilePaths,
success(fileInfo) {
if(fileInfo.size > 5 * 1024 * 1024){
uni.showToast({
title: '图片大小不能超过5MB',
icon: 'none',
duration:3000
})
return
}
// 显示上传加载提示
uni.showLoading({
title: '图片上传中...',
mask: true
})
// 上传到七牛云
wx.uploadFile({
url: 'https://up-z2.qiniup.com',
name: 'file',
filePath: tempFilePaths,
formData: {
token: _this.token,
key: 'smartmeter/img/' + math
},
success: function(res) {
try {
let str = JSON.parse(res.data)
let imageUrl = 'https://api.ccttiot.com/' + str.key
// 根据类型设置对应的图片
if(type === 'face'){
_this.legalIdCardFace = imageUrl
} else if(type === 'national'){
_this.legalIdCardNational = imageUrl
} else {
_this.licenseImage = imageUrl
}
// 不在这里隐藏 loading而是转到识别
// uni.showToast({
// title: '上传成功',
// icon: 'success',
// duration:3000
// })
// 触发OCR识别
_this.recognizeImage(type, imageUrl)
} catch(e) {
uni.hideLoading()
uni.showToast({
title: '上传失败,请重试',
icon: 'none',
duration:3000
})
}
},
fail: function() {
uni.hideLoading()
uni.showToast({
title: '上传失败,请重试',
icon: 'none',
duration:3000
})
}
})
}
})
}
})
},
// 提交数据
submitData(userId) {
let data = {
userId: userId,
licenseType: 1,
licenseUrl: this.licenseImage,
licenseName: this.licenseName.trim(),
licenseNo: this.licenseNo.trim(),
legalName: this.legalName.trim(),
legalIdCard: this.legalIdCard.trim(),
// 新增字段
licenseStartTime: this.licenseStartTime ? this.formatDateTime(this.licenseStartTime) : null,
licenseEndTime: this.licenseEndTime ? this.formatDateTime(this.licenseEndTime) : null,
licenseIsLongTime: this.licenseIsLongTime,
licenseAlias: this.licenseAlias.trim(),
licenseAddress: this.licenseAddress.trim(),
legalMobile: this.legalMobile.trim(),
legalIdCardNational: this.legalIdCardNational,
legalIdCardFace: this.legalIdCardFace,
legalStartTime: this.legalStartTime ? this.formatDateTime(this.legalStartTime) : null,
legalEndTime: this.legalEndTime ? this.formatDateTime(this.legalEndTime) : null,
legalIsLongTime: this.legalIsLongTime
}
// 如果是编辑模式使用PUT请求
let url = `/bst/enterpriseAuth`
let method = 'post'
this.$u[method](url, data).then((res) => {
this.submitting = false
if(res.code == 200){
uni.showToast({
title: this.licenseId ? '更新成功' : '提交成功',
icon: 'success',
duration: 2000
})
setTimeout(() => {
let pages = getCurrentPages()
if(pages.length > 1){
let prevPage = pages[pages.length - 2]
if(prevPage && typeof prevPage.getchaxun === 'function'){
prevPage.getchaxun()
}
}
uni.navigateBack()
}, 1500)
} else {
uni.showToast({
title: res.msg || '提交失败',
icon: 'none',
duration:2000
})
}
}).catch(() => {
this.submitting = false
uni.showToast({
title: '提交失败,请重试',
icon: 'none',
duration:2000
})
})
}
}
}
</script>
<style lang="scss">
page {
background: #F8FAFC;
}
.page {
min-height: 100vh;
padding-bottom: 220rpx;
position: relative;
overflow-x: hidden;
// 背景装饰光斑
&::before {
content: '';
position: absolute;
top: -100rpx;
right: -100rpx;
width: 600rpx;
height: 600rpx;
background: radial-gradient(circle, rgba(37, 99, 235, 0.08) 0%, rgba(37, 99, 235, 0) 70%);
border-radius: 50%;
pointer-events: none;
z-index: 0;
}
&::after {
content: '';
position: absolute;
top: 20%;
left: -200rpx;
width: 500rpx;
height: 500rpx;
background: radial-gradient(circle, rgba(139, 92, 246, 0.06) 0%, rgba(139, 92, 246, 0) 70%);
border-radius: 50%;
pointer-events: none;
z-index: 0;
}
}
.content {
padding: 32rpx;
position: relative;
z-index: 1;
}
// 通用卡片样式 - 玻璃质感微调
.card {
background: rgba(255, 255, 255, 0.95);
border-radius: 32rpx;
box-shadow: 0 4rpx 6rpx -1rpx rgba(0, 0, 0, 0.02),
0 10rpx 15rpx -3rpx rgba(0, 0, 0, 0.04),
0 0 0 1rpx rgba(0, 0, 0, 0.02); // 极细边框替代 border
overflow: hidden;
backdrop-filter: blur(10px);
}
// 状态卡片
.status-card {
@extend .card;
margin-bottom: 32rpx;
position: relative;
padding: 0 0 20rpx 0;
.status-header {
display: flex;
align-items: flex-start;
padding: 36rpx;
padding-bottom: 24rpx;
gap: 28rpx;
}
.status-icon {
width: 96rpx;
height: 96rpx;
border-radius: 28rpx;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
box-shadow: inset 0 0 0 1rpx rgba(255,255,255,0.2);
}
.status-content {
flex: 1;
padding-top: 4rpx;
.status-title {
font-size: 34rpx;
font-weight: 800;
color: #1e293b;
margin-bottom: 8rpx;
letter-spacing: -0.5rpx;
}
.status-desc {
font-size: 26rpx;
color: #64748b;
line-height: 1.5;
}
}
.reject-reason {
margin: 0 36rpx 24rpx;
padding: 24rpx;
border-radius: 20rpx;
background: #FEF2F2;
border: 1rpx solid rgba(254, 202, 202, 0.5);
.reason-label {
font-size: 24rpx;
font-weight: 700;
color: #EF4444;
margin-bottom: 8rpx;
display: flex;
align-items: center;
&::before {
content: '';
display: inline-block;
width: 8rpx;
height: 8rpx;
background: #EF4444;
border-radius: 50%;
margin-right: 12rpx;
}
}
.reason-text {
font-size: 26rpx;
color: #7F1D1D;
line-height: 1.6;
}
}
&.status-wait {
.status-icon {
background: linear-gradient(135deg, #FFF7ED 0%, #FEF3C7 100%);
color: #D97706;
}
}
&.status-success {
.status-icon {
background: linear-gradient(135deg, #F0FDF4 0%, #DCFCE7 100%);
color: #059669;
}
}
&.status-reject {
.status-icon {
background: linear-gradient(135deg, #FEF2F2 0%, #FEE2E2 100%);
color: #DC2626;
}
}
}
// 分段标题
.section-title {
font-size: 32rpx;
font-weight: 800;
color: #0f172a;
margin-bottom: 32rpx;
display: flex;
align-items: center;
&::after {
content: '';
flex: 1;
height: 2rpx;
background: linear-gradient(to right, #F1F5F9 0%, transparent 100%);
margin-left: 24rpx;
}
}
// 上传区域
.upload-section {
@extend .card;
padding: 40rpx;
margin-bottom: 32rpx;
.upload-box {
width: 100%;
height: 380rpx;
border-radius: 28rpx;
border: 3rpx dashed #CBD5E1;
background: linear-gradient(180deg, #F8FAFC 0%, #F1F5F9 100%);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 16rpx;
transition: all 0.3s ease;
position: relative;
overflow: hidden;
&:active {
transform: scale(0.99);
border-color: #3B82F6;
background: #EFF6FF;
}
.upload-icon {
width: 108rpx;
height: 108rpx;
opacity: 0.9;
filter: drop-shadow(0 4rpx 6rpx rgba(0,0,0,0.05));
}
.upload-tip {
font-size: 30rpx;
font-weight: 700;
color: #334155;
}
.upload-desc {
font-size: 24rpx;
color: #94a3b8;
}
}
.upload-preview {
.preview-img {
width: 100%;
height: 500rpx;
border-radius: 28rpx;
box-shadow: 0 10rpx 30rpx rgba(0, 0, 0, 0.08);
object-fit: cover;
}
.empty-img {
height: 400rpx;
border-radius: 28rpx;
background: #F8FAFC;
border: 2rpx dashed #E2E8F0;
display: flex;
align-items: center;
justify-content: center;
text {
font-size: 28rpx;
color: #94a3b8;
font-weight: 500;
}
}
.preview-actions {
margin-top: 32rpx;
display: flex;
gap: 24rpx;
.action-btn {
flex: 1;
height: 88rpx;
border-radius: 24rpx;
text-align: center;
line-height: 88rpx;
font-size: 28rpx;
font-weight: 700;
background: #EFF6FF;
color: #2563eb;
transition: all 0.2s;
border: 1rpx solid rgba(37, 99, 235, 0.1);
&:active { transform: scale(0.98); }
&.delete {
background: #FEF2F2;
color: #DC2626;
border-color: rgba(220, 38, 38, 0.1);
}
}
}
}
}
// 表单区域
.form-section {
@extend .card;
padding: 40rpx;
margin-bottom: 32rpx;
.form-item {
margin-bottom: 32rpx;
&:last-child { margin-bottom: 0; }
.form-label {
font-size: 28rpx;
color: #475569;
margin-bottom: 16rpx;
font-weight: 600;
display: flex;
align-items: center;
.required {
color: #EF4444;
margin-left: 8rpx;
font-size: 32rpx;
line-height: 1;
}
}
.form-input, .form-text, .picker-input {
width: 100%;
min-height: 100rpx;
background: #F8FAFC;
border: 2rpx solid transparent;
border-radius: 24rpx;
padding: 0 32rpx;
font-size: 30rpx;
color: #0f172a;
box-sizing: border-box;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
&:focus {
background: #ffffff;
border-color: #3B82F6;
box-shadow: 0 0 0 6rpx rgba(59, 130, 246, 0.1);
}
}
.form-text {
padding: 30rpx 32rpx;
line-height: 1.6;
color: #334155;
}
.picker-input {
display: flex;
align-items: center;
justify-content: space-between;
text { color: #0f172a; }
.placeholder-text { color: #94a3b8; }
}
}
}
// 身份证上传
.idcard-upload-row {
display: flex;
gap: 24rpx;
.idcard-upload-item { flex: 1; }
.upload-label {
font-size: 26rpx;
color: #475569;
margin-bottom: 16rpx;
text-align: center;
font-weight: 600;
}
}
.upload-box-small {
height: 240rpx;
background: #F8FAFC;
border: 3rpx dashed #CBD5E1;
border-radius: 24rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 12rpx;
transition: all 0.2s;
&:active {
border-color: #3B82F6;
background: #EFF6FF;
}
.upload-icon-small { width: 64rpx; height: 64rpx; opacity: 0.7; }
.upload-tip-small { font-size: 24rpx; color: #64748B; font-weight: 500; }
}
.upload-preview-small {
height: 240rpx;
border-radius: 24rpx;
overflow: hidden;
position: relative;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
border: 1rpx solid rgba(0,0,0,0.05);
.preview-img-small { width: 100%; height: 100%; object-fit: cover; }
.preview-actions-small {
position: absolute;
left: 0; right: 0; bottom: 0;
display: flex;
gap: 16rpx;
padding: 16rpx;
background: rgba(255, 255, 255, 0.85);
backdrop-filter: blur(8rpx);
border-top: 1rpx solid rgba(255,255,255,0.5);
.action-btn-small {
flex: 1;
height: 60rpx;
line-height: 60rpx;
text-align: center;
border-radius: 16rpx;
font-size: 24rpx;
font-weight: 700;
color: #ffffff;
background: #3B82F6;
color: #fff;
box-shadow: 0 2rpx 6rpx rgba(59, 130, 246, 0.2);
&.delete { background: #EF4444; box-shadow: 0 2rpx 6rpx rgba(239, 68, 68, 0.2); }
}
}
.empty-img-small {
width: 100%; height: 100%;
display: flex;
align-items: center;
justify-content: center;
background: #F8FAFC;
color: #94a3b8;
font-size: 24rpx;
}
}
.tips-section {
@extend .card;
padding: 32rpx;
background: #F8FAFC;
border: 1rpx solid #E2E8F0;
box-shadow: none;
.tips-title {
font-size: 28rpx;
font-weight: 700;
color: #64748B;
margin-bottom: 16rpx;
}
.tips-item {
font-size: 24rpx;
color: #94A3B8;
line-height: 1.6;
margin-bottom: 8rpx;
}
}
// 底部按钮
.bottom-btn {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
height: 180rpx;
background: transparent;
display: flex;
align-items: center;
justify-content: center;
padding-bottom: 40rpx;
z-index: 999;
pointer-events: none;
// 底部渐变遮罩防止内容滚动时与按钮重叠太乱
background: linear-gradient(to top, rgba(248,250,252,0.9) 0%, rgba(248,250,252,0) 100%);
text {
pointer-events: auto;
width: 90%;
height: 100rpx;
border-radius: 50rpx;
line-height: 100rpx;
text-align: center;
font-size: 32rpx;
font-weight: 800;
color: #ffffff;
background: linear-gradient(135deg, #3B82F6 0%, #2563EB 100%);
box-shadow: 0 20rpx 40rpx -10rpx rgba(37, 99, 235, 0.4);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
letter-spacing: 2rpx;
&:active {
transform: scale(0.96);
box-shadow: 0 10rpx 20rpx -5rpx rgba(37, 99, 235, 0.3);
}
}
&.btn-resubmit text {
background: linear-gradient(135deg, #EF4444 0%, #DC2626 100%);
box-shadow: 0 20rpx 40rpx -10rpx rgba(220, 38, 38, 0.4);
}
}
</style>