868 lines
22 KiB
Vue
868 lines
22 KiB
Vue
<template>
|
||
<view class="min-h-100vh bg-gray">
|
||
<up-navbar bg-color="transparent" title="分销中心" @leftClick="back" :fixed="true"></up-navbar>
|
||
<view class="top">
|
||
<image class="top_bg" src="/distribution/static/top_bg.png" :style="imageStyle"></image>
|
||
<view class="box" :class="{ type1: isActivated }">
|
||
<view class="u-flex align-center justify-between">
|
||
<view class="u-flex align-center">
|
||
<!-- <up-avatar size="62rpx" /> -->
|
||
<text class="u-m-l-14 font-14 color-333 font-700" @click="distributionClear">{{ state.shopName }}</text>
|
||
</view>
|
||
<view>
|
||
<template v-if="state.parentPhone">
|
||
<view class="font-12 color-666">上级:{{ state.parentName }}{{ state.parentPhone }}</view>
|
||
</template>
|
||
<template v-if="!state.parentPhone">
|
||
<view class="bind" @click="showBindShangji = true">绑定上级</view>
|
||
</template>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="top_content type1 u-m-t-32" v-if="state.distributionUser && state.distributionUser.level">
|
||
<view class="font-14">
|
||
<view class="u-flex align-center">
|
||
<text class="color-666">我的分销等级:</text>
|
||
<text class="color-333 font-700 u-m-r-6" v-if="state.distributionUser">
|
||
{{ state.distributionUser.level }}级 {{ state.distributionUser.levelName }}
|
||
</text>
|
||
<up-icon name="question-circle" size="24rpx" color="#666" @click="questionClick('等级升级条件')" />
|
||
</view>
|
||
<view class="u-m-t-28 u-flex align-center" v-if="juNextLvMoney && state.distributionUser && state.distributionUser.isAssignLevel == 0">
|
||
<text class="color-666">距离下一级还差:</text>
|
||
<text class="color-333 font-700 u-m-r-18">{{ juNextLvMoney }}</text>
|
||
<text class="color-333 font-700 u-m-r-18">{{ config.upgradeType == 'cost' ? '元' : '人' }}</text>
|
||
<!-- <up-icon
|
||
name="question-circle"
|
||
size="24rpx"
|
||
color="#666"
|
||
@click="showRule = true"
|
||
/> -->
|
||
</view>
|
||
<view class="u-flex u-m-t-28">
|
||
<view class="u-flex-1">
|
||
<view class="u-flex align-center">
|
||
<text class="u-m-r-10 font-12 color-666" @click="toShouyiDetail('')">总收益</text>
|
||
<up-icon name="question-circle" size="24rpx" color="#666" @click="questionClick('总收益')" />
|
||
</view>
|
||
<view class="u-m-t-16 price" @click="toShouyiDetail('')" v-if="state.distributionUser">
|
||
{{ state.distributionUser.totalIncome }}
|
||
</view>
|
||
</view>
|
||
<view class="u-flex-1">
|
||
<view class="u-flex align-center">
|
||
<text class="u-m-r-10 font-12 color-666" @click="toShouyiDetail('待入账')">待入账</text>
|
||
<up-icon name="question-circle" size="24rpx" color="#666" @click="questionClick('待入账')" />
|
||
</view>
|
||
<view class="u-m-t-16 price" @click="toShouyiDetail('待入账')" v-if="state.distributionUser">{{ state.distributionUser.pendingIncome }}</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<template v-else>
|
||
<view class="top_content u-m-t-32" v-if="config">
|
||
<template v-if="config.openType == 'auto'">
|
||
<view class="color-333 font-16 font-700">如何成为分销员</view>
|
||
<view class="u-m-t-16 color-666 font-14">
|
||
<view>需要邀请人数:{{ config.inviteCount }}人</view>
|
||
<view>是否需要邀请人数下单:{{ config.inviteConsume ? '是' : '否' }}</view>
|
||
<view>每人可获得的分销奖励次数:{{ config.rewardCount == -1 ? '永久' : config.rewardCount + '次' }}</view>
|
||
</view>
|
||
</template>
|
||
<template v-if="config.openType == 'pay'">
|
||
<view class="color-333 font-16 font-700 text-center">如何成为分销员</view>
|
||
<view class="u-m-t-16 color-666 font-14 text-center">
|
||
<view>只需付费{{ config.payAmount || '' }}元,即可成为分销员</view>
|
||
</view>
|
||
</template>
|
||
<template v-if="config.openType == 'manual'">
|
||
<view class="color-333 font-16 font-700 text-center">如何成为分销员</view>
|
||
<view class="u-m-t-16 color-666 font-14 text-center">
|
||
<view>请联系商家咨询详情</view>
|
||
</view>
|
||
</template>
|
||
</view>
|
||
</template>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="bottom type1" v-if="isActivated">
|
||
<view class="u-flex justify-between align-center">
|
||
<view class="u-flex align-center">
|
||
<view class="color-333 font-16 u-m-r-6">我的邀请({{ inviteUserRes.totalRow }})</view>
|
||
<up-icon name="question-circle" size="24rpx" @click="showRule = true" color="#666" />
|
||
</view>
|
||
<view class="font-10 color-999 u-flex align-center">
|
||
<text>分成比例{{ state.distributionUser.levelOneCommission || 0 }}%</text>
|
||
<up-icon name="question-circle" size="24rpx" color="#666" @click="questionClick('等级分成比例')" />
|
||
</view>
|
||
</view>
|
||
|
||
<view class="tabs" v-if="false">
|
||
<view class="tabs-item" :class="{ active: activeTab == 'distributor' }" @click="activeTab = 'distributor'">分销员</view>
|
||
<view class="tabs-item" :class="{ active: activeTab == 'inviter' }" @click="activeTab = 'inviter'">邀请人</view>
|
||
</view>
|
||
|
||
<view class="u-m-t-48 font-14">
|
||
<view class="u-flex justify-between color-333">
|
||
<view>用户</view>
|
||
<view>获得利益(元)</view>
|
||
<view>邀请时间</view>
|
||
</view>
|
||
<view class="u-m-t-16">
|
||
<view v-for="(item, index) in userList" :key="index" class="u-flex justify-between align-center recoder-item color-666 font-12">
|
||
<view class="">
|
||
<view class="u-line-1" style="max-width: 160rpx">
|
||
<text>
|
||
{{ item.shopUserName }}
|
||
</text>
|
||
</view>
|
||
<view class="u-line-1" style="max-width: 160rpx">
|
||
<text v-if="item.levelName">( {{ item.levelName }})</text>
|
||
</view>
|
||
|
||
<view>{{ desensitizePhone(item.shopUserPhone) }}</view>
|
||
</view>
|
||
<view>
|
||
<text>{{ item.oneIncome }}</text>
|
||
<text v-if="item.distributionLevelName">({{ item.distributionLevelName }})</text>
|
||
</view>
|
||
<view>
|
||
<text v-if="item.inviteTime">{{ item.inviteTime.split(' ')[0] }}</text>
|
||
<text style="color: #fff" v-else>{{ 'yyyy-MM-dd' }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<template v-else>
|
||
<view class="bottom" v-if="config">
|
||
<view class="u-flex">
|
||
<view class="title">规则说明</view>
|
||
</view>
|
||
<view>
|
||
<view class="font-12 color-666 u-m-t-16">
|
||
<view>
|
||
<view>我的收益什么时候可以到账?</view>
|
||
<view>分销的结算时长为{{ config.settlementDay || 0 }}天</view>
|
||
</view>
|
||
<template v-if="config.upgradeType != 'not_upgrade' && config.levelConfigList && config.levelConfigList.length >= 2">
|
||
<view class="u-m-t-40">
|
||
<view>怎么样才能升级分销员等级?</view>
|
||
|
||
<template v-if="config.upgradeType == 'invite' && nextLvMoney">
|
||
<view>邀请的有效人数达到{{ nextLvMoney }}人即可升级</view>
|
||
<view class="u-m-t-40">什么是有效邀请人数?</view>
|
||
<view>被邀请人在店铺消费过,即有一笔订单完成才算有效</view>
|
||
</template>
|
||
<template v-if="config.upgradeType == 'cost' && nextLvMoney">
|
||
<view>消费金额总计达到{{ nextLvMoney }}元即可升级</view>
|
||
</template>
|
||
|
||
<template v-else>
|
||
<view>请联系商家</view>
|
||
</template>
|
||
</view>
|
||
</template>
|
||
|
||
<view class="u-m-t-40" v-if="config.upgradeType == 'cost'">
|
||
<view>消费金额如何计算?</view>
|
||
<view>消费金额是计算您和您邀请的人在店铺消费的总金额,但退款订单不计入</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="parse-html">
|
||
<up-parse :content="content"></up-parse>
|
||
</view>
|
||
<view style="height: 240rpx"></view>
|
||
</template>
|
||
|
||
<view class="tips u-m-t-32" v-if="state.distributionUser && state.distributionUser.status">您的分销员身份已取消,不再获得分成有疑问可联系商家</view>
|
||
|
||
<view class="u-flex justify-center bottom-btn" v-if="showInviteCode">
|
||
<view class="copy" @click="copyCode">
|
||
<view>复制邀请码</view>
|
||
<view v-if="inviteCode">{{ inviteCode }}</view>
|
||
</view>
|
||
<view class="u-flex u-flex-col justify-center">
|
||
<view class="share" @click="showSharePopup = true">分享邀请</view>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="buy" v-if="config.openType == 'pay' && config.payAmount && !isActivated" @click="buy">付费{{ config.payAmount }}元开通</view>
|
||
|
||
<bindShangji v-model="showBindShangji" @confirm="confirmBindShangji"></bindShangji>
|
||
<sharePopup
|
||
v-model="showSharePopup"
|
||
v-if="(state.distributionUser && state.distributionUser.inviteCode) || inviteCode"
|
||
:inviteCode="state.distributionUser ? state.distributionUser.inviteCode : inviteCode"
|
||
:shopUserInfo="shopUserInfo"
|
||
></sharePopup>
|
||
|
||
<TipsPopup v-model="showPopup" :tips-type="tipsType"></TipsPopup>
|
||
<commissionPopup :tipsType="commissionTipsType" v-model="showCommission" :config="config" :levelConfigList="config.levelConfigList || []"></commissionPopup>
|
||
<rulePopup v-model="showRule" :config="config" :distributionUser="state.distributionUser"></rulePopup>
|
||
</view>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { distributionClear } from '@/common/api/market';
|
||
import { shareMixin, handleMixinOnLoad, returnQuery } from '@/utils/share.js';
|
||
import bindShangji from './components/bind-shangji.vue';
|
||
import sharePopup from './components/share-popup.vue';
|
||
import TipsPopup from '../components/tips-popup.vue';
|
||
import commissionPopup from '../components/commission.vue';
|
||
import rulePopup from '../components/rule.vue';
|
||
import { desensitizePhone } from '@/utils/util.js';
|
||
import BigNumber from 'bignumber.js';
|
||
import * as distributionApi from '@/common/api/market/distribution.js';
|
||
import { distributionLtPayOrder } from '@/common/api/order/index.js';
|
||
import { APIshopUserInfo } from '@/common/api/member.js';
|
||
import { pay } from '@/utils/pay.js';
|
||
import { onLoad, onReachBottom } from '@dcloudio/uni-app';
|
||
const showBindShangji = ref(false);
|
||
const showSharePopup = ref(false);
|
||
import { ref, reactive, computed, watch } from 'vue';
|
||
const content = ref('');
|
||
const showPopup = ref(false);
|
||
const showRule = ref(false);
|
||
const showCommission = ref(false);
|
||
const tipsType = ref('');
|
||
const commissionTipsType = ref('');
|
||
|
||
function toShouyiDetail(name) {
|
||
uni.navigateTo({
|
||
url: '/distribution/income-details/index?name=' + name + '&shopId=' + options.shopId
|
||
});
|
||
}
|
||
function questionClick(title) {
|
||
if (title == '总收益') {
|
||
tipsType.value = '总收益';
|
||
showPopup.value = true;
|
||
}
|
||
if (title == '待入账') {
|
||
tipsType.value = '待入账';
|
||
showPopup.value = true;
|
||
}
|
||
if (title == '等级分成比例') {
|
||
commissionTipsType.value = '等级分成比例';
|
||
showCommission.value = true;
|
||
}
|
||
if (title == '等级升级条件') {
|
||
commissionTipsType.value = '等级升级条件';
|
||
showCommission.value = true;
|
||
}
|
||
}
|
||
function back() {
|
||
// uni.navigateBack({
|
||
// delta: 1
|
||
// });
|
||
safeNavigateBack();
|
||
}
|
||
|
||
/**
|
||
* 修复版:安全的页面返回方法
|
||
* 彻底避免 "cannot navigate back at first page" 报错
|
||
* @param {Number} delta 返回的页面数,默认1
|
||
* @param {Function} fallback 失败时的降级处理函数
|
||
*/
|
||
function safeNavigateBack(delta = 1) {
|
||
// 1. 立即获取页面栈,确保拿到最新状态(关键修复点)
|
||
const pages = getCurrentPages();
|
||
// 2. 严谨判断:页面栈长度必须大于 delta 才能返回
|
||
const canNavigateBack = pages.length > delta;
|
||
|
||
console.log('页面栈信息:', {
|
||
pagesLength: pages.length,
|
||
delta: delta,
|
||
canNavigateBack: canNavigateBack
|
||
});
|
||
|
||
// 3. 如果不能返回,直接执行降级逻辑
|
||
if (!canNavigateBack) {
|
||
console.warn('当前是首页/页面栈不足,无法返回');
|
||
handleFallback();
|
||
return; // 终止后续执行,彻底避免调用 navigateBack
|
||
}
|
||
|
||
// 4. 能返回时才执行 navigateBack
|
||
try {
|
||
uni.navigateBack({
|
||
delta: delta,
|
||
success: () => {
|
||
console.log('页面返回成功');
|
||
},
|
||
fail: (err) => {
|
||
console.error('navigateBack 执行失败:', err);
|
||
handleFallback();
|
||
}
|
||
});
|
||
} catch (error) {
|
||
console.error('页面返回异常:', error);
|
||
handleFallback();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 统一处理降级逻辑
|
||
* @param {Function} fallback 自定义降级函数
|
||
*/
|
||
function handleFallback() {
|
||
uni.switchTab({
|
||
url: '/pages/index/index',
|
||
fail: () => {
|
||
uni.redirectTo({
|
||
url: '/pages/index/index'
|
||
});
|
||
}
|
||
});
|
||
}
|
||
|
||
async function confirmBindShangji(code) {
|
||
const res = await distributionApi.bindInviteUser({
|
||
shopId: options.shopId,
|
||
inviteCode: code,
|
||
id: shopUserInfo.value.id
|
||
});
|
||
if (res) {
|
||
uni.showToast({
|
||
title: '绑定成功',
|
||
icon: 'none'
|
||
});
|
||
setTimeout(() => {
|
||
init();
|
||
}, 1500);
|
||
}
|
||
// else {
|
||
// uni.showToast({
|
||
// title: "绑定失败",
|
||
// icon: "none",
|
||
// });
|
||
// }
|
||
}
|
||
function copyCode() {
|
||
uni.setClipboardData({
|
||
data: inviteCode.value,
|
||
success: function () {
|
||
console.log('success');
|
||
}
|
||
});
|
||
}
|
||
|
||
const shopUserInfo = ref();
|
||
const config = reactive({});
|
||
//邀请码
|
||
const inviteCode = ref('');
|
||
async function init() {
|
||
const shopUserRes = await APIshopUserInfo({
|
||
shopId: options.shopId
|
||
});
|
||
|
||
const configRes = await distributionApi.getConfig({
|
||
shopId: options.shopId
|
||
});
|
||
Object.assign(config, configRes);
|
||
|
||
if (shopUserRes) {
|
||
shopUserInfo.value = shopUserRes;
|
||
}
|
||
if (configRes && configRes.openType == 'auto') {
|
||
const codeRes = await distributionApi.getInviteCode({
|
||
shopId: options.shopId,
|
||
shopUserId: shopUserRes.id
|
||
});
|
||
if (codeRes) {
|
||
inviteCode.value = codeRes;
|
||
}
|
||
}
|
||
|
||
const res = await distributionApi.centerConfig({
|
||
shopId: options.shopId
|
||
});
|
||
if (res) {
|
||
if (res.distributionId) {
|
||
options.type = 'activates';
|
||
}
|
||
Object.assign(state, res);
|
||
if (res.distributionUser) {
|
||
inviteCode.value = res.distributionUser.inviteCode;
|
||
}
|
||
content.value = res.config ? res.config.notActivatedPage : '';
|
||
}
|
||
|
||
return res;
|
||
}
|
||
const options = reactive({ type: '' });
|
||
const imageStyle = computed(() => {
|
||
return {
|
||
height: isActivated.value ? '580rpx' : '580rpx'
|
||
};
|
||
});
|
||
|
||
async function buy() {
|
||
const res = await distributionLtPayOrder({
|
||
shopId: options.shopId,
|
||
userId: uni.cache.get('userInfo') ? uni.cache.get('userInfo').id : '',
|
||
returnUrl: '',
|
||
buyerRemark: '',
|
||
amount: '',
|
||
remark: '',
|
||
code: ''
|
||
});
|
||
const payRes = await pay(res);
|
||
if (payRes) {
|
||
uni.showToast({
|
||
title: '购买成功',
|
||
icon: 'none'
|
||
});
|
||
setTimeout(() => {
|
||
init();
|
||
getRecoders();
|
||
}, 1500);
|
||
}
|
||
}
|
||
|
||
const state = reactive({
|
||
parentPhone: '',
|
||
parentName: '',
|
||
shopName: ''
|
||
});
|
||
|
||
const query = reactive({
|
||
page: 1,
|
||
size: 10
|
||
});
|
||
const isEnd = ref(false);
|
||
const activeTab = ref('inviter');
|
||
const userList = ref([]);
|
||
|
||
const inviteUserRes = reactive({
|
||
records: [],
|
||
totalRow: 0,
|
||
totalPage: 0
|
||
});
|
||
async function getRecoders() {
|
||
if (state.config) return;
|
||
const ajaxQuery = {
|
||
...query,
|
||
shopId: options.shopId
|
||
};
|
||
if (activeTab.value == 'distributor') {
|
||
ajaxQuery.parentId = state.distributionUser.distributionId;
|
||
} else {
|
||
ajaxQuery.id = state.distributionUser.distributionId;
|
||
}
|
||
const res = activeTab.value == 'distributor' ? await distributionApi.childUser(ajaxQuery) : await distributionApi.inviteUser(ajaxQuery);
|
||
if (res) {
|
||
Object.assign(inviteUserRes, res);
|
||
if (query.page == 1) {
|
||
userList.value = res.records || [];
|
||
} else {
|
||
userList.value.push(...(res.records || []));
|
||
}
|
||
isEnd.value = query.page >= res.totalPage * 1;
|
||
}
|
||
}
|
||
const nextLvMoney = computed(() => {
|
||
let nextLv = undefined;
|
||
|
||
if (!config.levelConfigList || !config.levelConfigList.length) {
|
||
return '';
|
||
}
|
||
const nowLevel = state.distributionUser ? state.distributionUser.level || 1 : 1;
|
||
if (!nowLevel) {
|
||
nextLv = config.levelConfigList[0];
|
||
} else {
|
||
nextLv = config.levelConfigList.find((v) => v.level == nowLevel + 1);
|
||
}
|
||
|
||
if (nextLv) {
|
||
if (config.upgradeType == 'cost') {
|
||
return nextLv.costAmount;
|
||
}
|
||
if (config.upgradeType == 'invite') {
|
||
return nextLv.inviteCount;
|
||
}
|
||
}
|
||
return '';
|
||
});
|
||
|
||
const juNextLvMoney = computed(() => {
|
||
if (!nextLvMoney.value) {
|
||
return '';
|
||
}
|
||
let total = 0;
|
||
if (config.upgradeType == 'cost' && state.distributionUser) {
|
||
total = new BigNumber(nextLvMoney.value).minus(state.distributionUser.consumeAmount || 0).toNumber();
|
||
}
|
||
if (config.upgradeType == 'invite' && state.distributionUser) {
|
||
total = new BigNumber(nextLvMoney.value).minus(config.inviteCount || 0).toNumber();
|
||
}
|
||
return Math.max(total, 0);
|
||
});
|
||
//是否显示邀请码
|
||
|
||
const showInviteCode = computed(() => {
|
||
if (config.upgradeType == 'invite') {
|
||
return true;
|
||
}
|
||
if (config.openType == 'manual' && (!state.distributionUser || !state.distributionUser.level)) {
|
||
return false;
|
||
}
|
||
if (state.distributionUser && state.distributionUser.level && inviteCode.value) {
|
||
return true;
|
||
}
|
||
if (config.openType == 'auto') {
|
||
return true;
|
||
}
|
||
if (!state.distributionUser && config.openType == 'manual') {
|
||
return true;
|
||
}
|
||
return false;
|
||
});
|
||
|
||
//是否已成为分销员
|
||
const isActivated = computed(() => {
|
||
return state.distributionUser && state.distributionUser.level;
|
||
});
|
||
watch(
|
||
() => activeTab.value,
|
||
(newVal, oldVal) => {
|
||
query.page = 1;
|
||
isEnd.value = false;
|
||
if (newVal != oldVal) {
|
||
getRecoders();
|
||
}
|
||
}
|
||
);
|
||
|
||
function parseQueryString(queryString) {
|
||
const queryParams = queryString.split('&').map((param) => param.split('='));
|
||
const params = {};
|
||
for (const [key, value] of queryParams) {
|
||
params[key] = value;
|
||
}
|
||
return params;
|
||
}
|
||
|
||
// defineOptions({
|
||
// mixins: [shareMixin]
|
||
// });
|
||
|
||
onShareAppMessage(async (res) => {
|
||
let query = await returnQuery();
|
||
return {
|
||
title: `股东共享-${state.shopName}`,
|
||
path: `/distribution/shop-detail/index?${query}`,
|
||
imageUrl: 'https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/3/ec402c96a183489788f9e43430962d04.png',
|
||
query
|
||
};
|
||
});
|
||
|
||
onLoad(async (opt) => {
|
||
try {
|
||
await handleMixinOnLoad(opt);
|
||
if (opt.q) {
|
||
const q = decodeURIComponent(opt.q);
|
||
const params = parseQueryString(q.split('?')[1]);
|
||
Object.assign(options, params);
|
||
} else {
|
||
Object.assign(options, opt);
|
||
}
|
||
console.log(options);
|
||
await init();
|
||
getRecoders();
|
||
} catch (error) {
|
||
console.log(error);
|
||
}
|
||
});
|
||
|
||
onReachBottom(async () => {
|
||
if (!isEnd.value) {
|
||
query.page++;
|
||
await getRecoders();
|
||
}
|
||
});
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
.input-number-box {
|
||
width: 428rpx;
|
||
padding-bottom: 10rpx;
|
||
border-bottom: 1px solid #999;
|
||
font-size: 28rpx;
|
||
align-items: baseline;
|
||
|
||
.fuhao {
|
||
font-size: 64rpx;
|
||
color: #333;
|
||
}
|
||
|
||
.input-number {
|
||
flex: 1;
|
||
height: 100%;
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
padding-left: 24rpx;
|
||
padding-right: 10rpx;
|
||
}
|
||
|
||
.all-in {
|
||
font-size: 28rpx;
|
||
color: #fe7e00;
|
||
}
|
||
}
|
||
|
||
.list {
|
||
.shop-item {
|
||
padding: 32rpx 28rpx;
|
||
border-bottom: 2rpx solid #ededed;
|
||
font-size: 28rpx;
|
||
color: #666;
|
||
display: flex;
|
||
align-items: center;
|
||
|
||
&:last-child {
|
||
border-bottom: none;
|
||
}
|
||
|
||
.fufei {
|
||
color: #e8ad7b;
|
||
}
|
||
|
||
.tag {
|
||
font-size: 24rpx;
|
||
color: #ff1c1c;
|
||
background-color: #ffe4e4;
|
||
padding: 8rpx 20rpx;
|
||
border-radius: 8rpx;
|
||
}
|
||
|
||
.name {
|
||
color: #333;
|
||
font-weight: 700;
|
||
}
|
||
|
||
.shouxufei {
|
||
}
|
||
|
||
.shouyi {
|
||
font-size: 24rpx;
|
||
color: #666;
|
||
text-align: center;
|
||
}
|
||
}
|
||
}
|
||
|
||
.status {
|
||
font-size: 28rpx;
|
||
font-weight: 700;
|
||
text-align: right;
|
||
color: #333333;
|
||
|
||
&.fail {
|
||
color: #ff1c1c;
|
||
}
|
||
}
|
||
|
||
.lingqu {
|
||
font-size: 28rpx;
|
||
border-radius: 8rpx;
|
||
background: #fe6d11;
|
||
padding: 8rpx 16rpx;
|
||
color: #ffffff;
|
||
}
|
||
|
||
.price {
|
||
font-weight: 700;
|
||
font-size: 40rpx;
|
||
color: #333;
|
||
}
|
||
|
||
.top {
|
||
position: relative;
|
||
|
||
.box {
|
||
position: absolute;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
padding: 28rpx 28rpx 52rpx 28rpx;
|
||
|
||
&.type1 {
|
||
padding-bottom: 0;
|
||
}
|
||
}
|
||
|
||
.top_content {
|
||
border: 1px solid rgba(255, 255, 255, 0.8);
|
||
border-radius: 16rpx;
|
||
flex-shrink: 0;
|
||
fill: #ffffff3b;
|
||
stroke-width: 2rpx;
|
||
padding: 32rpx 28rpx;
|
||
stroke: #fff;
|
||
filter: drop-shadow(2rpx -4rpx 13.4rpx #ff6f0124);
|
||
backdrop-filter: blur(5.1rpx);
|
||
|
||
&.type1 {
|
||
filter: none;
|
||
border: none;
|
||
background-color: #fcf5ed;
|
||
border-radius: 36rpx 36rpx 0 0;
|
||
padding: 32rpx 36rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.btn-group {
|
||
position: absolute;
|
||
right: 28rpx;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
|
||
.btn {
|
||
padding: 8rpx 16rpx;
|
||
border-radius: 8rpx;
|
||
font-size: 24rpx;
|
||
border: 2rpx solid #fe6d11;
|
||
|
||
&.shiming {
|
||
color: #fe6d11;
|
||
}
|
||
|
||
&.tixian {
|
||
color: #fff;
|
||
background-color: #fe6d11;
|
||
}
|
||
}
|
||
}
|
||
|
||
.tips {
|
||
padding: 16rpx 18rpx;
|
||
background: #ffe2e2;
|
||
padding: 16rpx 18rpx;
|
||
font-size: 28rpx;
|
||
line-height: 48rpx;
|
||
color: #ff1c1c;
|
||
}
|
||
|
||
.bind {
|
||
padding: 8rpx 32rpx;
|
||
border-radius: 8rpx;
|
||
font-size: 24rpx;
|
||
border: 2rpx solid #fe6d11;
|
||
color: #fff;
|
||
background-color: #fe6d11;
|
||
}
|
||
|
||
.top_bg {
|
||
width: 100%;
|
||
}
|
||
|
||
.bottom {
|
||
margin: 0 28rpx;
|
||
border-radius: 36rpx;
|
||
background-color: #fff;
|
||
transform: translateY(-20rpx);
|
||
padding: 32rpx 28rpx;
|
||
|
||
&.type1 {
|
||
transform: translateY(0);
|
||
margin: 0;
|
||
padding-bottom: 42rpx;
|
||
}
|
||
}
|
||
|
||
.title {
|
||
font-size: 32rpx;
|
||
font-weight: 700;
|
||
color: #333;
|
||
}
|
||
|
||
.small-title {
|
||
font-size: 28rpx;
|
||
font-weight: 700;
|
||
color: #333;
|
||
}
|
||
|
||
.parse-html {
|
||
margin: 32rpx 28rpx;
|
||
font-size: 28rpx;
|
||
}
|
||
|
||
.recoder-item {
|
||
padding: 16rpx 0;
|
||
border-bottom: 2rpx solid #ededed;
|
||
}
|
||
|
||
.share {
|
||
border-radius: 16rpx;
|
||
background: #e8ad7b;
|
||
padding: 14rpx 76rpx;
|
||
font-size: 32rpx;
|
||
line-height: 48rpx;
|
||
color: #fff;
|
||
}
|
||
|
||
.copy {
|
||
padding: 4rpx 30rpx;
|
||
border-radius: 18rpx;
|
||
border: 2rpx solid #e8ad7b;
|
||
background: #fff;
|
||
font-size: 28rpx;
|
||
color: #e8ad7b;
|
||
line-height: 48rpx;
|
||
text-align: center;
|
||
}
|
||
|
||
.bottom-btn {
|
||
position: fixed;
|
||
left: 84rpx;
|
||
right: 84rpx;
|
||
bottom: 100rpx;
|
||
white-space: nowrap;
|
||
gap: 54rpx;
|
||
}
|
||
|
||
.buy {
|
||
padding: 32rpx 224rpx;
|
||
border-radius: 40rpx;
|
||
background: linear-gradient(98deg, #fe6d1100 40.64%, #ffd1b4 105.2%), linear-gradient(259deg, #fe6d11 50.14%, #ffd1b4 114.93%);
|
||
box-shadow: 0 14rpx 30.4rpx 0 #fe8b435e;
|
||
font-size: 32rpx;
|
||
color: #fff;
|
||
font-weight: 700;
|
||
position: fixed;
|
||
left: 28rpx;
|
||
right: 28rpx;
|
||
bottom: 62rpx;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.tabs {
|
||
display: flex;
|
||
margin: 20rpx 0;
|
||
gap: 30rpx;
|
||
|
||
.tabs-item {
|
||
flex: 1;
|
||
padding: 4rpx 30rpx;
|
||
border-radius: 18rpx;
|
||
border: 2rpx solid #e8ad7b;
|
||
background: #fff;
|
||
font-size: 28rpx;
|
||
color: #e8ad7b;
|
||
line-height: 48rpx;
|
||
text-align: center;
|
||
transition: all 0.3s ease-in-out;
|
||
|
||
&.active {
|
||
background-color: #e8ad7b;
|
||
color: #fff;
|
||
}
|
||
}
|
||
}
|
||
</style>
|