新增营销系统、分销系统、会员功能、门店、提现功能

This commit is contained in:
Shaw
2024-02-08 21:01:37 +08:00
parent 68b3f2dcc3
commit 17c043348a
1398 changed files with 81279 additions and 56269 deletions

View File

@ -0,0 +1,504 @@
<!--
@name: index
@author: kahu4
@date: 2024-01-17 11:12
@description申请分销商
@update: 2024-01-17 11:12
-->
<script setup>
import Header from '@/components/Header/index.vue'
import AddressSelect from '@/components/AddressSelect/index.vue'
import { useScroll } from "@/hooks/useScroll";
import { onLoad, onPageScroll, onShow } from "@dcloudio/uni-app";
import { useMainStore } from "@/store/store";
import { storeToRefs } from "pinia";
import { nextTick, ref } from "vue";
import { distributionAudit, distributionError } from "@/utils/images";
import { useJump } from "@/hooks/useJump";
import { useInterface } from "@/hooks/useInterface";
import { applyDistribution, checkIsDistribution, updateApply } from "@/api/distribution";
import { useRouter } from "@/hooks/useRouter";
import { getDictByType } from "@/api/global";
import { distributionAgreementUrl } from "@/api/auth";
const {scrollTop} = useScroll()
onPageScroll(() => {
})
const {goDistribution} = useJump()
const {getParams} = useRouter()
const mainStore = useMainStore();
const {user, areaList} = storeToRefs(mainStore);
const {goWebview, goHome} = useJump();
const {push} = useRouter();
const {toast} = useInterface()
// ======================== 表单 ===================================
const showPrivacy = ref(true)
/**
* 设置隐私协议模块是否可见
* 解决键盘弹起fixed内容上顶问题
* @param flag
*/
function setShowPrivacy(flag) {
nextTick(() => {
showPrivacy.value = flag
})
}
const userCheckData = ref({
status: null,
refuse: '',
realName: '',
levelName: '',
superiorName: '',
addUpWages: 0,
refuseAmount: 0,
amount: 0
})
const subLoading = ref(false)
const form = ref({
realName: '',
address: '',
reason: '',
superiorIdP1: undefined
})
function verify() {
// 校验表单
if (agreementFlag.value.length <= 0) {
toast({title: '请先阅读并勾选协议'})
return false
}
if (!form.value.realName) {
toast({title: '请输入真实姓名'})
return false
}
if (!form.value.address) {
toast({title: '请选择真实地址'})
return false
}
return true
}
async function handleSubmit() {
if (subLoading.value) return
if (!verify()) return
try {
subLoading.value = true
if (!isUpdate.value) {
await applyDistribution(form.value)
} else {
await updateApply(form.value)
isUpdate.value = false
}
await doCheckIsDistribution()
} finally {
subLoading.value = false
}
}
/**
* 检查当前用户是否是分销商
* @returns {Promise<void>}
*/
async function doCheckIsDistribution() {
userCheckData.value = await checkIsDistribution();
if (userCheckData.value.status === 1 && !isUpdate.value) {
goDistribution({}, true)
}
return userCheckData.value
}
/**
* 再次申请
*/
function applyForAgain() {
form.value = {
...form.value,
...{
realName: '',
address: '',
reason: ''
}
}
userCheckData.value = {
status: null,
refuse: '',
realName: '',
levelName: '',
superiorName: '',
addUpWages: 0,
refuseAmount: 0,
amount: 0
}
}
// ======================== 地址相关 ================================
const addressPickerRef = ref()
const defaultSelect = ref([0, 0, 0])
function handleChooseAddress() {
addressPickerRef.value.open(isUpdate.value ? form.value.address : '')
}
function handleConfirmAddress(values) {
form.value.address = values.reduce((pre, now, index) => {
if (index === 0) {
pre = now.name
} else {
pre = pre + '-' + now.name
}
return pre
}, '');
}
const agreementFlag = ref([]) // length > 0就是勾选了
/**
* 阅读分销协议
*/
async function readAgreement() {
push({url: '/pages/webview/index'}, {data: {src: distributionAgreementUrl}})
}
const showFlag = ref(false)
onShow(async () => {
showFlag.value = false
if (isUpdate.value) {
const data = await doCheckIsDistribution()
form.value.realName = data.realName
form.value.address = data.address
// form.value.address =
form.value.reason = data.reason
} else {
await doCheckIsDistribution()
}
showFlag.value = true
})
const isUpdate = ref(false)
onLoad(async (options) => {
const params = getParams(options);
// 是否是更新
isUpdate.value = (params && params.update) || false
// 有上级ID处理上级ID
form.value.superiorIdP1 = (params && params.id) || undefined;
})
</script>
<template>
<view
class="apply-for"
v-if="user">
<Header
:scroll-top="scrollTop"
system-bar-area-bg="#fff"
header-area-bg="#fff">申请分销商
</Header>
<view class="inner">
<view class="bg"></view>
<!-- userinfo -->
<view class="userinfo flex flex-column flex-ai__center flex-jc__center">
<image :src="user.avatar" />
<text class="username">{{ userCheckData.realName || user.nickname }}</text>
</view>
<!-- card -->
<view
class="apply-card"
v-if="showFlag">
<!-- form -->
<view
v-if="userCheckData.status === null || isUpdate"
class="form">
<view class="row">
<text class="label">
真实姓名
</text>
<div class="right">
<input
:adjust-position="false"
v-model="form.realName"
type="text"
placeholder="请输入真实姓名"
@focus="setShowPrivacy(false)"
@blur="setShowPrivacy(true)" />
</div>
</view>
<view class="row">
<text class="label">
现居城市
</text>
<div
class="right flex flex-jc__sb flex-ai__center"
@click="handleChooseAddress">
<text
class="placeholder"
v-if="!form.address">
请选择省
</text>
<text
class="placeholder"
v-else>
{{ form.address }}
</text>
<u-icon name="arrow-right" />
</div>
</view>
<view class="row">
<text class="label">
申请原因
</text>
<div class="right">
<input
:adjust-position="false"
@focus="setShowPrivacy(false)"
@blur="setShowPrivacy(true)"
v-model="form.reason"
type="text"
placeholder="请输入申请原因" />
</div>
</view>
<view
class="submit"
:class="{'hide-box':!showPrivacy}">
<view class="tips">提交成功后我们将会在1-3个工作日内给您回复</view>
<view
class="button animation-button"
@click="handleSubmit">提交审核
</view>
<view class="agreement tips flex flex-ai__center">
<u-checkbox-group
activeColor="#ed6d47"
shape="circle"
v-model="agreementFlag"
>
<u-checkbox
name=""
/>
</u-checkbox-group>
勾选代表同意
<text
class="primary-color"
@click="readAgreement">分销协议
</text>
</view>
</view>
</view>
<!-- state success -->
<view
class="state"
v-if="userCheckData.status === 0 && !isUpdate">
<image :src="distributionAudit" />
<view class="title">申请提交成功请耐心等待...</view>
<view
class="btn"
@click="goHome">继续逛逛
</view>
</view>
<!-- state error -->
<view
class="state"
v-if="userCheckData.status === 2 && !isUpdate">
<image :src="distributionError" />
<view class="title">不好意思商家拒绝了您的申请...</view>
<view class="sub-title">拒绝理由{{ userCheckData.refuse }}</view>
<view class="flex flex-jc__center flex-ai__center">
<view
class="btn line-btn"
@click="applyForAgain">
再次申请
</view>
<view
class="btn"
@click="goHome">
继续逛逛
</view>
</view>
</view>
<!-- state 清退 -->
<view
class="state"
v-if="userCheckData.status === -1 && !isUpdate">
<image :src="distributionError" />
<view class="title">您已被清退请重新申请</view>
<view class="sub-title">{{ userCheckData.refuse }}</view>
<view class="flex flex-jc__center flex-ai__center">
<view
class="btn line-btn"
@click="applyForAgain">
再次申请
</view>
<view
class="btn"
@click="goHome">
继续逛逛
</view>
</view>
</view>
</view>
</view>
<AddressSelect
ref="addressPickerRef"
v-model:default-value="defaultSelect"
@confirm="handleConfirmAddress" />
</view>
</template>
<style
scoped
lang="scss">
.apply-for {
width: 100%;
position: relative;
.header {
position: relative;
}
.inner {
position: relative;
.bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
aspect-ratio: 750/460;
background: #333333;
z-index: 0;
}
.userinfo {
position: relative;
z-index: 1;
width: 100%;
@include usePadding(0, 72);
image {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
border: 4rpx solid #fff;
}
.username {
color: #fff;
font-size: 34rpx;
margin-top: 30rpx;
font-weight: bold;
}
}
.apply-card {
position: relative;
z-index: 1;
background: #f6f6f6;
border-radius: 30rpx;
@include usePadding(34, 34);
.form {
width: 100%;
background: #fff;
@include usePadding(32, 0);
border-radius: 30rpx;
.row {
@include useFlex(flex-start, center);
.label {
font-size: 28rpx;
margin-right: 24rpx;
}
.right {
@include usePadding(0, 32);
border-bottom: 1rpx solid #f6f6f6;
flex-grow: 1;
.placeholder {
color: #808080;
}
}
}
.submit {
width: 80%;
position: fixed;
bottom: 50rpx;
@include useFlex(center, center, column);
.tips {
color: $tips-color;
font-size: 24rpx;
}
.button {
width: 100%;
margin-top: 30rpx;
height: 80rpx;
@include useFlex(center, center);
border-radius: 15rpx;
}
.agreement {
margin-top: 30rpx;
}
}
}
.state {
width: 100%;
@include useFlex(center, center, column);
@include usePadding(0, 50);
image {
width: 170rpx;
height: 170rpx;
}
.title {
font-size: 28rpx;
margin-bottom: 12rpx;
}
.sub-title {
font-size: 24rpx;
margin-bottom: 32rpx;
color: $tips-color
}
.btn {
width: 230rpx;
height: 80rpx;
background: #333333;
color: #fff;
@include useFlex(center, center, column);
border-radius: 15rpx;
margin: 30rpx 15rpx;
}
.line-btn {
background: #fff;
border: 1rpx solid #333333;
color: #333;
box-sizing: border-box;
}
}
}
}
}
.hide-box {
bottom: -500rpx !important;
}
</style>

View File

@ -0,0 +1,67 @@
import {
distributionGoods,
distributionMoney,
distributionOrder,
distributionShare,
distributionTeam,
distributionUser
} from "@/utils/images";
import { useJump } from "@/hooks/useJump";
const {
goDistribution,
goDistributionApplyFor,
goDistributionTeam,
goDistributionCommission,
goDistributionOrder,
goDistributionGoods,
goDistributionDatum
} = useJump();
export const distributionCenterInfoList = [
{
label: '总收益(元)',
field: 'addUpWages'
},
{
label: '待入账佣金(元)',
field: 'refuseAmount'
},
{
label: '已入账佣金(元)',
field: 'amount'
}
]
export const distributionCenterCardList = [
{
label: '我的团队',
path: goDistributionTeam,
icon: distributionTeam
},
{
label: '佣金明细',
path: goDistributionCommission,
icon: distributionMoney
},
{
label: '分销订单',
path: goDistributionOrder,
icon: distributionOrder
},
{
label: '推广商品',
path: (data) => goDistributionGoods({distributionId: data.id}),
icon: distributionGoods
},
{
label: '邀请海报',
path: 'share',
icon: distributionShare
},
{
label: '我的资料',
path: goDistributionDatum,
icon: distributionUser
}
]

View File

@ -0,0 +1,307 @@
<!--
@name: index
@author: kahu4
@date: 2024-01-17 11:12
@description分销中心
@update: 2024-01-17 11:12
-->
<script setup>
import Header from "@/components/Header/index.vue";
import { useScroll } from "@/hooks/useScroll";
import { onLoad, onPageScroll, onShareAppMessage, onShareTimeline, onShow } from "@dcloudio/uni-app";
import { useMainStore } from "@/store/store";
import { storeToRefs } from "pinia";
import { computed, ref } from "vue";
import { distributionCenterCardList, distributionCenterInfoList } from "@/views/distribution/center/index.data";
import DistributionShare from '@/components/Share/Distribution.vue'
import DistributionPoster from '@/components/Poster/Distribution.vue'
import { checkIsDistribution } from "@/api/distribution";
import { useJump } from "@/hooks/useJump";
import { SharePathKey, useShare } from "@/hooks/useShare";
import { useRouter } from "@/hooks/useRouter";
// ========================= hooks =========================
const {scrollTop} = useScroll();
const {getParams} = useRouter();
const {goDistributionApplyFor} = useJump();
const {distributionShare, shareAppMessage, shareTimeline, shareH5} = useShare();
onShareAppMessage(shareAppMessage)
onShareTimeline(shareTimeline)
onPageScroll(() => {
})
const mainStore = useMainStore();
const {user} = storeToRefs(mainStore);
const phoneEncrypt = computed(() => {
if (!user.value || !user.value.mobile) return '-'
const truePhone = user.value.mobile
return `${ truePhone.slice(0, 3) }****${ truePhone.slice(-4) }`
})
const distributionShareRef = ref()
const distributionPosterRef = ref()
/**
* 确认分享
* @param shareItem
*/
function shareConfirm(shareItem) {
// 调用share方法
const shareInfo = distributionShare(userDistributionInfo.value.id);
if (shareItem.value === 'photo') {
distributionPosterRef.value.open(shareInfo, userDistributionInfo.value)
} else {
// 邀请好友 处理h5 微信的邀请逻辑已经在share组件内部做了
shareH5()
}
}
/**
* 点击了卡片选项
* @param cardItem
*/
function clickCardItem(cardItem) {
if (cardItem.path === 'share') {
distributionShareRef.value.open()
return
}
if (typeof cardItem.path === 'function') {
cardItem.path(userDistributionInfo.value)
}
}
// 经销商详情
const userDistributionInfo = ref({
id: '',
status: -1,
refuse: '',
realName: '',
levelName: '',
superiorName: '',
addUpWages: 0,
refuseAmount: 0,
amount: 0
})
// 是否展示当前页面
const showPage = ref(false)
/**
* 检查当前用户是否是分销商
* @returns {Promise<void>}
*/
async function doCheckIsDistribution() {
userDistributionInfo.value = await checkIsDistribution();
// 使用一个flag避免页面山东问题
if (userDistributionInfo.value.status !== 1) {
// status不等于2不是经销商跳转申请页面
goDistributionApplyFor({id: shareId.value}, true)
// showPage.value = true
} else {
// 否则展示
showPage.value = true
}
}
onShow(() => {
doCheckIsDistribution()
})
const shareId = ref(undefined)
onLoad((options) => {
const params = getParams(options);
// 处理是否是扫码跳转过来的扫码跳转过来的会携带上级ID赋值给shareId并且传递给申请页面处理
if (Reflect.ownKeys(params).length > 0 && params.t && params.t === SharePathKey.DISTRIBUTION_USER) {
shareId.value = params.id
}
})
</script>
<template>
<Header
:scroll-top="scrollTop"
system-bar-area-bg="#fff"
header-area-bg="#fff">
分销中心
</Header>
<view
class="distribution-center"
v-if="showPage">
<!-- userinfo -->
<view
class="userinfo-box flex flex-jc__start"
v-if="user">
<image
class="user-header"
:src="user.avatar" />
<view class="userinfo flex flex-column flex-jc__sb">
<view class="phone"> {{ phoneEncrypt }}</view>
<view class="tag-list flex flex-jc__start flex-ai__center flex-wrap">
<view class="tag-item primary-color">
{{ userDistributionInfo.superiorName }} 推荐
</view>
<view class="tag-item">
分销等级 {{ userDistributionInfo.levelName }}
</view>
</view>
</view>
</view>
<!-- 分销信息 -->
<view class="distribution-card">
<view class="info-row flex flex-ai__center flex-jc__sa">
<view
class="item"
v-for="infoItem in distributionCenterInfoList"
:key="infoItem.field">
<span class="data"> {{ userDistributionInfo[infoItem.field] || '0.00' }} </span>
<span class="title">{{ infoItem.label }}</span>
</view>
</view>
<!-- grid -->
<view class="grid-row">
<view
class="item"
v-for="cardItem in distributionCenterCardList"
:key="cardItem.label"
@click="clickCardItem(cardItem)">
<image :src="cardItem.icon" />
<text>{{ cardItem.label }}</text>
</view>
</view>
</view>
<DistributionShare
ref="distributionShareRef"
@share="shareConfirm" />
<DistributionPoster ref="distributionPosterRef" />
</view>
</template>
<style lang="scss">
page {
background: $page-bg-color;
}
</style>
<style
scoped
lang="scss">
.distribution-center {
width: 100%;
min-height: 100vh;
background: linear-gradient(to bottom, #fdfdfd, $page-bg-color);
@include usePadding(30, 30);
.userinfo-box {
width: 100%;
.user-header, .userinfo {
flex-shrink: 0
}
.user-header {
width: 120rpx;
height: 120rpx;
border-radius: 50%
}
.userinfo {
margin-left: 24rpx;
font-size: 44rpx;
font-weight: bold;
max-width: 80%;
.tag-list {
margin-top: 5rpx;
gap: 10rpx;
.tag-item {
font-size: 20rpx;
flex-shrink: 0;
@include usePadding(16, 5);
border-radius: 50rpx;
border: 1rpx solid #697591;
color: #697591;
}
}
}
}
.distribution-card {
margin-top: 30rpx;
width: 100%;
background: #333333;
color: #fff;
border-radius: 15rpx;
.info-row {
@include usePadding(0, 30);
.item {
@include useFlex(center, center, column);
font-size: 32rpx;
position: relative;
flex: 1 0 auto;
.title {
font-size: 24rpx;
color: $tips-color;
}
&:after {
content: '';
position: absolute;
top: 50%;
right: 0;
transform: translateY(-50%);
width: 2rpx;
border-radius: 2rpx;
height: 50%;
background: #fff;
}
&:last-child {
&:after {
width: 0;
}
}
}
}
.grid-row {
@include usePadding(0, 48);
background: #fff;
color: #2B2B2B;
display: grid;
grid-template-columns: repeat(4, 1fr);
row-gap: 32rpx;
border-radius: 15rpx;
.item {
@include useFlex(center, center, column);
transition: all .3s;
image {
width: 60rpx;
height: 60rpx;
background: #fbfbfb;
}
text {
margin-top: 16rpx;
font-size: 24rpx;
}
&:active {
scale: 0.9;
}
}
}
}
}
.primary-color {
border-color: $primary-color !important;
color: $primary-color !important;
}
</style>

View File

@ -0,0 +1,414 @@
<!--
@name: index
@author: kahu4
@date: 2024-01-17 15:53
@description佣金明细
@update: 2024-01-17 15:53
-->
<script setup>
import Header from '@/components/Header/index.vue'
import { onLoad, onShow, onPageScroll } from "@dcloudio/uni-app";
import { useScroll } from "@/hooks/useScroll";
import { ref } from "vue";
import moment from "moment";
import { usePaging } from "@/hooks/usePaging";
import { checkIsDistribution, getMyCommissionDetail, pageCommission } from "@/api/distribution";
import { emptyOrderIcon } from "@/utils/images";
import Empty from "@/components/Empty/index.vue";
import { useJump } from "@/hooks/useJump";
// ================================= hooks ================================
const {scrollTop} = useScroll()
const {goWithdraw} = useJump()
onPageScroll(() => {
})
// ============================== 数据 ==================================
const {otherParams, list, loading, refreshPage} = usePaging({
request: pageCommission,
});
const myCommissionDetail = ref({
income: 0, // 总收入
expenses: 0 // 总支出
})
/**
* 获取总收入、总支出
* @return {Promise<void>}
*/
async function doGetMyCommissionDetail() {
myCommissionDetail.value = await getMyCommissionDetail({createTime: otherParams.value.createTime});
}
const userDistributionInfo = ref({
status: -1,
refuse: '',
realName: '',
levelName: '',
superiorName: '',
addUpWages: 0,
refuseAmount: 0,
amount: 0
})
/**
* 查询分销商详细信息
* @returns {Promise<void>}
*/
async function doCheckIsDistribution() {
userDistributionInfo.value = await checkIsDistribution();
}
onShow(() => {
doCheckIsDistribution()
})
onLoad(() => {
otherParams.value.createTime = [`${ selectTimeStr.value } 00:00:00`, `${ selectTimeStr.value } 23:59:59`]
refreshPage()
doGetMyCommissionDetail()
})
// ======================== level tab ====================
const leverTabs = [
{
label: '全部',
filed: '',
value: 0
}, {
label: '收入',
filed: '',
value: 1
}, {
label: '支出',
filed: '',
value: 4
}]
const leverCurrent = ref(0)
function leverSelect(value) {
leverCurrent.value = value
if (value !== 0) {
otherParams.value.type = value
} else {
delete otherParams.value.type
}
refreshPage()
}
// ============================ time ===========================
const selectTimeStr = ref(moment(Date.now()).format('YYYY-MM-DD'))
const showTime = ref(false)
const timeModelValue = ref(Date.now())
function doShowTime() {
showTime.value = true
}
function dateTimeConfirm(e) {
selectTimeStr.value = moment(e.value).format('YYYY-MM-DD')
otherParams.value.createTime = [`${ selectTimeStr.value } 00:00:00`, `${ selectTimeStr.value } 23:59:59`]
showTime.value = false
refreshPage()
doGetMyCommissionDetail()
}
const colorType = ['red-color', '', 'red-color', 'yellow-color', 'green-color', 'red-color']
const statusType = ['待入账', '已入账', '已取消', '提现中', '提现成功', '提现失败']
</script>
<template>
<view class="commission">
<Header
:scroll-top="scrollTop"
system-bar-area-bg="#fff"
header-area-bg="#fff">佣金明细
</Header>
<view class="commission__inner">
<!-- 账户信息-->
<view class="account-card">
<view class="header flex flex-jc__sb flex-ai__center">
<view class="col">
<view class="title grey-color">
总收益
</view>
<view class="money">
{{ userDistributionInfo.addUpWages || '0.00' }}
</view>
</view>
<view class="col flex flex-jc__sb flex-ai__center btn-group">
<view
class="btn line-btn"
@click="goWithdraw({type:0,maxMoney:userDistributionInfo.amount||0})"> 提现
</view>
<view
class="btn"
@click="goWithdraw({type:1,maxMoney:userDistributionInfo.amount||0})">转余额
</view>
</view>
</view>
<view class="gradation-line"></view>
<view class="bottom">
<view class="item">
<view class="title grey-color">待入账佣金</view>
<view class="count"> {{ userDistributionInfo.refuseAmount || '0.00' }}</view>
</view>
<view class="item">
<view class="title grey-color">可提现佣金</view>
<view class="count"> {{ userDistributionInfo.amount || '0.00' }}</view>
</view>
</view>
</view>
<!-- 筛选 -->
<view class="filtrate-row flex flex-ai__center flex-jc__sb">
<view
class="date flex flex-ai__center"
@click="doShowTime">
{{ selectTimeStr }}
<u-icon
name="arrow-down"
color="#333" />
</view>
<view class="info grey-color">
总收入{{ myCommissionDetail.income }} 总支出{{ myCommissionDetail.expenses }}
</view>
</view>
<!-- 佣金明细列表 -->
<view class="money-list">
<!-- tab -->
<view class="tab-content">
<view
class="tab-item"
:class="{current:leverCurrent===lever.value}"
v-for="lever in leverTabs"
:key="lever.value"
@click="leverSelect(lever.value)"
>
{{ lever.label }}
</view>
</view>
<!-- money-item -->
<template v-if="list.length>0">
<view
class="money-item flex flex-jc__sb"
v-for="item in list">
<view class="left flex flex-column flex-jc__sb">
<view class="name">{{ item.distributorName }}</view>
<view class="id">订单号{{ item.orderId }}</view>
</view>
<view class="right">
<view class="title">
<text v-if="item.type===1"> +</text>
<text v-if="item.type===4"> -</text>
${{ item.amount }}
</view>
<view
class="status"
:class="[colorType[item.type]]">
{{ statusType[item.type] }}
</view>
</view>
</view>
</template>
<Empty
padding="30rpx 0 0 0"
:iconSrc="emptyOrderIcon"
v-else
>
您还没有相关订单~
</Empty>
</view>
</view>
<!-- 时间选择器 -->
<u-datetime-picker
:show="showTime"
v-model="timeModelValue"
mode="date"
@confirm="dateTimeConfirm"
@cancel="showTime=false"
/>
</view>
</template>
<style
scoped
lang="scss">
.commission {
&__inner {
@include usePadding(34, 34);
.account-card {
@include usePadding(32, 32);
width: 100%;
background: #333333;
border-radius: 15rpx;
color: #fff;
font-size: 28rpx;
.header {
padding-bottom: 32rpx;
//border-bottom: 1rpx dashed #f5f5f5;
.col {
.money {
font-size: 48rpx;
font-weight: bold;
}
.btn {
@include usePadding(24, 13);
background: #fff;
color: #333;
border-radius: 15rpx;
}
.line-btn {
border: 1rpx solid #fff;
background: #333;
color: #fff;
}
}
.btn-group {
gap: 20rpx
}
}
.gradation-line {
margin: 0 auto;
width: 90%;
height: 1rpx;
background: linear-gradient(to right, #333333, #f5f5f5, #333);
}
.bottom {
margin-top: 32rpx;
display: grid;
grid-template-columns: repeat(2, 1fr);
.item {
font-size: 28rpx;
.count {
font-size: 32rpx;
margin-top: 5rpx;
}
}
}
}
.filtrate-row {
font-size: 28rpx;
color: #333;
margin: 24rpx 0;
.date {
font-weight: 600;
}
.info {
font-size: 24rpx;
}
}
.money-list {
@include usePadding(32, 32);
border-radius: 15rpx;
background: #fff;
.tab-content {
width: 100%;
background: #fff;
padding-bottom: 20rpx;
border-bottom: 1rpx solid #f5f5f5;
@include useFlex(space-between, center, row, nowrap, 30rpx);
.tab-item {
@include usePadding(0, 16);
text-align: center;
border-radius: 15rpx;
flex: 1 0 auto;
background: #f6f8f8;
color: #333333;
transition: all .3s;
&.current {
background: $primary-color;
color: $white-color;
}
}
}
.money-item {
@include usePadding(0, 20);
width: 100%;
border-bottom: 1rpx solid #f5f5f5;
&:last-child {
border-bottom: none;
}
.left {
color: $tips-color;
.name {
color: #333;
font-weight: bold;
font-size: 28rpx;
}
.id {
font-size: 24rpx;
}
}
.right {
.title {
color: #333;
font-weight: bold;
font-size: 28rpx;
}
.status {
@include usePadding(24, 4);
background: #f6f6f6;
color: #999999;
border-radius: 50rpx;
font-size: 24rpx;
margin-top: 20rpx;
}
}
}
}
.grey-color {
color: $tips-color;
}
}
}
.orange-color {
background: #E85A2B12 !important;
color: #E85A2B !important;
}
.yellow-color {
background: #FFFADF !important;
color: #E8A31D !important;
}
.green-color {
background: #EAF9EC !important;
color: #28c445 !important;
}
.red-color {
background: rgba(232, 43, 150, 0.07) !important;
color: #df151c !important;
}
</style>

View File

@ -0,0 +1,243 @@
<!--
@name: index
@author: kahu4
@date: 2024-01-17 11:12
@description我的资料
@update: 2024-01-17 11:12
-->
<script setup>
import Header from '@/components/Header/index.vue'
import { useScroll } from "@/hooks/useScroll";
import { onPageScroll } from "@dcloudio/uni-app";
import { useMainStore } from "@/store/store";
import { storeToRefs } from "pinia";
import { checkIsDistribution } from "@/api/distribution";
import { ref } from "vue";
import { useJump } from "@/hooks/useJump";
const {goDistributionApplyFor} = useJump();
const {scrollTop} = useScroll()
onPageScroll(() => {
})
const mainStore = useMainStore();
const {user, areaList} = storeToRefs(mainStore);
const distributionDetailsInfo = ref({})
async function doGetDistributionDetails() {
distributionDetailsInfo.value = await checkIsDistribution();
}
function doUpdate() {
goDistributionApplyFor({update: true})
}
doGetDistributionDetails()
</script>
<template>
<view
class="apply-for"
v-if="user">
<Header
:scroll-top="scrollTop"
system-bar-area-bg="#fff"
header-area-bg="#fff">我的资料
</Header>
<view
class="inner"
v-if="distributionDetailsInfo.realName">
<view class="bg"></view>
<!-- userinfo -->
<view class="userinfo flex flex-column flex-ai__center flex-jc__center">
<image :src="user.avatar" />
<text class="username">{{ user.nickname }}</text>
</view>
<!-- card -->
<view class="apply-card">
<!-- form -->
<view class="form">
<view class="row">
<text class="label">
真实姓名
</text>
<div class="right">
<input
type="text"
disabled
v-model="distributionDetailsInfo.realName"
placeholder="请输入真实姓名" />
</div>
</view>
<view class="row">
<text class="label">
现居城市
</text>
<div
class="right flex flex-jc__sb flex-ai__center">
<text class="placeholder">{{ distributionDetailsInfo.address || '-' }}</text>
</div>
</view>
<view class="row">
<text class="label">
申请原因
</text>
<div class="right">
<input
disabled
v-model="distributionDetailsInfo.reason"
type="text"
placeholder="请输入申请原因" />
</div>
</view>
<view class="submit">
<view
class="button animation-button"
@click="doUpdate">修改信息
</view>
</view>
</view>
</view>
</view>
</view>
</template>
<style
scoped
lang="scss">
.apply-for {
width: 100%;
position: relative;
.header {
position: relative;
}
.inner {
position: relative;
.bg {
position: absolute;
top: 0;
left: 0;
width: 0;
aspect-ratio: 750/460;
background: #333333;
z-index: 0;
}
.userinfo {
position: relative;
z-index: 1;
width: 100%;
@include usePadding(0, 72);
image {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
border: 4rpx solid #fff;
}
.username {
font-size: 34rpx;
margin-top: 30rpx;
font-weight: bold;
}
}
.apply-card {
position: relative;
z-index: 1;
background: #f6f6f6;
border-radius: 30rpx;
@include usePadding(34, 34);
.form {
width: 100%;
background: #fff;
@include usePadding(32, 0);
border-radius: 30rpx;
.row {
@include useFlex(flex-start, center);
.label {
font-size: 28rpx;
margin-right: 24rpx;
}
.right {
@include usePadding(0, 32);
border-bottom: 1rpx solid #f6f6f6;
flex-grow: 1;
.placeholder {
color: #808080;
}
}
}
.submit {
width: 80%;
position: fixed;
bottom: 50rpx;
@include useFlex(center, center, column);
.tips {
color: $tips-color;
font-size: 24rpx;
}
.button {
width: 100%;
margin-top: 30rpx;
height: 80rpx;
@include useFlex(center, center);
border-radius: 15rpx;
}
}
}
.state {
width: 100%;
@include useFlex(center, center, column);
@include usePadding(0, 50);
image {
width: 170rpx;
height: 170rpx;
}
.title {
font-size: 28rpx;
margin-bottom: 32rpx;
}
.btn {
width: 230rpx;
height: 80rpx;
background: #333333;
color: #fff;
@include useFlex(center, center, column);
border-radius: 15rpx;
margin: 0 15rpx;
}
.line-btn {
background: #fff;
border: 1rpx solid #333333;
color: #333;
box-sizing: border-box;
}
}
}
}
}
</style>

View File

@ -0,0 +1,159 @@
<!--
@name: index
@author: kahu4
@date: 2024-01-17 17:00
@description分销商品
@update: 2024-01-17 17:00
-->
<script setup>
import Header from '@/components/Header/index.vue'
import { useScroll } from "@/hooks/useScroll";
import { onLoad, onPageScroll, onShareAppMessage, onShareTimeline } from "@dcloudio/uni-app";
import { onMounted, ref } from "vue";
import GoodsCom from "@/components/goodsComponents/Goods.vue";
import { usePage } from "@/hooks";
import { getProductList } from "@/api/product";
import { useRouter } from "@/hooks/useRouter";
import { useMainStore } from "@/store/store";
import { useShare } from "@/hooks/useShare";
import GoodsSharePopup from '@/components/Share/Goods.vue'
import GoodsPoster from '@/components/Poster/Goods.vue'
const mainStore = useMainStore();
const {scrollTop} = useScroll()
onPageScroll(() => {
})
const {refresh, dataList, loadend, loading, listEmpty, otherQuery} = usePage(getProductList)
const {shareAppMessage, shareTimeline, distributionGoodsDetailShare, shareH5} = useShare();
onShareAppMessage(shareAppMessage)
onShareTimeline(shareTimeline)
const {push, getParams} = useRouter()
const distributorId = ref()
onLoad((options) => {
const params = getParams(options);
distributorId.value = params.distributionId
otherQuery.value = {
isDistribution: 1
}
})
// ======================= 分享相关 ================================
const goodsShare = ref()
const goodsPoster = ref()
function doShare(goods) {
goodsShare.value.open('分享赚', goods)
}
async function shareConfirm(shareItem, goods) {
distributionGoodsDetailShare(goods, distributorId.value)
if (shareItem.value === 'photo') {
goodsPoster.value.open(goods)
return
}
if (shareItem.value === 'wechat') {
shareH5()
}
}
onMounted(() => {
refresh()
})
</script>
<template>
<view class="goods-list">
<Header
:scroll-top="scrollTop"
system-bar-area-bg="#fff"
header-area-bg="#fff"> 分销商品
</Header>
<view class="goods-list__inner">
<template
v-for="item in dataList"
:key="item.id"
>
<view class="product">
<GoodsCom
row
img-width="160rpx"
:ratio="true"
:goods="item"
infoPadding="10rpx 10rpx"
>
<template #options>
<view class="good-bottom">
<view class="price">
{{ item.price }}
</view>
<view class="sale flex flex-jc__sb flex-ai__end">
<view class="left">
<text class="gray-color">预计佣金</text>
999-999
</view>
<view
class="btn"
@click.stop="doShare(item)">
分享赚
</view>
</view>
</view>
</template>
</GoodsCom>
</view>
</template>
</view>
<GoodsSharePopup
ref="goodsShare"
@share="shareConfirm" />
<GoodsPoster ref="goodsPoster" />
</view>
</template>
<style
scoped
lang="scss">
.goods-list {
&__inner {
width: 100%;
@include usePadding(34, 34);
.product {
background: #fff;
border-radius: 15rpx;
margin-bottom: 20rpx;
.good-bottom {
width: 100%;
.price {
color: $primary-color;
font-size: 30rpx;
}
.sale {
width: 100%;
font-size: 24rpx;
.btn {
@include usePadding(24, 11);
color: #fff;
background: #333;
border-radius: 15rpx;
margin-right: 20rpx;
}
}
}
}
}
}
.gray-color {
color: $tips-color;
}
</style>

View File

@ -0,0 +1,142 @@
<!--
@name: DistributorDataItem
@author: kahu4
@date: 2024-01-17 15:50
@descriptionDistributorDataItem
@update: 2024-01-17 15:50
-->
<script setup>
import { distributorDataList } from "../index.data";
import { computed, toRefs } from "vue";
const props = defineProps({
data: {
type: Object,
required: true
}
})
const {data} = toRefs(props)
const tagType = computed(() => {
return ["待结算", "已结算", "已取消"][data.value.status]
})
const tagClass = computed(() => {
return ["", "success-tag", "default-tag"][data.value.status]
})
</script>
<template>
<view class="user-item">
<view class="userinfo-row flex flex-jc__start">
<view class="userinfo flex flex-column flex-jc__sb">
<view class="username flex flex-jc__sb">
{{ data.userName }}
<text
class="tag default-tag"
:class="tagClass">
{{ tagType }}
</text>
</view>
<view class="time">订单号{{ data.orderId }}</view>
</view>
</view>
<view class="distribution-info-row">
<view
class="info-item"
v-for="distributorData in distributorDataList"
:key="distributorData.label">
<view class="title">{{ distributorData.label }}</view>
<view class="count">{{ data[distributorData.field] || 0 }}</view>
</view>
</view>
</view>
</template>
<style
scoped
lang="scss">
.user-item {
margin-bottom: 16rpx;
@include usePadding(32, 32);
background: $white-color;
border-radius: 15rpx;
.userinfo-row {
padding-bottom: 16rpx;
margin-bottom: 16rpx;
border-bottom: 1rpx solid $page-bg-color;
image {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
margin-right: 24rpx;
background: #fbfbfb;
}
.userinfo {
width: 100%;
.username {
width: 100%;
font-size: 28rpx;
font-weight: bold;
@include useFlex(space-between, center);
.tag {
@include usePadding(24, 4);
margin-left: 12rpx;
color: $primary-color;
background: #E85A2B12;
border-radius: 50rpx;
font-size: 24rpx;
font-weight: normal;
}
.default-tag {
color: #999999;
background: #F6F6F6;
}
.success-tag {
background: #EAF9EC !important;
color: #28c445 !important;
}
}
.time {
color: $tips-color;
font-size: 24rpx;
}
}
}
.distribution-info-row {
width: 100%;
display: grid;
grid-template-columns: repeat(2, 1fr);
column-gap: 16rpx;
.info-item {
@include usePadding(16, 16);
border-radius: 15rpx;
background: #f6f6f6;
color: #7A7A7A;
font-size: 24rpx;
.title {
white-space: nowrap;
}
.count {
color: #333;
font-weight: bold;
}
}
}
}
</style>

View File

@ -0,0 +1,17 @@
/**
* @name: index.data
* @author: kahu4
* @date: 2024-01-17 15:39
* @descriptionindex.data
* @update: 2024-01-17 15:39
* */
export const distributorDataList = [
{
label: '商品金额(元)',
field: 'productPrice'
},
{
label: '商品佣金(元)',
field: 'wages'
},
]

View File

@ -0,0 +1,264 @@
<!--
@name: index
@author: kahu4
@date: 2024-01-17 16:30
@description分销订单
@update: 2024-01-17 16:30
-->
<script setup>
import Header from '@/components/Header/index.vue'
import { useScroll } from "@/hooks/useScroll";
import { onLoad, onPageScroll } from "@dcloudio/uni-app";
import { ref } from "vue";
import DistributorInfoItem from "./component/DistributorInfoItem.vue";
import UniDatetimePicker from "@/components/Uni/uni-datetime-picker/uni-datetime-picker.vue";
import { usePaging } from "@/hooks/usePaging";
import { getDistributionDetail, pageDistributionOrder } from "@/api/distribution";
import moment from "moment";
import { emptyOrderIcon } from "@/utils/images";
import Empty from "@/components/Empty/index.vue";
// ======================= hooks =====================
const {scrollTop} = useScroll()
onPageScroll(() => {
})
// ======================== level tab ====================
const leverTabs = ref([
{label: '全部', filed: '', value: 0, time: []},
{
label: '今日',
filed: '',
value: 1,
time: [moment().format("YYYY-MM-DD 00:00:00"), moment().format("YYYY-MM-DD 23:59:59")]
},
{
label: '昨日',
filed: '',
value: 2,
time: [moment().subtract(1, "days").format("YYYY-MM-DD 00:00:00"), moment().subtract(1, "days").format("YYYY-MM-DD 23:59:59")]
},
{
label: '本月', filed: '', value: 3, time: [
moment()
.startOf("month")
.format("YYYY-MM-DD 00:00:00"),
moment()
.endOf("month")
.format("YYYY-MM-DD 23:59:59")
]
},
{label: '自定义', filed: '', value: 4, time: []}
])
const leverCurrent = ref(0)
function leverSelect(value) {
if (value === 4) {
showSelectTime()
leverCurrent.value = value
} else {
leverTabs.value[4].time = []
leverCurrent.value = value
otherParams.value.createTime = leverTabs.value[leverCurrent.value].time
if(!otherParams.value.createTime || otherParams.value.createTime.length<=0){
delete otherParams.value.createTime
}
refreshPage()
doGetDistributionDetail()
}
}
// ==================== date ==============================
const dateRangeRef = ref()
function showSelectTime() {
dateRangeRef.value.show()
}
function timeChange(e) {
leverTabs.value[4].time = e
// 请求接口
otherParams.value.createTime = e
refreshPage()
doGetDistributionDetail()
}
// ===================== data ==============================
const {otherParams, list, loading, refreshPage} = usePaging({
request: pageDistributionOrder,
load:false
});
const distributionDetail = ref({
"refuseAmount": 0,
"amount": 0,
"orderCount": 0
})
/**
* 获取分销佣金详情
* @return {Promise<void>}
*/
async function doGetDistributionDetail() {
const data = {}
if(otherParams.value.createTime&&otherParams.value.createTime.length>0){
data.createTime = otherParams.value.createTime
}
distributionDetail.value = await getDistributionDetail(data);
}
onLoad(() => {
otherParams.value.createTime = leverTabs.value[leverCurrent.value].time
if(!otherParams.value.createTime || otherParams.value.createTime.length<=0){
delete otherParams.value.createTime
}
refreshPage()
doGetDistributionDetail()
})
</script>
<template>
<view class="distribution-order">
<Header
:scroll-top="scrollTop"
header-area-bg="#fff"
system-bar-area-bg="#fff">
分销订单
</Header>
<!-- tabs -->
<view class="tab-content">
<view
class="tab-item"
:class="{current:leverCurrent===lever.value}"
v-for="lever in leverTabs"
:key="lever.value"
@click="leverSelect(lever.value)"
>
{{ lever.label }}
</view>
</view>
<!-- main -->
<view class="distribution-order__inner">
<!-- 统计 -->
<view class="statistics-card">
<view class="header">
{{ distributionDetail.orderCount }}笔订单
</view>
<view class="row flex flex-jc__sb flex-ai__center">
<view class="item">
<view class="count">{{ distributionDetail.refuseAmount }}</view>
<view class="title gray-color">待结算佣金()</view>
</view>
<view class="item">
<view class="count">{{ distributionDetail.amount }}</view>
<view class="title gray-color">已结算佣金()</view>
</view>
</view>
</view>
<view class="user-list">
<template v-if="list.length>0">
<DistributorInfoItem
v-for="item in list"
:data="item" />
</template>
<Empty :icon-src="emptyOrderIcon" />
</view>
</view>
<!-- 时间选择器 -->
<uni-datetime-picker
style="width: 0;height: 0;overflow: hidden"
ref="dateRangeRef"
type="datetimerange"
:value="leverTabs[4].time"
@change="timeChange"
>
</uni-datetime-picker>
</view>
</template>
<style
scoped
lang="scss">
.distribution-order {
width: 100%;
.tab-content {
width: 100%;
background: #fff;
@include usePadding(34, 34);
@include useFlex(space-between, center, row, nowrap, 30rpx);
.tab-item {
@include usePadding(0, 16);
text-align: center;
border-radius: 15rpx;
flex: 1 0 auto;
background: #f6f8f8;
color: #333333;
transition: all .3s;
&.current {
background: $primary-color;
color: $white-color;
}
}
}
&__inner {
@include usePadding(34, 34)
}
.statistics-card {
width: 100%;
@include usePadding(8, 8);
border-radius: 15rpx;
background: #333333;
color: #fff;
.header {
width: 100%;
@include usePadding(24, 16);
border-radius: 15rpx;
background: linear-gradient(to right, rgba(246, 246, 246, 0.4) 0%, rgba(246, 246, 246, 0.2) 15%, transparent 50%);
}
.row {
@include usePadding(0, 32);
.item {
flex: 1 0 auto;
font-size: 24rpx;
@include useFlex(center, center, column);
border-right: 1rpx solid #fff;
&:last-child {
border-right: none;
}
.count {
font-size: 32rpx;
font-weight: bold;
}
}
}
}
.user-list {
@include usePadding(0, 34)
}
.gray-color {
color: #999999;
}
}
</style>
<style>
// #ifdef MP-WEIXIN
.uni-date{
position: absolute;
top: -500px!important;
}
// #endif
</style>

View File

@ -0,0 +1,121 @@
<!--
@name: DistributorDataItem
@author: kahu4
@date: 2024-01-17 15:50
@descriptionDistributorDataItem
@update: 2024-01-17 15:50
-->
<script setup>
import { distributorDataList } from "@/views/distribution/team/index.data";
import { toRefs } from "vue";
import moment from "moment";
const props = defineProps({
data: {
type: Object,
required: true
}
})
const {data} = toRefs(props)
</script>
<template>
<view class="user-item">
<view class="userinfo-row flex flex-jc__start">
<image :src="data.avatar" />
<view class="userinfo flex flex-column flex-jc__sb">
<view class="username">
{{ data.nickname }}
<text class="tag">{{ data.isDistributor === 0 ? '客户' : '分销商' }}</text>
</view>
<view class="time">加入时间{{ moment(data.createTime).format('YYYY-MM-DD') }}</view>
</view>
</view>
<view class="distribution-info-row">
<view
class="info-item"
v-for="distributorData in distributorDataList"
:key="distributorData.label">
<view class="title">{{ distributorData.label }}</view>
<view class="count">{{ data[distributorData.field] || '0' }}</view>
</view>
</view>
</view>
</template>
<style
scoped
lang="scss">
.user-item {
margin-bottom: 16rpx;
@include usePadding(32, 32);
background: $white-color;
border-radius: 15rpx;
.userinfo-row {
padding-bottom: 16rpx;
margin-bottom: 16rpx;
border-bottom: 1rpx solid $page-bg-color;
image {
width: 80rpx;
height: 80rpx;
border-radius: 50%;
margin-right: 24rpx;
background: #fbfbfb;
}
.userinfo {
.username {
font-size: 28rpx;
font-weight: bold;
.tag {
@include usePadding(24, 4);
margin-left: 12rpx;
color: $primary-color;
background: #E85A2B12;
border-radius: 50rpx;
font-size: 24rpx;
font-weight: normal;
}
}
.time {
color: $tips-color;
font-size: 24rpx;
}
}
}
.distribution-info-row {
width: 100%;
display: grid;
grid-template-columns: repeat(3, 1fr);
column-gap: 16rpx;
.info-item {
@include usePadding(16, 16);
border-radius: 15rpx;
background: #f6f6f6;
color: #7A7A7A;
font-size: 24rpx;
.title {
white-space: nowrap;
}
.count {
color: #333;
font-weight: bold;
}
}
}
}
</style>

View File

@ -0,0 +1,21 @@
/**
* @name: index.data
* @author: kahu4
* @date: 2024-01-17 15:39
* @descriptionindex.data
* @update: 2024-01-17 15:39
* */
export const distributorDataList = [
{
label: '商品金额(元)',
field: 'productAmount'
},
{
label: '订单数',
field: 'orderCount'
},
{
label: '佣金收入(元)',
field: 'wages'
},
]

View File

@ -0,0 +1,170 @@
<!--
@name: index
@author: kahu4
@date: 2024-01-17 14:52
@description我的团队
@update: 2024-01-17 14:52
-->
<script setup>
import Header from '@/components/Header/index.vue'
import { useScroll } from "@/hooks/useScroll";
import { onLoad, onPageScroll } from "@dcloudio/uni-app";
import { ref } from "vue";
import DistributorInfoItem from "@/views/distribution/team/component/DistributorInfoItem.vue";
import { usePaging } from "@/hooks/usePaging";
import { getUserAddCount, getUserAllCount, pageMyUserTeam } from "@/api/distribution";
import Empty from "@/components/Empty/index.vue"
import { emptyOrderIcon } from "@/utils/images";
// ======================= hooks =====================
const {scrollTop} = useScroll()
onPageScroll(() => {
})
// ======================== level tab ====================
const leverTabs = [{label: '一级', filed: 'p1Count', value: 1}, {label: '二级', filed: 'p2Count', value: 2}]
const leverCurrent = ref(1)
async function leverSelect(value) {
leverCurrent.value = value
otherParams.value.type = value
await refreshPage()
await doGetUserAddCount()
}
const {loading, otherParams, list, refreshPage} = usePaging({
request: pageMyUserTeam,
});
const addUserCount = ref(0)
async function doGetUserAddCount() {
addUserCount.value = await getUserAddCount({
type: otherParams.value.type
})
}
const allUserCount = ref({
p1Count: 0,
p2Count: 0
})
async function doGetUserAllCount() {
allUserCount.value = await getUserAllCount()
}
onLoad(async () => {
otherParams.value.type = 1
await refreshPage()
await doGetUserAddCount()
await doGetUserAllCount()
})
</script>
<template>
<view class="team">
<Header
:scroll-top="scrollTop"
system-bar-area-bg="#fff"
header-area-bg="#fff"> 我的团队
</Header>
<!-- tabs -->
<view class="tab-content">
<view class="tab-inner">
<view
class="tab-item"
:class="{current:leverCurrent===lever.value}"
v-for="lever in leverTabs"
:key="lever.value"
@click="leverSelect(lever.value)"
>
{{ lever.label }}{{ allUserCount[lever.filed] }}
</view>
</view>
</view>
<!-- main -->
<view class="main">
<!-- user num -->
<view class="user-num-box">
<view class="title">今日新增
<text class="num primary-color">{{ addUserCount }}</text>
</view>
</view>
<!-- user list -->
<view
class="user-list-box"
v-if="list.length>0">
<template
v-for="item in list"
:key="item.id">
<DistributorInfoItem :data="item" />
</template>
</view>
<view
class="user-list-box"
v-else>
<Empty :icon-src="emptyOrderIcon" />
</view>
</view>
</view>
</template>
<style
scoped
lang="scss">
.team {
width: 100%;
.tab-content {
width: 100%;
background: #fff;
@include usePadding(34, 34);
.tab-inner {
@include useFlex(space-between, center, row, nowrap, 30rpx);
border-radius: 50rpx;
width: 100%;
background: #f5f5f5;
border: 5rpx solid #f5f5f5;
overflow: hidden;
.tab-item {
border-radius: 50rpx;
@include usePadding(0, 16);
text-align: center;
flex: 1 0 auto;
background: #f6f8f8;
color: #333333;
transition: all .3s;
&.current {
background: $white-color;
font-weight: bold;
}
}
}
}
.main {
width: 100%;
@include usePadding(34, 34);
}
.user-num-box {
margin-bottom: 24rpx;
width: 100%;
@include useFlex(flex-start, center);
font-size: 28rpx;
.title {
color: $tips-color;
font-size: 24rpx;
}
}
.user-list-box {
}
}
</style>