mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp.git
synced 2026-08-06 10:57:25 +08:00
feat(distribution): 实现分销员中心完整功能
- 新增分销业绩统计页面,包含时间范围筛选和自定义日期选择功能 - 重构分销认证页面,改为跳转至招募页面申请分销员身份 - 添加分销商品访问记录功能,支持分享追踪和佣金计算 - 更新分销历史记录页面,优化数据结构和显示字段 - 完全重写分销员首页,包含用户信息、收益统计、等级系统等功能
This commit is contained in:
@@ -1,127 +1,756 @@
|
||||
<template>
|
||||
<view class="wrapper" :style="themeStyle">
|
||||
<u-tabs
|
||||
:list="stepList"
|
||||
:scrollable="false"
|
||||
v-model:current="currentStep"
|
||||
:lineColor="lightColor"
|
||||
:activeStyle="{ color: lightColor }"
|
||||
></u-tabs>
|
||||
|
||||
<view class="feedBack-box">
|
||||
<up-form
|
||||
:model="formData"
|
||||
label-position="top"
|
||||
ref="uFormRef"
|
||||
>
|
||||
<up-form-item label="会员昵称" prop="name">
|
||||
<u-input
|
||||
border="none"
|
||||
class="field-input"
|
||||
v-model="formData.name"
|
||||
:custom-style="fieldInputStyle"
|
||||
/>
|
||||
</up-form-item>
|
||||
<up-form-item label="账户类型" prop="name"></up-form-item>
|
||||
<up-form-item label="收款人姓名" prop="name">
|
||||
<u-input
|
||||
border="none"
|
||||
class="field-input"
|
||||
v-model="formData.name"
|
||||
placeholder="请输入收款人姓名"
|
||||
:custom-style="fieldInputStyle"
|
||||
/>
|
||||
</up-form-item>
|
||||
<up-form-item label="收款账号" prop="name">
|
||||
<u-input
|
||||
border="none"
|
||||
class="field-input"
|
||||
v-model="formData.name"
|
||||
placeholder="请输入收款人账号"
|
||||
:custom-style="fieldInputStyle"
|
||||
/>
|
||||
</up-form-item>
|
||||
<up-form-item label="银行名称" prop="name">
|
||||
<u-input
|
||||
border="none"
|
||||
class="field-input"
|
||||
v-model="formData.name"
|
||||
placeholder="请输入开户银行支行名称"
|
||||
:custom-style="fieldInputStyle"
|
||||
/>
|
||||
</up-form-item>
|
||||
</up-form>
|
||||
</view>
|
||||
|
||||
<view class="submit" @click="submitForm">提交</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed } from 'vue'
|
||||
import { onReady } from '@dcloudio/uni-app'
|
||||
import { useStore } from '@/store'
|
||||
import { getThemeStyle } from '@/utils/theme'
|
||||
import { fieldInputStyle } from '@/utils/form-style.js'
|
||||
|
||||
const store = useStore()
|
||||
|
||||
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
||||
const lightColor = computed(() => store.getters.lightColor)
|
||||
const currentStep = ref(0)
|
||||
const uFormRef = ref<any>(null)
|
||||
|
||||
const stepList = [
|
||||
{ name: '推广人资料' },
|
||||
{ name: '平台审核' },
|
||||
{ name: '完成' },
|
||||
]
|
||||
|
||||
const formData = reactive({
|
||||
name: '',
|
||||
radio: '',
|
||||
})
|
||||
|
||||
const rules = {
|
||||
name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
|
||||
}
|
||||
|
||||
onReady(() => {
|
||||
uFormRef.value?.setRules(rules)
|
||||
})
|
||||
|
||||
function submitForm() {
|
||||
uFormRef.value?.validate().catch(() => {
|
||||
uni.showToast({ title: '请填写有效信息', icon: 'none' })
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background: #f8f8f8;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import '@/pages/passport/entry/seller/entry-form.scss';
|
||||
|
||||
.wrapper {
|
||||
box-sizing: border-box;
|
||||
min-height: 100vh;
|
||||
padding: 20rpx 24rpx 40rpx;
|
||||
background: #f8f8f8;
|
||||
@include seller-entry-form;
|
||||
}
|
||||
|
||||
.feedBack-box {
|
||||
background: #fff;
|
||||
border-radius: 20rpx;
|
||||
padding: 32rpx;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.submit {
|
||||
@include seller-entry-submit;
|
||||
}
|
||||
</style>
|
||||
<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>
|
||||
|
||||
Reference in New Issue
Block a user