mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp.git
synced 2026-08-06 10:57:25 +08:00
- 新增分销业绩统计页面,包含时间范围筛选和自定义日期选择功能 - 重构分销认证页面,改为跳转至招募页面申请分销员身份 - 添加分销商品访问记录功能,支持分享追踪和佣金计算 - 更新分销历史记录页面,优化数据结构和显示字段 - 完全重写分销员首页,包含用户信息、收益统计、等级系统等功能
757 lines
19 KiB
Vue
757 lines
19 KiB
Vue
<template>
|
||
<view class="wrapper" :style="themeStyle">
|
||
<view v-if="loading" class="loading">加载中...</view>
|
||
<view v-else-if="!plan">
|
||
<view class="empty">暂未开放线上招募</view>
|
||
</view>
|
||
<view v-else class="page-body" :class="{ 'with-footer': showManualApply || isApplyPending }">
|
||
<!-- 招募海报 -->
|
||
<view class="section poster-section" v-if="showPoster">
|
||
<image
|
||
class="poster-image"
|
||
:src="plan.posterBackground"
|
||
mode="widthFix"
|
||
@click="previewPoster"
|
||
/>
|
||
<view class="poster-text" v-if="posterTitle">{{ posterTitle }}</view>
|
||
<view class="poster-benefit" v-if="posterBenefitText">{{ posterBenefitText }}</view>
|
||
<view class="poster-rule" v-if="posterRuleText">{{ posterRuleText }}</view>
|
||
<view class="poster-contact" v-if="posterContact">联系方式:{{ posterContact }}</view>
|
||
</view>
|
||
|
||
<!-- 加入条件 -->
|
||
<view class="section" v-if="hasJoinCondition">
|
||
<view class="title">加入条件</view>
|
||
<view class="condition-tip">满足以下条件后可申请成为分销员</view>
|
||
|
||
<view class="condition-item" v-if="plan.requireSelfPurchaseAmount">
|
||
<view class="condition-head">
|
||
<text class="condition-label">自购金额</text>
|
||
<text class="condition-status" :class="selfPurchaseOk ? 'ok' : 'pending'">
|
||
{{ selfPurchaseOk ? '已达标' : '未达标' }}
|
||
</text>
|
||
</view>
|
||
<view class="condition-value">
|
||
{{ formatMoney(progress?.currentSelfPurchaseAmount) }} / {{ formatMoney(plan.minSelfPurchaseAmount) }} 元
|
||
</view>
|
||
</view>
|
||
|
||
<view class="condition-item" v-if="plan.requireConsumeCount">
|
||
<view class="condition-head">
|
||
<text class="condition-label">消费笔数</text>
|
||
<text class="condition-status" :class="consumeCountOk ? 'ok' : 'pending'">
|
||
{{ consumeCountOk ? '已达标' : '未达标' }}
|
||
</text>
|
||
</view>
|
||
<view class="condition-value">
|
||
{{ progress?.currentConsumeCount || 0 }} / {{ plan.minConsumeCount || 0 }} 笔
|
||
</view>
|
||
</view>
|
||
|
||
<view class="condition-item" v-if="plan.requirePurchaseGoods">
|
||
<view class="condition-head">
|
||
<text class="condition-label">购买指定商品</text>
|
||
<text class="condition-status" :class="progress?.purchaseGoodsSatisfied ? 'ok' : 'pending'">
|
||
{{ progress?.purchaseGoodsSatisfied ? '已达标' : '未达标' }}
|
||
</text>
|
||
</view>
|
||
<view class="goods-list" v-if="recruitGoods.length">
|
||
<view class="goods-item" v-for="item in recruitGoods" :key="item.skuId || item.goodsId">
|
||
<image class="goods-thumb" :src="item.thumbnail" mode="aspectFill" />
|
||
<view class="goods-meta">
|
||
<view class="goods-name">{{ item.goodsName }}</view>
|
||
<view class="goods-spec" v-if="item.simpleSpecs">{{ item.simpleSpecs }}</view>
|
||
<view class="goods-price" v-if="item.price != null">¥{{ formatMoney(item.price) }}</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="condition-value" v-else>需购买指定商品中的任意一件</view>
|
||
</view>
|
||
|
||
<view class="summary-status" :class="progress?.satisfied ? 'ok' : 'pending'">
|
||
{{ progress?.satisfied ? '已满足全部加入条件' : '未满足加入条件' }}
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 申请通过 -->
|
||
<view class="section result-section" v-if="isApplyApproved">
|
||
<view class="result-icon approved">✓</view>
|
||
<view class="result-title">已成为分销员</view>
|
||
<view class="result-desc">恭喜您已通过审核,可进入分销员中心开始推广</view>
|
||
<view class="submit" @click="goDistributionHome">进入分销员中心</view>
|
||
</view>
|
||
|
||
<!-- 自动申请提示 -->
|
||
<view class="section auto-tip" v-else-if="showAutoApplyTip">
|
||
<view class="auto-tip-text">您已满足加入条件,系统将自动为您申请成为分销员</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="apply-footer-fixed" v-if="showManualApply || isApplyPending">
|
||
<view class="apply-footer-card">
|
||
<view class="agree" v-if="showManualApply" @click="agreed = !agreed">
|
||
<checkbox :checked="agreed" @click.stop="agreed = !agreed" />
|
||
<text>我已阅读并同意</text>
|
||
<text class="agreement-link" @click.stop="openAgreement">《分销员推广服务协议》</text>
|
||
</view>
|
||
<view
|
||
class="submit"
|
||
:class="{ disabled: isApplyPending || !canApply }"
|
||
@click="submit"
|
||
>
|
||
{{ isApplyPending ? '等待审核' : '申请成为分销员' }}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<u-popup v-model:show="applyFormVisible" mode="bottom" round="16" :closeable="true">
|
||
<view class="apply-form-popup">
|
||
<view class="apply-form-header">
|
||
<view class="apply-form-title">填写审核信息</view>
|
||
<view class="apply-form-subtitle">商家设置了信息审核,请填写真实信息</view>
|
||
</view>
|
||
<view
|
||
v-for="field in fields"
|
||
:key="field.id"
|
||
class="popup-field"
|
||
>
|
||
<view class="popup-label">
|
||
<text v-if="field.required" class="required">*</text>
|
||
<text>{{ field.fieldName }}</text>
|
||
</view>
|
||
<input
|
||
v-model="formItems[field.id]"
|
||
class="popup-input"
|
||
:placeholder="field.placeholder || `请输入${field.fieldName}`"
|
||
@input="clearFieldError(field.id)"
|
||
/>
|
||
<view v-if="fieldErrors[field.id]" class="field-error">{{ fieldErrors[field.id] }}</view>
|
||
</view>
|
||
<view class="popup-next-btn" @click="confirmApplyForm">下一步</view>
|
||
</view>
|
||
</u-popup>
|
||
|
||
<u-popup v-model:show="agreementVisible" mode="bottom" round="16" :closeable="true">
|
||
<view class="agreement-popup">
|
||
<view class="agreement-popup-title">分销员推广服务协议</view>
|
||
<scroll-view scroll-y class="agreement-popup-body">
|
||
<rich-text v-if="agreementContent" :nodes="agreementContent" />
|
||
<view v-else class="agreement-empty">暂无协议内容</view>
|
||
</scroll-view>
|
||
</view>
|
||
</u-popup>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { ref, reactive, computed } from 'vue'
|
||
import { onLoad, onShow } from '@dcloudio/uni-app'
|
||
import { useStore } from '@/store'
|
||
import { getThemeStyle } from '@/utils/theme'
|
||
import { getRecruitPage, getRecruitProgress, submitRecruitApplication } from '@/api/distribution'
|
||
import { tipsToLogin } from '@/utils/filters.js'
|
||
|
||
const store = useStore()
|
||
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
||
const loading = ref(true)
|
||
const pageInfo = ref<any>({})
|
||
const progress = ref<any>(null)
|
||
const formItems = reactive<Record<string, string>>({})
|
||
const agreed = ref(false)
|
||
const recruitToken = ref('')
|
||
const applySubmitted = ref(false)
|
||
const submitAuditMode = ref('')
|
||
const submitApplicationStatus = ref('')
|
||
const agreementVisible = ref(false)
|
||
const applyFormVisible = ref(false)
|
||
const formInfoCompleted = ref(false)
|
||
const fieldErrors = reactive<Record<string, string>>({})
|
||
|
||
const plan = computed(() => pageInfo.value.plan || null)
|
||
const fields = computed(() => pageInfo.value.fields || [])
|
||
const recruitGoods = computed(() => plan.value?.recruitGoods || [])
|
||
const agreementContent = computed(() => plan.value?.agreementContent || '')
|
||
|
||
const showPoster = computed(() => {
|
||
const p = plan.value
|
||
if (!p) return false
|
||
if (p.posterEnabled === false) return false
|
||
return !!(p.posterBackground && String(p.posterBackground).trim())
|
||
})
|
||
|
||
const posterTitle = computed(() => plan.value?.posterTitle || '')
|
||
const posterBenefitText = computed(() => plan.value?.posterBenefitText || '')
|
||
const posterRuleText = computed(() => plan.value?.posterRuleText || '')
|
||
const posterContact = computed(() => plan.value?.posterContact || '')
|
||
|
||
const hasJoinCondition = computed(() => {
|
||
const p = plan.value
|
||
if (!p || p.joinConditionType !== 'CONDITIONAL') return false
|
||
return !!(p.requireSelfPurchaseAmount || p.requireConsumeCount || p.requirePurchaseGoods)
|
||
})
|
||
|
||
const conditionsMet = computed(() => {
|
||
if (!hasJoinCondition.value) return true
|
||
return !!progress.value?.satisfied
|
||
})
|
||
|
||
const distributionStatus = computed(() => pageInfo.value.distributionStatus || '')
|
||
const currentApplication = computed(() => pageInfo.value.currentApplication || null)
|
||
|
||
const isApplyApproved = computed(() => {
|
||
if (distributionStatus.value === 'PASS') return true
|
||
if (submitApplicationStatus.value === 'APPROVED') return true
|
||
if (applySubmitted.value && submitAuditMode.value === 'AUTO_PASS') return true
|
||
return currentApplication.value?.applicationStatus === 'APPROVED'
|
||
})
|
||
|
||
const isApplyPending = computed(() => {
|
||
if (isApplyApproved.value) return false
|
||
if (distributionStatus.value === 'APPLY') return true
|
||
if (submitApplicationStatus.value === 'PENDING') return true
|
||
if (applySubmitted.value && submitAuditMode.value === 'MANUAL') return true
|
||
return currentApplication.value?.applicationStatus === 'PENDING'
|
||
})
|
||
|
||
const showApplyResult = computed(() => isApplyApproved.value || isApplyPending.value)
|
||
|
||
const isManualApply = computed(() => {
|
||
return (plan.value?.applyMode || 'MANUAL') === 'MANUAL'
|
||
})
|
||
|
||
const showManualApply = computed(() => {
|
||
return !showApplyResult.value && conditionsMet.value && isManualApply.value
|
||
})
|
||
|
||
const showAutoApplyTip = computed(() => {
|
||
return !showApplyResult.value && conditionsMet.value && plan.value?.applyMode === 'AUTO'
|
||
})
|
||
|
||
const showApplyForm = computed(() => {
|
||
return !!plan.value?.requireApplyInfo && fields.value.length > 0
|
||
})
|
||
|
||
const canApply = computed(() => {
|
||
return showManualApply.value && agreed.value
|
||
})
|
||
|
||
const selfPurchaseOk = computed(() => {
|
||
if (!plan.value?.requireSelfPurchaseAmount) return true
|
||
const current = Number(progress.value?.currentSelfPurchaseAmount || 0)
|
||
const min = Number(plan.value?.minSelfPurchaseAmount || 0)
|
||
return current >= min
|
||
})
|
||
|
||
const consumeCountOk = computed(() => {
|
||
if (!plan.value?.requireConsumeCount) return true
|
||
const current = Number(progress.value?.currentConsumeCount || 0)
|
||
const min = Number(plan.value?.minConsumeCount || 0)
|
||
return current >= min
|
||
})
|
||
|
||
|
||
onLoad((query) => {
|
||
recruitToken.value = query?.token || query?.distributionId || ''
|
||
})
|
||
|
||
onShow(() => {
|
||
loadPageData()
|
||
})
|
||
|
||
function loadPageData() {
|
||
loading.value = true
|
||
applySubmitted.value = false
|
||
submitAuditMode.value = ''
|
||
submitApplicationStatus.value = ''
|
||
formInfoCompleted.value = false
|
||
Object.keys(fieldErrors).forEach((key) => delete fieldErrors[key])
|
||
Promise.all([getRecruitPage(), getRecruitProgress()])
|
||
.then(([pageRes, progressRes]) => {
|
||
pageInfo.value = pageRes.data?.result || {}
|
||
progress.value = progressRes.data?.result || null
|
||
})
|
||
.finally(() => {
|
||
loading.value = false
|
||
})
|
||
}
|
||
|
||
function formatMoney(val: number | string | undefined) {
|
||
return Number(val || 0).toFixed(2)
|
||
}
|
||
|
||
function previewPoster() {
|
||
if (!plan.value?.posterBackground) return
|
||
uni.previewImage({
|
||
urls: [plan.value.posterBackground],
|
||
current: plan.value.posterBackground,
|
||
})
|
||
}
|
||
|
||
function goDistributionHome() {
|
||
uni.redirectTo({
|
||
url: '/pages/mine/distribution/home',
|
||
})
|
||
}
|
||
|
||
function openAgreement() {
|
||
agreementVisible.value = true
|
||
}
|
||
|
||
function clearFieldError(fieldId: string) {
|
||
if (fieldErrors[fieldId]) {
|
||
delete fieldErrors[fieldId]
|
||
}
|
||
}
|
||
|
||
function validateFormFields() {
|
||
let valid = true
|
||
Object.keys(fieldErrors).forEach((key) => delete fieldErrors[key])
|
||
fields.value.forEach((field: any) => {
|
||
if (!field.required) return
|
||
const value = formItems[field.id]
|
||
if (value == null || String(value).trim() === '') {
|
||
fieldErrors[field.id] = `请填写${field.fieldName}`
|
||
valid = false
|
||
}
|
||
})
|
||
return valid
|
||
}
|
||
|
||
function confirmApplyForm() {
|
||
if (!validateFormFields()) {
|
||
return
|
||
}
|
||
formInfoCompleted.value = true
|
||
applyFormVisible.value = false
|
||
uni.showToast({ title: '请点击申请成为分销员', icon: 'none' })
|
||
}
|
||
|
||
function doSubmit() {
|
||
const formItemList = showApplyForm.value
|
||
? fields.value.map((field: any) => ({
|
||
fieldId: field.id,
|
||
fieldValue: formItems[field.id] || '',
|
||
}))
|
||
: []
|
||
submitRecruitApplication({
|
||
recruitToken: recruitToken.value,
|
||
agreementAccepted: agreed.value,
|
||
formItems: formItemList,
|
||
}).then((res) => {
|
||
if (res.data?.success) {
|
||
handleApplySuccess(res.data.result)
|
||
if (isApplyApproved.value) {
|
||
uni.showToast({ title: '申请成功', icon: 'success' })
|
||
} else {
|
||
uni.showToast({ title: '已提交,等待审核', icon: 'none' })
|
||
}
|
||
} else {
|
||
uni.showToast({ title: res.data?.message || '提交失败', icon: 'none' })
|
||
}
|
||
})
|
||
}
|
||
|
||
function handleApplySuccess(application: any) {
|
||
const auditMode = application?.auditMode || plan.value?.auditMode || 'MANUAL'
|
||
const status = application?.applicationStatus || 'PENDING'
|
||
applySubmitted.value = true
|
||
submitAuditMode.value = auditMode
|
||
submitApplicationStatus.value = status
|
||
if (auditMode === 'AUTO_PASS' || status === 'APPROVED') {
|
||
pageInfo.value.distributionStatus = 'PASS'
|
||
if (pageInfo.value.currentApplication) {
|
||
pageInfo.value.currentApplication.applicationStatus = 'APPROVED'
|
||
}
|
||
} else if (pageInfo.value.currentApplication) {
|
||
pageInfo.value.currentApplication.applicationStatus = 'PENDING'
|
||
}
|
||
}
|
||
|
||
function submit() {
|
||
if (!tipsToLogin('normal')) {
|
||
return
|
||
}
|
||
if (!showManualApply.value) {
|
||
return
|
||
}
|
||
if (!agreed.value) {
|
||
uni.showToast({ title: '请先同意分销推广服务协议', icon: 'none' })
|
||
return
|
||
}
|
||
if (showApplyForm.value && !formInfoCompleted.value) {
|
||
applyFormVisible.value = true
|
||
return
|
||
}
|
||
doSubmit()
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.wrapper {
|
||
min-height: 100vh;
|
||
padding: 24rpx;
|
||
background: #f5f6f8;
|
||
}
|
||
|
||
.loading,
|
||
.empty {
|
||
text-align: center;
|
||
color: #999;
|
||
padding: 80rpx 0;
|
||
font-size: 28rpx;
|
||
}
|
||
|
||
.section {
|
||
background: #fff;
|
||
border-radius: 16rpx;
|
||
padding: 28rpx;
|
||
margin-bottom: 24rpx;
|
||
}
|
||
|
||
.poster-section {
|
||
padding: 0;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.poster-image {
|
||
display: block;
|
||
width: 100%;
|
||
border-radius: 16rpx 16rpx 0 0;
|
||
background: #f5f5f5;
|
||
}
|
||
|
||
.poster-text {
|
||
padding: 24rpx 28rpx 0;
|
||
font-size: 34rpx;
|
||
font-weight: 600;
|
||
color: #222;
|
||
line-height: 1.4;
|
||
}
|
||
|
||
.poster-benefit {
|
||
padding: 12rpx 28rpx 0;
|
||
font-size: 28rpx;
|
||
color: #ff6b35;
|
||
line-height: 1.5;
|
||
}
|
||
|
||
.poster-rule {
|
||
padding: 12rpx 28rpx 0;
|
||
font-size: 26rpx;
|
||
color: #666;
|
||
line-height: 1.6;
|
||
white-space: pre-wrap;
|
||
}
|
||
|
||
.poster-contact {
|
||
padding: 12rpx 28rpx 24rpx;
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
}
|
||
|
||
.title {
|
||
font-size: 32rpx;
|
||
font-weight: 600;
|
||
margin-bottom: 12rpx;
|
||
color: #222;
|
||
}
|
||
|
||
.condition-tip {
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
margin-bottom: 20rpx;
|
||
}
|
||
|
||
.condition-item {
|
||
padding: 20rpx 0;
|
||
border-bottom: 1rpx solid #f2f2f2;
|
||
}
|
||
|
||
.condition-item:last-of-type {
|
||
border-bottom: none;
|
||
}
|
||
|
||
.condition-head {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-bottom: 10rpx;
|
||
}
|
||
|
||
.condition-label {
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
}
|
||
|
||
.condition-status {
|
||
font-size: 22rpx;
|
||
padding: 4rpx 12rpx;
|
||
border-radius: 8rpx;
|
||
}
|
||
|
||
.condition-status.ok {
|
||
color: #52c41a;
|
||
background: #f6ffed;
|
||
}
|
||
|
||
.condition-status.pending {
|
||
color: #999;
|
||
background: #f5f5f5;
|
||
}
|
||
|
||
.condition-value {
|
||
font-size: 26rpx;
|
||
color: #666;
|
||
}
|
||
|
||
.summary-status {
|
||
margin-top: 20rpx;
|
||
padding: 16rpx 20rpx;
|
||
border-radius: 12rpx;
|
||
font-size: 26rpx;
|
||
text-align: center;
|
||
}
|
||
|
||
.summary-status.ok {
|
||
color: #52c41a;
|
||
background: #f6ffed;
|
||
}
|
||
|
||
.summary-status.pending {
|
||
color: #ff6b35;
|
||
background: #fff7f0;
|
||
}
|
||
|
||
.goods-list {
|
||
margin-top: 12rpx;
|
||
}
|
||
|
||
.goods-item {
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 16rpx 0;
|
||
}
|
||
|
||
.goods-thumb {
|
||
width: 96rpx;
|
||
height: 96rpx;
|
||
border-radius: 12rpx;
|
||
background: #f5f5f5;
|
||
margin-right: 16rpx;
|
||
}
|
||
|
||
.goods-meta {
|
||
flex: 1;
|
||
min-width: 0;
|
||
}
|
||
|
||
.goods-name {
|
||
font-size: 26rpx;
|
||
color: #333;
|
||
line-height: 1.4;
|
||
}
|
||
|
||
.goods-spec,
|
||
.goods-price {
|
||
margin-top: 6rpx;
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
}
|
||
|
||
.field {
|
||
margin-bottom: 20rpx;
|
||
}
|
||
|
||
.label {
|
||
font-size: 26rpx;
|
||
margin-bottom: 8rpx;
|
||
color: #333;
|
||
}
|
||
|
||
.required {
|
||
color: #ff4d4f;
|
||
margin-left: 4rpx;
|
||
}
|
||
|
||
.auto-tip {
|
||
text-align: center;
|
||
}
|
||
|
||
.auto-tip-text {
|
||
font-size: 28rpx;
|
||
color: #52c41a;
|
||
line-height: 1.6;
|
||
}
|
||
|
||
.result-section {
|
||
text-align: center;
|
||
padding: 48rpx 28rpx;
|
||
}
|
||
|
||
.result-icon {
|
||
width: 96rpx;
|
||
height: 96rpx;
|
||
margin: 0 auto 24rpx;
|
||
border-radius: 50%;
|
||
font-size: 48rpx;
|
||
line-height: 96rpx;
|
||
}
|
||
|
||
.result-icon.approved {
|
||
background: #f6ffed;
|
||
color: #52c41a;
|
||
}
|
||
|
||
.result-icon.pending {
|
||
background: #fff7e6;
|
||
color: #fa8c16;
|
||
}
|
||
|
||
.result-title {
|
||
font-size: 36rpx;
|
||
font-weight: 600;
|
||
color: #222;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
|
||
.result-desc {
|
||
font-size: 26rpx;
|
||
color: #999;
|
||
line-height: 1.6;
|
||
margin-bottom: 32rpx;
|
||
}
|
||
|
||
.result-section .submit {
|
||
margin-top: 0;
|
||
}
|
||
|
||
.page-body.with-footer {
|
||
padding-bottom: calc(260rpx + env(safe-area-inset-bottom));
|
||
}
|
||
|
||
.apply-footer-fixed {
|
||
position: fixed;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
z-index: 100;
|
||
}
|
||
|
||
.apply-footer-card {
|
||
background: #fff;
|
||
border-radius: 16rpx 16rpx 0 0;
|
||
padding: 24rpx 28rpx calc(24rpx + env(safe-area-inset-bottom));
|
||
box-shadow: 0 -4rpx 24rpx rgba(0, 0, 0, 0.06);
|
||
}
|
||
|
||
.apply-form-popup {
|
||
padding: 32rpx 32rpx calc(32rpx + env(safe-area-inset-bottom));
|
||
}
|
||
|
||
.apply-form-header {
|
||
margin-bottom: 32rpx;
|
||
}
|
||
|
||
.apply-form-title {
|
||
font-size: 34rpx;
|
||
font-weight: 600;
|
||
color: #222;
|
||
margin-bottom: 12rpx;
|
||
}
|
||
|
||
.apply-form-subtitle {
|
||
font-size: 24rpx;
|
||
color: #999;
|
||
line-height: 1.5;
|
||
}
|
||
|
||
.popup-field {
|
||
margin-bottom: 28rpx;
|
||
}
|
||
|
||
.popup-label {
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
|
||
.popup-input {
|
||
width: 100%;
|
||
height: 88rpx;
|
||
padding: 0 24rpx;
|
||
box-sizing: border-box;
|
||
background: #f7f7f7;
|
||
border-radius: 12rpx;
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
}
|
||
|
||
.field-error {
|
||
margin-top: 10rpx;
|
||
font-size: 24rpx;
|
||
color: #ff4d4f;
|
||
}
|
||
|
||
.popup-next-btn {
|
||
margin-top: 16rpx;
|
||
background: linear-gradient(90deg, #ff8f3f 0%, #ff6b35 100%);
|
||
color: #fff;
|
||
text-align: center;
|
||
padding: 24rpx;
|
||
border-radius: 44rpx;
|
||
font-size: 30rpx;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.agree {
|
||
display: flex;
|
||
align-items: center;
|
||
flex-wrap: wrap;
|
||
gap: 8rpx;
|
||
margin-bottom: 24rpx;
|
||
font-size: 24rpx;
|
||
color: #666;
|
||
}
|
||
|
||
.agreement-link {
|
||
color: $light-color;
|
||
}
|
||
|
||
.agreement-popup {
|
||
padding: 32rpx 28rpx 48rpx;
|
||
max-height: 70vh;
|
||
}
|
||
|
||
.agreement-popup-title {
|
||
font-size: 32rpx;
|
||
font-weight: 600;
|
||
color: #222;
|
||
margin-bottom: 24rpx;
|
||
text-align: center;
|
||
}
|
||
|
||
.agreement-popup-body {
|
||
max-height: 56vh;
|
||
}
|
||
|
||
.agreement-empty {
|
||
text-align: center;
|
||
color: #999;
|
||
font-size: 26rpx;
|
||
padding: 40rpx 0;
|
||
}
|
||
|
||
.submit {
|
||
background: $light-color;
|
||
color: #fff;
|
||
text-align: center;
|
||
padding: 24rpx;
|
||
border-radius: 40rpx;
|
||
font-size: 30rpx;
|
||
}
|
||
|
||
.submit.disabled {
|
||
opacity: 0.5;
|
||
}
|
||
</style>
|