分销问题修复,订单问题修复

This commit is contained in:
2025-10-30 17:11:18 +08:00
parent 6283d168e9
commit 09fc28de06
29 changed files with 2652 additions and 533 deletions

View File

@@ -0,0 +1,107 @@
<template>
<view>
<up-popup
:show="show"
@close="close"
mode="center"
:safe-area-inset-bottom="false"
>
<view class="u-flex top justify-between u-p-32">
<text class="title">{{ tipsType }}</text>
<up-icon name="close" @click="close"></up-icon>
</view>
<scroll-view style="width: 500rpx; max-height: 60vh">
<view class="u-p-30 font-14" style="width: 500rpx">
<template v-if="tipsType == '等级分成比例'">
<view class="u-flex justify-between font-bold u-m-b-20">
<view>等级</view>
<view>分成比例</view>
</view>
<view
class="u-m-b-10"
v-for="(item, index) in props.levelConfigList"
:key="index"
>
<view class="u-flex justify-between">
<view> {{ item.level }}({{ item.name }}) </view>
<view class="color-666"> {{ item.levelOneCommission }}% </view>
</view>
</view>
</template>
<template v-if="tipsType == '等级升级条件'">
<view class="u-flex justify-between font-bold u-m-b-20">
<view>等级</view>
<view v-if="config.upgradeType != 'not_upgrade'">升级条件</view>
</view>
<view
class="u-m-b-10"
v-for="(item, index) in props.levelConfigList"
:key="index"
>
<view class="u-flex justify-between">
<view>
<text>
{{ item.level }}
</text>
<text>({{ item.name }}) </text>
</view>
<view v-if="config.upgradeType != 'not_upgrade'"
>{{ returnTiaojain(item) }}
</view>
</view>
</view>
</template>
</view>
</scroll-view>
</up-popup>
</view>
</template>
<script setup>
import { ref, computed } from "vue";
const show = defineModel({
type: Boolean,
default: false,
});
const props = defineProps({
tipsType: {
type: String,
default: "",
},
config: {
type: Object,
default: () => {},
},
levelConfigList: {
type: Array,
default: () => [],
},
});
function close() {
show.value = false;
}
function returnTiaojain(item) {
if (props.config.upgradeType === "not_upgrade") {
return "";
}
if (props.config.upgradeType == "cost") {
return `订单金额满${item.costAmount}`;
}
if (props.config.upgradeType == "invite") {
return `邀请${item.inviteCount}`;
}
}
</script>
<style lang="scss">
.title {
color: #000000;
font-size: 32rpx;
font-weight: 700;
}
.top {
border-bottom: 2rpx solid #ededed;
}
</style>

View File

@@ -0,0 +1,137 @@
<template>
<view>
<up-popup
:show="show"
@close="close"
mode="center"
:safe-area-inset-bottom="false"
>
<view class="u-flex top justify-between u-p-32">
<text class="title">规则说明</text>
<up-icon name="close" @click="close"></up-icon>
</view>
<scroll-view style="width: 500rpx; max-height: 60vh">
<view class="u-p-30 font-14" style="width: 500rpx">
<view class="font-12 color-666 u-m-t-16">
<view>
<view> 我的收益什么时候可以到账</view>
<view> 分销的结算时长为{{ config.settlementDay || 0 }}</view>
</view>
<view class="u-m-t-40" v-if="nextLvMoney">
<view>怎么样才能升级分销员等级</view>
<template
v-if="
config.upgradeType != 'not_upgrade' &&
config.levelConfigList &&
config.levelConfigList.length >= 2
"
>
<template v-if="config.upgradeType == 'invite'">
<view
>邀请的有效人数达到{{
config.inviteCount || 0
}}人即可升级</view
>
<view class="u-m-t-40"> 什么是有效邀请人数?</view>
<view> 被邀请人在店铺消费过,即有一笔订单完成才算有效</view>
</template>
<template v-if="config.upgradeType == 'cost'&&nextLvMoney">
<view> 消费金额总计达到{{ nextLvMoney }}元即可升级</view>
</template>
</template>
<template v-else>
<view>请联系商家</view>
</template>
</view>
<view class="u-m-t-40" v-if="config.upgradeType == 'cost'">
<view>消费金额如何计算?</view>
<view
>消费金额是计算您和您邀请的人在店铺消费的总金额,但退款订单不计入</view
>
</view>
</view>
</view>
</scroll-view>
</up-popup>
</view>
</template>
<script setup>
import { ref, computed } from "vue";
const show = defineModel({
type: Boolean,
default: false,
});
const props = defineProps({
tipsType: {
type: String,
default: "",
},
config: {
type: Object,
default: () => {},
},
distributionUser: {
type: Object,
default: () => {},
},
});
function close() {
show.value = false;
}
const nextLvMoney = computed(() => {
let nextLv = undefined;
if (
!props.distributionUser ||
!props.config ||
!props.config.levelConfigList ||
!props.config.levelConfigList.length
) {
return "";
}
if (!props.distributionUser || !props.distributionUser.distributionId) {
nextLv = props.config.levelConfigList[0];
} else {
nextLv = props.config.levelConfigList.find(
(v) => v.level == props.distributionUser.level + 1
);
}
if (nextLv) {
if (props.config.upgradeType == "cost") {
return nextLv.costAmount;
}
if (props.config.upgradeType == "invite") {
return nextLv.inviteCount;
}
}
return "";
});
const juNextLvMoney = computed(() => {
if (!nextLvMoney.value) {
return "";
}
if (props.config.upgradeType == "cost" && props.distributionUser) {
return nextLvMoney.value - (props.distributionUser.consumeAmount || 0);
}
if (props.config.upgradeType == "invite" && props.distributionUser) {
return nextLvMoney.value - (props.config.inviteCount || 0);
}
});
</script>
<style lang="scss">
.title {
color: #000000;
font-size: 32rpx;
font-weight: 700;
}
.top {
border-bottom: 2rpx solid #ededed;
}
</style>

View File

@@ -0,0 +1,57 @@
<template>
<view>
<up-popup
:show="show"
@close="close"
mode="center"
:safe-area-inset-bottom="false"
>
<view class="u-flex top justify-between u-p-32">
<text class="title">{{props.tipsType}}</text>
<up-icon name="close" @click="close"></up-icon>
</view>
<view class="u-p-30 font-14" style="width: 500rpx">
{{ popupText }}
</view>
</up-popup>
</view>
</template>
<script setup>
import { ref, computed } from "vue";
const show = defineModel({
type: Boolean,
default: false,
});
const props = defineProps({
tipsType: {
type: String,
default: "",
},
});
function close() {
show.value = false;
}
const popupText = computed(() => {
if (props.tipsType === "总收益") {
return "总收益:即您在所有店铺通过分销获得总金额,包括待入账金额,但不包含已退款订单";
}
if (props.tipsType === "待入账") {
return "待入账:即已通过订单分销获得但未达到结算时间的金额,结算时间达到后将会计入可提现金额";
}
});
</script>
<style lang="scss">
.title {
color: #000000;
font-size: 32rpx;
font-weight: 700;
}
.top {
border-bottom: 2rpx solid #ededed;
}
</style>

View File

@@ -45,46 +45,66 @@
</view>
</view>
<view>
<view class="u-p-t-16 u-p-b-20 u-flex u-p-l-28 u-p-r-28 " style="align-items: baseline;justify-content: flex-end;">
<view
class="u-p-t-16 u-p-b-20 u-flex u-p-l-28 u-p-r-28"
style="align-items: baseline; justify-content: flex-end"
>
<text class="color-666 font-12"> 总计</text>
<text class="font-16 color-333 font-700"> 999.99</text>
<text class="font-16 color-333 font-700" v-if="centerUserInfo">
{{ centerUserInfo.totalIncome }}</text
>
</view>
<view class="list">
<view v-for="(item, index) in 3" :key="index" class="item">
<view v-for="(item, index) in state.records" :key="index" class="item">
<view class="u-flex justify-between">
<view>
<text class="color-666 ">来源</text>
<text class="color-333 font-700">儿童玩具部落</text>
<text class="color-666">来源</text>
<text class="color-333 font-700">{{ item.shopName }}</text>
</view>
<view>
<text class="color-666">待入账</text>
<text class="color-666" v-if="item.status == 'pending'"
>待入账</text
>
<text class="color-666" v-if="item.status == 'success'"
>已入账</text
>
<text class="color-666" v-if="item.status == 'REFUND'"
>已退款</text
>
</view>
</view>
<view class="u-flex justify-between u-m-t-16">
<view>
<text class="color-666 ">订单</text>
<text class="color-333 font-700">WEB1942482053783560192</text>
<text class="color-666">订单</text>
<text class="color-333 font-700">{{ item.orderNo }}</text>
</view>
<view class="money">
<text class="money reduce">+100</text>
<text class="tag">(订单一级分成)</text>
<text class="money reduce" v-if="item.status == 'REFUND'"
>-{{ item.rewardAmount }}</text
>
<text class="money" v-else>+{{ item.rewardAmount }}</text>
<text class="tag" v-if="item.status == 'REFUND'">订单退款</text>
<text class="tag" v-else-if="item.level == 1"
>(订单一级分成)</text
>
<text class="tag" v-else-if="item.level == 2"
>(订单二级分成)</text
>
</view>
</view>
<view class="u-flex justify-between u-m-t-16">
<view>
<text class="color-666 ">时间</text>
<text class="color-333 font-700">2025/01/21 04:03</text>
<text class="color-666">时间</text>
<text class="color-333 font-700">{{ item.createTime }}</text>
</view>
</view>
</view>
</view>
</view>
<u-loadmore :status="list.status"></u-loadmore>
<u-loadmore :status="isEnd ? 'nomore' : 'loading'"></u-loadmore>
<u-popup :show="show" round="20" closeable @close="show = false">
<view class="shoplist-popup">
<view class="title">
@@ -132,7 +152,9 @@
<script setup>
import dayjs from "dayjs";
import dateAreaSel from "@/components/date-range-picker/date-range-picker.vue";
import { ref, reactive, onMounted, computed } from "vue";
import { ref, reactive, onMounted, computed, watch } from "vue";
import * as distributionApi from "@/common/api/market/distribution.js";
import {
onLoad,
onReady,
@@ -150,43 +172,41 @@ const show = ref(false);
const showTimeArea = ref(false);
const querForm = ref({
searchValue: "",
shopId: "",
shopName: "",
statusActiveIndex: 0,
status: "",
statusName: "",
startDate: "",
startTime: "",
timeArea: "",
endDate: "",
date: [],
endTime: "",
page: 1,
});
function confirmTimeArea(e) {
console.log(e);
querForm.value.date = e;
querForm.value.startDate = e[0];
querForm.value.endDate = e[1];
querForm.value.startTime = e[0];
querForm.value.endTime = e[1];
querForm.value.timeArea = e[0] + "-" + e[1];
}
// 状态
const statusList = ref([
{
value: 0,
name: "未使用",
value: "pending",
name: "待入账",
color: "#333",
fontSize: "16",
},
{
value: 1,
name: "已使用",
value: "success",
name: "已入账",
color: "#333",
fontSize: "16",
},
{
value: 2,
name: "已失效",
value: "REFUND",
name: "已退款",
color: "#333",
fontSize: "16",
},
@@ -205,28 +225,17 @@ function selectStatusHandle(e) {
querForm.value.status = e.value;
querForm.value.statusName = returnStatusName();
}
const list = reactive({
page: 1,
size: 10,
status: "loading",
data: [],
});
onReachBottom(() => {
if (list.status != "nomore") {
list.page++;
console.log("到底了");
if (!isEnd.value) {
console.log("没有跟多了");
querForm.value.page++;
getIncomeDetailsAjax();
}
});
const showStatus = ref(false);
const selectListItemDetails = ref([]);
// 切换类型
function tabChange(index) {
querForm.value.statusActiveIndex = index;
list.page = 1;
list.status = "loading";
}
// 店铺列表滚动到底部了
function scrollBottom() {
@@ -237,25 +246,113 @@ function scrollBottom() {
function selectShopHandle(item) {
querForm.value.shopId = item.shopId;
querForm.value.shopName = item.shopName;
list.page = 1;
show.value = false;
}
// 获取当前店铺会员信息
const shopList = ref([]);
async function getCouponShopsAjax() {
try {
const res = await getCouponShops();
shopList.value = res;
const res = await distributionApi.activates({ page: 1, size: 999 });
shopList.value = res.records || [];
} catch (error) {
console.log(error);
}
}
// 获取收益明细
const state = reactive({
records: [],
totalRow: 0,
});
const isEnd = ref(false);
async function getIncomeDetailsAjax() {
try {
const ajaxQuery = {
shopId: querForm.value.shopId,
startTime: querForm.value.startTime
? `${querForm.value.startTime} 00:00:00`
: "",
endTime: querForm.value.endTime
? `${querForm.value.endTime} 23:59:59`
: "",
status: querForm.value.status,
page: querForm.value.page,
};
console.log("ajaxQuery,", ajaxQuery);
const res = await distributionApi.getIncomeDetails(ajaxQuery);
if (res) {
if (querForm.value.page == 1) {
Object.assign(state, res);
} else {
state.totalPage = res.totalPage * 1;
state.records.push(...(res.records || []));
}
isEnd.value = querForm.value.page >= res.totalPage * 1;
}
} catch (error) {
console.log(error);
}
}
const centerUserInfo = ref({});
async function centerUser() {
const res = await distributionApi.centerUser();
centerUserInfo.value = res;
}
onShow(() => {});
onLoad(() => {
getCouponShopsAjax();
onLoad(async (opt) => {
await getCouponShopsAjax();
console.log(opt);
if (opt.name) {
const findItem = statusList.value.find((item) => item.name == opt.name);
if (findItem) {
querForm.value.status = findItem.value;
querForm.value.statusName = findItem.name;
}
}
if (opt.shopId) {
querForm.value.shopId = opt.shopId;
const findItem = couponShops.value.find((item) => item.id == opt.shopId);
querForm.value.shopName = findItem.shopName || "";
}
centerUser();
getIncomeDetailsAjax();
});
watch(
() => querForm.value.status,
(newVal, oldVal) => {
querForm.value.page = 1;
isEnd.value = false;
getIncomeDetailsAjax();
}
);
watch(
() => querForm.value.shopId,
(newVal, oldVal) => {
querForm.value.page = 1;
isEnd.value = false;
getIncomeDetailsAjax();
}
);
watch(
() => querForm.value.startTime,
(newVal, oldVal) => {
querForm.value.page = 1;
isEnd.value = false;
getIncomeDetailsAjax();
}
);
watch(
() => querForm.value.endTime,
(newVal, oldVal) => {
querForm.value.page = 1;
isEnd.value = false;
getIncomeDetailsAjax();
}
);
</script>
<style>
@@ -267,33 +364,33 @@ page {
.container {
padding: 130rpx 0 28upx;
}
.list{
font-size: 28rpx;
.item{
background-color: #fff;
padding: 32rpx 28rpx 32rpx 36rpx;
margin-bottom: 16rpx;
.money{
line-height: 44rpx;
color: #FE7E00;
font-size: 48rpx;
font-weight: 700;
position: relative;
&.reduce{
color: #FF1C1C;
}
.tag{
position: absolute;
font-weight: 400;
right: 0;
top: 100%;
font-size: 28rpx;
white-space: nowrap;
color: #999;
transform: translateY(10rpx);
}
}
.list {
font-size: 28rpx;
.item {
background-color: #fff;
padding: 32rpx 28rpx 32rpx 36rpx;
margin-bottom: 16rpx;
.money {
line-height: 44rpx;
color: #fe7e00;
font-size: 48rpx;
font-weight: 700;
position: relative;
&.reduce {
color: #ff1c1c;
}
.tag {
position: absolute;
font-weight: 400;
right: 0;
top: 100%;
font-size: 28rpx;
white-space: nowrap;
color: #999;
transform: translateY(10rpx);
}
}
}
}
.header-wrap {
width: 100%;

View File

@@ -11,8 +11,10 @@
<view class="top_content">
<view class="u-flex justify-between">
<view>
<view class="u-flex" @click="toShouyiDetail">
<text class="font-12 color-666 u-m-r-6">总收益</text>
<view class="u-flex">
<text class="font-12 color-666 u-m-r-6" @click="toShouyiDetail('')"
>总收益</text
>
<up-icon
name="question-circle"
size="12"
@@ -20,11 +22,15 @@
@click="questionClick('总收益')"
></up-icon>
</view>
<view class="price">9925.56</view>
<view class="price" @click="toShouyiDetail('')">{{
state.totalIncome
}}</view>
</view>
<view>
<view class="u-flex" @click="toShouyiDetail">
<text class="font-12 color-666 u-m-r-6">待入账</text>
<view class="u-flex">
<text class="font-12 color-666 u-m-r-6" @click="toShouyiDetail('待入账')"
>待入账</text
>
<up-icon
name="question-circle"
size="12"
@@ -32,18 +38,22 @@
@click="questionClick('待入账')"
></up-icon>
</view>
<view class="price">1000.55</view>
<view class="price" @click="toShouyiDetail('待入账')">{{
state.pendingIncome
}}</view>
</view>
</view>
<view class="u-flex justify-between u-m-t-16">
<view>
<view class="u-flex">
<text class="font-12 color-666 u-m-r-6">可提现金额</text>
<text class="font-12 color-666 u-m-r-6" @click="toTixian"
>可提现金额</text
>
</view>
<view class="u-flex" style="align-items: baseline">
<text class="price">9999.99</text>
<text class="price">{{ state.cashOutAmount }}</text>
<view class="u-flex" @click="toTixian">
<text class="font-12 color-666 u-m-r-6">去提现</text>
<text class="font-12 color-666 u-m-r-6 u-m-l-6">去提现</text>
<up-icon
name="arrow-right"
size="12"
@@ -60,90 +70,126 @@
<view class="u-flex">
<view class="title">我的分销</view>
</view>
<view class="u-m-t-36 small-title">已成为100家店铺的分销员</view>
<view class="u-m-t-36 small-title"
>已成为{{ state.activates.totalRow }}家店铺的分销员</view
>
<view class="list">
<view v-for="(item, index) in 3" :key="index" class="shop-item">
<up-image width="104rpx" height="104rpx" radius="8rpx"></up-image>
<view
v-for="(item, index) in state.activates.records"
@click="toShopDetail(item, 'activates')"
:key="index"
class="shop-item"
>
<up-image
width="104rpx"
height="104rpx"
radius="8rpx"
:src="item.coverImg"
></up-image>
<view class="u-flex-1 u-m-l-14">
<view class="u-flex justify-between">
<view>
<view class="shop-name">儿童玩具部落</view>
<view class="address u-line-1 u-m-t-16"
>山西省大同市云冈区奥体西路 2666 号中国铁建国际中心</view
>
<view class="shop-name">{{ item.shopName }}</view>
<view class="address u-line-1 u-m-t-16">{{
item.shopAddress
}}</view>
</view>
<view>
<view class="shouyi">收益</view>
<view class="price">¥99.999</view>
<view class="price">¥{{ item.income || "0.00" }}</view>
</view>
</view>
</view>
</view>
<view
v-if="state.activates.totalRow > 0"
class="u-flex justify-center font-12 color-666"
style="align-items: baseline"
@click="toShopList('activates')"
>
<view>查看全部店铺</view>
<up-icon name="arrow-right" size="12" color="#666"></up-icon>
</view>
</view>
<view class="u-flex">
<view class="u-flex u-m-t-32">
<view class="title">更多店铺解锁</view>
</view>
<view class="list">
<view
v-for="(item, index) in 3"
v-for="(item, index) in state.unActivates.records"
:key="index"
class="shop-item"
@click="toShopDetail"
@click="toShopDetail(item, 'unActivates')"
>
<up-image width="104rpx" height="104rpx" radius="8rpx"></up-image>
<up-image
width="104rpx"
height="104rpx"
radius="8rpx"
:src="item.coverImg"
></up-image>
<view class="u-flex-1 u-m-l-14">
<view class="u-flex justify-between align-center">
<view>
<view class="shop-name">儿童玩具部落</view>
<view class="shop-name">{{ item.shopName }}</view>
<view class="u-flex">
<view class="tag">曾进入过店铺</view>
<view class="tag" v-if="item.labelContent">{{
item.labelContent
}}</view>
</view>
<view class="address u-line-1"
>山西省大同市云冈区奥体西路 2666 号中国铁建国际中心</view
>
<view class="address u-line-1">{{ item.shopAddress }}</view>
</view>
<view class="u-flex u-flex-col justify-center">
<view class="fufei" v-if="true">付费开通</view>
<template v-else>
<view class="fufei" v-if="item.openType == 'pay'"
>付费开通</view
>
<view class="fufei" v-else-if="item.openType == 'manual'"
>手动开通</view
>
<template v-else-if="item.openType == 'auto'">
<view class="font-12 color-333 font-700">自动开通</view>
<view class="u-m-t-8 color-666 font-12">还差10人开通</view>
<view class="u-m-t-8 color-666 font-12"
>还差{{
item.shopInviteCount - item.userInviteCount
}}人开通</view
>
</template>
</view>
</view>
</view>
</view>
<view
v-if="state.activates.totalRow > 0"
class="u-flex justify-center font-12 color-666"
style="align-items: baseline"
@click="toShopList('unActivates')"
>
<view>查看全部店铺</view>
<up-icon name="arrow-right" size="12" color="#666"></up-icon>
</view>
</view>
</view>
<up-popup :show="showPopup" @close="showPopup = false" mode="center" :safe-area-inset-bottom="false">
<view class="u-p-30" style="width: 500rpx;">
{{ popupText }}
总收益即您在所有店铺通过分销获得总金额包括待入账金额但不包含已退款订单
</view>
</up-popup>
<TipsPopup v-model="showPopup" :tips-type="tipsType"></TipsPopup>
</view>
</template>
<script setup>
import { ref } from "vue";
import { ref, reactive } from "vue";
import { onShow } from "@dcloudio/uni-app";
import TipsPopup from "./components/tips-popup.vue";
import * as distributionApi from "@/common/api/market/distribution.js";
const showPopup = ref(false);
const popupText = ref('');
const popupText = ref("");
const tipsType = ref("");
function questionClick(title) {
if(title=='总收益'){
popupText.value='总收益:即您在所有店铺通过分销获得总金额,包括待入账金额,但不包含已退款订单'
if (title == "总收益") {
tipsType.value = "总收益";
}
if(title=='待入账'){
popupText.value='待入账:即已通过订单分销获得但未达到结算时间的金额,结算时间达到后将会计入可提现金额'
if (title == "待入账") {
tipsType.value = "待入账";
}
showPopup.value=true
showPopup.value = true;
}
function back() {
uni.navigateBack({
@@ -151,15 +197,16 @@ function back() {
});
}
function toShouyiDetail(){
function toShouyiDetail(name) {
uni.navigateTo({
url: "/distribution/income-details/index",
url: "/distribution/income-details/index?name="+name,
});
}
function toShopDetail() {
function toShopDetail(item, type) {
uni.navigateTo({
url: "/distribution/shop-detail/index",
url:
"/distribution/shop-detail/index?shopId=" + item.shopId + "&type=" + type,
});
}
@@ -168,6 +215,32 @@ function toTixian() {
url: "/distribution/withdraw/index",
});
}
function toShopList(type) {
uni.navigateTo({
url: "/distribution/shop-list/index?type=" + type,
});
}
const state = reactive({
totalIncome: 0,
pendingIncome: 0,
cashOutAmount: 0,
totalIncome: 0,
activates: {
totalRow: 0,
records: [],
},
unActivates: {
totalRow: 0,
records: [],
},
});
async function init() {
const res = await distributionApi.centerUser();
if (res) {
Object.assign(state, res);
}
}
onShow(init);
</script>
<style scoped lang="scss">

View File

@@ -4,70 +4,129 @@
<view class="u-flex">
<view class="title">姓名</view>
<view class="u-flex-1 input-box">
<input type="text" class="input" placeholder="请输入姓名" />
<input
type="text"
v-model="form.realName"
class="input"
placeholder="请输入姓名"
/>
</view>
</view>
<view class="u-flex u-m-t-32">
<view class="title">身份证号</view>
<view class="u-flex-1 input-box">
<input type="text" class="input" placeholder="请输入身份证号" />
<input
type="text"
v-model="form.idCard"
class="input"
placeholder="请输入身份证号"
/>
</view>
</view>
<view class="tips">请输入和当前微信账号为同一实名否则将会提现失败</view>
</view>
<view class="u-m-t-60 u-p-l-28 u-p-r-28">
<view class="submit">提交</view>
<view class="cancel">取消</view>
<view class="submit" @click="submit">提交</view>
<view class="cancel" @click="cancel">取消</view>
</view>
</view>
</template>
<script setup>
import { realNameAuth } from "@/common/api/market/distribution";
import { ref, reactive } from "vue";
import {validateName,validateIdCard} from "@/utils/util.js"
const form = reactive({
realName: "",
idCard: "",
});
const userInfo = ref(uni.cache.get("userInfo") || {});
form.realName=userInfo.value.realName
form.idCard=userInfo.value.idCard
async function submit() {
const validNameResult = validateName(form.realName)
if(!validNameResult.valid){
return uni.showToast({
title: validNameResult.msg,
icon: "none",
duration: 1500,
})
}
const validIdCardResult = validateIdCard(form.idCard)
if(!validIdCardResult.valid){
return uni.showToast({
title: validIdCardResult.msg,
icon: "none",
duration: 1500,
})
}
const res = await realNameAuth({ ...form, id: userInfo.value.id });
if (res) {
uni.showToast({
title: "修改成功",
icon: "none",
duration: 1500,
});
setTimeout(() => {
uni.navigateBack({
delta: 1,
});
}, 1500);
}
}
function cancel() {
uni.navigateBack({
delta: 1,
});
}
</script>
<style scoped lang="scss">
.min-h-100vh {
padding: 32rpx 28rpx;
}
.tips{
font-size: 24rpx;
line-height: 40rpx;
color: #ff1c1c;
margin-top: 32rpx;
.tips {
font-size: 24rpx;
line-height: 40rpx;
color: #ff1c1c;
margin-top: 32rpx;
}
.box {
background-color: #fff;
padding: 32rpx 28rpx;
font-size: 28rpx;
border-radius: 16rpx;
color: #333;
.title{
.title {
min-width: 160rpx;
}
.input-box {
border-bottom: 2rpx solid #ededed;
.input{
.input {
}
}
}
.submit{
background: #FFD158;
border-radius: 100rpx;
padding: 22rpx 288rpx;
font-size: 32rpx;
line-height: 46rpx;
color: #ffffff;
text-align: center;
font-weight: 700;
white-space: nowrap;
.submit {
background: #ffd158;
border-radius: 100rpx;
padding: 22rpx 288rpx;
font-size: 32rpx;
line-height: 46rpx;
color: #ffffff;
text-align: center;
font-weight: 700;
white-space: nowrap;
}
.cancel{
color: #999999;
white-space: nowrap;
border-radius: 100rpx;
padding: 22rpx 288rpx;
font-size: 32rpx;
line-height: 46rpx;
text-align: center;
.cancel {
color: #999999;
white-space: nowrap;
border-radius: 100rpx;
padding: 22rpx 288rpx;
font-size: 32rpx;
line-height: 46rpx;
text-align: center;
}
</style>

View File

@@ -19,6 +19,7 @@
<view class="u-m-l-32 u-flex-1 border">
<input placeholder="请输入上级邀请码" v-model="code" />
</view>
<image src="/distribution/static/scan.svg" class="u-m-l-10" style="width: 60rpx; height: 60rpx;" @click="saoma"></image>
</view>
<view class="u-m-t-32 u-flex u-col-center" style="gap: 54rpx">
@@ -34,6 +35,7 @@
<script setup>
import { ref } from "vue";
const show = defineModel({
type: Boolean,
default: false,
@@ -55,6 +57,13 @@ function confirm() {
show.value = false;
emits("confirm", code.value);
}
function saoma(){
uni.scanCode({
success: (res) => {
code.value = res.result;
},
});
}
</script>
<style lang="scss" scoped>
.border {

View File

@@ -1,38 +1,38 @@
<template>
<view class="">
<view class="w-qrcode">
<w-qrcode
:options="codeOptions"
:opacity="0"
ref="wQrcode"
@generate="(e) => qrcodeResult(e)"
></w-qrcode>
<w-qrcode
:options="codeOptions"
:opacity="0"
ref="wQrcode"
@generate="(e) => qrcodeResult(e)"
></w-qrcode>
</view>
<up-popup
:show="show"
bgColor="transparent"
:safeAreaInsetBottom="false"
:closeOnClickOverlay="false"
:closeOnClickOverlay="true"
@close="close"
mode="center"
>
<view class="box">
<view class="info">
<view class="u-flex justify-center">
<up-avatar size="214rpx"></up-avatar>
<up-avatar size="214rpx" :src="shopUserInfo.headImg"></up-avatar>
</view>
<view
class="u-m-t-48 font-14 font-700 color-333 text-center line-height-54"
>
<view>躺平小王子 </view>
<view>158****0001</view>
<view>{{ shopUserInfo.nickName }} </view>
<view>{{ desensitizePhone(shopUserInfo.phone) }}</view>
</view>
<view class="u-m-t-16 font-14 line-height-54 text-center">
<text class="color-666">邀请码</text>
<text class="u-m-l-16 u-m-r-16 color-333 font-16 font-700"
>59124551</text
>
<text class="u-m-l-16 u-m-r-16 color-333 font-16 font-700">{{
inviteCode
}}</text>
<text class="" style="color: #fe6d11" @click="copyCode">复制</text>
</view>
<view class="u-flex justify-center" style="margin-top: 90rpx">
@@ -56,15 +56,25 @@
<script setup>
import wQrcode from "@/uni_modules/wmf-code/components/w-qrcode/w-qrcode.vue";
import {desensitizePhone} from "@/utils/util.js";
import { ref } from "vue";
const props = defineProps({
inviteCode: {
type: String,
default: "",
},
shopUserInfo: {
type: Object,
default: () => {},
},
});
const codeOptions = ref({
size: 200,
code: "1234",
code: props.inviteCode,
});
function copyCode() {
uni.setClipboardData({
data: "hello",
data: props.inviteCode,
success: function () {
console.log("success");
},
@@ -74,8 +84,8 @@ const code = ref("");
function qrcodeResult(e) {
console.log("qrcodeResult", e);
code.value=e.img.tempFilePath
console.log('code',code.value)
code.value = e.img.tempFilePath;
console.log("code", code.value);
}
const show = defineModel({
@@ -164,11 +174,11 @@ function save() {
.line-height-54 {
line-height: 54rpx;
}
.w-qrcode{
position: fixed;
left: -9999px;
top: -9999px;
z-index:-1;
.w-qrcode {
position: fixed;
left: -9999px;
top: -9999px;
z-index: -1;
}
</style>

View File

@@ -7,189 +7,636 @@
:fixed="true"
></up-navbar>
<view class="top">
<image class="top_bg" src="/distribution/static/top_bg.png"></image>
<view class="box type1">
<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"
>这里是店铺名称</text
>
<!-- <up-avatar size="62rpx" /> -->
<text class="u-m-l-14 font-14 color-333 font-700">{{
state.shopName
}}</text>
</view>
<view>
<template v-if="false">
<view class="font-12 color-666"> 上级用户昵称15812340001 </view>
<template v-if="state.parentPhone">
<view class="font-12 color-666">
上级{{ state.parentName }}{{ state.parentPhone }}
</view>
</template>
<template v-if="true">
<template v-if="!state.parentPhone">
<view class="bind" @click="showBindShangji = true">
绑定上级
</view>
</template>
</view>
</view>
<view class="top_content u-m-t-32" v-if="false">
<template v-if="false">
<view class="color-333 font-16 font-700"> 如何成为分销员 </view>
<view class="u-m-t-16 color-666 font-14">
<view> 需要邀请人数1000</view>
<view>是否需要邀请人数下单/</view>
<view>每人可获得的分销奖励次数永久/X次</view>
</view>
</template>
<template v-if="false">
<view class="color-333 font-16 font-700 text-center">
如何成为分销员
</view>
<view class="u-m-t-16 color-666 font-14 text-center">
<view>只需付费X元即可成为分销员</view>
</view>
</template>
<template v-if="false">
<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>
<view class="top_content type1 u-m-t-32">
<template v-if="true">
<view class="font-14">
<view>
<text class="color-666">我的分销等级</text>
<text class="color-333 font-700">一级 普通分销员</text>
</view>
<view class="u-m-t-28 u-flex align-center">
<text class="color-666">距离下一级还差</text>
<text class="color-333 font-700 u-m-r-18">100 </text>
<up-icon name="question-circle" size="24rpx" color="#666" />
</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">总收益</text>
<up-icon name="question-circle" size="24rpx" color="#666" />
</view>
<view class="u-m-t-16 price">9925.56</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">
<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-flex-1">
<view class="u-flex align-center">
<text class="u-m-r-10 font-12 color-666">待入账</text>
<up-icon name="question-circle" size="24rpx" color="#666" />
</view>
<view class="u-m-t-16 price">9925.56</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>
</template>
</view>
</view>
</view>
</view>
<template v-if="false">
<view class="bottom">
<view class="u-flex">
<view class="title">规则说明</view>
</view>
<view>
<template v-if="true">
<view class="font-12 color-666 u-m-t-16">
<view>
<view> 我的收益什么时候可以到账</view>
<view> 分销的结算时长为X天</view>
</view>
<view class="u-m-t-40">
<view>怎么样才能升级分销员等级</view>
<view>邀请的有效人数达到X人即可升级</view>
<view> 消费金额总计达到X元即可升级</view>
<view> 什么是有效邀请人数</view>
<view>被邀请人在店铺消费过即有一笔订单完成才算有效</view>
</view>
<view class="u-m-t-40">
<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
>消费金额是计算您和您邀请的人在店铺消费的总金额但退款订单不计入</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>
</view>
</template>
</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 class="parse-html">
<up-parse :content="content"></up-parse>
</view>
</template>
<view class="bottom type1" v-if="true">
</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">我的下级30/10</view>
<up-icon name="question-circle" size="24rpx" color="#666" />
<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">一级分成1.99%二级分成3.99%</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>
</view>
<view class="u-m-t-16">
<view
v-for="(item, index) in 3"
v-for="(item, index) in userList"
:key="index"
class="u-flex justify-between align-center recoder-item color-666 font-12"
>
<view class="">
<view>用户昵称</view>
<view>158****0001</view>
<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>0一级</view>
<view>2025/03/18 19:12</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>
<view class="tips u-m-t-32"
<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">
<view class="u-flex justify-center bottom-btn" v-if="showInviteCode">
<view class="copy" @click="copyCode">
<view>复制邀请码</view>
<view>123457891231</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 class="share" @click="showSharePopup = true">分享邀请</view>
</view>
</view>
<bindShangji v-model="showBindShangji"></bindShangji>
<sharePopup v-model="showSharePopup"></sharePopup>
<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 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 * 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 } from "vue";
const content = ref("123");
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,
});
}
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: "hello",
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 : "";
}
}
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 = nextLvMoney.value - (state.distributionUser.consumeAmount || 0);
}
if (config.upgradeType == "invite" && state.distributionUser) {
total = nextLvMoney.value - (config.inviteCount || 0);
}
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 (!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;
}
onLoad(async (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();
});
onReachBottom(async () => {
if (!isEnd.value) {
query.page++;
await getRecoders();
}
});
</script>
<style scoped lang="scss">
@@ -297,8 +744,8 @@ function copyCode() {
filter: none;
border: none;
background-color: #fcf5ed;
border-radius: 36rpx 36rpx 0 0 ;
padding: 32rpx 36rpx;
border-radius: 36rpx 36rpx 0 0;
padding: 32rpx 36rpx;
}
}
}
@@ -339,7 +786,6 @@ function copyCode() {
}
.top_bg {
width: 100%;
height: 580rpx;
}
.bottom {
margin: 0 28rpx;
@@ -397,4 +843,40 @@ function copyCode() {
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>

View File

@@ -0,0 +1,201 @@
<template>
<view class="box">
<!-- <up-search v-model="query.shopName" @search="getData" @custom="getData"></up-search> -->
<view class="list">
<view class="u-flex shop-item " v-for="(item, index) in list" :key="index" @click="toShopDetail(item)">
<up-image
width="104rpx"
height="104rpx"
radius="8rpx"
:src="item.coverImg"
></up-image>
<view class="u-flex-1 u-m-l-14">
<view class="u-flex justify-between align-center">
<view>
<view class="shop-name">{{ item.shopName }}</view>
<view class="u-flex">
<view class="tag" v-if="item.labelContent">{{
item.labelContent
}}</view>
</view>
<view class="address u-line-1">{{ item.shopAddress }}</view>
</view>
<view v-if="options.type == 'activates'">
<view class="shouyi">收益</view>
<view class="price">¥{{ item.income||'0.00' }}</view>
</view>
<view class="u-flex u-flex-col justify-center" v-else>
<view class="fufei" v-if="item.openType == 'pay'">付费开通</view>
<view class="fufei" v-else-if="item.openType == 'manual'"
>手动开通</view
>
<template v-else-if="item.openType == 'auto'">
<view class="font-12 color-333 font-700">自动开通</view>
<view class="u-m-t-8 color-666 font-12"
>还差{{
item.shopInviteCount - item.userInviteCount
}}人开通</view
>
</template>
</view>
</view>
</view>
</view>
</view>
<up-loadmore :status="query.isEnd?'noMore':'loadmore'"></up-loadmore>
</view>
</template>
<script setup>
import * as distributionApi from "@/common/api/market/distribution.js";
import { onLoad, onReachBottom } from "@dcloudio/uni-app";
import { onMounted, reactive, ref } from "vue";
const list = ref([]);
const query = reactive({
shopName: "",
page: 1,
size: 10,
isEnd: false,
});
async function getData() {
const res =
options.type == "activates"
? await distributionApi.activates(query)
: await distributionApi.unActivates(query);
if (res) {
if (query.page == 1) {
list.value = res.records || [];
} else {
list.value.push(...(res.records || []));
}
query.isEnd = query.page >= res.totalPage * 1;
}
}
function toShopDetail(item,type) {
uni.navigateTo({
url: "/distribution/shop-detail/index?shopId=" + item.shopId
});
}
const options = reactive({});
onLoad((opt) => {
console.log(opt);
Object.assign(options, opt);
getData();
});
onReachBottom(() => {
query.page++;
if (query.isEnd) {
return;
}
getData();
});
</script>
<style lang="scss" scoped>
.box {
padding: 32rpx 28rpx;
font-size: 28rpx;
}
.color-1 {
color: #ff6300;
}
.list {
.shop-item {
padding: 16rpx 0;
border-bottom: 2rpx solid #ededed;
font-size: 24rpx;
color: #666;
display: flex;
align-items: center;
.fufei {
color: #e8ad7b;
}
.tag {
font-size: 24rpx;
color: #ff1c1c;
background-color: #ffe4e4;
padding: 8rpx 20rpx;
border-radius: 8rpx;
}
.shop-name {
}
.address {
max-width: 390rpx;
}
.shouyi {
font-size: 24rpx;
color: #666;
text-align: center;
}
.price {
font-size: 20rpx;
color: #333;
font-weight: 500;
}
}
}
.price {
font-weight: 700;
color: #333;
font-size: 40rpx;
margin-top: 16rpx;
}
.top {
position: relative;
.top_content {
background-color: #faf7f4;
position: absolute;
left: 28rpx;
right: 28rpx;
bottom: 0;
padding: 32rpx 106rpx 32rpx 56rpx;
border-radius: 24rpx 24rpx 0 0;
}
}
.top_bg {
width: 100%;
height: 530rpx;
}
.bottom {
padding: 34rpx 28rpx;
}
.title {
font-size: 32rpx;
font-weight: 700;
color: #333;
position: relative;
overflow: hidden;
&::after {
display: block;
content: "";
position: absolute;
right: 0;
bottom: 4rpx;
background-color: #9ee708;
border-radius: 10rpx;
z-index: -1;
width: 94.2rpx;
height: 13.98rpx;
flex-shrink: 0;
stroke-width: 4rpx;
stroke: #9ee708d6;
}
}
.small-title {
font-size: 28rpx;
font-weight: 700;
color: #333;
}
</style>

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1761787146008" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4672" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M146.432 336.896h-81.92V106.496l40.96-40.96h231.424v81.92H146.432zM336.896 958.464H105.472l-40.96-40.96V687.104h81.92v189.44h190.464zM956.416 336.896h-81.92V147.456H684.032v-81.92h231.424l40.96 40.96zM915.456 958.464H613.376v-81.92h261.12V659.456h81.92v258.048z" fill="#437DFF" p-id="4673"></path><path d="M326.656 334.848h61.44v98.304h-61.44zM415.744 575.488h61.44v133.12h-61.44zM265.216 575.488h61.44v114.688h-61.44zM566.272 575.488h61.44v98.304h-61.44zM706.56 575.488h61.44v154.624h-61.44zM477.184 297.984h61.44v135.168h-61.44zM627.712 329.728h61.44v103.424h-61.44z" fill="#63F7DE" p-id="4674"></path><path d="M10.24 473.088h1003.52v61.44H10.24z" fill="#437DFF" p-id="4675"></path></svg>

After

Width:  |  Height:  |  Size: 1023 B

View File

@@ -13,20 +13,21 @@
<view class="u-m-t-32 u-flex input-number-box">
<text class="fuhao">¥</text>
<input
v-model="money"
type="digit"
class="input-number"
placeholder="最小提现金额为30"
/>
<text class="all-in">全部提现</text>
<text class="all-in" @click="allin">全部提现</text>
</view>
<view class="color-666 font-12 u-m-t-16">
<text>可提现金额399.99</text>
<text>可提现金额{{ state.cashOutAmount || 0 }}</text>
<text class="u-m-l-20">手续费为8%</text>
</view>
<view class="btn-group">
<view class="btn shiming" @click="toShiming">实名认证</view>
<view class="btn tixian u-m-t-32">立即提现</view>
<view class="btn tixian u-m-t-32" @click="tixian">立即提现</view>
</view>
</view>
</view>
@@ -35,26 +36,42 @@
<view class="title">提现记录</view>
</view>
<view class="list">
<view v-for="(item, index) in 3" :key="index" class="shop-item">
<view v-for="(item, index) in list" :key="index" class="shop-item">
<view class="u-flex-1">
<view class="u-flex justify-between">
<view>
<view class="name">提现</view>
<view class="shouxufei u-m-t-16"
>手续费9.99</view
>手续费{{ item.serviceFee }}</view
>
<view class="font-12 color-999 u-m-t-10">
时间2017/8/9 21:02
时间{{ item.createTime }}
</view>
</view>
<view class="u-flex u-flex-col justify-center">
<template v-if="!true">
<view class="lingqu">点击领取</view>
<view class="price reduce">-100</view>
<template v-if="item.status == 'pending'">
<view class="lingqu" @click="lingqu(item)">点击领取</view>
<view class="price reduce"
>-{{
BigNumber(item.serviceFee).plus(item.amount).toFixed(2)
}}</view
>
</template>
<template v-else>
<view class="status fail">提现失败</view>
<view class="price">-100</view>
<template v-if="item.status == 'finish'">
<view class="status">提现成功</view>
<view class="price reduce"
>-{{
BigNumber(item.serviceFee).plus(item.amount).toFixed(2)
}}</view
>
</template>
<template v-if="item.status == 'fail'">
<view class="status fail">提现失败</view>
<view class="price"
>+{{
BigNumber(item.serviceFee).plus(item.amount).toFixed(2)
}}</view
>
</template>
</view>
</view>
@@ -62,21 +79,153 @@
</view>
</view>
</view>
<view class="" style="padding-bottom: 60rpx;">
<up-loadmore
:status="isEnd?'no-more':'loadmore'"
></up-loadmore>
</view>
</view>
</template>
<script setup>
<script setup>
import * as distributionApi from "@/common/api/market/distribution.js";
import { productStore } from "@/stores/user.js";
const storeuser = productStore();
import { ref, onMounted, reactive } from "vue";
import { onLoad, onReachBottom, onShow } from "@dcloudio/uni-app";
import BigNumber from "bignumber.js";
function back() {
uni.navigateBack({
delta: 1,
});
}
async function lingqu(item) {
const res = await distributionApi.withdrawDetail({ id: item.id });
if (res) {
uni.requestMerchantTransfer({
...res,
success: (res) => {
uni.showToast({
title: "领取成功",
icon: "none",
});
refesh();
},
fail: (res) => {
uni.showToast({
title: "领取失败",
icon: "none",
});
refesh();
},
});
}
}
function toShiming() {
uni.navigateTo({
url: "/distribution/shiming/index",
});
}
const userinfo = ref(uni.cache.get("userinfo") || {});
const query = reactive({
page: 1,
size: 10,
});
const list = ref([]);
const isEnd = ref(false);
async function withdrawFlow() {
const res = await distributionApi.withdrawFlow(query);
if (res) {
if (query.page == 1) {
list.value = res.records;
} else {
list.value.push(...res.records);
}
isEnd.value = query.page >= res.totalPage * 1;
}
}
const state = reactive({
cashOutAmount: 0,
pendingIncome: 0,
totalIncome: 0,
});
async function centerUser() {
const res = await distributionApi.centerUser();
if (res) {
Object.assign(state, res);
}
}
const money = ref(0);
function allin() {
money.value = state.cashOutAmount;
}
async function tixian() {
if (!userinfo.value.idCard) {
uni.showToast({
title: "请先实名认证",
icon: "none",
});
setTimeout(() => {
toShiming();
}, 1500);
return;
}
if (money.value <= 0) {
uni.showToast({
title: "请输入提现金额",
icon: "none",
});
return;
}
if (money.value > state.cashOutAmount) {
uni.showToast({
title: "提现金额不能大于可提现金额",
icon: "none",
});
return;
}
const res = await distributionApi.withdraw({
amount: money.value,
});
if (res) {
uni.showToast({
title: "提现成功",
icon: "none",
});
}
refesh();
}
function refesh() {
setTimeout(() => {
query.page = 1;
init();
}, 3000);
}
async function init() {
await centerUser();
await withdrawFlow();
}
onReachBottom(async () => {
console.log('onReachBottom', isEnd.value);
if (!isEnd.value) {
query.page++;
await withdrawFlow();
}
});
onLoad(() => {
init();
});
onShow(() => {
storeuser.actionsAPIuser().then((res) => {
userinfo.value = res;
});
});
</script>
<style scoped lang="scss">
@@ -125,8 +274,8 @@ function toShiming() {
border-radius: 8rpx;
}
.name {
color: #333;
font-weight: 700;
color: #333;
font-weight: 700;
}
.shouxufei {
}
@@ -137,29 +286,29 @@ function toShiming() {
}
}
}
.status{
font-size: 28rpx;
font-weight: 700;
text-align: right;
color: #333333;
&.fail{
color: #ff1c1c;
}
.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;
.lingqu {
font-size: 28rpx;
border-radius: 8rpx;
background: #fe6d11;
padding: 8rpx 16rpx;
color: #ffffff;
}
.price {
font-weight: 700;
font-size: 48rpx;
margin-top: 16rpx;
color: #FE7E00;
color: #fe7e00;
text-align: right;
&.reduce{
&.reduce {
color: #666;
}
}
@@ -215,8 +364,7 @@ function toShiming() {
font-size: 32rpx;
font-weight: 700;
color: #333;
padding: 28rpx;
padding: 28rpx;
}
.small-title {
font-size: 28rpx;