mrr.sj.front/pages/shop/qualification_sj_change.vue

2968 lines
90 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="qualification-page">
<!-- 顶部导航栏 -->
<custom-navbar :title="navTitle" :showBack="true"></custom-navbar>
<!-- 变更提示 -->
<view class="change-tip" v-if="editable">
<text>请变更您需要变更的信息</text>
</view>
<!-- 页面内容容器 -->
<view class="content-area" :style="{ paddingBottom: buttonAreaHeight + 'px' }">
<!-- 营业执照部分 -->
<view class="section">
<view class="section-title">
<view class="title-bar"></view>
<text class="title-text">营业执照</text>
</view>
<!-- 资质照片 -->
<view class="form-item box-cont">
<text class="label required">资质照片</text>
<view class="upload-tip">请保证图片上的文字清晰、无遮挡、证件边角可见</view>
<view class="upload-container">
<view class="upload-box" @click="editable && chooseImage('uscc_photo')">
<view class="upload-camera license-upload">
<image v-if="displayData.uscc_photo" :src="displayData.uscc_photo" mode="aspectFill"
class="preview-image"></image>
<image v-else
src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/92bd4268-b4d7-4725-8664-9e44f828c7d9"
mode="aspectFit" class="camera-icon"></image>
</view>
</view>
<text class="upload-label required">请上传营业执照原件</text>
</view>
</view>
<!-- 商户类型信息 -->
<view class="form-item-one box-cont">
<view class="label-wrapper">
<text class="label required">商户类型</text>
</view>
<input type="text" v-model="displayData.uscc_type" placeholder="请输入商户类型" :disabled="!editable"
placeholder-class="placeholder" class="input" />
</view>
<!-- 营业执照信息 -->
<view class="form-item-one box-cont">
<view class="label-wrapper">
<text class="label required">证件号码</text>
<image class="label-icon"
src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/25bd7f38-1a3e-4282-84ea-190d7f820108"
mode="aspectFit" @click="showTipPopup('uscc_num')"></image>
</view>
<input type="text" v-model="displayData.uscc_num" placeholder="请输入营业执照的证件号码" :disabled="!editable"
placeholder-class="placeholder" class="input" />
</view>
<view class="form-item-one box-cont">
<view class="label-wrapper">
<text class="label required">企业名称</text>
<image class="label-icon"
src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/25bd7f38-1a3e-4282-84ea-190d7f820108"
mode="aspectFit" @click="showTipPopup('uscc_name')"></image>
</view>
<input type="text" v-model="displayData.uscc_name" placeholder="请输入营业执照的企业名称" :disabled="!editable"
placeholder-class="placeholder" class="input" />
</view>
<view class="form-item-one box-cont" @click="editable && showRegionPicker()">
<view class="label-wrapper">
<text class="label required">注册地区</text>
</view>
<view class="picker-content">
<text :class="displayData.uscc_dependency ? 'picker-value' : 'placeholder'">
{{ displayData.uscc_dependency || '请选择' }}
</text>
<image src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/dccc4513-377c-4bfa-9fd2-a5cfdb9798f3"
class="arrow-right" mode="aspectFit"></image>
</view>
</view>
<view class="form-item-one box-cont" @click="editable && getAddressInfo()">
<view class="label-wrapper">
<text class="label required">注册详细地址</text>
</view>
<view class="picker-content">
<text :class="displayData.uscc_address ? 'picker-value' : 'placeholder'">
{{ displayData.uscc_address || '请选择' }}
</text>
<image src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/dccc4513-377c-4bfa-9fd2-a5cfdb9798f3"
class="arrow-right" mode="aspectFit"></image>
</view>
</view>
</view>
<!-- 法人信息部分 -->
<view class="section">
<view class="section-title">
<view class="title-bar"></view>
<text>法人信息</text>
</view>
<!-- 身份证照片部分 -->
<view class="section">
<view class="box-cont">
<view class="form-item">
<text class="label required">身份证照片</text>
<view class="upload-tip">请保证图片上的文字清晰、无遮挡、证件边角可见</view>
<view class="idcard-upload-vertical-container">
<!-- 身份证正面 -->
<view class="idcard-upload-vertical-item">
<view class="upload-box" @click="editable && chooseImage('legal_idcard_positive')">
<view class="upload-camera idcard-front">
<image v-if="displayData.legal_idcard_positive" :src="displayData.legal_idcard_positive"
mode="aspectFill" class="preview-image"></image>
<image v-else
src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/043b0c97-79c1-4f95-810f-c33e3d5269a3"
mode="aspectFit" class="camera-icon"></image>
</view>
</view>
<text class="upload-label required">请上传身份证正面(人像面)</text>
</view>
<!-- 身份证反面 -->
<view class="idcard-upload-vertical-item">
<view class="upload-box" @click="editable && chooseImage('legal_idcard_negative')">
<view class="upload-camera idcard-back">
<image v-if="displayData.legal_idcard_negative" :src="displayData.legal_idcard_negative"
mode="aspectFill" class="preview-image"></image>
<image v-else
src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/203cfdf4-2501-44e6-8565-ad251c6bf0fa"
mode="aspectFit" class="camera-icon"></image>
</view>
</view>
<text class="upload-label required">请上传身份证反面(国徽面)</text>
</view>
</view>
</view>
</view>
</view>
<view class="form-item-one box-cont">
<view class="label-wrapper">
<text class="label required">法人代表</text>
<image class="label-icon"
src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/25bd7f38-1a3e-4282-84ea-190d7f820108"
mode="aspectFit" @click="showTipPopup('legal_name')"></image>
</view>
<input type="text" v-model="displayData.legal_name" placeholder="请输入营业执照的法人代表" :disabled="!editable"
placeholder-class="placeholder" class="input" />
</view>
<view class="form-item-one box-cont">
<text class="label required">法人联系方式</text>
<input type="number" v-model="displayData.legal_phone" placeholder="请输入法人的联系方式" :disabled="!editable"
placeholder-class="placeholder" class="input" />
</view>
<view class="form-item-one box-cont">
<text class="label required">法人身份证号</text>
<input type="idcard" v-model="displayData.legal_idcard_num" placeholder="请输入法人身份证号" :disabled="!editable"
placeholder-class="placeholder" class="input" />
</view>
<!-- 身份证有效期 -->
<view class="form-item box-cont">
<text class="label required">身份证有效期至</text>
<view class="radio-group">
<view class="radio-item" @click="editable && setIdcardValidType('permanent')">
<view class="radio" :class="{ checked: displayData.legal_idcard_expiry_type === 1 }">
<image v-if="displayData.legal_idcard_expiry_type === 1" src="/static/images/agree_y.png"
class="radio-icon-image" mode="aspectFit"></image>
</view>
<text class="radio-label">长久有效</text>
</view>
<view class="radio-item" @click="editable && setIdcardValidType('date')">
<view class="radio" :class="{ checked: displayData.legal_idcard_expiry_type === 2 }">
<image v-if="displayData.legal_idcard_expiry_type === 2" src="/static/images/agree_y.png"
class="radio-icon-image" mode="aspectFit"></image>
</view>
<text class="radio-label">指定日期有效</text>
</view>
</view>
</view>
<!-- 身份证有效期日期选择 -->
<view class="box-cont">
<view class="date-range-container">
<view class="date-item">
<text class="date-label">开始日期</text>
<view class="date-picker-box" @click="editable && openDatePicker('idcard_start_date')">
<text :class="displayData.idcard_start_date ? 'date-value' : 'placeholder'">
{{ formatDateForDisplay(displayData.idcard_start_date) || '请选择日期' }}
</text>
<view class="date-divider"></view>
<image
src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/ce52b49f-2261-49ca-96ed-e9ad47049649"
class="date-arrow" mode="aspectFit"></image>
</view>
</view>
<view class="date-item">
<text class="date-label">结束日期</text>
<view class="date-picker-box" :class="{ disabled: displayData.legal_idcard_expiry_type === 1 }"
@click="editable && displayData.legal_idcard_expiry_type !== 1 && openDatePicker('idcard_end_date')">
<text :class="displayData.idcard_end_date ? 'date-value' : 'placeholder'">
{{ formatDateForDisplay(displayData.idcard_end_date) || '请选择日期' }}
</text>
<view class="date-divider"></view>
<image :src="displayData.legal_idcard_expiry_type === 1 ?
'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/bb9a757f-a36c-46bb-a59f-2caddac5365b' :
'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/ce52b49f-2261-49ca-96ed-e9ad47049649'"
class="date-arrow" mode="aspectFit"></image>
</view>
</view>
</view>
</view>
</view>
<!-- 其他信息部分 -->
<view class="section">
<view class="section-title">
<view class="title-bar"></view>
<text class="title-text">其他信息</text>
</view>
<view class="form-item-image-box box-cont">
<text class="label required">行业资质</text>
<view class="image-list">
<view class="image-item" v-for="(img, index) in displayData.qualifications_sector"
:key="'industry-' + index">
<image :src="img" mode="aspectFill" class="qualification-image"></image>
<view class="image-delete" v-if="editable" @click="removeImage('qualifications_sector', index)">×</view>
</view>
<view class="image-add" @click="editable && chooseMultiImage('qualifications_sector')"
v-if="(displayData.qualifications_sector || []).length < 9">
<image
src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/0d4af728-c7bf-447d-85b2-e7c682471b86.png"
mode="aspectFit" class="upload-icon-small"></image>
<text class="add-text">添加照片</text>
</view>
</view>
<text class="label" style="margin-top: 30rpx;">其他资质</text>
<view class="image-list">
<view class="image-item" v-for="(img, index) in displayData.qualifications_other" :key="'other-' + index">
<image :src="img" mode="aspectFill" class="qualification-image"></image>
<view class="image-delete" v-if="editable" @click="removeImage('qualifications_other', index)">×</view>
</view>
<view class="image-add" @click="editable && chooseMultiImage('qualifications_other')"
v-if="(displayData.qualifications_other || []).length < 9">
<image
src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/0d4af728-c7bf-447d-85b2-e7c682471b86.png"
mode="aspectFit" class="upload-icon-small"></image>
<text class="add-text">添加照片</text>
</view>
</view>
</view>
</view>
<!-- 底部安全间距 -->
<view class="safe-bottom"></view>
</view>
<!-- 底部按钮区域 -->
<view class="bottom-actions" ref="buttonArea">
<!-- 驳回原因提示 -->
<view class="reject-reason" v-if="shouldShowRejectReason">
<view class="reject-title">您的变更申请已被驳回</view>
<view class="reject-detail">驳回原因:{{ backText }}</view>
</view>
<!-- 审核中提示 -->
<view class="audit-tip" v-if="showAuditTip">
<text class="audit-text">您的提交变更正在审核中...</text>
</view>
<!-- 变更信息按钮 -->
<view class="action-btn change-info-btn" v-if="buttonType === 'change'" @click="startChange">
<text class="btn-text">变更信息</text>
</view>
<!-- 取消和提交按钮 -->
<view class="action-buttons-row" v-if="buttonType === 'edit'">
<view class="action-btn cancel-btn" @click="cancelChange">
<text class="btn-text cancel-text">取消</text>
</view>
<view class="action-btn submit-btn" @click="submitChange">
<text class="btn-text">提交</text>
</view>
</view>
<!-- 查看我的变更/返回按钮 -->
<view class="action-btn view-change-btn" v-if="buttonType === 'view'" @click="togglePendingData">
<text class="btn-text">{{ showPendingData ? '返回' : '查看我的变更' }}</text>
</view>
<!-- 重新提交按钮 -->
<view class="action-btn resubmit-btn" v-if="buttonType === 'reject'" @click="startChange">
<text class="btn-text">重新提交</text>
</view>
</view>
<!-- 商户类型选择器 -->
<view class="popup" :class="{ show: showMerchantTypePickerFlag }">
<view class="popup-mask" @click="hideMerchantTypePicker"></view>
<view class="popup-content">
<view class="popup-header">
<text class="popup-title">选择商户类型</text>
<text class="popup-close" @click="hideMerchantTypePicker">×</text>
</view>
<view class="popup-body">
<view class="radio-list">
<view class="radio-item" v-for="(item, index) in merchantTypeList" :key="index"
@click="selectMerchantType(item)">
<view class="radio" :class="{ checked: displayData.uscc_type === item.value }">
<image v-if="displayData.uscc_type === item.value" src="/static/images/agree_y.png"
class="radio-icon-image" mode="aspectFit"></image>
</view>
<text class="radio-label">{{ item.label }}</text>
</view>
</view>
</view>
<view class="popup-footer">
<view class="popup-btn confirm" @click="confirmMerchantType">
<text class="btn-text">确定</text>
</view>
</view>
</view>
</view>
<!-- 日期选择器 -->
<view class="popup" :class="{ show: showDatePickerFlag }">
<view class="popup-mask" @click="hideDatePicker"></view>
<view class="popup-content">
<view class="popup-header">
<text class="cancel-text" @click="hideDatePicker">取消</text>
<text class="title">选择日期</text>
<text class="confirm-text" @click="confirmDate">确定</text>
</view>
<view class="region-body">
<picker-view :value="dateValue" @change="bindDateChange" class="picker-scroll"
:indicator-style="indicatorStyle" mode="date" fields="day">
<picker-view-column>
<view class="picker-item" v-for="(year, index) in years" :key="index">{{ year }}年</view>
</picker-view-column>
<picker-view-column>
<view class="picker-item" v-for="(month, index) in months" :key="index">{{ month }}月</view>
</picker-view-column>
<picker-view-column>
<view class="picker-item" v-for="(day, index) in days" :key="index">{{ day }}日</view>
</picker-view-column>
</picker-view>
</view>
</view>
</view>
<!-- 提示信息弹窗 -->
<view class="tip-popup" :class="{ show: showTipPopupFlag }">
<view class="tip-popup-mask" @click="hideTipPopup"></view>
<view class="tip-popup-content">
<!-- 弹窗背景图片 -->
<image class="tip-popup-bg"
src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/ab410a5d-5819-47f2-a0fc-3fd6b90d6770"
mode="aspectFit"></image>
<!-- 弹窗内容 -->
<view class="tip-popup-body">
<view class="tip-title">{{ tipTitle }}</view>
<view class="tip-image-container">
<image class="tip-image" :src="tipImage" mode="widthFix"></image>
</view>
<view class="tip-buttons">
<view class="tip-btn cancel" @click="hideTipPopup">
<text class="btn-text">取消</text>
</view>
<view class="tip-btn confirm" @click="hideTipPopup">
<text class="btn-text">我已了解</text>
</view>
</view>
</view>
</view>
</view>
<!-- 注册地区选择器 -->
<view class="popup" :class="{ show: showRegionPopupFlag }">
<view class="popup-mask" @click="hideRegionPopup"></view>
<view class="popup-content">
<view class="popup-header">
<text class="popup-title">选择注册地区</text>
<text class="popup-close" @click="hideRegionPopup">×</text>
</view>
<view class="region-body">
<picker-view @change="bindChangeRegion" class="picker-scroll" :indicator-style="indicatorStyle"
:value="regionValue">
<picker-view-column>
<view class="picker-item" v-for="(item, index) in ChinaCitys" :key="index">
{{ item.province }}
</view>
</picker-view-column>
<picker-view-column>
<view class="picker-item" v-for="(item, index) in regionCitys" :key="index">
{{ item.city }}
</view>
</picker-view-column>
<picker-view-column>
<view class="picker-item" v-for="(item, index) in regionAreas" :key="index">
{{ item.area }}
</view>
</picker-view-column>
</picker-view>
</view>
<view class="popup-footer">
<view class="popup-btn cancel" @click="hideRegionPopup">
<text class="btn-text">取消</text>
</view>
<view class="popup-btn confirm" @click="confirmRegionSelect">
<text class="btn-text">确定</text>
</view>
</view>
</view>
</view>
<!-- 存储权限提示 -->
<view class="permission" :class="{ transform: isShowStoragePer }">
<view class="per-tit">美融融plus 对储存空间/照片权限申请说明</view>
<view class="per-cont">便于您使用该功能上传您的照片/图片/视频以及用于更换头像发布商品等场景中读取相册和文件内容</view>
</view>
<!-- 相机权限提示 -->
<view class="permission" :class="{ transform: isShowCameraPer }">
<view class="per-tit">美融融plus 对相机拍摄权限申请说明</view>
<view class="per-cont">便于您使用该功能上传您的照片/图片/视频以及用于更换头像发布商品等场景中所需内容</view>
</view>
</view>
</template>
<script>
import request from '../../utils/request';
import { debounce } from '@/utils/debounce.js';
import uploadImage from '../../utils/uploadImage';
import permissionUtils from '../../utils/per';
import locationService from '../../utils/locationService';
import { recognizeIdCard, recognizeBusinessLicense, formatDateFromNumber, parseValidPeriod } from '../../utils/orc';
import ChinaCitys from '../../static/data/ChinaCitys.json';
export default {
data() {
const currentDate = new Date();
const currentYear = new Date().getFullYear();
const years = Array.from({ length: 130 }, (_, i) => 1970 + i);
const months = Array.from({ length: 12 }, (_, i) => i + 1);
const days = Array.from({ length: 31 }, (_, i) => i + 1);
return {
// 页面状态
editable: false,
buttonType: 'change',
showAuditTip: false,
auditStatus: null,
applyId: null,
showPendingData: false,
navTitle: '资质信息变更',
buttonAreaHeight: 120,
backText: '',
hasResubmitted: false,
// 数据管理
originalData: {},
pendingData: {},
displayData: {},
userId: null,
applyType: 4,
identity: null,
// UI状态
showMerchantTypePickerFlag: false,
showDatePickerFlag: false,
showTipPopupFlag: false,
currentDateField: '',
merchantTypeList: [
{ label: '个体工商户营业执照', value: '个体工商户营业执照' },
{ label: '企业法人营业执照', value: '企业法人营业执照' },
],
years,
months,
days,
dateValue: [currentYear - 1970, currentDate.getMonth(), currentDate.getDate() - 1],
indicatorStyle: 'height: 68rpx;',
tipTitle: '',
tipImage: '',
// 识别状态
isRecognizing: false,
recognizeType: '', // 'idcard_front', 'idcard_back', 'business_license'
isShowStoragePer: false,
isShowCameraPer: false,
showRegionPopupFlag: false,
ChinaCitys: ChinaCitys,
regionCitys: [],
regionAreas: [],
regionValue: [0, 0, 0],
addressListener: null,
sjAddressListener: null,
}
},
computed: {
shouldShowRejectReason() {
return this.auditStatus === 3 && !this.showPendingData && this.backText;
}
},
onLoad(options) {
console.log('资质信息变更页面开始加载...');
this.identity = getApp().globalData.artisanType;
this.hasResubmitted = false;
this.backText = '';
this.regionCitys = this.ChinaCitys[0].citys;
this.regionAreas = this.regionCitys[0].areas;
this.setupAddressListener();
this.getUserInfo().then(() => {
this.loadApplyDetails();
});
},
onReady() {
this.getButtonAreaHeight();
},
onShow() {
this.checkAddressData();
if (!this.editable) {
this.loadApplyDetails();
if (this.auditStatus !== 3) {
this.backText = '';
this.hasResubmitted = false;
}
}
},
onUnload() {
this.removeAddressListener();
},
methods: {
/**
* 识别营业执照
*/
async recognizeBusinessLicense(imageUrl) {
try {
this.isRecognizing = true;
this.recognizeType = 'business_license';
// 调用OCR接口
const result = await recognizeBusinessLicense(imageUrl);
console.log('营业执照识别结果:', result);
const hasRecognizedData = this.checkBusinessLicenseRecognition(result);
if (!hasRecognizedData) {
uni.showToast({
title: '未识别到营业执照信息,请手动填写或重新拍摄',
icon: 'none',
duration: 3000
});
this.isRecognizing = false;
return;
}
// 填充营业执照信息
let recognizedFields = 0;
// 企业名称:如果识别结果为"无",就设置为空字符串
if (result.uscc_name && result.uscc_name.trim() && result.uscc_name !== '无') {
this.displayData.uscc_name = result.uscc_name;
recognizedFields++;
} else {
// 如果是"无"或空值,设置为空字符串
this.displayData.uscc_name = '';
}
if (result.uscc_num && result.uscc_num.trim()) {
this.displayData.uscc_num = result.uscc_num;
recognizedFields++;
}
// if (result.legal_name && result.legal_name.trim()) {
// this.displayData.legal_name = result.legal_name;
// recognizedFields++;
// }
if (result.uscc_type && result.uscc_type.trim()) {
// 直接使用OCR识别的商户类型字符串
this.displayData.uscc_type = result.uscc_type.trim();
recognizedFields++;
}
// 根据识别的字段数量给出不同的提示
if (recognizedFields > 0) {
} else {
uni.showToast({
title: '识别完成,但未获取到有效信息',
icon: 'none',
duration: 3000
});
}
} catch (error) {
uni.showToast({
title: error.message || '识别失败,请手动填写',
icon: 'none',
});
console.error('营业执照识别失败:', error);
} finally {
this.isRecognizing = false;
}
},
// 检查营业执照识别结果是否有效
checkBusinessLicenseRecognition(result) {
const requiredFields = ['uscc_num', 'uscc_name', 'legal_name', 'uscc_type'];
for (const field of requiredFields) {
if (result[field] && result[field].trim()) {
return true;
}
}
return false;
},
/**
* 识别身份证正面
*/
async recognizeIdCardFront(imageUrl) {
try {
this.isRecognizing = true;
this.recognizeType = 'idcard_front';
uni.showLoading({
title: '正在识别身份证正面...',
mask: true
});
// 调用OCR接口
const result = await recognizeIdCard(imageUrl, 1);
// 验证是否真的识别到了数据
const hasRecognizedData = this.checkIdCardFrontRecognition(result);
if (!hasRecognizedData) {
uni.hideLoading();
uni.showToast({
title: '未识别到身份证信息,请手动填写或重新拍摄',
icon: 'none',
duration: 3000
});
this.isRecognizing = false;
return;
}
// 填充身份证正面信息
if (result.name) {
this.displayData.legal_name = result.name;
}
if (result.id_number) {
this.displayData.legal_idcard_num = result.id_number;
}
uni.hideLoading();
uni.showToast({
title: '身份证正面识别成功',
icon: 'none'
});
} catch (error) {
console.error('身份证正面识别失败:', error);
uni.hideLoading();
uni.showToast({
title: error.message || '识别失败,请手动填写',
icon: 'none',
duration: 3000
});
} finally {
this.isRecognizing = false;
}
},
// 检查身份证正面识别结果是否有效
checkIdCardFrontRecognition(result) {
return (result.name && result.name.trim()) || (result.id_number && result.id_number.trim());
},
/**
* 识别身份证反面
*/
async recognizeIdCardBack(imageUrl) {
try {
this.isRecognizing = true;
this.recognizeType = 'idcard_back';
uni.showLoading({
title: '正在识别身份证反面...',
mask: true
});
// 调用OCR接口
const result = await recognizeIdCard(imageUrl, 2);
// 验证是否真的识别到了数据
const hasRecognizedData = this.checkIdCardBackRecognition(result);
if (!hasRecognizedData) {
uni.hideLoading();
uni.showToast({
title: '未识别到身份证有效期信息,请手动填写或重新拍摄',
icon: 'none',
duration: 3000
});
this.isRecognizing = false;
return;
}
// 解析有效期
const validPeriod = parseValidPeriod(result.start_date, result.end_date);
// 填充有效期数据
if (validPeriod.startDate) {
this.displayData.idcard_start_date = validPeriod.startDate;
}
if (validPeriod.isPermanent) {
this.displayData.legal_idcard_expiry_type = 1;
this.displayData.idcard_end_date = '长久有效';
} else if (validPeriod.endDate) {
this.displayData.legal_idcard_expiry_type = 2;
this.displayData.idcard_end_date = validPeriod.endDate;
}
// 如果是长期有效,自动选择对应的选项
if (validPeriod.isPermanent) {
this.setIdcardValidType('permanent');
} else {
this.setIdcardValidType('date');
}
uni.hideLoading();
uni.showToast({
title: '身份证反面识别成功',
icon: 'none'
});
} catch (error) {
console.error('身份证反面识别失败:', error);
uni.hideLoading();
uni.showToast({
title: error.message || '识别失败,请手动填写',
icon: 'none',
duration: 3000
});
} finally {
this.isRecognizing = false;
}
},
// 检查身份证反面识别结果是否有效
checkIdCardBackRecognition(result) {
return (result.start_date && result.start_date.trim()) ||
(result.end_date && result.end_date.trim());
},
// 获取商户类型文本
getMerchantTypeText(type) {
const merchantType = this.merchantTypeList.find(item => item.value === type);
return merchantType ? merchantType.label : '';
},
// 获取用户信息
getUserInfo() {
return new Promise((resolve, reject) => {
const userType = 3;
request.post('/sj/user/getUser', { type: userType }).then(result => {
if (result.state === 1) {
this.userId = result.data.id;
console.log('用户ID获取成功:', this.userId);
this.populateFormDataFromUserInfo(result.data);
resolve(this.userId);
} else {
console.error('获取用户信息失败:', result.msg);
reject(result.msg);
}
}).catch(error => {
console.error('获取用户信息接口错误:', error);
reject(error);
});
});
},
// 从用户信息中填充表单数据
populateFormDataFromUserInfo(userData) {
console.log('从用户信息填充表单数据:', userData);
// 初始化老数据
this.originalData = {
uscc_type: userData.uscc_type ? String(userData.uscc_type) : null,
uscc_photo: userData.uscc_photo || '',
uscc_num: userData.uscc_num || '',
uscc_name: userData.uscc_name || '',
uscc_dependency: userData.uscc_dependency || '',
uscc_address: userData.uscc_address || '',
uscc_province: userData.uscc_province || '',
uscc_city: userData.uscc_city || '',
uscc_area: userData.uscc_area || '',
longitude: userData.longitude || '',
latitude: userData.latitude || '',
uscc_expiry_type: userData.uscc_expiry_type || null,
uscc_expiry: userData.uscc_expiry || '',
license_start_date: '',
license_end_date: '',
legal_name: userData.legal_name || '',
legal_phone: userData.legal_phone || '',
legal_idcard_num: userData.legal_idcard_num || '',
legal_idcard_expiry_type: userData.legal_idcard_expiry_type || null,
legal_idcard_expiry: userData.legal_idcard_expiry || '',
idcard_start_date: '',
idcard_end_date: '',
legal_idcard_positive: userData.legal_idcard_positive || '',
legal_idcard_negative: userData.legal_idcard_negative || '',
qualifications_sector: [],
qualifications_other: []
};
if (userData.qualifications_sector) {
try {
this.originalData.qualifications_sector = typeof userData.qualifications_sector === 'string' ? JSON.parse(userData.qualifications_sector) : userData.qualifications_sector;
} catch (e) {
this.originalData.qualifications_sector = [];
}
}
if (userData.qualifications_other) {
try {
this.originalData.qualifications_other = typeof userData.qualifications_other === 'string' ? JSON.parse(userData.qualifications_other) : userData.qualifications_other;
} catch (e) {
this.originalData.qualifications_other = [];
}
}
if (this.originalData.uscc_expiry) {
this.processLicenseExpiry(this.originalData.uscc_expiry, this.originalData);
}
if (this.originalData.legal_idcard_expiry) {
this.processIdcardExpiry(this.originalData.legal_idcard_expiry, this.originalData);
}
// 初始化pendingData和displayData
this.pendingData = { ...this.originalData };
this.displayData = { ...this.originalData };
console.log('数据初始化完成:', {
originalData: this.originalData,
pendingData: this.pendingData,
displayData: this.displayData
});
},
// 处理营业执照有效期
processLicenseExpiry(expiry, targetData) {
if (!expiry) return;
console.log('处理营业执照有效期:', expiry);
// 处理多种可能的分隔符
if (expiry.includes('——') || expiry.includes('--') || expiry.includes('-')) {
const separator = expiry.includes('——') ? '——' : (expiry.includes('--') ? '--' : '-');
const [startStr, endStr] = expiry.split(separator);
const startDate = startStr.trim();
const endDate = endStr.trim();
console.log('营业执照开始日期:', startDate, '结束日期:', endDate);
if (endDate === '长久' || !endDate) {
targetData.uscc_expiry_type = 1;
targetData.license_start_date = this.formatDateFromBackend(startDate);
targetData.license_end_date = '长久有效';
} else {
targetData.uscc_expiry_type = 2;
targetData.license_start_date = this.formatDateFromBackend(startDate);
targetData.license_end_date = this.formatDateFromBackend(endDate);
}
} else if (expiry === '长久' || expiry === '长久有效') {
targetData.uscc_expiry_type = 1;
targetData.license_end_date = '长久有效';
}
},
// 处理身份证有效期
processIdcardExpiry(expiry, targetData) {
if (!expiry) return;
console.log('处理身份证有效期:', expiry);
// 处理多种可能的分隔符
if (expiry.includes('——') || expiry.includes('--') || expiry.includes('-')) {
const separator = expiry.includes('——') ? '——' : (expiry.includes('--') ? '--' : '-');
const [startStr, endStr] = expiry.split(separator);
const startDate = startStr.trim();
const endDate = endStr.trim();
console.log('身份证开始日期:', startDate, '结束日期:', endDate);
if (endDate === '长久' || !endDate) {
targetData.legal_idcard_expiry_type = 1;
targetData.idcard_start_date = this.formatDateFromBackend(startDate);
targetData.idcard_end_date = '长久有效';
} else {
targetData.legal_idcard_expiry_type = 2;
targetData.idcard_start_date = this.formatDateFromBackend(startDate);
targetData.idcard_end_date = this.formatDateFromBackend(endDate);
}
} else if (expiry === '长久' || expiry === '长久有效') {
targetData.legal_idcard_expiry_type = 1;
targetData.idcard_end_date = '长久有效';
}
},
// 从后端格式转换日期
formatDateFromBackend(dateStr) {
if (!dateStr) return '';
if (dateStr.includes('-')) {
const [year, month, day] = dateStr.split('-');
return `${year}${parseInt(month)}${parseInt(day)}`;
}
return dateStr;
},
// 加载申请详情
async loadApplyDetails() {
try {
console.log('开始加载资质信息申请详情...');
const res = await request.post('/sj/userSjAuth/details', {
apply_type: this.applyType
});
console.log('资质信息申请详情接口返回:', res);
if (res.code === 200) {
if (res.data) {
const detail = res.data;
console.log('找到申请记录:', detail);
const statusCheck = this.intelligentStatusCheck(detail);
if (statusCheck.isValid) {
this.applyId = detail.id;
this.auditStatus = statusCheck.status;
this.backText = statusCheck.backText;
console.log('申请记录状态:', {
auditStatus: this.auditStatus,
backText: this.backText
});
if (this.auditStatus === 2) {
console.log('审核通过,强制清除驳回相关状态');
this.backText = '';
this.hasResubmitted = false;
}
this.updatePendingDataFromDetail(detail);
if (this.auditStatus === 2) {
this.originalData = { ...this.pendingData };
console.log('审核通过同步originalData到pendingData');
}
console.log('当前数据状态:', {
originalData: this.originalData,
pendingData: this.pendingData,
displayData: this.displayData
});
} else {
this.auditStatus = null;
this.backText = '';
this.applyId = null;
}
} else {
console.log('没有申请记录');
this.auditStatus = null;
this.backText = '';
this.applyId = null;
}
} else {
console.log('申请详情返回code不为200:', res);
this.auditStatus = null;
this.backText = '';
this.applyId = null;
}
await this.refreshUserData();
this.updatePageStatus();
} catch (error) {
console.error('加载申请详情失败:', error);
this.backText = '';
await this.refreshUserData();
this.updatePageStatus();
}
},
// 从申请记录详情更新 pendingData
updatePendingDataFromDetail(detail) {
console.log('从申请记录更新pendingData:', detail);
this.pendingData = {
uscc_type: detail.uscc_type ? String(detail.uscc_type) : this.originalData.uscc_type,
uscc_photo: detail.uscc_photo || this.originalData.uscc_photo,
uscc_num: detail.uscc_num || this.originalData.uscc_num,
uscc_name: detail.uscc_name || this.originalData.uscc_name,
uscc_dependency: detail.uscc_dependency || this.originalData.uscc_dependency,
uscc_address: detail.uscc_address || this.originalData.uscc_address,
uscc_province: detail.uscc_province || this.originalData.uscc_province,
uscc_city: detail.uscc_city || this.originalData.uscc_city,
uscc_area: detail.uscc_area || this.originalData.uscc_area,
longitude: detail.longitude || this.originalData.longitude || '',
latitude: detail.latitude || this.originalData.latitude || '',
uscc_expiry_type: detail.uscc_expiry_type || this.originalData.uscc_expiry_type,
uscc_expiry: detail.uscc_expiry || this.originalData.uscc_expiry,
license_start_date: '',
license_end_date: '',
legal_name: detail.legal_name || this.originalData.legal_name,
legal_phone: detail.legal_phone || this.originalData.legal_phone,
legal_idcard_num: detail.legal_idcard_num || this.originalData.legal_idcard_num,
legal_idcard_expiry_type: detail.legal_idcard_expiry_type || this.originalData.legal_idcard_expiry_type,
legal_idcard_expiry: detail.legal_idcard_expiry || this.originalData.legal_idcard_expiry,
idcard_start_date: '',
idcard_end_date: '',
legal_idcard_positive: detail.legal_idcard_positive || this.originalData.legal_idcard_positive,
legal_idcard_negative: detail.legal_idcard_negative || this.originalData.legal_idcard_negative,
qualifications_sector: this.originalData.qualifications_sector || [],
qualifications_other: this.originalData.qualifications_other || []
};
if (detail.qualifications_sector) {
try {
this.pendingData.qualifications_sector = typeof detail.qualifications_sector === 'string' ? JSON.parse(detail.qualifications_sector) : detail.qualifications_sector;
} catch (e) {
this.pendingData.qualifications_sector = this.originalData.qualifications_sector || [];
}
}
if (detail.qualifications_other) {
try {
this.pendingData.qualifications_other = typeof detail.qualifications_other === 'string' ? JSON.parse(detail.qualifications_other) : detail.qualifications_other;
} catch (e) {
this.pendingData.qualifications_other = this.originalData.qualifications_other || [];
}
}
console.log('处理前的pendingData日期字段:', {
uscc_expiry: this.pendingData.uscc_expiry,
legal_idcard_expiry: this.pendingData.legal_idcard_expiry
});
// 处理营业执照有效期显示
if (this.pendingData.uscc_expiry) {
this.processLicenseExpiry(this.pendingData.uscc_expiry, this.pendingData);
}
// 处理身份证有效期显示
if (this.pendingData.legal_idcard_expiry) {
this.processIdcardExpiry(this.pendingData.legal_idcard_expiry, this.pendingData);
}
console.log('更新后的pendingData:', this.pendingData);
},
// 刷新用户数据
async refreshUserData() {
try {
console.log('刷新商家最新数据...');
const userType = 3;
const result = await request.post('/sj/user/getUser', { type: userType });
if (result.state === 1 && result.data) {
const userData = result.data;
console.log('获取到商家最新数据:', userData);
this.updateOriginalDataFromUser(userData);
// 只有在审核通过时才同步 pendingData 到 originalData
if (this.auditStatus === 2) {
this.pendingData = { ...this.originalData };
console.log('审核通过状态同步pendingData到originalData');
} else {
console.log('非审核通过状态保持pendingData不变');
}
console.log('刷新后的数据状态:', {
originalData: this.originalData,
pendingData: this.pendingData,
auditStatus: this.auditStatus
});
// 重要:根据当前显示状态来设置 displayData
if (this.showPendingData) {
this.displayData = { ...this.pendingData };
console.log('refreshUserData - 更新displayData为pendingData');
} else {
this.displayData = { ...this.originalData };
console.log('refreshUserData - 更新displayData为originalData');
}
}
} catch (error) {
console.error('刷新用户数据失败:', error);
}
},
// 从用户数据更新原始数据
updateOriginalDataFromUser(userData) {
console.log('从用户数据更新原始数据:', userData);
this.originalData = {
uscc_type: userData.uscc_type ? String(userData.uscc_type) : null,
uscc_photo: userData.uscc_photo || '',
uscc_num: userData.uscc_num || '',
uscc_name: userData.uscc_name || '',
uscc_dependency: userData.uscc_dependency || '',
uscc_address: userData.uscc_address || '',
uscc_province: userData.uscc_province || '',
uscc_city: userData.uscc_city || '',
uscc_area: userData.uscc_area || '',
longitude: userData.longitude || '',
latitude: userData.latitude || '',
uscc_expiry_type: userData.uscc_expiry_type || null,
uscc_expiry: userData.uscc_expiry || '',
license_start_date: '',
license_end_date: '',
legal_name: userData.legal_name || '',
legal_phone: userData.legal_phone || '',
legal_idcard_num: userData.legal_idcard_num || '',
legal_idcard_expiry_type: userData.legal_idcard_expiry_type || null,
legal_idcard_expiry: userData.legal_idcard_expiry || '',
idcard_start_date: '',
idcard_end_date: '',
legal_idcard_positive: userData.legal_idcard_positive || '',
legal_idcard_negative: userData.legal_idcard_negative || '',
qualifications_sector: [],
qualifications_other: []
};
if (userData.qualifications_sector) {
try {
this.originalData.qualifications_sector = typeof userData.qualifications_sector === 'string' ? JSON.parse(userData.qualifications_sector) : userData.qualifications_sector;
} catch (e) {
this.originalData.qualifications_sector = [];
}
}
if (userData.qualifications_other) {
try {
this.originalData.qualifications_other = typeof userData.qualifications_other === 'string' ? JSON.parse(userData.qualifications_other) : userData.qualifications_other;
} catch (e) {
this.originalData.qualifications_other = [];
}
}
if (this.originalData.uscc_expiry) {
this.processLicenseExpiry(this.originalData.uscc_expiry, this.originalData);
}
if (this.originalData.legal_idcard_expiry) {
this.processIdcardExpiry(this.originalData.legal_idcard_expiry, this.originalData);
}
},
// 智能判断申请状态
intelligentStatusCheck(detail) {
if (detail.apply_state === 2) {
console.log('智能判断:申请已审核通过,需要刷新用户数据');
this.$nextTick(async () => {
await this.refreshUserData();
this.pendingData = { ...this.originalData };
});
return {
isValid: true,
status: 2,
backText: ''
};
}
if (detail.apply_time) {
const applyDate = new Date(detail.apply_time);
const now = new Date();
const daysDiff = (now - applyDate) / (1000 * 60 * 60 * 24);
if (daysDiff > 7 && this.originalData.uscc_name !== detail.uscc_name) {
console.log('智能判断:申请记录已过期,忽略历史记录');
return {
isValid: false,
status: null,
backText: ''
};
}
}
return {
isValid: true,
status: detail.apply_state,
backText: detail.back_text || ''
};
},
updatePageStatus() {
console.log('更新页面状态,审核状态:', this.auditStatus);
console.log('当前驳回原因:', this.backText);
// 终极保护:在任何非驳回状态下都强制清除驳回原因
if (this.auditStatus !== 3) {
this.backText = '';
console.log('非驳回状态,强制清除驳回原因');
}
// 根据审核状态更新页面
if (this.auditStatus === 1) { // 审核中
this.showAuditTip = true;
this.buttonType = 'view';
this.editable = false;
// 审核中状态,保持当前的 showPendingData 状态
if (this.showPendingData) {
this.displayData = { ...this.pendingData };
} else {
this.displayData = { ...this.originalData };
}
} else if (this.auditStatus === 2) { // 审核通过
this.showAuditTip = false;
this.buttonType = 'change';
this.editable = false;
this.showPendingData = false;
// 审核通过时,确保显示最新的 originalData
this.displayData = { ...this.originalData };
console.log('审核通过,显示最新数据:', this.displayData);
} else if (this.auditStatus === 3) { // 审核驳回
this.showAuditTip = false;
this.buttonType = 'reject';
this.editable = false;
this.showPendingData = false;
this.displayData = { ...this.originalData };
} else { // 无申请
this.showAuditTip = false;
this.buttonType = 'change';
this.editable = false;
this.showPendingData = false;
this.displayData = { ...this.originalData };
}
this.updateNavTitle();
console.log('最终页面状态:', {
auditStatus: this.auditStatus,
backText: this.backText,
buttonType: this.buttonType,
editable: this.editable,
showPendingData: this.showPendingData,
displayData: this.displayData
});
},
// 更新导航栏标题
updateNavTitle() {
if (this.editable || this.showPendingData) {
this.navTitle = '资质信息变更';
} else {
this.navTitle = '资质信息';
}
},
// 开始变更
startChange() {
this.editable = true;
this.buttonType = 'edit';
this.displayData = { ...this.pendingData };
this.updateNavTitle();
},
// 取消变更
cancelChange() {
this.editable = false;
this.buttonType = 'change';
this.displayData = { ...this.originalData };
this.updateNavTitle();
},
// 切换显示待审核数据
togglePendingData() {
this.showPendingData = !this.showPendingData;
console.log('切换显示待审核数据:', this.showPendingData);
if (this.showPendingData) {
// 显示待审核数据
this.displayData = { ...this.pendingData };
console.log('显示pendingData:', this.displayData);
} else {
// 显示原始数据
this.displayData = { ...this.originalData };
console.log('显示originalData:', this.displayData);
}
this.updateNavTitle();
},
// 提交变更
async submitChange() {
console.log('开始提交资质信息变更...');
if (!this.validateForm()) {
return;
}
try {
uni.showLoading({
title: '提交中...'
});
// 身份证姓名验证
const checkRes = await request.post('/user/check', {
name: this.displayData.legal_name,
idcard: this.displayData.legal_idcard_num
});
if (checkRes.Code == '401') {
uni.hideLoading();
uni.showToast({
title: '您的身份证号与姓名不匹配',
icon: 'none'
});
return;
}
if (checkRes.ResultObject?.BizCode != '1') {
uni.hideLoading();
uni.showToast({
title: '您的身份证号与姓名不匹配',
icon: 'none'
});
return;
}
const submitData = {
apply_type: this.applyType,
uscc_type: this.displayData.uscc_type,
uscc_photo: this.displayData.uscc_photo,
uscc_num: this.displayData.uscc_num,
uscc_name: this.displayData.uscc_name,
uscc_dependency: this.displayData.uscc_dependency,
uscc_address: this.displayData.uscc_address,
uscc_province: this.displayData.uscc_province,
uscc_city: this.displayData.uscc_city,
uscc_area: this.displayData.uscc_area,
uscc_expiry_type: this.displayData.uscc_expiry_type,
uscc_expiry: this.displayData.uscc_expiry,
legal_name: this.displayData.legal_name,
legal_phone: this.displayData.legal_phone,
legal_idcard_num: this.displayData.legal_idcard_num,
legal_idcard_expiry_type: this.displayData.legal_idcard_expiry_type,
legal_idcard_expiry: this.displayData.legal_idcard_expiry,
legal_idcard_positive: this.displayData.legal_idcard_positive,
legal_idcard_negative: this.displayData.legal_idcard_negative,
qualifications_sector: JSON.stringify(this.displayData.qualifications_sector || []),
qualifications_other: JSON.stringify(this.displayData.qualifications_other || [])
};
// 处理营业执照有效期
if (this.displayData.uscc_expiry_type === 1) {
submitData.uscc_expiry = '长久';
} else if (this.displayData.uscc_expiry_type === 2) {
const startDate = this.formatDateForBackend(this.displayData.license_start_date);
const endDate = this.formatDateForBackend(this.displayData.license_end_date);
submitData.uscc_expiry = `${startDate} —— ${endDate}`;
}
// 处理身份证有效期
if (this.displayData.legal_idcard_expiry_type === 1) {
submitData.legal_idcard_expiry = '长久';
} else if (this.displayData.legal_idcard_expiry_type === 2) {
const startDate = this.formatDateForBackend(this.displayData.idcard_start_date);
const endDate = this.formatDateForBackend(this.displayData.idcard_end_date);
submitData.legal_idcard_expiry = `${startDate} —— ${endDate}`;
}
console.log('提交的数据:', submitData);
const res = await request.post('/sj/userSjAuth/apply', submitData);
uni.hideLoading();
if (res.code === 200) {
uni.showToast({
title: '提交成功',
icon: 'none'
});
// 先更新 pendingData再设置其他状态
this.pendingData = { ...this.displayData };
console.log('提交成功更新pendingData:', this.pendingData);
this.auditStatus = 1;
this.backText = '';
this.hasResubmitted = true;
this.applyId = res.data?.id || this.applyId;
console.log('申请ID:', this.applyId);
this.editable = false;
this.buttonType = 'view';
this.showAuditTip = true;
this.showPendingData = false;
this.displayData = { ...this.originalData };
this.updateNavTitle();
setTimeout(() => {
this.loadApplyDetails();
}, 1500);
} else {
uni.showToast({
title: res.msg || '提交失败',
icon: 'none'
});
}
} catch (error) {
uni.hideLoading();
console.error('提交失败:', error);
uni.showToast({
title: '网络错误,请重试',
icon: 'none'
});
}
},
showPermissionDialog(title, content) {
return new Promise((resolve) => {
uni.showModal({
title,
content,
confirmText: '去开启',
success(res) {
resolve(res.confirm);
}
});
});
},
showRegionPicker() {
this.regionCitys = this.ChinaCitys[0].citys;
this.regionAreas = this.regionCitys[0].areas;
this.showRegionPopupFlag = true;
},
hideRegionPopup() {
this.showRegionPopupFlag = false;
},
bindChangeRegion(e) {
this.regionValue = e.detail.value;
let index1 = e.detail.value[0] || 0;
let index2 = e.detail.value[1] || 0;
this.regionCitys = this.ChinaCitys[index1].citys;
this.regionAreas = this.regionCitys[index2].areas;
},
confirmRegionSelect() {
let valueArr = this.regionValue;
let index1 = valueArr[0] || 0;
let index2 = valueArr[1] || 0;
let index3 = valueArr[2] || 0;
let province = this.ChinaCitys[index1].province;
let city = this.regionCitys[index2].city;
let area = this.regionAreas[index3].area;
this.$set(this.displayData, 'uscc_dependency', province + '-' + city + '-' + area);
if (this.ChinaCitys[index1] && this.ChinaCitys[index1].code) {
this.$set(this.displayData, 'uscc_province', String(this.ChinaCitys[index1].code).substring(0, 6));
}
if (this.regionCitys[index2] && this.regionCitys[index2].code) {
this.$set(this.displayData, 'uscc_city', String(this.regionCitys[index2].code).substring(0, 6));
}
if (this.regionAreas[index3] && this.regionAreas[index3].code) {
this.$set(this.displayData, 'uscc_area', String(this.regionAreas[index3].code).substring(0, 6));
}
this.$set(this.displayData, 'uscc_address', '');
this.$set(this.displayData, 'longitude', '');
this.$set(this.displayData, 'latitude', '');
this.hideRegionPopup();
},
chooseMultiImage(type) {
const current = this.displayData[type] || [];
const remaining = 9 - current.length;
if (remaining <= 0) {
uni.showToast({ title: '最多上传9张图片', icon: 'none' });
return;
}
uni.chooseImage({
count: remaining,
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success: async (res) => {
if (!res.tempFilePaths || res.tempFilePaths.length === 0) return;
uni.showLoading({ title: '上传中...' });
for (const tempFilePath of res.tempFilePaths) {
const file = { path: tempFilePath, size: 0 };
try {
const url = await this.directUpload(file, this.userId, 3, type);
if (url) {
current.push(url);
}
} catch (e) {
console.error('上传失败:', e);
}
}
this.$set(this.displayData, type, [...current]);
uni.hideLoading();
}
});
},
removeImage(type, index) {
const list = [...(this.displayData[type] || [])];
list.splice(index, 1);
this.$set(this.displayData, type, list);
},
// 表单验证
validateForm() {
const validationRules = [
{ field: 'uscc_photo', message: '请上传营业执照照片' },
{ field: 'uscc_type', message: '请输入商户类型' },
{ field: 'uscc_num', message: '请输入营业执照号码' },
{ field: 'uscc_name', message: '请输入企业名称' },
{ field: 'uscc_dependency', message: '请选择注册地区' },
{ field: 'uscc_address', message: '请输入注册详细地址' },
{ field: 'legal_idcard_positive', message: '请上传身份证正面照片' },
{ field: 'legal_idcard_negative', message: '请上传身份证反面照片' },
{ field: 'legal_name', message: '请输入法人代表' },
{ field: 'legal_phone', message: '请输入法人联系方式' },
{ field: 'legal_idcard_num', message: '请输入法人身份证号' },
{
condition: () => !this.displayData.legal_idcard_expiry_type,
message: '请选择身份证有效期类型'
},
{
condition: () => !this.displayData.idcard_start_date,
message: '请选择身份证开始日期'
},
{
condition: () => {
if (this.displayData.legal_idcard_expiry_type === 2 && !this.displayData.idcard_end_date) {
return true;
}
// 如果选择长久有效,则不需要结束日期
return false;
},
message: '请选择身份证结束日期'
},
];
for (let rule of validationRules) {
let isValid = true;
if (rule.field) {
if (!this.displayData[rule.field]) {
isValid = false;
}
} else if (rule.condition) {
if (rule.condition()) {
isValid = false;
}
}
if (!isValid) {
uni.showToast({
title: rule.message,
icon: 'none'
});
return false;
}
}
// 验证手机号格式
if (!/^1[3-9]\d{9}$/.test(this.displayData.legal_phone)) {
uni.showToast({
title: '请输入正确的手机号码',
icon: 'none'
});
return false;
}
// 验证身份证格式
if (!/(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(this.displayData.legal_idcard_num)) {
uni.showToast({
title: '请输入正确的身份证号码',
icon: 'none'
});
return false;
}
return true;
},
// 获取按钮区域高度
getButtonAreaHeight() {
setTimeout(() => {
const query = uni.createSelectorQuery().in(this);
query.select('.bottom-actions').boundingClientRect(data => {
if (data) {
this.buttonAreaHeight = data.height + 20;
}
}).exec();
}, 100);
},
// 设置营业执照有效期类型
setLicenseValidType(type) {
if (type === 'permanent') {
this.displayData.uscc_expiry_type = 1;
this.displayData.license_end_date = '长久有效';
} else {
this.displayData.uscc_expiry_type = 2;
if (this.displayData.license_end_date === '长久有效') {
this.displayData.license_end_date = '';
}
}
},
// 设置身份证有效期类型
setIdcardValidType(type) {
if (type === 'permanent') {
this.displayData.legal_idcard_expiry_type = 1;
this.displayData.idcard_end_date = '长久有效';
} else {
this.displayData.legal_idcard_expiry_type = 2;
if (this.displayData.idcard_end_date === '长久有效') {
this.displayData.idcard_end_date = '';
}
}
},
// 日期显示格式化
formatDateForDisplay(dateStr) {
if (!dateStr) return '';
if (dateStr === '长久有效') return '长久有效';
if (dateStr.includes('-')) {
const [year, month, day] = dateStr.split('-');
return `${year}${parseInt(month)}${parseInt(day)}`;
}
return dateStr;
},
// 日期转换为后端格式
formatDateForBackend(dateStr) {
if (!dateStr) return '';
if (dateStr === '长久有效') return '';
const match = dateStr.match(/(\d+)年(\d+)月(\d+)日/);
if (match) {
const year = match[1];
const month = match[2].padStart(2, '0');
const day = match[3].padStart(2, '0');
return `${year}-${month}-${day}`;
}
return dateStr;
},
// 打开日期选择器
openDatePicker(field) {
this.currentDateField = field;
const currentDate = new Date();
let initialDate = currentDate;
if (this.displayData[field] && this.displayData[field] !== '长久有效') {
const dateStr = this.displayData[field];
const match = dateStr.match(/(\d+)年(\d+)月(\d+)日/);
if (match) {
initialDate = new Date(parseInt(match[1]), parseInt(match[2]) - 1, parseInt(match[3]));
}
}
const yearIndex = this.years.indexOf(initialDate.getFullYear());
const monthIndex = initialDate.getMonth();
const dayIndex = initialDate.getDate() - 1;
this.dateValue = [
yearIndex >= 0 ? yearIndex : 0,
monthIndex,
dayIndex
];
this.showDatePickerFlag = true;
},
hideDatePicker() {
this.showDatePickerFlag = false;
},
bindDateChange(e) {
this.dateValue = e.detail.value;
},
confirmDate() {
const [yearIndex, monthIndex, dayIndex] = this.dateValue;
const year = this.years[yearIndex];
const month = this.months[monthIndex];
const day = this.days[dayIndex];
const dateStr = `${year}${month}${day}`;
const selectedDate = new Date(year, month - 1, day);
const today = new Date();
today.setHours(0, 0, 0, 0);
if (this.currentDateField.endsWith('_start_date')) {
if (selectedDate > today) {
uni.showToast({
title: '开始日期不能晚于今天',
icon: 'none'
});
return;
}
const relatedEndField = this.currentDateField.replace('_start_date', '_end_date');
if (this.displayData[relatedEndField] && this.displayData[relatedEndField] !== '长久有效') {
const endDateStr = this.displayData[relatedEndField];
const match = endDateStr.match(/(\d+)年(\d+)月(\d+)日/);
if (match) {
const endDate = new Date(parseInt(match[1]), parseInt(match[2]) - 1, parseInt(match[3]));
if (selectedDate > endDate) {
uni.showToast({
title: '开始日期不能晚于结束日期',
icon: 'none'
});
return;
}
}
}
// 如果是身份证开始日期自动计算20年后的结束日期
if (this.currentDateField === 'idcard_start_date') {
const endYear = year + 20;
const endDateStr = `${endYear}${month}${day}`;
this.displayData.idcard_end_date = endDateStr;
}
} else if (this.currentDateField.endsWith('_end_date')) {
const relatedStartField = this.currentDateField.replace('_end_date', '_start_date');
if (this.displayData[relatedStartField]) {
const startDateStr = this.displayData[relatedStartField];
const match = startDateStr.match(/(\d+)年(\d+)月(\d+)日/);
if (match) {
const startDate = new Date(parseInt(match[1]), parseInt(match[2]) - 1, parseInt(match[3]));
if (selectedDate <= startDate) {
uni.showToast({
title: '结束日期必须晚于开始日期',
icon: 'none'
});
return;
}
}
} else {
if (selectedDate < today) {
uni.showToast({
title: '结束日期不能早于今天',
icon: 'none'
});
return;
}
}
}
this.displayData[this.currentDateField] = dateStr;
this.hideDatePicker();
},
// 商户类型选择器相关方法
showMerchantTypePicker() {
this.showMerchantTypePickerFlag = true;
},
hideMerchantTypePicker() {
this.showMerchantTypePickerFlag = false;
},
selectMerchantType(item) {
this.displayData.uscc_type = item.value;
},
confirmMerchantType() {
this.hideMerchantTypePicker();
},
// 提示弹窗相关方法
showTipPopup(field) {
const tipConfig = {
'uscc_num': {
title: '如何找到证件号码',
image: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/72856aac-f0ac-49a1-a7f1-be3220ecb314'
},
'uscc_name': {
title: '如何找到企业名称',
image: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/4fb3e0a2-4c1a-4433-a181-b7a1dfefd030'
},
'legal_name': {
title: '如何找到法人代表',
image: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/24859872-da37-4beb-8e33-7743813bb5a1'
}
};
if (tipConfig[field]) {
this.tipTitle = tipConfig[field].title;
this.tipImage = tipConfig[field].image;
this.showTipPopupFlag = true;
}
},
hideTipPopup() {
this.showTipPopupFlag = false;
},
buildRegionTextForSearch() {
const dependency = String(this.displayData.uscc_dependency || '').trim();
if (!dependency) return '';
const parts = dependency.split('-');
const province = parts[0] || '';
const city = parts[1] || '';
const district = parts[2] || '';
let regionText = '';
if (province) regionText += province;
if (city && city !== province) regionText += city;
if (district) regionText += district;
return regionText;
},
getAddressValueForSearch() {
const rawAddress = String(this.displayData.uscc_address || '').trim();
if (!rawAddress) return '';
const dependencyText = String(this.displayData.uscc_dependency || '').trim();
const regionText = this.buildRegionTextForSearch();
let detail = rawAddress;
if (regionText && detail.indexOf(regionText) === 0) {
detail = detail.slice(regionText.length).trim();
} else if (dependencyText && detail.indexOf(dependencyText) === 0) {
detail = detail.slice(dependencyText.length).trim();
}
detail = detail.replace(/^[\s,-]+/, '').trim();
return detail || rawAddress;
},
getAddressInfo() {
const dependency = String(this.displayData.uscc_dependency || '').trim();
const dependencyCode = String(this.displayData.uscc_area || '').trim();
const address = this.getAddressValueForSearch();
const longitude = String(this.displayData.longitude || '').trim();
const latitude = String(this.displayData.latitude || '').trim();
const hasDependency = !!dependency;
const hasAddress = !!address;
const hasLocation = !!(longitude && latitude);
let params = 'source=sj_change';
if (hasDependency) {
params += `&dependency=${encodeURIComponent(dependency)}`;
if (dependencyCode) {
params += `&dependency_code=${dependencyCode}`;
}
}
if (hasAddress) {
params += `&address=${encodeURIComponent(address)}`;
}
if (hasLocation) {
params += `&longitude=${longitude}&latitude=${latitude}`;
}
if (!hasDependency && !hasAddress && !hasLocation) {
params += '&init_current_location=1&silent_locate=1';
}
uni.navigateTo({
url: `/pages/address/search?${params}`
});
},
setupAddressListener() {
this.addressListener = (addressData) => {
this.handleAddressSelected(addressData);
};
this.sjAddressListener = (addressData) => {
this.handleAddressSelected(addressData);
};
uni.$on('address-selected', this.addressListener);
uni.$on('address-selected-for-sj', this.sjAddressListener);
},
removeAddressListener() {
if (this.addressListener) {
uni.$off('address-selected', this.addressListener);
this.addressListener = null;
}
if (this.sjAddressListener) {
uni.$off('address-selected-for-sj', this.sjAddressListener);
this.sjAddressListener = null;
}
},
checkAddressData() {
try {
const storedAddress = uni.getStorageSync('sj_selected_address');
if (storedAddress) {
this.handleAddressSelected(storedAddress);
uni.removeStorageSync('sj_selected_address');
return;
}
} catch (e) { }
if (getApp().globalData && getApp().globalData.selectedAddress) {
this.handleAddressSelected(getApp().globalData.selectedAddress);
delete getApp().globalData.selectedAddress;
}
try {
const selectedAddress = uni.getStorageSync('selectedAddress');
if (selectedAddress) {
this.handleAddressSelected(selectedAddress);
uni.removeStorageSync('selectedAddress');
}
} catch (e) { }
},
handleAddressSelected(addressData) {
if (!addressData) return;
let detailAddress = '';
if (addressData.address) {
detailAddress = String(addressData.address).trim();
} else if (addressData.name) {
detailAddress = String(addressData.name).trim();
const regionParts = [];
if (addressData.pname) regionParts.push(addressData.pname);
if (addressData.cityname && addressData.cityname !== addressData.pname) regionParts.push(addressData.cityname);
if (addressData.adname) regionParts.push(addressData.adname);
const regionText = regionParts.join('');
if (regionText && detailAddress.indexOf(regionText) === 0) {
detailAddress = detailAddress.slice(regionText.length).trim();
}
detailAddress = detailAddress.replace(/^[\s,-]+/, '').trim();
}
this.$set(this.displayData, 'uscc_address', detailAddress);
if (addressData.location) {
const [longitude, latitude] = String(addressData.location).split(',');
this.$set(this.displayData, 'longitude', longitude || '');
this.$set(this.displayData, 'latitude', latitude || '');
}
if (addressData.pname || addressData.cityname || addressData.adname) {
const locationParts = [];
if (addressData.pname) locationParts.push(addressData.pname);
if (addressData.cityname) locationParts.push(addressData.cityname);
if (addressData.adname) locationParts.push(addressData.adname);
this.$set(this.displayData, 'uscc_dependency', locationParts.join('-'));
}
if (addressData.provinceCode) {
this.$set(this.displayData, 'uscc_province', String(addressData.provinceCode).substring(0, 6));
}
if (addressData.cityCode) {
this.$set(this.displayData, 'uscc_city', String(addressData.cityCode).substring(0, 6));
}
if (addressData.districtCode) {
this.$set(this.displayData, 'uscc_area', String(addressData.districtCode).substring(0, 6));
}
this.$forceUpdate();
},
// 图片上传方法
async chooseImage(type) {
if (!this.editable) return;
const systemInfo = uni.getSystemInfoSync();
const isIOS = systemInfo.platform === 'ios';
// 弹出操作菜单
const res = await new Promise((resolve, reject) => {
uni.showActionSheet({
itemList: ['拍照', '从相册选择'],
success: resolve,
fail: reject
});
}).catch(() => ({ tapIndex: -1 }));
if (res.tapIndex === -1) return; // 用户取消
// 处理拍照
if (res.tapIndex === 0) {
if (isIOS) {
// iOS 直接调用相机(系统自动处理权限)
this._openCamera(type, ['camera']);
} else {
this.isShowCameraPer = true;
const { granted } = await permissionUtils.checkPermission('camera', '需要相机权限以拍照');
if (granted) {
this.isShowCameraPer = false;
this._openCamera(type, ['camera']);
return;
}
this.isShowCameraPer = false;
const confirm = await this.showPermissionDialog('相机权限申请', '我们需要访问您的相机权限,以便您拍照上传资质照片');
if (!confirm) return;
const result = await permissionUtils.requestPermission('camera', '需要相机权限以拍照');
if (result) {
this._openCamera(type, ['camera']);
} else {
locationService.openAppSettings();
}
}
}
// 处理从相册选择
else if (res.tapIndex === 1) {
if (isIOS) {
this._openCamera(type, ['album']);
} else {
this.isShowStoragePer = true;
const { granted } = await permissionUtils.checkPermission('photo_library', '需要存储权限以选择照片');
if (granted) {
this.isShowStoragePer = false;
this._openCamera(type, ['album']);
return;
}
this.isShowStoragePer = false;
const confirm = await this.showPermissionDialog('存储权限申请', '我们需要访问您的相册权限,以便您上传资质照片');
if (!confirm) return;
const result = await permissionUtils.requestPermission('photo_library', '需要存储权限以选择照片');
if (result) {
this._openCamera(type, ['album']);
} else {
locationService.openAppSettings();
}
}
}
},
// 实际打开相机/相册并上传
async _openCamera(type, sourceType) {
try {
if (!this.userId) {
console.log('重新获取用户信息...');
await this.getUserInfo();
}
const chooseResult = await new Promise((resolve, reject) => {
uni.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: sourceType, // 使用传入的 sourceType
success: resolve,
fail: reject
});
});
if (!chooseResult.tempFilePaths || chooseResult.tempFilePaths.length === 0) {
uni.hideLoading();
return;
}
const tempFilePath = chooseResult.tempFilePaths[0];
const file = { path: tempFilePath, size: 0 };
console.log('_openCamera - 开始上传图片,字段类型:', type, '用户ID:', this.userId);
const result = await this.directUpload(file, this.userId, 3, type);
uni.hideLoading();
if (result) {
this.displayData[type] = result;
// 上传成功后自动识别
if (type === 'uscc_photo') {
await this.recognizeBusinessLicense(result);
} else if (type === 'legal_idcard_positive') {
await this.recognizeIdCardFront(result);
} else if (type === 'legal_idcard_negative') {
await this.recognizeIdCardBack(result);
}
}
} catch (err) {
uni.hideLoading();
console.log('上传图片错误:', err);
if (!err.errMsg || !err.errMsg.includes('cancel')) {
uni.showToast({
title: '上传失败,请重试',
icon: 'none'
});
}
}
},
// 直接上传方法
async directUpload(file, userId, type, fieldName) {
try {
console.log('directUpload - 开始上传,参数:', { userId, type, fieldName });
let artisan = type == 1 ? 'yh' : type == 2 ? 'syr' : type == 3 ? 'sj' : '';
console.log('directUpload - artisan类型:', artisan, '原始type:', type);
let fileExtension = 'jpg';
if (file.path.includes('.')) {
let parts = file.path.split('.');
let ext = parts[parts.length - 1].toLowerCase();
if (ext && ext.length <= 4) {
fileExtension = ext;
}
}
// 添加时间戳确保文件名唯一
const timestamp = Date.now();
const random = Math.floor(Math.random() * 10000);
let name = `${userId}_${artisan}_${fieldName}_${timestamp}_${random}.${fileExtension}`;
console.log('唯一文件名(包含时间戳):', name);
const ossConfig = await request.post('/user/getalioss', { type: type, kind: 1 });
return await new Promise((resolve, reject) => {
uni.uploadFile({
url: ossConfig.host,
filePath: file.path,
name: 'file',
formData: {
key: ossConfig.dir + name,
policy: ossConfig.policy,
OSSAccessKeyId: ossConfig.ossAccessKeyId,
success_action_status: '200',
signature: ossConfig.signature
},
success: (res) => {
if (res.statusCode === 200) {
const fileUrl = `${ossConfig.host}/${ossConfig.dir}${name}`;
console.log('上传成功新文件URL:', fileUrl);
resolve(fileUrl);
} else {
reject(new Error('上传失败'));
}
},
fail: reject
});
});
} catch (error) {
console.error('直接上传失败:', error);
throw error;
}
}
}
}
</script>
<style scoped>
.qualification-page {
display: flex;
flex-direction: column;
height: 100vh;
background: #f5f5f5;
}
.content-area {
flex: 1;
overflow-y: auto;
padding: 20rpx 20rpx;
padding-bottom: 0;
}
/* 变更提示 */
.change-tip {
background: #FAE7EC;
padding: 20rpx;
text-align: center;
}
.change-tip text {
font-size: 28rpx;
color: #D4131F;
}
/* 审核中提示 */
.audit-tip {
margin: 20rpx 24rpx 20rpx 24rpx;
border-radius: 12rpx;
}
.audit-text {
font-weight: 400;
font-size: 32rpx;
color: #333333;
text-align: center;
display: block;
}
/* 驳回原因样式 */
.reject-reason {
background: transparent;
padding: 24rpx 24rpx 0 24rpx;
}
.reject-title {
font-family: PingFangSC, PingFang SC;
font-weight: 500;
font-size: 32rpx;
color: #333333;
line-height: 45rpx;
text-align: center;
font-style: normal;
}
.reject-detail {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 28rpx;
color: #999999;
line-height: 40rpx;
text-align: center;
font-style: normal;
margin-top: 12rpx;
}
.section {
margin-bottom: 30rpx;
}
.section-title {
display: flex;
align-items: center;
margin-bottom: 30rpx;
}
.title-bar {
width: 6rpx;
height: 30rpx;
background-color: #FF4767;
margin-right: 7rpx;
border-radius: 5rpx;
}
.title-text {
font-family: PingFangSC, PingFang SC;
font-weight: 500;
font-size: 32rpx;
color: #1D2129;
line-height: 48rpx;
text-align: left;
font-style: normal;
}
.section-title text {
font-size: 36rpx;
color: #1D2129;
font-weight: 500;
}
.box-cont {
background: #FFFFFF;
border-radius: 20rpx;
margin-bottom: 24rpx;
margin-left: 8rpx;
margin-right: 8rpx;
box-shadow: none;
}
.form-item {
padding: 24rpx 22rpx;
}
.form-item-one {
display: flex;
align-items: center;
padding: 24rpx;
}
.label-wrapper {
display: inline-flex;
align-items: center;
}
.label {
font-size: 28rpx;
color: #333333;
font-weight: 500;
line-height: 1;
}
.label-icon {
width: 26rpx;
height: 26rpx;
margin-left: 8rpx;
align-items: center;
}
.required::before {
content: '*';
color: #FF0000;
margin-right: 4rpx;
}
.upload-tip {
font-size: 26rpx;
color: #999;
margin: 16rpx 0 24rpx 0;
font-weight: 400;
font-family: PingFangSC, PingFang SC;
text-align: left;
font-style: normal;
}
.upload-container {
display: flex;
flex-direction: column;
align-items: center;
}
.upload-box {
display: flex;
justify-content: center;
align-items: center;
}
.upload-camera {
width: 446rpx;
height: 298rpx;
display: flex;
align-items: center;
justify-content: center;
border-radius: 48rpx;
overflow: hidden;
background-color: #F8F9FD;
position: relative;
}
.idcard-upload-vertical-container {
display: flex;
flex-direction: column;
padding: 24rpx;
}
.idcard-upload-vertical-item {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 40rpx;
}
.idcard-upload-vertical-item:last-child {
margin-bottom: 0;
}
.upload-label.required::before {
content: '*';
color: #FF0000;
margin-right: 4rpx;
}
.camera-icon {
width: 446rpx;
height: 298rpx;
border-radius: 48rpx;
}
.preview-image {
border-radius: 48rpx;
width: 100%;
height: 100%;
}
/* 识别状态样式 */
.recognize-overlay {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.6);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border-radius: 48rpx;
}
.recognize-loading {
width: 60rpx;
height: 60rpx;
border: 4rpx solid #fff;
border-top: 4rpx solid #FF4767;
border-radius: 50%;
animation: spin 1s linear infinite;
margin-bottom: 16rpx;
}
.recognize-text {
color: #fff;
font-size: 24rpx;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.picker-content {
display: flex;
align-items: center;
justify-content: flex-end;
flex: 1;
}
.picker-content text {
margin-right: 19rpx;
}
.date-divider {
width: 2rpx;
height: 30rpx;
background-color: #E9E9E9;
flex-shrink: 0;
margin-right: 15rpx;
}
.date-picker-box.disabled .date-divider {
background-color: #F3F3F3;
}
.date-picker-box text {
flex: 1;
min-width: 0;
text-align: left;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.arrow-right {
width: 14rpx;
height: 26rpx;
}
.placeholder {
color: #999999;
font-size: 28rpx;
}
.date-right-container {
display: flex;
align-items: center;
flex-shrink: 0;
}
.picker-value {
font-size: 28rpx;
color: #333333;
}
.input {
flex: 1;
font-size: 28rpx;
color: #333333;
text-align: right;
margin-left: 20rpx;
}
.radio-group {
display: flex;
margin-top: 24rpx;
width: 100%;
}
.radio-item {
display: flex;
align-items: center;
margin-right: 130rpx;
}
.radio {
width: 30rpx;
height: 30rpx;
border: 2rpx solid #DDDDDD;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-right: 16rpx;
}
.radio.checked {
background-color: #FF4767;
border-color: #FF4767;
}
.radio-icon-image {
width: 32rpx;
height: 32rpx;
}
.radio-label {
font-size: 28rpx;
color: #333333;
}
.date-range-container {
padding: 24rpx;
display: flex;
justify-content: space-between;
}
.date-item {
flex: 1;
display: flex;
flex-direction: column;
}
.date-item:first-child {
margin-right: 24rpx;
}
.date-label {
font-size: 28rpx;
color: #333333;
margin-bottom: 16rpx;
font-weight: 500;
margin-left: 8rpx;
}
.date-picker-box {
display: flex;
align-items: center;
justify-content: space-between;
border: 2rpx solid #E9E9E9;
border-radius: 10rpx;
padding: 12rpx 19rpx;
background-color: transparent;
min-height: 40rpx;
}
.date-picker-box.disabled {
border: 2rpx solid #F3F3F3;
}
.date-picker-box.disabled .date-value,
.date-picker-box.disabled .placeholder {
color: #CCCCCC;
}
.date-value {
font-size: 28rpx;
color: #333;
}
.date-arrow {
width: 35rpx;
height: 33rpx;
}
.upload-label {
font-family: Helvetica;
font-size: 28rpx;
color: #999;
line-height: 40rpx;
text-align: left;
font-style: normal;
margin-top: 24rpx;
}
/* 底部按钮样式 */
.bottom-actions {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 0rpx 24rpx 40rpx 24rpx;
background: #ffffff;
z-index: 100;
}
.action-btn {
height: 88rpx;
border-radius: 43rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
font-weight: 400;
margin-top: 20rpx;
}
.change-info-btn,
.view-change-btn,
.resubmit-btn {
background: linear-gradient(180deg, #ff8e9d 0%, #FF4767 100%);
}
/* 双按钮行样式 */
.action-buttons-row {
display: flex;
justify-content: space-between;
margin: 0 30rpx;
}
.action-buttons-row .action-btn {
width: 270rpx;
}
.cancel-btn {
background: #E5E5E5;
border-radius: 43rpx;
padding: 0 15rpx;
}
.submit-btn {
background: linear-gradient(180deg, #ff8e9d 0%, #FF4767 100%);
border-radius: 43rpx;
padding: 0 15rpx;
}
.btn-text {
font-family: PingFangSC, PingFang SC;
font-weight: 400;
font-size: 36rpx;
color: #FFFFFF;
line-height: 50rpx;
text-align: left;
font-style: normal;
}
.cancel-text {
color: #666666;
}
/* 弹窗样式 */
.popup {
position: fixed;
left: 0;
right: 0;
bottom: 0;
z-index: 999;
visibility: hidden;
opacity: 0;
transition: all 0.3s ease;
}
.popup.show {
visibility: visible;
opacity: 1;
}
.popup-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
}
.popup-content {
position: relative;
background-color: #FFFFFF;
border-radius: 24rpx 24rpx 0 0;
padding: 32rpx;
transform: translateY(100%);
transition: transform 0.3s ease;
max-height: 70vh;
}
.popup.show .popup-content {
transform: translateY(0);
}
.popup-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 32rpx;
}
.popup-title {
font-size: 32rpx;
color: #333333;
font-weight: 500;
}
.popup-close {
font-size: 40rpx;
color: #999999;
padding: 16rpx;
}
.popup-body {
max-height: 400rpx;
overflow-y: auto;
}
.radio-list .radio-item {
margin-bottom: 32rpx;
}
.popup-footer {
margin-top: 32rpx;
display: flex;
justify-content: space-between;
padding: 0 28rpx;
}
.popup-btn {
width: 280rpx;
height: 88rpx;
border-radius: 44rpx;
display: flex;
align-items: center;
justify-content: center;
}
.popup-btn.confirm {
background: linear-gradient(180deg, #ff8e9d 0%, #FF4767 100%);
}
.popup-btn.cancel {
border: 2rpx solid #FF4767;
}
.popup-btn.confirm .btn-text {
font-size: 32rpx;
font-weight: 500;
color: #FFFFFF;
}
.popup-btn.cancel .btn-text {
font-size: 32rpx;
font-weight: 500;
color: #FF4767;
}
.cancel-text,
.confirm-text {
font-size: 32rpx;
padding: 16rpx;
}
.cancel-text {
color: #666666;
}
.confirm-text {
color: #FF4767;
font-weight: 500;
}
.picker-scroll {
height: 400rpx;
}
.picker-item {
height: 68rpx;
line-height: 68rpx;
text-align: center;
font-size: 28rpx;
}
.tip-popup {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 1000;
display: flex;
align-items: center;
justify-content: center;
visibility: hidden;
opacity: 0;
transition: all 0.3s ease;
}
.tip-popup.show {
visibility: visible;
opacity: 1;
}
.tip-popup-mask {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
}
.tip-popup-content {
position: relative;
width: 620rpx;
height: 810rpx;
}
.tip-popup-bg {
width: 620rpx;
height: 810rpx;
position: absolute;
top: 0;
left: 0;
}
.tip-popup-body {
position: relative;
flex-direction: column;
padding: 80rpx 20rpx 40rpx 20rpx;
box-sizing: border-box;
}
.tip-title {
font-size: 36rpx;
font-weight: bold;
color: #333;
text-align: center;
margin-top: 107rpx;
margin-bottom: 37rpx;
}
.tip-image-container {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 50rpx;
}
.tip-image {
width: 90%;
max-height: 400rpx;
}
.tip-buttons {
display: flex;
justify-content: space-between;
padding: 0 28rpx;
}
.tip-btn {
width: 250rpx;
height: 80rpx;
border-radius: 40rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
font-weight: 500;
}
.tip-btn.cancel {
border: #FF4767 2rpx solid;
background-color: transparent;
color: #FF4767;
}
.tip-btn.confirm {
background: linear-gradient(180deg, #ff8e9d 0%, #FF4767 100%);
color: #FFFFFF;
}
.tip-btn .btn-text {
color: inherit;
}
.permission.transform {
top: calc(var(--status-bar-height) + 88rpx + 20rpx);
opacity: 1;
visibility: visible;
}
.image-list {
display: flex;
flex-wrap: wrap;
gap: 16rpx;
margin-top: 16rpx;
}
.image-item {
position: relative;
width: 200rpx;
height: 200rpx;
}
.qualification-image {
width: 200rpx;
height: 200rpx;
border-radius: 12rpx;
}
.image-delete {
position: absolute;
top: -10rpx;
right: -10rpx;
width: 36rpx;
height: 36rpx;
background: #FF4767;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: #FFFFFF;
font-size: 28rpx;
}
.image-add {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border: 2rpx dashed #DDDDDD;
width: 214rpx;
height: 214rpx;
background: #F5F5F5;
border-radius: 20rpx;
}
.upload-icon-small {
width: 48rpx;
height: 48rpx;
margin-bottom: 8rpx;
}
.add-text {
font-size: 22rpx;
color: #999999;
}
.region-body {
margin-top: 20rpx;
}
.region-body .picker-scroll {
height: 400rpx;
}
.form-item-image-box {
display: flex;
flex-direction: column;
padding: 24rpx;
}
.form-item-image-box .label {
margin-bottom: 16rpx;
}
</style>