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

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,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>