| | |
| | | <template> |
| | | <view class="page"> |
| | | <view class="navigation-bar"><view class="back-button" @tap="goBack"><image class="back-icon" src="/static/icons/lucide/back-left.svg" mode="aspectFit"></image></view><text class="page-title">商户进件</text></view> |
| | | <view class="type-row"><text class="type-label">商户类型</text><view class="type-select" @tap="toggleMerchantTypeDropdown"><text>{{merchantType == 'enterprise' ? '企业' : '个人'}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view></view> |
| | | <scroll-view class="form-scroll" scroll-y="true" :show-scrollbar="false"><view class="form-body"> |
| | | <view v-if="merchantType == 'enterprise'"> |
| | | <view class="field-block"><text class="field-label required">商户名称</text><view class="input-shell" :class="invalidField == 'merchantName' ? 'field-invalid' : ''"><input class="text-input" v-model="merchantName" maxlength="128" placeholder="请输入" placeholder-class="input-placeholder" @input="clearFieldError('merchantName')" /></view><text v-if="invalidField == 'merchantName'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label">商户简称</text><view class="input-shell"><input class="text-input" v-model="merchantShortName" maxlength="128" placeholder="请输入" placeholder-class="input-placeholder" /></view></view> |
| | | <view class="field-block"><text class="field-label required">公司类型</text><picker class="date-picker" mode="selector" :range="companyTypeOptions" :value="companyTypeIndex" @change="onCompanyTypeChange"><view class="select-shell" :class="invalidField == 'companyType' ? 'field-invalid' : ''"><text>{{companyType}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view></picker><text v-if="invalidField == 'companyType'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">营业执照</text><view class="upload-box" :class="invalidField == 'businessLicenseUrl' ? 'field-invalid' : ''" @tap="chooseDocument('businessLicense')"><image v-if="businessLicenseUrl.length > 0" class="document-image" :src="businessLicenseUrl" mode="aspectFill"></image><text v-else>{{uploadingField == 'businessLicense' ? '上传中...' : '添加图片'}}</text></view><text v-if="invalidField == 'businessLicenseUrl'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">统一社会信用代码</text><view class="input-shell" :class="invalidField == 'creditCode' ? 'field-invalid' : ''"><input class="text-input" :value="creditCode" maxlength="18" placeholder="请输入" placeholder-class="input-placeholder" @input="normalizeCreditCode" /></view><text v-if="invalidField == 'creditCode'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">营业执照有效期</text><view class="dropdown-wrap"><view class="select-shell" @tap="toggleDropdown('businessValidity')"><text>{{businessValidity}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view></view></view> |
| | | <view class="field-block"><text class="field-label required">营业执照有效期起始日期</text><picker class="date-picker" mode="date" :value="businessStartDate" start="1900-01-01" end="2099-12-31" @change="onBusinessStartChange"><view class="select-shell" :class="invalidField == 'businessStartDate' ? 'field-invalid' : ''"><text :class="businessStartDate.length == 0 ? 'select-placeholder' : ''">{{businessStartDate.length > 0 ? businessStartDate : '请选择'}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view></picker><text v-if="invalidField == 'businessStartDate'" class="field-error">{{errorMessage}}</text></view> |
| | | <view v-if="businessValidity == '固定期限'" class="field-block"><text class="field-label required">营业执照有效期结束日期</text><picker class="date-picker" mode="date" :value="businessEndDate" start="1900-01-01" end="2099-12-31" @change="onBusinessEndChange"><view class="select-shell" :class="invalidField == 'businessEndDate' ? 'field-invalid' : ''"><text :class="businessEndDate.length == 0 ? 'select-placeholder' : ''">{{businessEndDate.length > 0 ? businessEndDate : '请选择'}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view></picker><text v-if="invalidField == 'businessEndDate'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">成立时间</text><picker class="date-picker" mode="date" :value="establishedDate" start="1900-01-01" end="2099-12-31" @change="onEstablishedDateChange"><view class="select-shell" :class="invalidField == 'establishedDate' ? 'field-invalid' : ''"><text :class="establishedDate.length == 0 ? 'select-placeholder' : ''">{{establishedDate.length > 0 ? establishedDate : '请选择'}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view></picker><text v-if="invalidField == 'establishedDate'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">注册地址(省、市、区)</text><picker class="region-picker" mode="region" @change="onRegisteredRegionChange"><view class="select-shell" :class="invalidField == 'registeredRegion' ? 'field-invalid' : ''"><text class="ellipsis-text" :class="registeredRegion.length == 0 ? 'select-placeholder' : ''">{{registeredRegion.length > 0 ? registeredRegion : '请选择'}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view></picker><text v-if="invalidField == 'registeredRegion'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">详细注册地址</text><view class="input-shell" :class="invalidField == 'registeredAddress' ? 'field-invalid' : ''"><input class="text-input" v-model="registeredAddress" maxlength="255" placeholder="请输入" placeholder-class="input-placeholder" @input="clearFieldError('registeredAddress')" /></view><text v-if="invalidField == 'registeredAddress'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label">注册资本</text><view class="input-shell"><input class="text-input" v-model="registeredCapital" maxlength="64" placeholder="请输入" placeholder-class="input-placeholder" /></view></view> |
| | | <view class="step-bar"><view class="step-item" v-for="(title, index) in stepTitles" :key="index"><text :class="currentStep - 1 >= index ? 'step-index step-index-active' : 'step-index'">{{index + 1}}</text><text :class="currentStep - 1 >= index ? 'step-label step-label-active' : 'step-label'">{{title}}</text></view></view> |
| | | <scroll-view class="form-scroll" scroll-y="true" :scroll-top="scrollTop" :show-scrollbar="false"><view class="form-body"> |
| | | <view v-if="draftNotice" class="draft-hint">已恢复上次未提交的草稿,可继续填写</view> |
| | | |
| | | <view v-if="currentStep == 1"> |
| | | <view class="field-block"><text class="field-label required">商户类型</text><view class="dropdown-wrap"><view class="select-shell" @tap="toggleMerchantTypeDropdown"><text>{{merchantType == 'enterprise' ? '企业' : '个人'}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view><view v-if="activeDropdown == 'merchantType'" class="dropdown-menu"><view class="dropdown-option" :class="merchantType == 'enterprise' ? 'dropdown-option-active' : ''" @tap="selectMerchantType('enterprise')"><text>企业</text></view><view class="dropdown-option" :class="merchantType == 'individual' ? 'dropdown-option-active' : ''" @tap="selectMerchantType('individual')"><text>个人</text></view></view></view></view> |
| | | <view v-if="merchantType == 'enterprise'"> |
| | | <view class="field-block"><text class="field-label required">商户名称</text><view class="input-shell" :class="invalidField == 'merchantName' ? 'field-invalid' : ''"><input class="text-input" v-model="merchantName" maxlength="128" placeholder="请输入" placeholder-class="input-placeholder" @input="clearFieldError('merchantName')" /></view><text class="field-hint">必须与营业执照上的名称完全一致</text><text v-if="invalidField == 'merchantName'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label">商户简称</text><view class="input-shell"><input class="text-input" v-model="merchantShortName" maxlength="128" placeholder="请输入" placeholder-class="input-placeholder" /></view><text class="field-hint">会显示在用户的支付页面上,留空则用商户名称</text></view> |
| | | <view class="field-block"><text class="field-label required">公司类型</text><picker class="date-picker" mode="selector" :range="companyTypeOptions" :value="companyTypeIndex" @change="onCompanyTypeChange"><view class="select-shell" :class="invalidField == 'companyType' ? 'field-invalid' : ''"><text :class="companyType.length == 0 ? 'select-placeholder' : ''">{{companyType.length > 0 ? companyType : '请选择'}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view></picker><text v-if="invalidField == 'companyType'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">营业执照</text><view class="upload-box" :class="invalidField == 'businessLicenseUrl' ? 'field-invalid' : ''" @tap="chooseDocument('businessLicense')"><image v-if="businessLicenseUrl.length > 0" class="document-image" :src="businessLicenseUrl" mode="aspectFill"></image><text v-else>{{uploadingField == 'businessLicense' ? '上传中...' : '添加图片'}}</text></view><text class="field-hint">JPG/PNG/BMP,单张不超过 2MB,证照不能过期</text><text v-if="invalidField == 'businessLicenseUrl'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">统一社会信用代码</text><view class="input-shell" :class="invalidField == 'creditCode' ? 'field-invalid' : ''"><input class="text-input" :value="creditCode" maxlength="18" placeholder="请输入" placeholder-class="input-placeholder" @input="normalizeCreditCode" /></view><text class="field-hint">18 位,字母会自动转大写</text><text v-if="invalidField == 'creditCode'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">营业执照有效期</text><view class="dropdown-wrap"><view class="select-shell" @tap="toggleDropdown('businessValidity')"><text>{{businessValidity}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view><view v-if="activeDropdown == 'businessValidity'" class="dropdown-menu"><view class="dropdown-option" :class="businessValidity == '固定期限' ? 'dropdown-option-active' : ''" @tap="selectBusinessValidity('固定期限')"><text>固定期限</text></view><view class="dropdown-option" :class="businessValidity == '长期' ? 'dropdown-option-active' : ''" @tap="selectBusinessValidity('长期')"><text>长期</text></view></view></view></view> |
| | | <view class="field-block"><text class="field-label required">营业执照有效期起始日期</text><picker class="date-picker" mode="date" :value="businessStartDate" start="1900-01-01" end="2099-12-31" @change="onBusinessStartChange"><view class="select-shell" :class="invalidField == 'businessStartDate' ? 'field-invalid' : ''"><text :class="businessStartDate.length == 0 ? 'select-placeholder' : ''">{{businessStartDate.length > 0 ? businessStartDate : '请选择'}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view></picker><text v-if="invalidField == 'businessStartDate'" class="field-error">{{errorMessage}}</text></view> |
| | | <view v-if="businessValidity == '固定期限'" class="field-block"><text class="field-label required">营业执照有效期结束日期</text><picker class="date-picker" mode="date" :value="businessEndDate" start="1900-01-01" end="2099-12-31" @change="onBusinessEndChange"><view class="select-shell" :class="invalidField == 'businessEndDate' ? 'field-invalid' : ''"><text :class="businessEndDate.length == 0 ? 'select-placeholder' : ''">{{businessEndDate.length > 0 ? businessEndDate : '请选择'}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view></picker><text v-if="invalidField == 'businessEndDate'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">成立时间</text><picker class="date-picker" mode="date" :value="establishedDate" start="1900-01-01" end="2099-12-31" @change="onEstablishedDateChange"><view class="select-shell" :class="invalidField == 'establishedDate' ? 'field-invalid' : ''"><text :class="establishedDate.length == 0 ? 'select-placeholder' : ''">{{establishedDate.length > 0 ? establishedDate : '请选择'}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view></picker><text v-if="invalidField == 'establishedDate'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">注册地址(省、市、区)</text><picker class="region-picker" mode="region" @change="onRegisteredRegionChange"><view class="select-shell" :class="invalidField == 'registeredRegion' ? 'field-invalid' : ''"><text class="ellipsis-text" :class="registeredRegion.length == 0 ? 'select-placeholder' : ''">{{registeredRegion.length > 0 ? registeredRegion : '请选择'}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view></picker><text v-if="invalidField == 'registeredRegion'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">详细注册地址</text><view class="input-shell" :class="invalidField == 'registeredAddress' ? 'field-invalid' : ''"><input class="text-input" v-model="registeredAddress" maxlength="255" placeholder="请输入" placeholder-class="input-placeholder" @input="clearFieldError('registeredAddress')" /></view><text class="field-hint">与营业执照上的住所一致</text><text v-if="invalidField == 'registeredAddress'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text :class="capitalRequired() ? 'field-label required' : 'field-label'">注册资本</text><view class="input-shell" :class="invalidField == 'registeredCapital' ? 'field-invalid' : ''"><input class="text-input" type="digit" v-model="registeredCapital" maxlength="64" placeholder="请输入" placeholder-class="input-placeholder" @input="clearFieldError('registeredCapital')" /></view><text class="field-hint">单位:万元,可填小数</text><text v-if="invalidField == 'registeredCapital'" class="field-error">{{errorMessage}}</text></view> |
| | | </view> |
| | | <view v-if="merchantType == 'individual'"> |
| | | <view class="field-block"><text class="field-label required">行业类型</text><picker class="date-picker" mode="selector" :range="industryTypeOptions" :value="industryTypeIndex" @change="onIndustryTypeChange"><view class="select-shell" :class="invalidField == 'industryType' ? 'field-invalid' : ''"><text :class="industryType.length == 0 ? 'select-placeholder' : ''">{{industryType.length > 0 ? industryType : '请选择'}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view></picker><text v-if="invalidField == 'industryType'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">经营地区(省、市、区)</text><picker class="region-picker" mode="region" @change="onRegisteredRegionChange"><view class="select-shell" :class="invalidField == 'registeredRegion' ? 'field-invalid' : ''"><text class="ellipsis-text" :class="registeredRegion.length == 0 ? 'select-placeholder' : ''">{{registeredRegion.length > 0 ? registeredRegion : '请选择'}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view></picker><text v-if="invalidField == 'registeredRegion'" class="field-error">{{errorMessage}}</text></view> |
| | | </view> |
| | | </view> |
| | | <view class="field-block"><text class="field-label required">{{merchantType == 'enterprise' ? '法人姓名' : '个人姓名'}}</text><view class="input-shell" :class="invalidField == 'subjectName' ? 'field-invalid' : ''"><input class="text-input" v-model="subjectName" maxlength="64" placeholder="请输入" placeholder-class="input-placeholder" @input="clearFieldError('subjectName')" /></view><text v-if="invalidField == 'subjectName'" class="field-error">{{errorMessage}}</text></view> |
| | | <view v-if="merchantType == 'individual'"> |
| | | <view class="field-block"><text class="field-label required">行业类型</text><picker class="date-picker" mode="selector" :range="industryTypeOptions" :value="industryTypeIndex" @change="onIndustryTypeChange"><view class="select-shell" :class="invalidField == 'industryType' ? 'field-invalid' : ''"><text :class="industryType.length == 0 ? 'select-placeholder' : ''">{{industryType.length > 0 ? industryType : '请选择'}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view></picker><text v-if="invalidField == 'industryType'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">经营地区(省、市、区)</text><picker class="region-picker" mode="region" @change="onRegisteredRegionChange"><view class="select-shell" :class="invalidField == 'registeredRegion' ? 'field-invalid' : ''"><text class="ellipsis-text" :class="registeredRegion.length == 0 ? 'select-placeholder' : ''">{{registeredRegion.length > 0 ? registeredRegion : '请选择'}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view></picker><text v-if="invalidField == 'registeredRegion'" class="field-error">{{errorMessage}}</text></view> |
| | | |
| | | <view v-if="currentStep == 2"> |
| | | <view class="field-block"><text class="field-label required">{{merchantType == 'enterprise' ? '法人姓名' : '个人姓名'}}</text><view class="input-shell" :class="invalidField == 'subjectName' ? 'field-invalid' : ''"><input class="text-input" v-model="subjectName" maxlength="64" placeholder="请输入" placeholder-class="input-placeholder" @input="clearFieldError('subjectName')" /></view><text class="field-hint">与身份证上的姓名一致</text><text v-if="invalidField == 'subjectName'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">{{merchantType == 'enterprise' ? '法人身份证件类型' : '负责人证件类型'}}</text><view class="select-shell readonly-shell"><text>身份证</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view></view> |
| | | <view class="field-block"><text class="field-label required">{{merchantType == 'enterprise' ? '法人身份证件人像面' : '负责人身份证件人像面'}}</text><view class="upload-box" :class="invalidField == 'legalIdFrontUrl' ? 'field-invalid' : ''" @tap="chooseDocument('legalIdFront')"><image v-if="legalIdFrontUrl.length > 0" class="document-image" :src="legalIdFrontUrl" mode="aspectFill"></image><text v-else>{{uploadingField == 'legalIdFront' ? '上传中...' : '添加图片'}}</text></view><text class="field-hint">JPG/PNG/BMP,单张不超过 2MB,四角完整、不要反光</text><text v-if="invalidField == 'legalIdFrontUrl'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">{{merchantType == 'enterprise' ? '法人身份证件国徽面' : '负责人身份证件国徽面'}}</text><view class="upload-box" :class="invalidField == 'legalIdBackUrl' ? 'field-invalid' : ''" @tap="chooseDocument('legalIdBack')"><image v-if="legalIdBackUrl.length > 0" class="document-image" :src="legalIdBackUrl" mode="aspectFill"></image><text v-else>{{uploadingField == 'legalIdBack' ? '上传中...' : '添加图片'}}</text></view><text class="field-hint">JPG/PNG/BMP,单张不超过 2MB,四角完整、不要反光</text><text v-if="invalidField == 'legalIdBackUrl'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">{{merchantType == 'enterprise' ? '法人证件号码' : '负责人证件号码'}}</text><view class="input-shell" :class="invalidField == 'subjectIdNumber' ? 'field-invalid' : ''"><input class="text-input" :value="subjectIdNumber" maxlength="18" placeholder="请输入" placeholder-class="input-placeholder" @input="normalizeIdNumber" /></view><text v-if="invalidField == 'subjectIdNumber'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">{{merchantType == 'enterprise' ? '法人证件有效期类型' : '负责人证件有效期类型'}}</text><view class="dropdown-wrap"><view class="select-shell" @tap="toggleDropdown('subjectValidity')"><text>{{subjectValidity}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view><view v-if="activeDropdown == 'subjectValidity'" class="dropdown-menu"><view class="dropdown-option" :class="subjectValidity == '10年' ? 'dropdown-option-active' : ''" @tap="selectSubjectValidity('10年')"><text>10年</text></view><view class="dropdown-option" :class="subjectValidity == '20年' ? 'dropdown-option-active' : ''" @tap="selectSubjectValidity('20年')"><text>20年</text></view><view class="dropdown-option" :class="subjectValidity == '长期有效' ? 'dropdown-option-active' : ''" @tap="selectSubjectValidity('长期有效')"><text>长期有效</text></view></view></view></view> |
| | | <view class="field-block"><text class="field-label required">{{merchantType == 'enterprise' ? '法人证件有效期开始日期' : '负责人证件有效期开始日期'}}</text><picker class="date-picker" mode="date" :value="subjectStartDate" start="1900-01-01" end="2099-12-31" @change="onSubjectStartChange"><view class="select-shell" :class="invalidField == 'subjectStartDate' ? 'field-invalid' : ''"><text :class="subjectStartDate.length == 0 ? 'select-placeholder' : ''">{{subjectStartDate.length > 0 ? subjectStartDate : '请选择'}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view></picker><text v-if="invalidField == 'subjectStartDate'" class="field-error">{{errorMessage}}</text></view> |
| | | <view v-if="subjectValidity != '长期有效'" class="field-block"><text class="field-label required">{{merchantType == 'enterprise' ? '法人证件有效期截止日期' : '负责人证件有效期截止日期'}}</text><picker class="date-picker" mode="date" :value="subjectEndDate" start="1900-01-01" end="2099-12-31" @change="onSubjectEndChange"><view class="select-shell" :class="invalidField == 'subjectEndDate' ? 'field-invalid' : ''"><text :class="subjectEndDate.length == 0 ? 'select-placeholder' : ''">{{subjectEndDate.length > 0 ? subjectEndDate : '请选择'}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view></picker><text v-if="invalidField == 'subjectEndDate'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">{{merchantType == 'enterprise' ? '法人证件地址' : '负责人证件地址'}}</text><view class="input-shell" :class="invalidField == 'legalCertificateAddress' ? 'field-invalid' : ''"><input class="text-input" v-model="legalCertificateAddress" maxlength="255" placeholder="请输入" placeholder-class="input-placeholder" @input="clearFieldError('legalCertificateAddress')" /></view><text class="field-hint">与身份证上的住址一致,至少 4 个字</text><text v-if="invalidField == 'legalCertificateAddress'" class="field-error">{{errorMessage}}</text></view> |
| | | </view> |
| | | <view class="field-block"><text class="field-label required">{{merchantType == 'enterprise' ? '法人身份证件类型' : '负责人证件类型'}}</text><view class="select-shell readonly-shell"><text>身份证</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view></view> |
| | | <view class="field-block"><text class="field-label required">{{merchantType == 'enterprise' ? '法人身份证件人像面' : '负责人身份证件人像面'}}</text><view class="upload-box" :class="invalidField == 'legalIdFrontUrl' ? 'field-invalid' : ''" @tap="chooseDocument('legalIdFront')"><image v-if="legalIdFrontUrl.length > 0" class="document-image" :src="legalIdFrontUrl" mode="aspectFill"></image><text v-else>{{uploadingField == 'legalIdFront' ? '上传中...' : '添加图片'}}</text></view><text v-if="invalidField == 'legalIdFrontUrl'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">{{merchantType == 'enterprise' ? '法人身份证件国徽面' : '负责人身份证件国徽面'}}</text><view class="upload-box" :class="invalidField == 'legalIdBackUrl' ? 'field-invalid' : ''" @tap="chooseDocument('legalIdBack')"><image v-if="legalIdBackUrl.length > 0" class="document-image" :src="legalIdBackUrl" mode="aspectFill"></image><text v-else>{{uploadingField == 'legalIdBack' ? '上传中...' : '添加图片'}}</text></view><text v-if="invalidField == 'legalIdBackUrl'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">{{merchantType == 'enterprise' ? '法人证件号码' : '负责人证件号码'}}</text><view class="input-shell" :class="invalidField == 'subjectIdNumber' ? 'field-invalid' : ''"><input class="text-input" :value="subjectIdNumber" maxlength="18" placeholder="请输入" placeholder-class="input-placeholder" @input="normalizeIdNumber" /></view><text v-if="invalidField == 'subjectIdNumber'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">{{merchantType == 'enterprise' ? '法人证件有效期类型' : '负责人证件有效期类型'}}</text><view class="dropdown-wrap"><view class="select-shell" @tap="toggleDropdown('subjectValidity')"><text>{{subjectValidity}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view></view></view> |
| | | <view class="field-block"><text class="field-label required">{{merchantType == 'enterprise' ? '法人证件有效期开始日期' : '负责人证件有效期开始日期'}}</text><picker class="date-picker" mode="date" :value="subjectStartDate" start="1900-01-01" end="2099-12-31" @change="onSubjectStartChange"><view class="select-shell" :class="invalidField == 'subjectStartDate' ? 'field-invalid' : ''"><text :class="subjectStartDate.length == 0 ? 'select-placeholder' : ''">{{subjectStartDate.length > 0 ? subjectStartDate : '请选择'}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view></picker><text v-if="invalidField == 'subjectStartDate'" class="field-error">{{errorMessage}}</text></view> |
| | | <view v-if="subjectValidity != '长期有效'" class="field-block"><text class="field-label required">{{merchantType == 'enterprise' ? '法人证件有效期截止日期' : '负责人证件有效期截止日期'}}</text><picker class="date-picker" mode="date" :value="subjectEndDate" start="1900-01-01" end="2099-12-31" @change="onSubjectEndChange"><view class="select-shell" :class="invalidField == 'subjectEndDate' ? 'field-invalid' : ''"><text :class="subjectEndDate.length == 0 ? 'select-placeholder' : ''">{{subjectEndDate.length > 0 ? subjectEndDate : '请选择'}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view></picker><text v-if="invalidField == 'subjectEndDate'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label">{{merchantType == 'enterprise' ? '法人证件地址' : '负责人证件地址'}}</text><view class="input-shell"><input class="text-input" v-model="legalCertificateAddress" maxlength="255" placeholder="请输入" placeholder-class="input-placeholder" /></view></view> |
| | | <view v-if="merchantType == 'enterprise'" class="field-block"><text class="field-label required">管理员姓名</text><view class="input-shell" :class="invalidField == 'contactName' ? 'field-invalid' : ''"><input class="text-input" v-model="contactName" maxlength="64" placeholder="请输入" placeholder-class="input-placeholder" @input="clearFieldError('contactName')" /></view><text v-if="invalidField == 'contactName'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">{{merchantType == 'enterprise' ? '管理员手机号' : '手机号'}}</text><view class="input-shell" :class="invalidField == 'contactMobile' ? 'field-invalid' : ''"><input class="text-input" type="number" :value="contactMobile" maxlength="11" placeholder="请输入" placeholder-class="input-placeholder" @input="normalizePhone" /></view><text v-if="invalidField == 'contactMobile'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">{{merchantType == 'enterprise' ? '管理员邮箱' : '邮箱'}}</text><view class="input-shell" :class="invalidField == 'administratorEmail' ? 'field-invalid' : ''"><input class="text-input" v-model="administratorEmail" maxlength="128" placeholder="请输入" placeholder-class="input-placeholder" @input="clearFieldError('administratorEmail')" /></view><text v-if="invalidField == 'administratorEmail'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="settlement-title">结算银行卡信息</view> |
| | | <view class="field-block"><text class="field-label required">银行卡号</text><view class="input-shell" :class="invalidField == 'bankCardNumber' ? 'field-invalid' : ''"><input class="text-input" type="number" maxlength="32" :value="bankCardNumber" placeholder="请输入银行卡号" placeholder-class="input-placeholder" @input="normalizeBankNumber" /></view><text v-if="invalidField == 'bankCardNumber'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">开户省份</text><picker class="region-picker" mode="selector" :range="areaProvinceNames" :value="bankProvinceIndex" @change="onBankProvinceChange"><view class="select-shell" :class="invalidField == 'bankProvince' ? 'field-invalid' : ''"><text :class="bankProvince.length == 0 ? 'select-placeholder' : ''">{{bankProvince.length > 0 ? bankProvince : '请选择'}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view></picker></view> |
| | | <view class="field-block"><text class="field-label required">开户城市</text><picker class="region-picker" mode="selector" :range="bankCityNames" :value="bankCityIndex" :disabled="bankProvince.length == 0" @change="onBankCityChange"><view class="select-shell" :class="invalidField == 'bankCity' ? 'field-invalid' : ''"><text :class="bankCity.length == 0 ? 'select-placeholder' : ''">{{bankCity.length > 0 ? bankCity : '请选择'}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view></picker></view> |
| | | <view class="field-block"><text class="field-label required">开户行</text><view class="select-shell" :class="invalidField == 'bankBranch' ? 'field-invalid' : ''" @tap="chooseBankBranch"><text class="ellipsis-text" :class="bankBranch.length == 0 ? 'select-placeholder' : ''">{{bankBranch.length > 0 ? bankBranch : '请选择'}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view><text v-if="invalidField == 'bankBranch'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">{{merchantType == 'enterprise' && companyType != '个体工商户' ? '开户许可证' : '银行卡卡号面'}}</text><view class="upload-box" :class="invalidField == 'settlementProofUrl' ? 'field-invalid' : ''" @tap="chooseDocument('settlementProof')"><image v-if="settlementProofUrl.length > 0" class="document-image" :src="settlementProofUrl" mode="aspectFill"></image><text v-else>{{uploadingField == 'settlementProof' ? '上传中...' : '添加图片'}}</text></view><text v-if="invalidField == 'settlementProofUrl'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="submit-button" :class="submitting || uploadingField.length > 0 ? 'button-disabled' : ''" @tap="submitForm"><text>{{submitting ? '提交中...' : '提交'}}</text></view><view class="safe-space"></view> |
| | | |
| | | <view v-if="currentStep == 3"> |
| | | <view v-if="merchantType == 'enterprise'" class="field-block"><text class="field-label required">管理员姓名</text><view class="input-shell" :class="invalidField == 'contactName' ? 'field-invalid' : ''"><input class="text-input" v-model="contactName" maxlength="64" placeholder="请输入" placeholder-class="input-placeholder" @input="clearFieldError('contactName')" /></view><text v-if="invalidField == 'contactName'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">{{merchantType == 'enterprise' ? '管理员手机号' : '手机号'}}</text><view class="input-shell" :class="invalidField == 'contactMobile' ? 'field-invalid' : ''"><input class="text-input" type="number" :value="contactMobile" maxlength="11" placeholder="请输入" placeholder-class="input-placeholder" @input="normalizePhone" /></view><text class="field-hint">汇付审核如需联系会打这个号码</text><text v-if="invalidField == 'contactMobile'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">{{merchantType == 'enterprise' ? '管理员邮箱' : '邮箱'}}</text><view class="input-shell" :class="invalidField == 'administratorEmail' ? 'field-invalid' : ''"><input class="text-input" v-model="administratorEmail" maxlength="128" placeholder="请输入" placeholder-class="input-placeholder" @input="clearFieldError('administratorEmail')" /></view><text class="field-hint">用于接收进件结果通知,必须能收信</text><text v-if="invalidField == 'administratorEmail'" class="field-error">{{errorMessage}}</text></view> |
| | | </view> |
| | | |
| | | <view v-if="currentStep == 4"> |
| | | <view class="settlement-title">结算账户信息</view> |
| | | <view class="field-block"><text class="field-label required">{{bankAccountLabel()}}</text><view class="input-shell" :class="invalidField == 'bankCardNumber' ? 'field-invalid' : ''"><input class="text-input" type="number" maxlength="32" :value="bankCardNumber" placeholder="请输入结算账号" placeholder-class="input-placeholder" @input="normalizeBankNumber" /></view><text v-if="bankAccountLabel() == '对公账号'" class="field-hint">账号名必须与营业执照上的名称一致</text><text v-if="invalidField == 'bankCardNumber'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">开户省份</text><picker class="region-picker" mode="selector" :range="areaProvinceNames" :value="bankProvinceIndex" @change="onBankProvinceChange"><view class="select-shell" :class="invalidField == 'bankProvince' ? 'field-invalid' : ''"><text :class="bankProvince.length == 0 ? 'select-placeholder' : ''">{{bankProvince.length > 0 ? bankProvince : '请选择'}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view></picker></view> |
| | | <view class="field-block"><text class="field-label required">开户城市</text><picker class="region-picker" mode="selector" :range="bankCityNames" :value="bankCityIndex" :disabled="bankProvince.length == 0" @change="onBankCityChange"><view class="select-shell" :class="invalidField == 'bankCity' ? 'field-invalid' : ''"><text :class="bankCity.length == 0 ? 'select-placeholder' : ''">{{bankCity.length > 0 ? bankCity : '请选择'}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view></picker><text class="field-hint">先选省份和城市,再选开户行</text></view> |
| | | <view class="field-block"><text class="field-label required">开户行(支行)</text><view :class="invalidField == 'bankBranch' ? 'select-shell field-invalid' : (bankCityCode.length == 0 ? 'select-shell readonly-shell' : 'select-shell')" @tap="chooseBankBranch"><text class="ellipsis-text" :class="bankBranch.length == 0 ? 'select-placeholder' : ''">{{bankBranch.length > 0 ? bankBranch : (bankCityCode.length == 0 ? '请先选择开户城市' : '请选择')}}</text><image class="down-icon" src="/static/icons/lucide/chevron-down.svg" mode="aspectFit"></image></view><text v-if="invalidField == 'bankBranch'" class="field-error">{{errorMessage}}</text></view> |
| | | <view class="field-block"><text class="field-label required">{{settlementProofLabel()}}</text><view class="upload-box" :class="invalidField == 'settlementProofUrl' ? 'field-invalid' : ''" @tap="chooseDocument('settlementProof')"><image v-if="settlementProofUrl.length > 0" class="document-image" :src="settlementProofUrl" mode="aspectFill"></image><text v-else>{{uploadingField == 'settlementProof' ? '上传中...' : '添加图片'}}</text></view><text class="field-hint">{{settlementProofHint()}}</text><text v-if="invalidField == 'settlementProofUrl'" class="field-error">{{errorMessage}}</text></view> |
| | | </view> |
| | | |
| | | <view v-if="submitError.length > 0" class="banner-error">{{submitError}}</view> |
| | | <view class="step-actions"> |
| | | <view v-if="currentStep > 1" class="secondary-button" @tap="goPrevStep"><text>上一步</text></view> |
| | | <view v-if="currentStep < 4" class="action-primary" @tap="goNextStep"><text>下一步</text></view> |
| | | <view v-else class="action-primary" :class="submitting || uploadingField.length > 0 ? 'button-disabled' : ''" @tap="submitForm"><text>{{submitting ? '提交中...' : '提交进件'}}</text></view> |
| | | </view> |
| | | <view class="safe-space"></view> |
| | | </view></scroll-view> |
| | | <view v-if="activeDropdown.length > 0" class="dropdown-mask" @tap="closeDropdown"></view> |
| | | <view v-if="activeDropdown == 'merchantType'" class="dropdown-menu type-menu"><view class="dropdown-option" :class="merchantType == 'enterprise' ? 'dropdown-option-active' : ''" @tap="selectMerchantType('enterprise')"><text>企业</text></view><view class="dropdown-option" :class="merchantType == 'individual' ? 'dropdown-option-active' : ''" @tap="selectMerchantType('individual')"><text>个人</text></view></view> |
| | | <view v-if="activeDropdown == 'businessValidity'" class="dropdown-menu validity-menu business-validity-menu"><view class="dropdown-option" :class="businessValidity == '固定期限' ? 'dropdown-option-active' : ''" @tap="selectBusinessValidity('固定期限')"><text>固定期限</text></view><view class="dropdown-option" :class="businessValidity == '长期' ? 'dropdown-option-active' : ''" @tap="selectBusinessValidity('长期')"><text>长期</text></view></view> |
| | | <view v-if="activeDropdown == 'subjectValidity'" class="dropdown-menu validity-menu subject-validity-menu"><view class="dropdown-option" :class="subjectValidity == '10年' ? 'dropdown-option-active' : ''" @tap="selectSubjectValidity('10年')"><text>10年</text></view><view class="dropdown-option" :class="subjectValidity == '20年' ? 'dropdown-option-active' : ''" @tap="selectSubjectValidity('20年')"><text>20年</text></view><view class="dropdown-option" :class="subjectValidity == '长期有效' ? 'dropdown-option-active' : ''" @tap="selectSubjectValidity('长期有效')"><text>长期有效</text></view></view> |
| | | </view> |
| | | </template> |
| | | |
| | |
| | | import { loadOnboardingStatus, SettlementOnboarding, submitOnboarding as submitOnboardingRemote } from '../../services/settlement.uts' |
| | | import { uploadMerchantProductImage } from '../../services/merchant-management.uts' |
| | | import { areaProvinceNames, areaProvinceCodes, areaCityNames, areaCityCodes } from '../../config/area-codes.uts' |
| | | const submitting = ref(false); const uploadingField = ref(''); const activeDropdown = ref(''); const merchantType = ref('enterprise'); const merchantName = ref(''); const merchantShortName = ref(''); const companyType = ref('政府机构'); const companyTypeIndex = ref(0); const companyTypeOptions = ['政府机构', '国营企业', '私营企业', '外资企业', '个体工商户', '其它组织', '事业单位', '业主委员会']; const industryType = ref(''); const industryTypeIndex = ref(0); const industryTypeOptions = ['餐饮服务', '酒店服务', '景区服务', '加油服务', '停车服务', '其它']; const businessLicenseUrl = ref(''); const creditCode = ref(''); const businessValidity = ref('固定期限'); const businessStartDate = ref(''); const businessEndDate = ref(''); const establishedDate = ref(''); const registeredRegion = ref(''); const registeredProvinceCode = ref(''); const registeredCityCode = ref(''); const registeredDistrictCode = ref(''); const registeredAddress = ref(''); const registeredCapital = ref(''); const subjectName = ref(''); const legalIdFrontUrl = ref(''); const legalIdBackUrl = ref(''); const subjectIdNumber = ref(''); const subjectValidity = ref('10年'); const subjectStartDate = ref(''); const subjectEndDate = ref(''); const legalCertificateAddress = ref(''); const contactName = ref(''); const contactMobile = ref(''); const administratorEmail = ref(''); const bankCardNumber = ref(''); const bankProvince = ref(''); const bankProvinceCode = ref(''); const bankProvinceIndex = ref(0); const bankCity = ref(''); const bankCityCode = ref(''); const bankCityNames = ref([] as string[]); const bankCityCodes = ref([] as string[]); const bankCityIndex = ref(0); const bankBranch = ref(''); const bankBranchCode = ref(''); const bankName = ref(''); const settlementProofUrl = ref(''); const invalidField = ref(''); const errorMessage = ref('') |
| | | |
| | | const stepTitles = ['主体信息', '法人信息', '联系人', '结算账户'] |
| | | const currentStep = ref(1) |
| | | const scrollTop = ref(0) |
| | | const draftNotice = ref(false) |
| | | const submitError = ref('') |
| | | |
| | | const submitting = ref(false); const uploadingField = ref(''); const activeDropdown = ref(''); const merchantType = ref('enterprise'); const merchantName = ref(''); const merchantShortName = ref(''); const companyType = ref(''); const companyTypeIndex = ref(-1); const companyTypeOptions = ['政府机构', '国营企业', '私营企业', '外资企业', '个体工商户', '其它组织', '事业单位', '业主委员会']; const industryType = ref(''); const industryTypeIndex = ref(0); const industryTypeOptions = ['餐饮服务', '酒店服务', '景区服务', '加油服务', '停车服务', '其它']; const businessLicenseUrl = ref(''); const creditCode = ref(''); const businessValidity = ref('固定期限'); const businessStartDate = ref(''); const businessEndDate = ref(''); const establishedDate = ref(''); const registeredRegion = ref(''); const registeredProvinceCode = ref(''); const registeredCityCode = ref(''); const registeredDistrictCode = ref(''); const registeredAddress = ref(''); const registeredCapital = ref(''); const subjectName = ref(''); const legalIdFrontUrl = ref(''); const legalIdBackUrl = ref(''); const subjectIdNumber = ref(''); const subjectValidity = ref('10年'); const subjectStartDate = ref(''); const subjectEndDate = ref(''); const legalCertificateAddress = ref(''); const contactName = ref(''); const contactMobile = ref(''); const administratorEmail = ref(''); const bankCardNumber = ref(''); const bankProvince = ref(''); const bankProvinceCode = ref(''); const bankProvinceIndex = ref(0); const bankCity = ref(''); const bankCityCode = ref(''); const bankCityNames = ref([] as string[]); const bankCityCodes = ref([] as string[]); const bankCityIndex = ref(0); const bankBranch = ref(''); const bankBranchCode = ref(''); const bankName = ref(''); const settlementProofUrl = ref(''); const invalidField = ref(''); const errorMessage = ref('') |
| | | const draftStorageKey = 'merchant-onboarding-draft' |
| | | let draftRestored = false |
| | | const draftPayload = (): any => ({ merchantType: merchantType.value, merchantName: merchantName.value, merchantShortName: merchantShortName.value, companyType: companyType.value, companyTypeIndex: companyTypeIndex.value, industryType: industryType.value, industryTypeIndex: industryTypeIndex.value, businessLicenseUrl: businessLicenseUrl.value, creditCode: creditCode.value, businessValidity: businessValidity.value, businessStartDate: businessStartDate.value, businessEndDate: businessEndDate.value, establishedDate: establishedDate.value, registeredRegion: registeredRegion.value, registeredProvinceCode: registeredProvinceCode.value, registeredCityCode: registeredCityCode.value, registeredDistrictCode: registeredDistrictCode.value, registeredAddress: registeredAddress.value, registeredCapital: registeredCapital.value, subjectName: subjectName.value, legalIdFrontUrl: legalIdFrontUrl.value, legalIdBackUrl: legalIdBackUrl.value, subjectIdNumber: subjectIdNumber.value, subjectValidity: subjectValidity.value, subjectStartDate: subjectStartDate.value, subjectEndDate: subjectEndDate.value, legalCertificateAddress: legalCertificateAddress.value, contactName: contactName.value, contactMobile: contactMobile.value, administratorEmail: administratorEmail.value, bankCardNumber: bankCardNumber.value, bankProvince: bankProvince.value, bankProvinceCode: bankProvinceCode.value, bankProvinceIndex: bankProvinceIndex.value, bankCity: bankCity.value, bankCityCode: bankCityCode.value, bankCityIndex: bankCityIndex.value, bankBranch: bankBranch.value, bankBranchCode: bankBranchCode.value, bankName: bankName.value, settlementProofUrl: settlementProofUrl.value }) |
| | | |
| | | /** 私营企业等类型汇付要求必须填注册资本,这里与服务端 normalizeRegisteredCapital 保持一致。 */ |
| | | const capitalRequired = (): boolean => merchantType.value == 'enterprise' && ['国营企业', '私营企业', '外资企业', '其它组织', '事业单位'].indexOf(companyType.value) >= 0 |
| | | const bankAccountLabel = (): string => (merchantType.value == 'enterprise' && companyType.value != '个体工商户') ? '对公账号' : '银行卡号' |
| | | const settlementProofLabel = (): string => (merchantType.value == 'enterprise' && companyType.value != '个体工商户') ? '开户许可证' : '银行卡卡号面' |
| | | const settlementProofHint = (): string => (merchantType.value == 'enterprise' && companyType.value != '个体工商户') ? '银行出具的开户许可证或基本存款账户信息,JPG/PNG/BMP,不超过 2MB' : '银行卡正面照片,JPG/PNG/BMP,不超过 2MB,卡号清晰' |
| | | |
| | | /** 返回本步骤第一处问题,格式「字段|提示」;没有问题时返回空串。纯函数,不改动错误状态。 */ |
| | | const stepProblem = (step: number): string => { |
| | | if (step == 1) { |
| | | if (merchantType.value == 'enterprise') { |
| | | if (merchantName.value.trim().length == 0) return 'merchantName|必须与营业执照一致,请输入商户名称' |
| | | if (companyType.value.length == 0) return 'companyType|请选择公司类型' |
| | | if (businessLicenseUrl.value.length == 0) return 'businessLicenseUrl|请上传营业执照' |
| | | if (!(/^[0-9A-Z]{18}$/).test(creditCode.value)) return 'creditCode|请输入正确的18位统一社会信用代码' |
| | | if (businessStartDate.value.length == 0) return 'businessStartDate|请选择营业执照有效期开始日期' |
| | | if (businessValidity.value == '固定期限' && businessEndDate.value.length == 0) return 'businessEndDate|请选择营业执照有效期结束日期' |
| | | if (businessStartDate.value.length > 0 && businessEndDate.value.length > 0 && businessStartDate.value > businessEndDate.value) return 'businessEndDate|结束日期不能早于开始日期' |
| | | if (establishedDate.value.length == 0) return 'establishedDate|请选择成立时间' |
| | | if (registeredRegion.value.length == 0) return 'registeredRegion|请选择注册地址' |
| | | if (registeredAddress.value.trim().length == 0) return 'registeredAddress|请输入详细注册地址' |
| | | if (capitalRequired() && registeredCapital.value.trim().length == 0) return 'registeredCapital|该类型必须填写注册资本(单位:万元)' |
| | | if (registeredCapital.value.trim().length > 0 && !(/^\d+(\.\d{1,2})?$/).test(registeredCapital.value.trim())) return 'registeredCapital|注册资本请输入数字,单位为万元' |
| | | } else { |
| | | if (industryType.value.length == 0) return 'industryType|请选择行业类型' |
| | | if (registeredRegion.value.length == 0) return 'registeredRegion|请选择经营地区' |
| | | } |
| | | } |
| | | if (step == 2) { |
| | | if (subjectName.value.trim().length == 0) return 'subjectName|' + (merchantType.value == 'enterprise' ? '请输入法人姓名' : '请输入个人姓名') |
| | | if (legalIdFrontUrl.value.length == 0) return 'legalIdFrontUrl|请上传身份证人像面' |
| | | if (legalIdBackUrl.value.length == 0) return 'legalIdBackUrl|请上传身份证国徽面' |
| | | if (!(/^\d{17}[0-9X]$/).test(subjectIdNumber.value)) return 'subjectIdNumber|请输入正确的18位身份证号码' |
| | | if (subjectStartDate.value.length == 0) return 'subjectStartDate|请选择证件有效期开始日期' |
| | | if (subjectValidity.value != '长期有效' && subjectEndDate.value.length == 0) return 'subjectEndDate|请选择证件有效期截止日期' |
| | | const address = legalCertificateAddress.value.trim() |
| | | if (address.length == 0) return 'legalCertificateAddress|请输入证件地址(与身份证一致)' |
| | | if (address.length < 4) return 'legalCertificateAddress|证件地址至少 4 个字,请写完整' |
| | | } |
| | | if (step == 3) { |
| | | if (merchantType.value == 'enterprise' && contactName.value.trim().length == 0) return 'contactName|请输入管理员姓名' |
| | | if (!(/^1\d{10}$/).test(contactMobile.value)) return 'contactMobile|请输入正确的11位手机号' |
| | | if (!(/^[^\s@]+@[^\s@]+\.[^\s@]+$/).test(administratorEmail.value.trim())) return 'administratorEmail|请输入正确的邮箱,用于接收进件结果' |
| | | } |
| | | if (step == 4) { |
| | | if (!(/^\d{16,32}$/).test(bankCardNumber.value)) return 'bankCardNumber|请输入正确的' + bankAccountLabel() |
| | | if (bankProvinceCode.value.length == 0) return 'bankProvince|请选择开户省份' |
| | | if (bankCityCode.value.length == 0) return 'bankCity|请选择开户城市' |
| | | if (bankBranchCode.value.length == 0) return 'bankBranch|请选择开户行(支行)' |
| | | if (settlementProofUrl.value.length == 0) return 'settlementProofUrl|请上传' + settlementProofLabel() |
| | | } |
| | | return '' |
| | | } |
| | | |
| | | /** 校验某一步:通过返回 true;否则把第一处问题写进 invalidField / errorMessage 并返回 false。 */ |
| | | const validateStep = (step: number): boolean => { |
| | | invalidField.value = '' |
| | | errorMessage.value = '' |
| | | const problem = stepProblem(step) |
| | | if (problem.length == 0) return true |
| | | const separator = problem.indexOf('|') |
| | | invalidField.value = problem.substring(0, separator) |
| | | errorMessage.value = problem.substring(separator + 1) |
| | | return false |
| | | } |
| | | |
| | | const resetScroll = () => { scrollTop.value = scrollTop.value == 0 ? 1 : 0 } |
| | | const goNextStep = () => { |
| | | if (!validateStep(currentStep.value)) { uni.showToast({ title: errorMessage.value, icon: 'none' }); return } |
| | | saveDraft(); activeDropdown.value = '' |
| | | if (currentStep.value < 4) currentStep.value = currentStep.value + 1 |
| | | resetScroll() |
| | | } |
| | | const goPrevStep = () => { saveDraft(); activeDropdown.value = ''; if (currentStep.value > 1) currentStep.value = currentStep.value - 1; resetScroll() } |
| | | |
| | | const draftPayload = (): any => ({ merchantType: merchantType.value, merchantName: merchantName.value, merchantShortName: merchantShortName.value, companyType: companyType.value, companyTypeIndex: companyTypeIndex.value, industryType: industryType.value, industryTypeIndex: industryTypeIndex.value, businessLicenseUrl: businessLicenseUrl.value, creditCode: creditCode.value, businessValidity: businessValidity.value, businessStartDate: businessStartDate.value, businessEndDate: businessEndDate.value, establishedDate: establishedDate.value, registeredRegion: registeredRegion.value, registeredProvinceCode: registeredProvinceCode.value, registeredCityCode: registeredCityCode.value, registeredDistrictCode: registeredDistrictCode.value, registeredAddress: registeredAddress.value, registeredCapital: registeredCapital.value, subjectName: subjectName.value, legalIdFrontUrl: legalIdFrontUrl.value, legalIdBackUrl: legalIdBackUrl.value, subjectIdNumber: subjectIdNumber.value, subjectValidity: subjectValidity.value, subjectStartDate: subjectStartDate.value, subjectEndDate: subjectEndDate.value, legalCertificateAddress: legalCertificateAddress.value, contactName: contactName.value, contactMobile: contactMobile.value, administratorEmail: administratorEmail.value, bankCardNumber: bankCardNumber.value, bankProvince: bankProvince.value, bankProvinceCode: bankProvinceCode.value, bankProvinceIndex: bankProvinceIndex.value, bankCity: bankCity.value, bankCityCode: bankCityCode.value, bankCityIndex: bankCityIndex.value, bankBranch: bankBranch.value, bankBranchCode: bankBranchCode.value, bankName: bankName.value, settlementProofUrl: settlementProofUrl.value, currentStep: currentStep.value }) |
| | | const saveDraft = () => { uni.setStorageSync(draftStorageKey, JSON.stringify(draftPayload())) } |
| | | const clearDraft = () => { uni.removeStorageSync(draftStorageKey) } |
| | | const restoreDraft = () => { |
| | |
| | | if (draft.bankName != null) bankName.value = draft.bankName as string |
| | | if (draft.settlementProofUrl != null) settlementProofUrl.value = draft.settlementProofUrl as string |
| | | if (bankProvince.value.length > 0 && bankProvinceIndex.value >= 0 && bankProvinceIndex.value < areaCityNames.length) { bankCityNames.value = areaCityNames[bankProvinceIndex.value]; bankCityCodes.value = areaCityCodes[bankProvinceIndex.value] } |
| | | if (draft.currentStep != null) { const restoredStep = Number(draft.currentStep); currentStep.value = (restoredStep >= 1 && restoredStep <= 4) ? restoredStep : 1 } |
| | | draftNotice.value = true |
| | | } catch (_error) { clearDraft() } |
| | | } |
| | | const goBack = () => uni.navigateBack() |
| | | const setError = (field: string, message: string) => { invalidField.value = field; errorMessage.value = message } |
| | | const clearFieldError = (field: string) => { if (invalidField.value == field) { invalidField.value = ''; errorMessage.value = '' } } |
| | | const clearFieldError = (field: string) => { if (invalidField.value == field) { invalidField.value = ''; errorMessage.value = '' }; if (submitError.value.length > 0) submitError.value = '' } |
| | | const normalizeCreditCode = (e: any) => { creditCode.value = (e.detail.value as string).toUpperCase().replace(/[^0-9A-Z]/g, ''); clearFieldError('creditCode') } |
| | | const normalizeIdNumber = (e: any) => { subjectIdNumber.value = (e.detail.value as string).toUpperCase().replace(/[^0-9X]/g, ''); clearFieldError('subjectIdNumber') } |
| | | const normalizePhone = (e: any) => { contactMobile.value = (e.detail.value as string).replace(/[^0-9]/g, ''); clearFieldError('contactMobile') } |
| | |
| | | const toggleDropdown = (name: string) => { activeDropdown.value = activeDropdown.value == name ? '' : name } |
| | | const closeDropdown = () => { activeDropdown.value = '' } |
| | | const toggleMerchantTypeDropdown = () => { toggleDropdown('merchantType') } |
| | | const selectMerchantType = (value: string) => { merchantType.value = value; activeDropdown.value = '' } |
| | | const selectMerchantType = (value: string) => { merchantType.value = value; activeDropdown.value = ''; invalidField.value = ''; errorMessage.value = '' } |
| | | const onCompanyTypeChange = (event: any) => { const index = parseInt(event.detail.value as string); if (index < 0 || index >= companyTypeOptions.length) return; companyTypeIndex.value = index; companyType.value = companyTypeOptions[index]; clearFieldError('companyType') } |
| | | const onIndustryTypeChange = (event: any) => { const index = parseInt(event.detail.value as string); if (index < 0 || index >= industryTypeOptions.length) return; industryTypeIndex.value = index; industryType.value = industryTypeOptions[index] } |
| | | const onIndustryTypeChange = (event: any) => { const index = parseInt(event.detail.value as string); if (index < 0 || index >= industryTypeOptions.length) return; industryTypeIndex.value = index; industryType.value = industryTypeOptions[index]; clearFieldError('industryType') } |
| | | const selectBusinessValidity = (value: string) => { businessValidity.value = value; activeDropdown.value = ''; if (value == '长期') businessEndDate.value = '' } |
| | | const selectSubjectValidity = (value: string) => { subjectValidity.value = value; activeDropdown.value = ''; if (value == '长期有效') subjectEndDate.value = '' } |
| | | const onBusinessStartChange = (e: any) => { businessStartDate.value = e.detail.value as string; clearFieldError('businessStartDate') }; const onBusinessEndChange = (e: any) => { businessEndDate.value = e.detail.value as string; clearFieldError('businessEndDate') }; const onEstablishedDateChange = (e: any) => { establishedDate.value = e.detail.value as string; clearFieldError('establishedDate') }; const onSubjectStartChange = (e: any) => { subjectStartDate.value = e.detail.value as string; clearFieldError('subjectStartDate') }; const onSubjectEndChange = (e: any) => { subjectEndDate.value = e.detail.value as string; clearFieldError('subjectEndDate') } |
| | |
| | | const onBankProvinceChange = (event: any) => { const index = parseInt(event.detail.value as string); if (index < 0 || index >= areaProvinceNames.length) return; bankProvinceIndex.value = index; bankProvince.value = areaProvinceNames[index]; bankProvinceCode.value = areaProvinceCodes[index]; bankCityNames.value = areaCityNames[index]; bankCityCodes.value = areaCityCodes[index]; bankCityIndex.value = 0; bankCity.value = ''; bankCityCode.value = ''; bankBranch.value = ''; bankBranchCode.value = ''; bankName.value = '' } |
| | | const onBankCityChange = (event: any) => { const index = parseInt(event.detail.value as string); if (index < 0 || index >= bankCityNames.value.length) return; bankCityIndex.value = index; bankCity.value = bankCityNames.value[index]; bankCityCode.value = bankCityCodes.value[index]; bankBranch.value = ''; bankBranchCode.value = ''; bankName.value = '' } |
| | | const chooseBankBranch = () => { if (bankCityCode.value.length == 0) { uni.showToast({ title: '请先选择开户城市', icon: 'none' }); return }; uni.navigateTo({ url: '/pages/bank-branch-select/bank-branch-select?city=' + encodeURIComponent(bankProvince.value + ' ' + bankCity.value) + '&cityCode=' + encodeURIComponent(bankCityCode.value) }) } |
| | | const dateRange = (start: string, end: string, field: string, name: string): boolean => { if (start.length == 0) { setError(field, '请选择' + name + '开始日期'); return false }; if (end.length > 0 && start > end) { setError(field, name + '结束日期不能早于开始日期'); return false }; return true } |
| | | const validate = (): boolean => { if (merchantType.value == 'enterprise') { if (merchantName.value.trim().length == 0) { setError('merchantName', '请输入商户名称'); return false }; if (companyTypeOptions.indexOf(companyType.value) < 0) { setError('companyType', '请选择公司类型'); return false }; if (businessLicenseUrl.value.length == 0) { setError('businessLicenseUrl', '请上传营业执照'); return false }; if (!(/^[0-9A-Z]{18}$/).test(creditCode.value)) { setError('creditCode', '请输入正确的18位统一社会信用代码'); return false }; if (!dateRange(businessStartDate.value, businessEndDate.value, 'businessStartDate', '营业执照有效期')) return false; if (businessValidity.value == '固定期限' && businessEndDate.value.length == 0) { setError('businessEndDate', '请选择营业执照有效期结束日期'); return false }; if (establishedDate.value.length == 0) { setError('establishedDate', '请选择成立时间'); return false }; if (registeredRegion.value.length == 0) { setError('registeredRegion', '请选择注册地址'); return false }; if (registeredAddress.value.trim().length == 0) { setError('registeredAddress', '请输入详细注册地址'); return false } } else { if (industryType.value.length == 0) { setError('industryType', '请选择行业类型'); return false }; if (registeredRegion.value.length == 0) { setError('registeredRegion', '请选择经营地区'); return false }; if (legalCertificateAddress.value.trim().length == 0) { setError('legalCertificateAddress', '请输入负责人证件地址'); return false } }; if (subjectName.value.trim().length == 0) { setError('subjectName', '请输入姓名'); return false }; if (legalIdFrontUrl.value.length == 0) { setError('legalIdFrontUrl', '请上传负责人身份证人像面'); return false }; if (legalIdBackUrl.value.length == 0) { setError('legalIdBackUrl', '请上传负责人身份证国徽面'); return false }; if (!(/^\d{17}[0-9X]$/).test(subjectIdNumber.value)) { setError('subjectIdNumber', '请输入正确的18位身份证号码'); return false }; if (!dateRange(subjectStartDate.value, subjectEndDate.value, 'subjectStartDate', '证件有效期')) return false; if (subjectValidity.value != '长期有效' && subjectEndDate.value.length == 0) { setError('subjectEndDate', '请选择证件有效期截止日期'); return false }; if (merchantType.value == 'enterprise' && contactName.value.trim().length == 0) { setError('contactName', '请输入管理员姓名'); return false }; if (!(/^1[3-9]\d{9}$/).test(contactMobile.value)) { setError('contactMobile', '请输入正确的手机号'); return false }; if (!(/^[^\s@]+@[^\s@]+\.[^\s@]+$/).test(administratorEmail.value)) { setError('administratorEmail', '请输入正确的邮箱'); return false }; if (!(/^\d{16,32}$/).test(bankCardNumber.value)) { setError('bankCardNumber', '请输入正确的银行卡号'); return false }; if (bankProvinceCode.value.length == 0) { setError('bankProvince', '请选择开户省份'); return false }; if (bankCityCode.value.length == 0) { setError('bankCity', '请选择开户城市'); return false }; if (bankBranchCode.value.length == 0) { setError('bankBranch', '请选择开户行'); return false }; if (settlementProofUrl.value.length == 0) { setError('settlementProofUrl', merchantType.value == 'enterprise' && companyType.value != '个体工商户' ? '请上传开户许可证' : '请上传银行卡卡号面'); return false }; return true } |
| | | const submitForm = () => { if (submitting.value || uploadingField.value.length > 0) return; saveDraft(); invalidField.value = ''; errorMessage.value = ''; if (!validate()) { uni.showToast({ title: errorMessage.value, icon: 'none' }); return }; submitting.value = true; submitOnboardingRemote({ subjectType: merchantType.value, subjectName: subjectName.value.trim(), creditCode: creditCode.value, subjectCertificateValidityType: subjectValidity.value == '长期有效' ? 'long_term' : 'fixed', subjectCertificateBeginDate: subjectStartDate.value, subjectCertificateEndDate: subjectEndDate.value, subjectIdNumber: subjectIdNumber.value, licenseValidityType: businessValidity.value == '长期' ? 'long_term' : 'fixed', licenseBeginDate: businessStartDate.value, licenseEndDate: businessEndDate.value, registeredRegion: registeredRegion.value, registeredProvinceCode: registeredProvinceCode.value, registeredCityCode: registeredCityCode.value, registeredDistrictCode: registeredDistrictCode.value, registeredAddress: merchantType.value == 'enterprise' ? registeredAddress.value.trim() : legalCertificateAddress.value.trim(), merchantName: merchantName.value.trim(), merchantShortName: merchantShortName.value.trim(), companyType: merchantType.value == 'enterprise' ? companyType.value : industryType.value, businessLicenseUrl: businessLicenseUrl.value, establishedDate: establishedDate.value, registeredCapital: registeredCapital.value.trim(), legalIdFrontUrl: legalIdFrontUrl.value, legalIdBackUrl: legalIdBackUrl.value, legalCertificateAddress: legalCertificateAddress.value.trim(), administratorEmail: administratorEmail.value.trim(), contactName: merchantType.value == 'enterprise' ? contactName.value.trim() : subjectName.value.trim(), contactMobile: contactMobile.value, bankCardNumber: bankCardNumber.value, bankProvinceCode: bankProvinceCode.value, bankCityCode: bankCityCode.value, bankBranchCode: bankBranchCode.value, settlementCardFrontUrl: merchantType.value == 'enterprise' && companyType.value != '个体工商户' ? '' : settlementProofUrl.value, registrationAccountUrl: merchantType.value == 'enterprise' && companyType.value != '个体工商户' ? settlementProofUrl.value : '' }, 'onboarding-' + Date.now(), (result: SettlementOnboarding) => { submitting.value = false; if (result.status == 'approved') clearDraft(); uni.redirectTo({ url: '/pages/merchant-onboarding-pending/merchant-onboarding-pending' }) }, (error: any) => { submitting.value = false; uni.showToast({ title: error.message != null ? error.message : '提交失败,请重试', icon: 'none' }) }) } |
| | | const submitForm = () => { |
| | | if (submitting.value || uploadingField.value.length > 0) return |
| | | saveDraft(); submitError.value = '' |
| | | for (let step = 1; step <= 4; step = step + 1) { |
| | | if (!validateStep(step)) { |
| | | currentStep.value = step |
| | | resetScroll() |
| | | uni.showToast({ title: errorMessage.value, icon: 'none' }) |
| | | return |
| | | } |
| | | } |
| | | activeDropdown.value = '' |
| | | submitting.value = true |
| | | submitOnboardingRemote({ subjectType: merchantType.value, subjectName: subjectName.value.trim(), creditCode: creditCode.value, subjectCertificateValidityType: subjectValidity.value == '长期有效' ? 'long_term' : 'fixed', subjectCertificateBeginDate: subjectStartDate.value, subjectCertificateEndDate: subjectEndDate.value, subjectIdNumber: subjectIdNumber.value, licenseValidityType: businessValidity.value == '长期' ? 'long_term' : 'fixed', licenseBeginDate: businessStartDate.value, licenseEndDate: businessEndDate.value, registeredRegion: registeredRegion.value, registeredProvinceCode: registeredProvinceCode.value, registeredCityCode: registeredCityCode.value, registeredDistrictCode: registeredDistrictCode.value, registeredAddress: merchantType.value == 'enterprise' ? registeredAddress.value.trim() : legalCertificateAddress.value.trim(), merchantName: merchantName.value.trim(), merchantShortName: merchantShortName.value.trim(), companyType: merchantType.value == 'enterprise' ? companyType.value : industryType.value, businessLicenseUrl: businessLicenseUrl.value, establishedDate: establishedDate.value, registeredCapital: registeredCapital.value.trim(), legalIdFrontUrl: legalIdFrontUrl.value, legalIdBackUrl: legalIdBackUrl.value, legalCertificateAddress: legalCertificateAddress.value.trim(), administratorEmail: administratorEmail.value.trim(), contactName: merchantType.value == 'enterprise' ? contactName.value.trim() : subjectName.value.trim(), contactMobile: contactMobile.value, bankCardNumber: bankCardNumber.value, bankProvinceCode: bankProvinceCode.value, bankCityCode: bankCityCode.value, bankBranchCode: bankBranchCode.value, settlementCardFrontUrl: merchantType.value == 'enterprise' && companyType.value != '个体工商户' ? '' : settlementProofUrl.value, registrationAccountUrl: merchantType.value == 'enterprise' && companyType.value != '个体工商户' ? settlementProofUrl.value : '' }, 'onboarding-' + Date.now(), (result: SettlementOnboarding) => { submitting.value = false; if (result.status == 'approved') clearDraft(); uni.redirectTo({ url: '/pages/merchant-onboarding-pending/merchant-onboarding-pending' }) }, (error: any) => { submitting.value = false; submitError.value = error.message != null ? error.message : '提交失败,请重试'; uni.showToast({ title: submitError.value, icon: 'none' }) }) |
| | | } |
| | | |
| | | onShow(() => { |
| | | if (!draftRestored) { draftRestored = true; restoreDraft() } |
| | |
| | | .back-button { display: flex; width: 64rpx; height: 64rpx; justify-content: center; align-items: center; position: absolute; left: 30rpx; top: 90rpx; z-index: 2; } |
| | | .back-icon { width: 35rpx; height: 35rpx; } |
| | | .page-title { width: 100%; color: #FFFFFF; font-size: 30rpx; line-height: 42rpx; text-align: center; font-weight: 700; } |
| | | .step-bar { display: flex; height: 92rpx; padding: 12rpx 32rpx 0; flex: none; flex-direction: row; align-items: flex-start; background-color: #FFFFFF; box-sizing: border-box; } |
| | | .step-item { display: flex; flex: 1; flex-direction: column; align-items: center; } |
| | | .step-index { width: 36rpx; height: 36rpx; border-radius: 18rpx; color: #9C9C9C; font-size: 22rpx; line-height: 36rpx; text-align: center; background-color: #EDEDED; } |
| | | .step-index-active { color: #FFFFFF; background-color: #2F6DF6; } |
| | | .step-label { margin-top: 6rpx; color: #9C9C9C; font-size: 20rpx; line-height: 28rpx; } |
| | | .step-label-active { color: #2F6DF6; font-weight: 700; } |
| | | .form-scroll { flex: 1; height: 0; background-color: #FFFFFF; } |
| | | .form-body { width: 518rpx; margin-left: 48rpx; padding-top: 0; background-color: #FFFFFF; box-sizing: border-box; } |
| | | .type-row { display: flex; width: 518rpx; height: 64rpx; margin: 18rpx 0 19rpx 48rpx; flex-direction: row; align-items: center; position: relative; z-index: 100; } |
| | | .type-label { width: 120rpx; color: #202020; font-size: 24rpx; line-height: 34rpx; font-weight: 600; } |
| | | .type-select { display: flex; width: 320rpx; height: 48rpx; padding: 0 14rpx; justify-content: space-between; align-items: center; border: 1rpx solid #CFCFCF; border-radius: 4rpx; color: #202020; font-size: 24rpx; line-height: 34rpx; background-color: #FFFFFF; box-sizing: border-box; } |
| | | .form-body { width: 518rpx; margin-left: 48rpx; padding-top: 18rpx; background-color: #FFFFFF; box-sizing: border-box; } |
| | | .draft-hint { margin-bottom: 18rpx; padding: 12rpx 16rpx; color: #8A6D3B; font-size: 22rpx; line-height: 32rpx; background-color: #FCF8E3; border-radius: 4rpx; } |
| | | .banner-error { margin-top: 8rpx; padding: 14rpx 16rpx; color: #B42318; font-size: 22rpx; line-height: 32rpx; background-color: #FEF3F2; border-radius: 4rpx; } |
| | | .dropdown-wrap { position: relative; z-index: 40; width: 518rpx; } |
| | | .dropdown-menu { position: absolute; top: 62rpx; left: 0; z-index: 80; width: 518rpx; overflow: hidden; border: 1rpx solid #8D8D8D; border-top: 0; background-color: #FFFFFF; box-sizing: border-box; } |
| | | .dropdown-mask { position: fixed; top: 0; right: 0; bottom: 0; left: 0; z-index: 900; background-color: rgba(0, 0, 0, 0); } |
| | | .type-menu { position: fixed; top: 250rpx; left: 168rpx; width: 320rpx; z-index: 1000; border-top: 1rpx solid #8D8D8D; } |
| | | .validity-menu { position: fixed; left: 48rpx; width: 518rpx; z-index: 1000; border-top: 1rpx solid #8D8D8D; } |
| | | .business-validity-menu { top: 65vh; } |
| | | .subject-validity-menu { top: 48vh; } |
| | | .dropdown-option { display: flex; height: 54rpx; padding: 0 16rpx; align-items: center; color: #202020; font-size: 24rpx; line-height: 34rpx; background-color: #FFFFFF; box-sizing: border-box; } |
| | | .dropdown-option-active { color: #FFFFFF; background-color: #2768C7; } |
| | | .field-block { display: flex; margin-bottom: 27rpx; flex-direction: column; } |
| | | .settlement-title { margin: 36rpx 0 24rpx; color: #202020; font-size: 27rpx; line-height: 38rpx; font-weight: 700; } |
| | | .settlement-title { margin: 0 0 24rpx; color: #202020; font-size: 27rpx; line-height: 38rpx; font-weight: 700; } |
| | | .field-label { display: block; margin-bottom: 12rpx; color: #202020; font-size: 24rpx; line-height: 34rpx; font-weight: 600; } |
| | | .field-hint { margin-top: 8rpx; color: #9C9C9C; font-size: 20rpx; line-height: 28rpx; } |
| | | .input-shell, .select-shell { display: flex; width: 518rpx; height: 62rpx; padding: 0 16rpx; align-items: center; border: 1rpx solid #CFCFCF; border-radius: 4rpx; color: #222222; font-size: 24rpx; line-height: 34rpx; background-color: #FFFFFF; box-sizing: border-box; } |
| | | .text-input { flex: 1; height: 60rpx; color: #222222; font-size: 24rpx; line-height: 60rpx; } |
| | | .input-placeholder, .select-placeholder { color: #9C9C9C; font-size: 24rpx; } |
| | |
| | | .document-image { width: 100%; height: 100%; } |
| | | .field-invalid { border-color: #F05252; } |
| | | .field-error { margin-top: 8rpx; color: #E64B4B; font-size: 22rpx; line-height: 30rpx; } |
| | | .submit-button { display: flex; width: 518rpx; height: 66rpx; margin-top: 18rpx; justify-content: center; align-items: center; border-radius: 4rpx; color: #FFFFFF; font-size: 24rpx; line-height: 34rpx; font-weight: 700; background-color: #2F6DF6; } |
| | | .step-actions { display: flex; margin-top: 18rpx; flex-direction: row; align-items: center; } |
| | | .secondary-button { display: flex; width: 190rpx; height: 66rpx; margin-right: 18rpx; justify-content: center; align-items: center; border: 1rpx solid #CFCFCF; border-radius: 4rpx; color: #202020; font-size: 24rpx; line-height: 34rpx; background-color: #FFFFFF; } |
| | | .action-primary { display: flex; flex: 1; height: 66rpx; justify-content: center; align-items: center; border-radius: 4rpx; color: #FFFFFF; font-size: 24rpx; line-height: 34rpx; font-weight: 700; background-color: #2F6DF6; } |
| | | .button-disabled { opacity: 0.58; } |
| | | .safe-space { height: 72rpx; } |
| | | </style> |