分销问题修复,订单问题修复
This commit is contained in:
149
common/api/market/distribution.js
Normal file
149
common/api/market/distribution.js
Normal file
@@ -0,0 +1,149 @@
|
||||
// 引入 request 文件
|
||||
import request from "@/common/api/request.js";
|
||||
import { prveUrl } from "./config.js";
|
||||
|
||||
export const pay = (data) => {
|
||||
let platformType = "";
|
||||
let payType = "";
|
||||
// #ifdef APP-PLUS
|
||||
platformType = "APP";
|
||||
// #endif
|
||||
// #ifdef H5
|
||||
platformType = "H5";
|
||||
// #endif
|
||||
// #ifdef MP-WEIXIN
|
||||
platformType = "WX";
|
||||
platformType = "wechat";
|
||||
payType = "wechatPay";
|
||||
// #endif
|
||||
// #ifdef MP-ALIPAY
|
||||
platformType = "alipay";
|
||||
payType = "aliPay";
|
||||
// #endif
|
||||
|
||||
|
||||
return request({
|
||||
url: prveUrl + "/user/distribution/pay",
|
||||
method: "post",
|
||||
data: { platformType, payType, ...data },
|
||||
});
|
||||
};
|
||||
|
||||
export const centerUser = (data) => {
|
||||
return request({
|
||||
url: prveUrl + "/user/distribution/centerUser",
|
||||
method: "post",
|
||||
data: data,
|
||||
});
|
||||
};
|
||||
export const activates = (data) => {
|
||||
return request({
|
||||
url: prveUrl + "/user/distribution/centerUser/activates",
|
||||
method: "get",
|
||||
data: data,
|
||||
});
|
||||
};
|
||||
export const unActivates = (data) => {
|
||||
return request({
|
||||
url: prveUrl + "/user/distribution/centerUser/unActivates",
|
||||
method: "get",
|
||||
data: data,
|
||||
});
|
||||
};
|
||||
export const centerConfig = (data) => {
|
||||
return request({
|
||||
url: prveUrl + "/user/distribution/centerConfig",
|
||||
method: "get",
|
||||
data: data,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// 绑定邀请用户
|
||||
export const bindInviteUser = (data) => {
|
||||
return request({
|
||||
url: prveUrl + "/user/distribution/bindInviteUser",
|
||||
method: "post",
|
||||
data: data,
|
||||
});
|
||||
};
|
||||
|
||||
export const childUser = (data) => {
|
||||
return request({
|
||||
url: prveUrl + "/user/distribution/childUser",
|
||||
method: "get",
|
||||
data: data,
|
||||
});
|
||||
};
|
||||
export const inviteUser = (data) => {
|
||||
return request({
|
||||
url: prveUrl + "/user/distribution/inviteUser",
|
||||
method: "get",
|
||||
data: data,
|
||||
});
|
||||
};
|
||||
|
||||
// 提现
|
||||
export const withdraw = (data) => {
|
||||
return request({
|
||||
url: prveUrl + "/user/distribution/withdraw",
|
||||
method: "post",
|
||||
data: data,
|
||||
});
|
||||
};
|
||||
|
||||
// 提现详情
|
||||
export const withdrawDetail = (data) => {
|
||||
return request({
|
||||
url: prveUrl + "/user/distribution/withdraw/detail",
|
||||
method: "get",
|
||||
data: data,
|
||||
});
|
||||
};
|
||||
//提现记录
|
||||
export const withdrawFlow = (data) => {
|
||||
return request({
|
||||
url: prveUrl + "/user/distribution/withdraw/flow",
|
||||
method: "get",
|
||||
data: data,
|
||||
});
|
||||
};
|
||||
|
||||
// 实名认证
|
||||
export const realNameAuth = (data) => {
|
||||
return request({
|
||||
url: prveUrl + "/user/distribution/realNameAuth",
|
||||
method: "post",
|
||||
data: data,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// 收益明细
|
||||
export const getIncomeDetails = (data) => {
|
||||
return request({
|
||||
url: prveUrl + "/user/distribution/distributionFlow",
|
||||
method: "get",
|
||||
data: data,
|
||||
});
|
||||
};
|
||||
|
||||
// 获取邀请码
|
||||
export const getInviteCode = (data) => {
|
||||
return request({
|
||||
url: prveUrl + "/user/distribution/getInviteCode",
|
||||
method: "get",
|
||||
data: data,
|
||||
});
|
||||
};
|
||||
|
||||
// 获取配置
|
||||
export const getConfig = (data) => {
|
||||
return request({
|
||||
url: prveUrl + "/user/distribution/getConfig",
|
||||
method: "get",
|
||||
data: data,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -135,4 +135,18 @@ export const rechargePayOrder = (data) => {
|
||||
...data
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
//分销员支付订单
|
||||
export const distributionLtPayOrder = (data) => {
|
||||
return request({
|
||||
url: url + '/pay/distribution/ltPayOrder',
|
||||
method: 'post',
|
||||
data: {
|
||||
platformType,
|
||||
payType,
|
||||
openId: uni.cache.get('userInfo').wechatOpenId,
|
||||
...data
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
285
components/devetools.vue
Normal file
285
components/devetools.vue
Normal file
@@ -0,0 +1,285 @@
|
||||
<template>
|
||||
<view class="floating-widget" v-if="show">
|
||||
<!-- 悬浮按钮 -->
|
||||
<view
|
||||
class="floating-btn"
|
||||
@click="togglePopup"
|
||||
:style="{
|
||||
backgroundColor: btnColor,
|
||||
width: `${btnSize}px`,
|
||||
height: `${btnSize}px`,
|
||||
}"
|
||||
:class="{ active: isPopupVisible }"
|
||||
>
|
||||
<up-icon
|
||||
name="plus"
|
||||
size="24"
|
||||
color="#ffffff"
|
||||
:class="{ rotate: isPopupVisible }"
|
||||
></up-icon>
|
||||
</view>
|
||||
|
||||
<!-- 操作弹窗 -->
|
||||
<view class="popup" v-if="isPopupVisible" :class="{ show: isPopupVisible }">
|
||||
<view class="popup-arrow"></view>
|
||||
<view class="popup-content">
|
||||
<view
|
||||
class="popup-item"
|
||||
v-for="(item, index) in operations"
|
||||
:key="index"
|
||||
@click="handleOperation(item.action)"
|
||||
>
|
||||
<text class="item-text">{{ item.name }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 点击外部关闭遮罩 -->
|
||||
<view class="overlay" v-if="isPopupVisible" @click="closePopup"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, defineProps, defineEmits,computed } from "vue";
|
||||
const show=computed(()=>{
|
||||
const sysInfo=uni.getAccountInfoSync();
|
||||
if(sysInfo&&sysInfo.miniProgram && (sysInfo.miniProgram.envVersion == 'release'||sysInfo.miniProgram.envVersion == 'develop')) {
|
||||
return true;
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
// 定义组件属性
|
||||
const props = defineProps({
|
||||
// 操作选项列表
|
||||
operations: {
|
||||
type: Array,
|
||||
default: () => [
|
||||
{
|
||||
name: "复制token",
|
||||
icon: "arrowup",
|
||||
action: "token",
|
||||
color: "#007aff",
|
||||
},
|
||||
{
|
||||
name: "复制用户信息",
|
||||
icon: "userInfo",
|
||||
action: "userInfo",
|
||||
color: "#52c41a",
|
||||
},
|
||||
{
|
||||
name: "获取登录code",
|
||||
icon: "userInfo",
|
||||
action: "getLoginCode",
|
||||
color: "#52c41a",
|
||||
},
|
||||
{
|
||||
name: "复制当前门店信息",
|
||||
icon: "userInfo",
|
||||
action: "copyStoreInfo",
|
||||
color: "#52c41a",
|
||||
},
|
||||
{
|
||||
name: "复制当前门店用户信息",
|
||||
icon: "userInfo",
|
||||
action: "copyStoreUserInfo",
|
||||
color: "#52c41a",
|
||||
},
|
||||
],
|
||||
},
|
||||
// 悬浮按钮颜色
|
||||
btnColor: {
|
||||
type: String,
|
||||
default: "#007aff",
|
||||
},
|
||||
// 悬浮按钮大小(px)
|
||||
btnSize: {
|
||||
type: Number,
|
||||
default: 60,
|
||||
},
|
||||
// 弹窗距离底部的距离
|
||||
bottomDistance: {
|
||||
type: Number,
|
||||
default: 20,
|
||||
},
|
||||
// 弹窗距离右侧的距离
|
||||
rightDistance: {
|
||||
type: Number,
|
||||
default: 20,
|
||||
},
|
||||
});
|
||||
|
||||
// 定义组件事件
|
||||
const emit = defineEmits(["onOperation", "onOpen", "onClose"]);
|
||||
|
||||
// 弹窗显示状态
|
||||
const isPopupVisible = ref(false);
|
||||
|
||||
// 切换弹窗显示/隐藏
|
||||
const togglePopup = () => {
|
||||
isPopupVisible.value = !isPopupVisible.value;
|
||||
if (isPopupVisible.value) {
|
||||
emit("onOpen");
|
||||
} else {
|
||||
emit("onClose");
|
||||
}
|
||||
};
|
||||
|
||||
// 关闭弹窗
|
||||
const closePopup = () => {
|
||||
if (isPopupVisible.value) {
|
||||
isPopupVisible.value = false;
|
||||
emit("onClose");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
async function getWxloginCode(){
|
||||
return new Promise((resolve, reject) => {
|
||||
uni.login({
|
||||
success: (res) => {
|
||||
if (res.code) {
|
||||
resolve(res.code);
|
||||
} else {
|
||||
console.log("获取登录凭证(code)失败!" + res.errMsg);
|
||||
reject(res.errMsg);
|
||||
}
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
// 处理操作选择
|
||||
const handleOperation = async (action) => {
|
||||
let data='';
|
||||
if (action == "token") {
|
||||
data=uni.cache.get("token");
|
||||
|
||||
}
|
||||
if (action == "userInfo") {
|
||||
data=JSON.stringify(uni.cache.get("userInfo"));
|
||||
}
|
||||
if(action == "getLoginCode"){
|
||||
data=await getWxloginCode();
|
||||
}
|
||||
if(action == "copyStoreInfo"){
|
||||
data=JSON.stringify(uni.cache.get("shopInfo"));
|
||||
}
|
||||
if(action == "copyStoreUserInfo"){
|
||||
data=JSON.stringify(uni.cache.get("shopUserInfo"));
|
||||
}
|
||||
console.log('data',data)
|
||||
uni.setClipboardData({
|
||||
data: data,
|
||||
success: function () {},
|
||||
});
|
||||
emit("onOperation", action);
|
||||
closePopup();
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.floating-widget {
|
||||
position: fixed;
|
||||
right: v-bind(rightDistance + "px");
|
||||
bottom: v-bind(bottomDistance + "px");
|
||||
z-index: 9999;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
/* 悬浮按钮样式 */
|
||||
.floating-btn {
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background: linear-gradient(98deg, #fe6d1100 40.64%, #ffd1b4 105.2%),
|
||||
linear-gradient(259deg, #fe6d11 50.14%, #ffd1b4 114.93%);
|
||||
box-shadow: 0 0.4375rem 0.95rem 0 #fe8b435e;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
z-index: 1001;
|
||||
}
|
||||
|
||||
.floating-btn.active {
|
||||
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.2);
|
||||
transform: scale(1.05);
|
||||
}
|
||||
|
||||
.floating-btn .rotate {
|
||||
transform: rotate(45deg);
|
||||
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
/* 弹窗样式 */
|
||||
.popup {
|
||||
position: absolute;
|
||||
bottom: calc(100% + 15px);
|
||||
right: 0;
|
||||
min-width: 160px;
|
||||
background-color: #ffffff;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
|
||||
opacity: 0;
|
||||
transform: translateY(10px) scale(0.95);
|
||||
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
z-index: 1000;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.popup.show {
|
||||
opacity: 1;
|
||||
transform: translateY(0) scale(1);
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
/* 弹窗箭头 */
|
||||
.popup-arrow {
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
bottom: -8px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-color: #ffffff;
|
||||
transform: rotate(45deg);
|
||||
box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.popup-content {
|
||||
padding: 8px 0;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* 操作选项样式 */
|
||||
.popup-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 12px 20px;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.popup-item:hover {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.item-text {
|
||||
margin-left: 12px;
|
||||
font-size: 14px;
|
||||
color: #333333;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
/* 遮罩层样式 */
|
||||
.overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
z-index: 999;
|
||||
}
|
||||
</style>
|
||||
@@ -1,11 +1,24 @@
|
||||
<template>
|
||||
<text v-if="limitDiscount && limitDiscount.id" class="limit-price">
|
||||
{{ returnPrice() }}
|
||||
</text>
|
||||
<text v-else>
|
||||
<text v-if="shopInfo.isMemberPrice == 1 && shopUserInfo.isVip == 1" class="memberPrice">
|
||||
{{ cart.memberPrice || cart.salePrice }}
|
||||
<block v-if="limitDiscount && limitDiscount.id" class="limit-price">
|
||||
<text>
|
||||
{{ returnPrice() }}
|
||||
</text>
|
||||
</block>
|
||||
|
||||
<text v-else>
|
||||
<block
|
||||
v-if="
|
||||
shopUserInfo.isMemberPrice == 1 &&
|
||||
shopUserInfo.isVip == 1 &&
|
||||
cart.memberPrice * 1 > 0
|
||||
"
|
||||
class="memberPrice"
|
||||
>
|
||||
<text>
|
||||
{{ cart.memberPrice }}
|
||||
</text>
|
||||
</block>
|
||||
|
||||
<text v-else class="salePrice">{{ cart.salePrice }}</text>
|
||||
</text>
|
||||
</template>
|
||||
@@ -14,15 +27,14 @@
|
||||
import BigNumber from "bignumber.js";
|
||||
import * as orderUtils from "@/utils/order-utils.js";
|
||||
|
||||
|
||||
function returnPrice(){
|
||||
function returnPrice() {
|
||||
return orderUtils.returnPrice({
|
||||
goods:props.cart,
|
||||
shopInfo:props.shopInfo,
|
||||
limitTimeDiscountRes:props.limitDiscount,
|
||||
shopUserInfo:props.shopUserInfo,
|
||||
idKey:props.idKey
|
||||
})
|
||||
goods: props.cart,
|
||||
shopInfo: props.shopInfo,
|
||||
limitTimeDiscountRes: props.limitDiscount,
|
||||
shopUserInfo: props.shopUserInfo,
|
||||
idKey: props.idKey,
|
||||
});
|
||||
}
|
||||
|
||||
const props = defineProps({
|
||||
@@ -31,9 +43,9 @@ const props = defineProps({
|
||||
type: Object,
|
||||
default: () => {},
|
||||
},
|
||||
idKey:{
|
||||
idKey: {
|
||||
type: String,
|
||||
default: 'id',
|
||||
default: "id",
|
||||
},
|
||||
//限时折扣
|
||||
limitDiscount: {
|
||||
@@ -53,4 +65,11 @@ const props = defineProps({
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss"></style>
|
||||
<style lang="scss">
|
||||
.old-price {
|
||||
color: #999;
|
||||
font-size: 24rpx;
|
||||
text-decoration: line-through;
|
||||
margin-left: 8rpx;
|
||||
}
|
||||
</style>
|
||||
107
distribution/components/commission.vue
Normal file
107
distribution/components/commission.vue
Normal 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>
|
||||
137
distribution/components/rule.vue
Normal file
137
distribution/components/rule.vue
Normal 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>
|
||||
57
distribution/components/tips-popup.vue
Normal file
57
distribution/components/tips-popup.vue
Normal 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>
|
||||
@@ -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%;
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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>
|
||||
@@ -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 {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
201
distribution/shop-list/index.vue
Normal file
201
distribution/shop-list/index.vue
Normal 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>
|
||||
1
distribution/static/scan.svg
Normal file
1
distribution/static/scan.svg
Normal 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 |
@@ -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;
|
||||
|
||||
@@ -270,6 +270,12 @@
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "shop-list/index",
|
||||
"style": {
|
||||
"navigationBarTitleText": "店铺列表"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "income-details/index",
|
||||
"style": {
|
||||
|
||||
@@ -110,7 +110,7 @@ const shopUserInfo = inject("shopUserInfo");
|
||||
const shopInfo = inject("shopInfo");
|
||||
|
||||
function showLimitDiscount(item) {
|
||||
if (!props.limitDiscount || !props.li) {
|
||||
if (!props.limitDiscount || !props.limitDiscount.id) {
|
||||
return false;
|
||||
}
|
||||
return orderUtils.canUseLimitTimeDiscount(
|
||||
@@ -118,7 +118,7 @@ function showLimitDiscount(item) {
|
||||
props.limitDiscount,
|
||||
shopInfo.value,
|
||||
shopUserInfo.value,
|
||||
"id"
|
||||
"productId"
|
||||
);
|
||||
}
|
||||
onMounted(() => {
|
||||
|
||||
@@ -891,7 +891,7 @@ async function getDiscountActivity() {
|
||||
}
|
||||
onMounted(async () => {
|
||||
await getConsumeDiscount();
|
||||
getDiscountActivity();
|
||||
// getDiscountActivity();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -442,6 +442,9 @@ const orderorderInfo = async () => {
|
||||
if (!listinfo.id && !options.tableCode) {
|
||||
return;
|
||||
}
|
||||
if (isPayBefor() && !listinfo.id) {
|
||||
return;
|
||||
}
|
||||
let res = listinfo.id
|
||||
? await APIgetOrderById({
|
||||
orderId: listinfo.id,
|
||||
@@ -640,15 +643,16 @@ const createOrder = async () => {
|
||||
orderId: listinfo.id || "",
|
||||
tableCode: options.tableCode || "",
|
||||
userId: uni.cache.get("userInfo").id || "", //
|
||||
limitRate: (cartStore.limitTimeDiscount&&cartStore.limitTimeDiscount.id)
|
||||
? {
|
||||
id: cartStore.limitTimeDiscount.id,
|
||||
discountRate: cartStore.limitTimeDiscount.discountRate,
|
||||
discountPriority: cartStore.limitTimeDiscount.discountPriority,
|
||||
foodType: cartStore.limitTimeDiscount.foodType,
|
||||
foods: cartStore.limitTimeDiscount.foods,
|
||||
}
|
||||
: null,
|
||||
limitRate:
|
||||
cartStore.limitTimeDiscount && cartStore.limitTimeDiscount.id
|
||||
? {
|
||||
id: cartStore.limitTimeDiscount.id,
|
||||
discountRate: cartStore.limitTimeDiscount.discountRate,
|
||||
discountPriority: cartStore.limitTimeDiscount.discountPriority,
|
||||
foodType: cartStore.limitTimeDiscount.foodType,
|
||||
foods: cartStore.limitTimeDiscount.foods,
|
||||
}
|
||||
: null,
|
||||
});
|
||||
// 清空购物车
|
||||
if (res) {
|
||||
@@ -709,7 +713,7 @@ function returnPayParams() {
|
||||
vipPrice: cartStore.useVipPrice ? 1 : 0, //是否使用会员价0否1是
|
||||
userAllPack: is_type.value == 0 ? 0 : 1, //是否整单打包
|
||||
seatNum: is_type.value == 0 ? cartStore.seatFeeConfig.personCount : 0, //用餐人数
|
||||
originAmount: cartStore.orderCostSummary.goodsRealAmount, //订单原金额(包含打包费+餐位费) 不含折扣价格
|
||||
originAmount: cartStore.orderCostSummary.goodsRealAmount, //订单原金额(不包含打包费+餐位费)
|
||||
discountRatio: 1, //折扣比例(计算时 向上取整保留 两位小数) 写死1
|
||||
discountAmount: 0, //手动优惠金额 写死0
|
||||
productCouponDiscountAmount:
|
||||
@@ -729,18 +733,21 @@ function returnPayParams() {
|
||||
: "",
|
||||
remark: orderRemarker.value, //用户备注
|
||||
discountActAmount: cartStore.orderCostSummary.fullReduction.actualAmount, //满减抵扣金额
|
||||
discountActId:cartStore.orderCostSummary.fullReduction.usedActivity?cartStore.orderCostSummary.fullReduction.usedActivity.id:null,
|
||||
userId: uni.cache.get("userInfo").id || "", //
|
||||
limitRate: (cartStore.limitTimeDiscount&&cartStore.limitTimeDiscount.id)
|
||||
? {
|
||||
id: cartStore.limitTimeDiscount.id,
|
||||
discountRate: cartStore.limitTimeDiscount.discountRate,
|
||||
discountPriority: cartStore.limitTimeDiscount.discountPriority,
|
||||
foodType: cartStore.limitTimeDiscount.foodType,
|
||||
foods: cartStore.limitTimeDiscount.foods,
|
||||
}
|
||||
discountActId: cartStore.orderCostSummary.fullReduction.usedActivity
|
||||
? cartStore.orderCostSummary.fullReduction.usedActivity.id
|
||||
: null,
|
||||
vipDiscountAmount: cartStore.orderCostSummary.vipDiscountAmount, //会员折扣减免金额
|
||||
userId: uni.cache.get("userInfo").id || "", //
|
||||
limitRate:
|
||||
cartStore.limitTimeDiscount && cartStore.limitTimeDiscount.id
|
||||
? {
|
||||
id: cartStore.limitTimeDiscount.id,
|
||||
discountRate: cartStore.limitTimeDiscount.discountRate,
|
||||
discountPriority: cartStore.limitTimeDiscount.discountPriority,
|
||||
foodType: cartStore.limitTimeDiscount.foodType,
|
||||
foods: cartStore.limitTimeDiscount.foods,
|
||||
}
|
||||
: null,
|
||||
vipDiscountAmount: cartStore.orderCostSummary.vipDiscountAmount, //会员折扣减免金额
|
||||
};
|
||||
return {
|
||||
isBwc: isBwc.value,
|
||||
@@ -899,6 +906,7 @@ const goToPay = async (payParams) => {
|
||||
amount: cartStore.orderCostSummary.finalPayAmount, // 最终订单金额
|
||||
orderAmount: cartStore.orderCostSummary.orderOriginFinalPayAmount, // 最终订单原金额
|
||||
originAmount: cartStore.orderCostSummary.goodsRealAmount, //订单原金额(不包含打包费+餐位费)
|
||||
|
||||
returnUrl: "", //跳转地址
|
||||
buyerRemark: "",
|
||||
seatNum: is_type.value == 0 ? cartStore.seatFeeConfig.personCount : 0, //用餐人数
|
||||
@@ -1090,8 +1098,8 @@ async function init(opt) {
|
||||
cartStore.setSeatFeeConfig("personCount", res.seatNum);
|
||||
cartStore.setDinnerType(res.dineMode || "dine-in");
|
||||
cartStore.setOldOrder(res);
|
||||
if(res.limitRate){
|
||||
cartStore.limitTimeDiscount=res.limitRate
|
||||
if (res.limitRate) {
|
||||
cartStore.limitTimeDiscount = res.limitRate;
|
||||
}
|
||||
orderRemarker.value = res.remark;
|
||||
Object.assign(listinfo, res);
|
||||
@@ -1110,6 +1118,8 @@ async function init(opt) {
|
||||
|
||||
orderVIP.value = uni.cache.get("orderVIP");
|
||||
cartStore.freeDineConfig = orderVIP.value.freeDineConfig;
|
||||
const shopUserInfo = uni.cache.get("shopUserInfo");
|
||||
cartStore.shopUserInfo = shopUserInfo;
|
||||
if (options.tableCode) {
|
||||
socketInitPar.table_code = options.tableCode;
|
||||
socketInit();
|
||||
@@ -1124,6 +1134,16 @@ onLoad((opt) => {
|
||||
watch(
|
||||
() => cartStore.orderCostSummary.orderOriginFinalPayAmount,
|
||||
(newval) => {
|
||||
console.log(
|
||||
"cartStore.orderCostSummary.orderOriginFinalPayAmount",
|
||||
orderVIP.value
|
||||
);
|
||||
if (JSON.stringify(orderVIP.value) == "{}") {
|
||||
return;
|
||||
}
|
||||
if (!orderVIP.value) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
!orderVIP.value.freeDineConfig ||
|
||||
!orderVIP.value.freeDineConfig.enable
|
||||
@@ -1178,14 +1198,18 @@ const disablePayType = computed(() => {
|
||||
if (rechargeItem.value.id) {
|
||||
arr.add("余额支付");
|
||||
}
|
||||
if (!orderVIP.value.amount) {
|
||||
if (!orderVIP.value || !orderVIP.value.amount) {
|
||||
arr.add("余额支付");
|
||||
}
|
||||
if (
|
||||
orderVIP.value.amount < cartStore.orderCostSummary.orderOriginFinalPayAmount
|
||||
) {
|
||||
arr.add("余额支付");
|
||||
if (orderVIP.value) {
|
||||
if (
|
||||
orderVIP.value.amount <
|
||||
cartStore.orderCostSummary.orderOriginFinalPayAmount
|
||||
) {
|
||||
arr.add("余额支付");
|
||||
}
|
||||
}
|
||||
|
||||
// if (cartStore.orderCostSummary.orderOriginFinalPayAmount <= 0) {
|
||||
// arr.add("微信支付");
|
||||
// }
|
||||
|
||||
@@ -219,6 +219,7 @@
|
||||
|
||||
const orderinfo = (e) => {
|
||||
if(e.status=='unpaid'){
|
||||
uni.cache.set('shopId',e.shopId)
|
||||
uni.pro.navigateTo('order/confirm-order', {
|
||||
orderId: e.id,
|
||||
shopId: e.shopId,
|
||||
|
||||
@@ -155,9 +155,7 @@
|
||||
>/{{ item.unitName }}</text
|
||||
>
|
||||
|
||||
<text class="old-price"
|
||||
>¥{{ item.salePrice }}</text
|
||||
>
|
||||
<text class="old-price">¥{{ item.salePrice }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="panelfiveitemNum">
|
||||
@@ -201,6 +199,7 @@
|
||||
:limitDiscount="limitTimeDiscountRes"
|
||||
:cart="item"
|
||||
:shopUserInfo="shopUserInfo"
|
||||
:key="item.id"
|
||||
:shopInfo="shopInfo"
|
||||
></GoodsPrice>
|
||||
</view>
|
||||
@@ -208,9 +207,7 @@
|
||||
<text class="unit" v-if="item.unitName"
|
||||
>/{{ item.unitName }}</text
|
||||
>
|
||||
<text class="old-price"
|
||||
>¥{{ item.salePrice }}</text
|
||||
>
|
||||
<text class="old-price">¥{{ item.salePrice }}</text>
|
||||
<!-- <text v-if="item.suitNum>1 && item.type!= 'sku'"
|
||||
style="font-size: 16rpx;">「{{item.suitNum}}{{item.unitName}}起点」</text> -->
|
||||
</view>
|
||||
@@ -444,9 +441,7 @@
|
||||
<text class="money_num" v-if="item1.unitName"
|
||||
>/{{ item1.unitName }}</text
|
||||
>
|
||||
<text class="old-price"
|
||||
>¥{{ item1.salePrice }}</text
|
||||
>
|
||||
<text class="old-price">¥{{ item1.salePrice }}</text>
|
||||
|
||||
<!-- <text v-if="item1.suitNum>1 && item1.type!= 'sku'"
|
||||
style="font-size: 14rpx;">
|
||||
@@ -701,7 +696,17 @@
|
||||
"
|
||||
>
|
||||
<text class="i">¥</text>
|
||||
<text class="num">
|
||||
<view class="num">
|
||||
<GoodsPrice
|
||||
:limitDiscount="limitTimeDiscountRes"
|
||||
:cart="specifications.item.result"
|
||||
:shopUserInfo="shopUserInfo"
|
||||
:shopInfo="shopInfo"
|
||||
></GoodsPrice>
|
||||
</view>
|
||||
|
||||
<text class="num" v-if="false">
|
||||
|
||||
{{
|
||||
shopInfo.isVip == 1 && shopInfo.isMemberPrice == 1
|
||||
? specifications.item.result.memberPrice ||
|
||||
@@ -719,7 +724,15 @@
|
||||
</view>
|
||||
<view class="price" v-else>
|
||||
<text class="i">¥</text>
|
||||
<text class="num">
|
||||
<view class="num">
|
||||
<GoodsPrice
|
||||
:limitDiscount="limitTimeDiscountRes"
|
||||
:cart="specifications.item"
|
||||
:shopUserInfo="shopUserInfo"
|
||||
:shopInfo="shopInfo"
|
||||
></GoodsPrice>
|
||||
</view>
|
||||
<text class="num" v-if="false">
|
||||
{{
|
||||
shopInfo.isVip == 1 && shopInfo.isMemberPrice == 1
|
||||
? specifications.item.memberPrice ||
|
||||
@@ -871,7 +884,7 @@ function onBuyClick(item) {
|
||||
) {
|
||||
for (let i in shopProductList.hots) {
|
||||
const goods = shopProductList.hots[i];
|
||||
if (goods.id==item.id) {
|
||||
if (goods.id == item.id) {
|
||||
index = i;
|
||||
clickspecifications(item, index, index);
|
||||
break;
|
||||
@@ -1424,6 +1437,7 @@ const submitSelection = async () => {
|
||||
: shopCartNumber.value,
|
||||
pro_group_info: selectedGroupSnap.value,
|
||||
goods_type: specifications.item.type == "package" ? "package" : "",
|
||||
memberPrice: specifications.item.memberPrice,
|
||||
is_print: 1,
|
||||
product_type: specifications.item.type,
|
||||
});
|
||||
@@ -1569,6 +1583,7 @@ const singleclick = async (item, i) => {
|
||||
: "add",
|
||||
product_id: item.id,
|
||||
sku_id: item.skuId,
|
||||
memberPrice: item.memberPrice,
|
||||
number: await calculateValue(item.cartNumber, i, suitNum),
|
||||
is_print: 1,
|
||||
product_type: item.type,
|
||||
@@ -1647,21 +1662,25 @@ const updateProductQuantities = () => {
|
||||
|
||||
//websocket产值
|
||||
const websocketsendMessage = (data) => {
|
||||
console.log("websocketsendMessage", data);
|
||||
const sendData = { ...data, is_time_discount: 0 };
|
||||
if (cartStore.limitTimeDiscount && cartStore.limitTimeDiscount.id && data.discount_sale_amount*1<=0) {
|
||||
if (
|
||||
orderUtils.canUseLimitTimeDiscount(
|
||||
data,
|
||||
cartStore.limitTimeDiscount,
|
||||
shopInfo,
|
||||
shopUserInfo.value,
|
||||
"product_id"
|
||||
)
|
||||
) {
|
||||
if (cartStore.limitTimeDiscount && cartStore.limitTimeDiscount.id) {
|
||||
const canUse = orderUtils.canUseLimitTimeDiscount(
|
||||
data,
|
||||
cartStore.limitTimeDiscount,
|
||||
shopInfo,
|
||||
shopUserInfo.value,
|
||||
"product_id"
|
||||
);
|
||||
console.log("canUse", canUse);
|
||||
if (canUse) {
|
||||
sendData.is_time_discount = 1;
|
||||
}
|
||||
}
|
||||
uni.$u.debounce(useSocket.sendMessage(sendData), 500);
|
||||
delete sendData.memberPrice;
|
||||
uni.$u.debounce(() => {
|
||||
useSocket.sendMessage(sendData);
|
||||
}, 500);
|
||||
};
|
||||
|
||||
// 用于记录已经处理过的消息的 msg_id
|
||||
@@ -1792,8 +1811,8 @@ async function onMessage(Message) {
|
||||
});
|
||||
}
|
||||
if (Message.operate_type == "time_discount_save") {
|
||||
console.log("time_discount_save", Message.data);
|
||||
cartStore.limitTimeDiscount = Message.data;
|
||||
console.log("time_discount_save", cartStore.limitTimeDiscount);
|
||||
}
|
||||
|
||||
//除去p 每次返回都回执消息
|
||||
@@ -1955,11 +1974,10 @@ const totalPrices = computed(() => {
|
||||
shopUserInfo: shopUserInfo.value,
|
||||
idKey: "id",
|
||||
});
|
||||
console.log("限时折扣", item, price);
|
||||
return total + parseFloat(price) * parseFloat(item.cartNumber);
|
||||
}
|
||||
// 是否启用会员价 0否1是
|
||||
if (shopInfo.isVip == 1 && shopInfo.isMemberPrice == 1) {
|
||||
if (shopUserInfo.isVip == 1 && shopUserInfo.isMemberPrice == 1) {
|
||||
// memberPrice会员价
|
||||
return (
|
||||
total +
|
||||
@@ -2174,12 +2192,12 @@ onLoad(async (e) => {
|
||||
const limitTimeDiscountRes = ref(null);
|
||||
|
||||
function showLimitDiscount(item) {
|
||||
if (!limitTimeDiscountRes.value) {
|
||||
if (!cartStore.limitTimeDiscount || !cartStore.limitTimeDiscount.id) {
|
||||
return false;
|
||||
}
|
||||
return orderUtils.canUseLimitTimeDiscount(
|
||||
item,
|
||||
limitTimeDiscountRes.value,
|
||||
cartStore.limitTimeDiscount,
|
||||
shopInfo,
|
||||
shopUserInfo.value,
|
||||
"id"
|
||||
@@ -2187,25 +2205,6 @@ function showLimitDiscount(item) {
|
||||
}
|
||||
|
||||
onShow(async () => {
|
||||
limitTimeDiscountapi
|
||||
.getConfig({
|
||||
shopId: uni.cache.get("shopId"),
|
||||
})
|
||||
.then((res) => {
|
||||
console.log("limitTimeDiscountapi", res);
|
||||
if (res && typeof res == "object") {
|
||||
limitTimeDiscountRes.value = res;
|
||||
cartStore.limitTimeDiscount = res;
|
||||
websocketsendMessage({
|
||||
type: "shopping",
|
||||
operate_type: "time_discount_save",
|
||||
table_code: uni.cache.get("tableCode"),
|
||||
shop_id: uni.cache.get("shopId"),
|
||||
operate_type: "time_discount_save",
|
||||
data: res,
|
||||
});
|
||||
}
|
||||
});
|
||||
// 监听页面显示和隐藏
|
||||
useSocket.setOnMessage(onMessage);
|
||||
useSocket.onShowconnect();
|
||||
@@ -2238,6 +2237,29 @@ onMounted(async () => {
|
||||
let res = await APIhistoryOrder({
|
||||
tableCode: uni.cache.get("tableCode"),
|
||||
});
|
||||
const limitRes = await limitTimeDiscountapi.getConfig({
|
||||
shopId: uni.cache.get("shopId"),
|
||||
});
|
||||
if (limitRes && typeof limitRes == "object") {
|
||||
limitTimeDiscountRes.value = limitRes;
|
||||
websocketsendMessage({
|
||||
type: "shopping",
|
||||
operate_type: "time_discount_save",
|
||||
table_code: uni.cache.get("tableCode"),
|
||||
shop_id: uni.cache.get("shopId"),
|
||||
operate_type: "time_discount_save",
|
||||
data: limitRes,
|
||||
});
|
||||
} else {
|
||||
websocketsendMessage({
|
||||
type: "shopping",
|
||||
operate_type: "time_discount_save",
|
||||
table_code: uni.cache.get("tableCode"),
|
||||
shop_id: uni.cache.get("shopId"),
|
||||
operate_type: "time_discount_save",
|
||||
data: null,
|
||||
});
|
||||
}
|
||||
|
||||
await productqueryProduct();
|
||||
if (res && res.id && shopInfo.registerType == "after") {
|
||||
|
||||
@@ -243,11 +243,14 @@
|
||||
|
||||
<!-- 生成公众号二维码 -->
|
||||
<we-qrcode @generate="(e) => qrcodeResult(e)"></we-qrcode>
|
||||
|
||||
<devetools></devetools>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import weQrcode from "@/components/wechat-ac-qrcode.vue";
|
||||
import devetools from "@/components/devetools.vue";
|
||||
|
||||
import { ref, computed, onMounted, reactive, watch } from "vue";
|
||||
import { onLoad, onReady, onShow } from "@dcloudio/uni-app";
|
||||
@@ -276,7 +279,7 @@ const myFunList = ref([
|
||||
{
|
||||
name: "分销",
|
||||
type: "fenxiao",
|
||||
icon: "https://czg-qr-order.oss-cn-beijing.aliyuncs.com/my/my_coupon.png",
|
||||
icon: "/static/icon/fenxiao.svg",
|
||||
},
|
||||
// {
|
||||
// name: "我的订单",
|
||||
|
||||
1
static/icon/fenxiao.svg
Normal file
1
static/icon/fenxiao.svg
Normal 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="1761788431710" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5024" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M381.952 539.136h-31.744v-16.384h31.744c14.848 0 26.112-8.704 26.112-19.968s-11.776-19.968-26.112-19.968h-17.408l38.4-66.048c4.096-6.656 5.12-14.848 3.584-21.504-1.024-5.12-4.608-9.728-9.216-12.288-10.24-5.632-25.088 0-31.744 12.288L338.432 445.44c-9.728 17.92-10.24 19.456-10.24 19.456l-0.512 1.024c-12.8-25.088-36.352-68.608-37.376-71.168-6.656-12.288-22.016-17.92-32.256-11.776-4.608 3.072-8.192 7.68-9.728 12.8-2.048 6.656-0.512 14.336 3.072 20.992l35.84 61.952 2.048 3.584h-18.944c-14.848 0-26.112 8.704-26.112 19.968s11.776 19.968 26.112 19.968h33.792v16.384h-33.792c-14.848 0-26.112 8.704-26.112 20.48 0 10.752 10.24 18.944 24.576 19.968h35.84v21.504c0 14.336 10.24 26.112 23.04 26.112s23.04-11.264 23.04-25.6V578.56h36.864c12.8-2.048 20.992-9.728 20.992-19.456-0.512-11.264-11.776-19.968-26.624-19.968z" fill="#333333" p-id="5025"></path><path d="M817.152 354.304c82.944 0 150.528-67.584 150.528-150.528s-67.584-150.528-150.528-150.528-150.528 67.584-150.528 150.528c0 13.312 1.536 25.6 4.608 37.888l-138.752 92.16c-5.632-6.656-11.264-13.312-17.92-19.456-50.688-50.688-117.76-78.336-189.44-78.336s-138.752 27.648-189.44 78.336c-50.688 50.688-78.336 117.76-78.336 189.44s27.648 138.752 78.336 189.44c50.688 50.688 117.76 78.336 189.44 78.336 71.168 0 138.24-27.648 188.928-77.824l146.944 102.4c-6.144 14.336-9.216 30.72-9.216 47.104 0 23.04 6.144 44.544 17.408 62.976h-139.776c-16.384 0-30.208 13.312-30.208 30.208 0 16.384 13.312 30.208 30.208 30.208h247.296c67.584-1.024 121.856-55.808 121.856-123.392 0-68.096-55.296-123.392-123.392-123.392-29.696 0-56.832 10.24-77.824 27.648l-145.408-101.376c26.624-42.496 40.96-91.648 40.96-142.848 0-41.984-9.728-82.944-27.648-119.296l133.12-88.576c28.16 35.84 70.656 58.88 118.784 58.88z m0-248.832c54.272 0 98.304 44.032 98.304 98.304S871.424 302.08 817.152 302.08s-98.304-44.032-98.304-98.304 44.032-98.304 98.304-98.304z m-41.472 674.816c34.816 0 62.976 28.16 62.976 62.976s-28.16 62.976-62.976 62.976-62.976-28.16-62.976-62.976 28.16-62.976 62.976-62.976zM326.144 711.68c-114.688 0-207.872-93.184-207.872-207.872 0-114.688 93.184-207.872 207.872-207.872s207.872 93.184 207.872 207.872C533.504 618.496 440.32 711.68 326.144 711.68z" fill="#333333" p-id="5026"></path></svg>
|
||||
|
After Width: | Height: | Size: 2.5 KiB |
@@ -47,6 +47,7 @@ export const useCartsStore = defineStore("cart", () => {
|
||||
product_id: item.product_id || item.productId,
|
||||
sku_id: item.skuId || item.sku_id,
|
||||
});
|
||||
const discountSaleAmount=item.discount_sale_amount?(item.discount_sale_amount*1) : (item.discountSaleAmount?item.discountSaleAmount*1:0)
|
||||
return {
|
||||
...item,
|
||||
id: item.id,
|
||||
@@ -57,10 +58,10 @@ export const useCartsStore = defineStore("cart", () => {
|
||||
product_type: item.productType,
|
||||
is_temporary: !!(item.is_temporary || item.isTemporary),
|
||||
is_gift: !!(item.is_gift || item.isGift),
|
||||
is_time_discount: item.is_time_discount || item.isTimeDiscount ,
|
||||
returnNum: item.returnNum || 0,
|
||||
memberPrice: item.memberPrice || 0,
|
||||
discountSaleAmount:
|
||||
item.discount_sale_amount || item.discountSaleAmount || 0,
|
||||
discountSaleAmount:discountSaleAmount,
|
||||
packFee: item.packFee || (goods ? goods.packFee : 0) || 0,
|
||||
packNumber: item.pack_number || item.packNumber || 0,
|
||||
activityInfo: item.activityInfo
|
||||
@@ -86,6 +87,11 @@ export const useCartsStore = defineStore("cart", () => {
|
||||
const oldOrderGoods = Object.values(oldOrder.value.detailMap || {})
|
||||
.flat()
|
||||
.map(convertToBaseCartItem);
|
||||
|
||||
console.log('oldOrder.value',oldOrder.value)
|
||||
if(!oldOrder.value.id){
|
||||
|
||||
}
|
||||
return [...currentGoods, ...giftGoods, ...oldOrderGoods];
|
||||
}
|
||||
|
||||
@@ -217,8 +223,8 @@ export const useCartsStore = defineStore("cart", () => {
|
||||
//商品数据Map
|
||||
const goodsMap = reactive({});
|
||||
|
||||
function returnGoods(product_id){
|
||||
return goodsMap[product_id*1]
|
||||
function returnGoods(product_id) {
|
||||
return goodsMap[product_id * 1];
|
||||
}
|
||||
|
||||
//获取商品数据
|
||||
@@ -244,7 +250,6 @@ export const useCartsStore = defineStore("cart", () => {
|
||||
goodsMap[product_id] = data;
|
||||
}
|
||||
|
||||
|
||||
const isLoading = ref(true);
|
||||
|
||||
function getProductDetails(v) {
|
||||
@@ -308,7 +313,9 @@ export const useCartsStore = defineStore("cart", () => {
|
||||
const msgData = Message.data;
|
||||
// 初始化
|
||||
if (Message.operate_type == "init") {
|
||||
console.log("carts init Message", Message);
|
||||
console.log("carts init", msgData);
|
||||
limitTimeDiscount.value = Message.time_dis_info;
|
||||
cartsGoodsInfoInit(msgData);
|
||||
uni.hideLoading();
|
||||
isLoading.value = false;
|
||||
@@ -357,10 +364,14 @@ export const useCartsStore = defineStore("cart", () => {
|
||||
});
|
||||
}
|
||||
//获取限时折扣
|
||||
// if(Message.operate_type == "time_discount_get"){
|
||||
// console.log("time_discount_get", Message.data);
|
||||
// limitTimeDiscount.value = Message.data;
|
||||
// }
|
||||
if(Message.operate_type == "time_discount_get"){
|
||||
console.log("time_discount_get", Message.data);
|
||||
limitTimeDiscount.value = Message.data;
|
||||
}
|
||||
if(Message.operate_type == "time_discount_save"){
|
||||
console.log("time_discount_save", Message.data);
|
||||
limitTimeDiscount.value = Message.data;
|
||||
}
|
||||
|
||||
if (Message.type == "no_suit_num") {
|
||||
uni.showModal({
|
||||
@@ -407,11 +418,13 @@ export const useCartsStore = defineStore("cart", () => {
|
||||
|
||||
//是否使用会员价
|
||||
const useVipPrice = computed(() => {
|
||||
if (!orderVIP.value) {
|
||||
if (!shopUserInfo.value) {
|
||||
return false;
|
||||
}
|
||||
const isUse =
|
||||
orderVIP.value.isVip && shopInfo.value.isMemberPrice ? true : false;
|
||||
shopUserInfo.value.isVip && shopUserInfo.value.isMemberPrice
|
||||
? true
|
||||
: false;
|
||||
return isUse;
|
||||
});
|
||||
|
||||
@@ -636,7 +649,7 @@ export const useCartsStore = defineStore("cart", () => {
|
||||
carts,
|
||||
isEmpty,
|
||||
setGoodsMap,
|
||||
goodsMap:goodsMap,
|
||||
goodsMap: goodsMap,
|
||||
goodsIsloading,
|
||||
goodsInit,
|
||||
onMessage,
|
||||
@@ -676,5 +689,6 @@ export const useCartsStore = defineStore("cart", () => {
|
||||
freeDineConfig,
|
||||
//限时折扣
|
||||
limitTimeDiscount,
|
||||
shopUserInfo,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -12,41 +12,41 @@ export function returnGoodsPrice(goods, user, shopInfo, limitTimeDiscount) {
|
||||
if (!goods) {
|
||||
return 0;
|
||||
}
|
||||
//是否可以使用会员价
|
||||
const canUseVipPrice =
|
||||
user && user.isVip && user.isMemberPrice && goods.memberPrice * 1 > 0;
|
||||
// 商家改价
|
||||
if (goods.discount_sale_amount * 1 > 0) {
|
||||
return goods.salePrice;
|
||||
}
|
||||
// 限时折扣
|
||||
if (limitTimeDiscount && limitTimeDiscount.id) {
|
||||
if (
|
||||
limitTimeDiscount.foodType == 1 &&
|
||||
limitTimeDiscount.discountPriority == "limit-time"
|
||||
) {
|
||||
return new BigNumber(goods.salePrice)
|
||||
.times(limitTimeDiscount.discountRate / 100)
|
||||
.decimalPlaces(2, BigNumber.ROUND_UP)
|
||||
.toNumber();
|
||||
}
|
||||
const canUseFoods = limitTimeDiscount.foods.split(",");
|
||||
if (
|
||||
limitTimeDiscount.foodType == 2 &&
|
||||
limitTimeDiscount.discountPriority == "limit-time" &&
|
||||
canUseFoods.includes(`${goods.productId}`)
|
||||
) {
|
||||
const canUseLimit =
|
||||
limitTimeDiscount.foodType == 1 ||
|
||||
canUseFoods.includes(`${goods.productId}`);
|
||||
if (canUseLimit && limitTimeDiscount.discountPriority == "limit-time") {
|
||||
return new BigNumber(goods.salePrice)
|
||||
.times(limitTimeDiscount.discountRate / 100)
|
||||
.decimalPlaces(2, BigNumber.ROUND_UP)
|
||||
.toNumber();
|
||||
}
|
||||
if (
|
||||
canUseLimit &&
|
||||
limitTimeDiscount.discountPriority == "vip-price" &&
|
||||
!canUseVipPrice
|
||||
) {
|
||||
if (canUseVipPrice) {
|
||||
return goods.memberPrice;
|
||||
} else {
|
||||
return new BigNumber(goods.salePrice)
|
||||
.times(limitTimeDiscount.discountRate / 100)
|
||||
.decimalPlaces(2, BigNumber.ROUND_UP)
|
||||
.toNumber();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (shopInfo && !shopInfo.isMemberPrice) {
|
||||
return goods.salePrice;
|
||||
}
|
||||
if (
|
||||
user.isVip &&
|
||||
goods.memberPrice * 1 <= goods.salePrice * 1 &&
|
||||
goods.memberPrice * 1 > 0
|
||||
) {
|
||||
if (canUseVipPrice) {
|
||||
return goods.memberPrice;
|
||||
}
|
||||
return goods.salePrice;
|
||||
@@ -124,12 +124,12 @@ export function returnCanDikouGoodsArr(args) {
|
||||
return v;
|
||||
})
|
||||
.filter((v) => {
|
||||
const canUseNum=v.num-(v.returnNum||0)
|
||||
if(canUseNum <= 0||v.is_temporary==1||v.is_gift==1){
|
||||
return false
|
||||
const canUseNum = v.num - (v.returnNum || 0);
|
||||
if (canUseNum <= 0 || v.is_temporary == 1 || v.is_gift == 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true
|
||||
return true;
|
||||
}); // 过滤掉数量<=0的商品,赠菜,临时菜
|
||||
|
||||
return arr;
|
||||
@@ -139,20 +139,19 @@ export function returnCanDikouGoodsArr(args) {
|
||||
* 返回商品是否享用了会员价/会员折扣
|
||||
* @param {*} goods
|
||||
*/
|
||||
function returnGoodsIsUseVipPrice(shopInfo,user,goods) {
|
||||
if(goods.is_time_discount){
|
||||
return false
|
||||
function returnGoodsIsUseVipPrice(shopInfo, user, goods) {
|
||||
if (goods.is_time_discount) {
|
||||
return false;
|
||||
}
|
||||
if(shopInfo.isMemberPrice!=1||user.isVip!=1){
|
||||
return false
|
||||
if (shopInfo.isMemberPrice != 1 || user.isVip != 1) {
|
||||
return false;
|
||||
}
|
||||
if(shopInfo.isMemberPrice==1&&user.isVip==1){
|
||||
if(goods.memberPrice<=0){
|
||||
return false
|
||||
if (shopInfo.isMemberPrice == 1 && user.isVip == 1) {
|
||||
if (goods.memberPrice <= 0) {
|
||||
return false;
|
||||
}
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -160,10 +159,15 @@ function returnGoodsIsUseVipPrice(shopInfo,user,goods) {
|
||||
*/
|
||||
function returnCanCalcGoodsList(canCalcGoodsArr, coupon, shopInfo, user) {
|
||||
return canCalcGoodsArr.filter((goods) => {
|
||||
if (!coupon.discountShare && goods.is_time_discount) {
|
||||
console.log("goods");
|
||||
console.log(goods);
|
||||
if (!coupon.discountShare && (goods.is_time_discount||goods.isTimeDiscount)) {
|
||||
return false;
|
||||
}
|
||||
if(!coupon.vipPriceShare&& returnGoodsIsUseVipPrice(shopInfo,user,goods)){
|
||||
if (
|
||||
!coupon.vipPriceShare &&
|
||||
returnGoodsIsUseVipPrice(shopInfo, user, goods)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -240,6 +244,8 @@ export function returnCouponCanUse(args) {
|
||||
shopInfo,
|
||||
user
|
||||
);
|
||||
console.log("canCalcGoodsArr");
|
||||
console.log(canCalcGoodsArr);
|
||||
fullAmount = canCalcGoodsArr.reduce((pre, cur) => {
|
||||
return (
|
||||
pre + returnGoodsPrice(cur, user, shopInfo, limitTimeDiscount) * cur.num
|
||||
@@ -291,8 +297,8 @@ export function returnCouponCanUse(args) {
|
||||
}
|
||||
// 商品兑换券,第二件半价和买一送一判断是否有可用商品
|
||||
if ([2, 4, 5].includes(coupon.type)) {
|
||||
// 没有符合条件的商品
|
||||
if (isDikouAll && canDikouGoodsArr.length === 0) {
|
||||
// 没有符合条件的商品
|
||||
if (isDikouAll && canDikouGoodsArr.length === 0) {
|
||||
return {
|
||||
canUse: false,
|
||||
reason: "没有符合条件的商品",
|
||||
@@ -304,23 +310,20 @@ export function returnCouponCanUse(args) {
|
||||
reason: "没有符合条件的商品",
|
||||
};
|
||||
}
|
||||
if (coupon.type == 2 ) {
|
||||
if(canCalcGoodsArr.length<=0){
|
||||
if (coupon.type == 2) {
|
||||
if (canCalcGoodsArr.length <= 0) {
|
||||
return {
|
||||
canUse: false,
|
||||
reason: "没有符合计算门槛条件的商品",
|
||||
};
|
||||
}
|
||||
if(fullAmount < coupon.fullAmount){
|
||||
if (fullAmount < coupon.fullAmount) {
|
||||
return {
|
||||
canUse: false,
|
||||
reason: `满${coupon.fullAmount}元可用,当前可参与金额${fullAmount}元`,
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
//商品兑换券是否达到门槛金额
|
||||
if (coupon.type == 2 && goodsOrderPrice < coupon.fullAmount) {
|
||||
|
||||
101
utils/goods.ts
101
utils/goods.ts
@@ -455,18 +455,23 @@ export function returnCanUseLimitTimeDiscount(
|
||||
return false;
|
||||
}
|
||||
const canUseFoods = (limitTimeDiscount.foods || "").split(",");
|
||||
const goodsCanUse =
|
||||
limitTimeDiscount.foodType == 1 || canUseFoods.includes("" + goods[idKey]);
|
||||
if (!goodsCanUse) {
|
||||
return false;
|
||||
}
|
||||
if (limitTimeDiscount.discountPriority == "limit-time") {
|
||||
if (
|
||||
limitTimeDiscount.foodType == 1 ||
|
||||
canUseFoods.includes("" + goods[idKey])
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (limitTimeDiscount.discountPriority == "vip-price") {
|
||||
if (!useVipPrice) {
|
||||
return true;
|
||||
}
|
||||
if (useVipPrice && goods.hasOwnProperty("memberPrice")) {
|
||||
if (goods.memberPrice && goods.memberPrice * 1 <= 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -512,7 +517,7 @@ function returnLimitPrice(
|
||||
}
|
||||
if (limitTimeDiscount.discountPriority == "vip-price") {
|
||||
//会员价优先
|
||||
if (useVipPrice) {
|
||||
if (useVipPrice && goods.memberPrice && goods.memberPrice * 1 > 0) {
|
||||
//使用会员价
|
||||
return returnMemberPrice(useVipPrice, goods);
|
||||
} else {
|
||||
@@ -598,7 +603,9 @@ export function calcFullReductionActivityFullAmount(
|
||||
goodsList: BaseCartItem[],
|
||||
fullReductionActivitie: FullReductionActivity | undefined,
|
||||
limitTimeDiscount: TimeLimitDiscountConfig | null | undefined,
|
||||
useVipPrice: boolean
|
||||
useVipPrice: boolean,
|
||||
seatFee: number,
|
||||
packFee: number
|
||||
): number {
|
||||
if (!fullReductionActivitie) {
|
||||
return 0;
|
||||
@@ -621,7 +628,7 @@ export function calcFullReductionActivityFullAmount(
|
||||
amount += calcPrice * availableNum;
|
||||
}
|
||||
}
|
||||
return amount;
|
||||
return amount + seatFee + packFee;
|
||||
console.log("amount", amount);
|
||||
}
|
||||
|
||||
@@ -902,6 +909,7 @@ export function calcSingleGoodsRealPrice(
|
||||
>
|
||||
): number {
|
||||
const { isMember, memberDiscountRate, limitTimeDiscount: activity } = config;
|
||||
console.log("activity", activity);
|
||||
|
||||
//如果是增菜价格为0
|
||||
if (goods.is_gift) {
|
||||
@@ -912,7 +920,6 @@ export function calcSingleGoodsRealPrice(
|
||||
if (goods.discountSaleAmount && goods.discountSaleAmount > 0) {
|
||||
return truncateToTwoDecimals(goods.discountSaleAmount);
|
||||
}
|
||||
console.log("calcSingleGoodsRealPrice:goods", goods);
|
||||
|
||||
// 2. 优先级2:会员价(含会员折扣率,SKU会员价优先)
|
||||
const memberPrice = new BigNumber(
|
||||
@@ -934,15 +941,18 @@ export function calcSingleGoodsRealPrice(
|
||||
if (!activity || !isActivityApplicable) {
|
||||
return memberPrice.toNumber();
|
||||
}
|
||||
console.log("isMember", isMember);
|
||||
//限时折扣优先或者会员价优先但是不是会员或者未开启会员价格时限时折扣优先
|
||||
if (
|
||||
activity.discountPriority == "limit-time" ||
|
||||
(activity.discountPriority == "vip-price" && !isMember)
|
||||
(activity.discountPriority == "vip-price" && !isMember) ||
|
||||
(activity.discountPriority == "vip-price" && isMember && !goods.memberPrice)
|
||||
) {
|
||||
//限时折扣优先
|
||||
return truncateToTwoDecimals(
|
||||
new BigNumber(goods.salePrice)
|
||||
.multipliedBy(activity.discountRate / 100)
|
||||
.times(activity.discountRate / 100)
|
||||
.decimalPlaces(2, BigNumber.ROUND_UP)
|
||||
.toNumber()
|
||||
);
|
||||
}
|
||||
@@ -1017,6 +1027,7 @@ export function calcGoodsRealAmount(
|
||||
for (const goods of goodsList) {
|
||||
const availableNum = Math.max(0, goods.number - (goods.returnNum || 0));
|
||||
if (availableNum <= 0) continue;
|
||||
console.log("goods", goods);
|
||||
const realPrice = new BigNumber(calcSingleGoodsRealPrice(goods, config));
|
||||
total = total.plus(realPrice.multipliedBy(availableNum));
|
||||
}
|
||||
@@ -1065,11 +1076,15 @@ export function selectOptimalThreshold(
|
||||
const validThresholds = thresholds.filter((threshold) => {
|
||||
const fullAmount = new BigNumber(threshold.fullAmount || 0);
|
||||
const discountAmount = new BigNumber(threshold.discountAmount || 0);
|
||||
console.log("fullAmount", fullAmount);
|
||||
console.log("discountAmount", discountAmount);
|
||||
|
||||
return (
|
||||
fullAmount.isLessThanOrEqualTo(thresholdBase) &&
|
||||
discountAmount.isGreaterThan(0)
|
||||
);
|
||||
});
|
||||
console.log("validThresholds", validThresholds);
|
||||
|
||||
if (!validThresholds.length) return undefined;
|
||||
|
||||
@@ -1298,9 +1313,11 @@ function calcVipDiscountAmount(
|
||||
if (shopUserInfo.isVip == 1 && shopUserInfo.isMemberPrice != 1) {
|
||||
return 0;
|
||||
}
|
||||
console.log("goodsRealAmount", goodsRealAmount);
|
||||
console.log("discount", (100 - (shopUserInfo.discount || 0)) / 100);
|
||||
return truncateToTwoDecimals(
|
||||
new BigNumber(goodsRealAmount)
|
||||
.multipliedBy((100 - (shopUserInfo.discount || 0)) / 100)
|
||||
.times((100 - (shopUserInfo.discount || 0)) / 100)
|
||||
.decimalPlaces(2, BigNumber.ROUND_UP)
|
||||
.toNumber()
|
||||
);
|
||||
@@ -1348,26 +1365,32 @@ export function calculateOrderCostSummary(
|
||||
limitTimeDiscount: config.limitTimeDiscount,
|
||||
}
|
||||
);
|
||||
|
||||
// 会员折扣减免
|
||||
const vipDiscountAmount = calcVipDiscountAmount(
|
||||
goodsRealAmount,
|
||||
shopUserInfo
|
||||
); // 会员折扣减免金额
|
||||
|
||||
const goodsDiscountAmount = calcGoodsDiscountAmount(
|
||||
goodsOriginalAmount,
|
||||
goodsRealAmount
|
||||
); // 商品折扣金额
|
||||
|
||||
|
||||
|
||||
const newUserDiscount = config.newUserDiscount || 0; // 新客立减
|
||||
|
||||
// 其他费用计算(原有逻辑不变) ------------------------------
|
||||
const packFee = calcTotalPackFee(goodsList, dinnerType); // 打包费
|
||||
let seatFee = calcSeatFee(config.seatFeeConfig); // 餐位费
|
||||
seatFee = dinnerType === "dine-in" ? seatFee : 0; // 外卖不收餐位费
|
||||
const additionalFee = Math.max(0, config.additionalFee); // 附加费
|
||||
|
||||
// ------------------------------ 2. 满减活动计算(核心步骤) ------------------------------
|
||||
let usedFullReductionActivity: FullReductionActivity | undefined;
|
||||
let usedFullReductionThreshold: FullReductionThreshold | undefined;
|
||||
let fullReductionAmount = 0;
|
||||
let usedFullReductionActivityFullAmount = calcFullReductionActivityFullAmount(
|
||||
goodsList,
|
||||
usedFullReductionActivity,
|
||||
config.limitTimeDiscount,
|
||||
config.isMember,
|
||||
seatFee,
|
||||
packFee
|
||||
);
|
||||
|
||||
// 2.1 筛选最优满减活动(后端活动列表、当前店铺、就餐类型、时间)
|
||||
usedFullReductionActivity = filterOptimalFullReductionActivity(
|
||||
config.fullReductionActivities,
|
||||
@@ -1376,12 +1399,6 @@ export function calculateOrderCostSummary(
|
||||
currentTime
|
||||
);
|
||||
|
||||
// 其他费用计算(原有逻辑不变) ------------------------------
|
||||
const packFee = calcTotalPackFee(goodsList, dinnerType); // 打包费
|
||||
let seatFee = calcSeatFee(config.seatFeeConfig); // 餐位费
|
||||
seatFee = dinnerType === "dine-in" ? seatFee : 0; // 外卖不收餐位费
|
||||
const additionalFee = Math.max(0, config.additionalFee); // 附加费
|
||||
|
||||
// 2.2 计算满减基数(先扣新客立减)
|
||||
let baseAfterNewUserDiscount = new BigNumber(
|
||||
limitTimeDiscount &&
|
||||
@@ -1400,14 +1417,15 @@ export function calculateOrderCostSummary(
|
||||
baseAfterNewUserDiscount > 0 ? baseAfterNewUserDiscount : 0;
|
||||
|
||||
// 2.3 选择最优满减阈值(多门槛场景)
|
||||
let usedFullReductionActivityFullAmount = 0;
|
||||
if (usedFullReductionActivity) {
|
||||
//计算当前满减活动的门槛金额
|
||||
usedFullReductionActivityFullAmount = calcFullReductionActivityFullAmount(
|
||||
goodsList,
|
||||
usedFullReductionActivity,
|
||||
config.limitTimeDiscount,
|
||||
config.isMember
|
||||
config.isMember,
|
||||
seatFee,
|
||||
packFee
|
||||
);
|
||||
|
||||
usedFullReductionThreshold = selectOptimalThreshold(
|
||||
@@ -1425,6 +1443,7 @@ export function calculateOrderCostSummary(
|
||||
usedFullReductionThreshold
|
||||
);
|
||||
}
|
||||
|
||||
// ------------------------------ 3. 优惠券抵扣(适配满减同享规则) ------------------------------
|
||||
let couponDeductionAmount = 0;
|
||||
let productCouponDeduction = 0;
|
||||
@@ -1446,6 +1465,7 @@ export function calculateOrderCostSummary(
|
||||
currentTime,
|
||||
}
|
||||
);
|
||||
console.log("couponResult", couponResult);
|
||||
couponDeductionAmount = couponResult.deductionAmount;
|
||||
productCouponDeduction = couponResult.productCouponDeduction;
|
||||
fullCouponDeduction = couponResult.fullCouponDeduction;
|
||||
@@ -1453,7 +1473,10 @@ export function calculateOrderCostSummary(
|
||||
excludedProductIds = couponResult.excludedProductIds;
|
||||
|
||||
// 若满减与优惠券同享(couponShare=1),才计算优惠券;否则优惠券抵扣为0
|
||||
if (usedFullReductionActivity && !usedFullReductionActivity.couponShare) {
|
||||
if (
|
||||
usedFullReductionThreshold &&
|
||||
(!usedFullReductionActivity || !usedFullReductionActivity.couponShare)
|
||||
) {
|
||||
couponDeductionAmount = 0;
|
||||
productCouponDeduction = 0;
|
||||
fullCouponDeduction = 0;
|
||||
@@ -1486,7 +1509,10 @@ export function calculateOrderCostSummary(
|
||||
pointDeductionAmount = pointResult.deductionAmount;
|
||||
usedPoints = pointResult.usedPoints;
|
||||
// 若满减与积分不同享(pointsShare=1)积分抵扣为0
|
||||
if (usedFullReductionActivity && !usedFullReductionActivity.pointsShare) {
|
||||
if (
|
||||
usedFullReductionThreshold &&
|
||||
(!usedFullReductionActivity || !usedFullReductionActivity.pointsShare)
|
||||
) {
|
||||
pointDeductionAmount = 0;
|
||||
usedPoints = 0;
|
||||
}
|
||||
@@ -1550,6 +1576,17 @@ export function calculateOrderCostSummary(
|
||||
truncateToTwoDecimals(merchantReductionActualAmount)
|
||||
);
|
||||
|
||||
// 会员折扣减免
|
||||
const vipDiscountAmount = calcVipDiscountAmount(
|
||||
new BigNumber(goodsRealAmount)
|
||||
.minus(couponDeductionAmount)
|
||||
.plus(packFee)
|
||||
.plus(seatFee)
|
||||
.minus(newUserDiscount)
|
||||
.minus(fullReductionAmount)
|
||||
.toNumber(),
|
||||
shopUserInfo
|
||||
); // 会员折扣减免金额
|
||||
// ------------------------------ 6. 最终实付金额计算 ------------------------------
|
||||
const finalPayAmountBn = new BigNumber(goodsRealAmount)
|
||||
.minus(newUserDiscount)
|
||||
|
||||
@@ -8,26 +8,32 @@ export function canUseLimitTimeDiscount(
|
||||
shopUserInfo,
|
||||
idKey = "id"
|
||||
) {
|
||||
shopInfo=shopInfo||{}
|
||||
shopUserInfo=shopUserInfo||{}
|
||||
shopInfo = shopInfo || {};
|
||||
shopUserInfo = shopUserInfo || {};
|
||||
if (!limitTimeDiscountRes || !limitTimeDiscountRes.id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const canUseFoods = (limitTimeDiscountRes.foods || "").split(",");
|
||||
const goodsCanUse =
|
||||
limitTimeDiscountRes.foodType == 1 ||
|
||||
canUseFoods.includes("" + goods[idKey]);
|
||||
if (!goodsCanUse) {
|
||||
return false;
|
||||
}
|
||||
if (limitTimeDiscountRes.discountPriority == "limit-time") {
|
||||
if (
|
||||
limitTimeDiscountRes.foodType == 1 ||
|
||||
canUseFoods.includes("" + goods[idKey])
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
if (limitTimeDiscountRes.discountPriority == "vip-price") {
|
||||
if (shopUserInfo.isVip != 1 || shopUserInfo.isMemberPrice != 1) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (
|
||||
limitTimeDiscountRes.discountPriority == "vip-price"
|
||||
|
||||
) {
|
||||
|
||||
if(shopUserInfo.isVip != 1 || shopInfo.isMemberPrice != 1){
|
||||
|
||||
if (
|
||||
shopUserInfo.isVip == 1 &&
|
||||
shopUserInfo.isMemberPrice == 1 &&
|
||||
goods.memberPrice * 1 <= 0
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -53,9 +59,10 @@ export function returnPrice(args) {
|
||||
idKey = "product_id",
|
||||
} = args;
|
||||
const canUseFoods = (limitTimeDiscountRes.foods || "").split(",");
|
||||
shopInfo=shopInfo||{}
|
||||
shopUserInfo=shopUserInfo||{}
|
||||
if (shopInfo.isMemberPrice == 1 && shopUserInfo.isVip == 1) {
|
||||
shopInfo = shopInfo || {};
|
||||
shopUserInfo = shopUserInfo || {};
|
||||
|
||||
if (shopUserInfo.isMemberPrice == 1 && shopUserInfo.isVip == 1) {
|
||||
const memberPrice = goods.memberPrice || goods.salePrice;
|
||||
|
||||
//是会员而且启用会员价
|
||||
@@ -76,8 +83,18 @@ export function returnPrice(args) {
|
||||
}
|
||||
}
|
||||
if (limitTimeDiscountRes.discountPriority == "vip-price") {
|
||||
//会员优先
|
||||
return memberPrice;
|
||||
if (goods.memberPrice * 1 > 0) {
|
||||
//会员优先
|
||||
return memberPrice;
|
||||
} else {
|
||||
const price = returnLimitPrice({
|
||||
price: goods.salePrice,
|
||||
limitTimeDiscountRes,
|
||||
goods: goods,
|
||||
});
|
||||
|
||||
return price;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//是会员没有限时折扣
|
||||
@@ -135,7 +152,7 @@ export function returnLimitPrice(args) {
|
||||
*/
|
||||
export function canReturnMemberPrice(args) {
|
||||
const { shopInfo, shopUserInfo } = args;
|
||||
if (shopInfo.isMemberPrice == 1 && shopUserInfo.isVip == 1) {
|
||||
if (shopUserInfo.isMemberPrice == 1 && shopUserInfo.isVip == 1) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
||||
143
utils/util.js
Normal file
143
utils/util.js
Normal file
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
* 手机号脱敏:隐藏中间4位(11位手机号通用)
|
||||
* @param {string} phone - 原始手机号(可带非数字字符,如138-1234-5678)
|
||||
* @returns {string} 脱敏后手机号
|
||||
*/
|
||||
export function desensitizePhone(phone) {
|
||||
// 1. 提取纯数字(过滤非数字字符)
|
||||
const purePhone = (phone || "").replace(/[^\d]/g, "");
|
||||
|
||||
// 2. 边界判断:非11位手机号返回原字符串(或自定义提示)
|
||||
if (purePhone.length !== 11) {
|
||||
console.warn("手机号格式不正确,需11位纯数字");
|
||||
return phone; // 或返回 ''、'手机号格式错误' 等
|
||||
}
|
||||
|
||||
// 3. 脱敏:前3位 + **** + 后4位
|
||||
return purePhone.replace(/(\d{3})(\d{4})(\d{4})/, "$1****$3");
|
||||
}
|
||||
|
||||
/**
|
||||
* 姓名合法性校验
|
||||
* @param {string} name - 待校验的姓名
|
||||
* @returns {Object} 校验结果:{ valid: boolean, msg: string }
|
||||
*/
|
||||
export function validateName(name) {
|
||||
// 1. 空值校验
|
||||
if (!name || name.trim() === '') {
|
||||
return { valid: false, msg: '姓名不能为空' };
|
||||
}
|
||||
const pureName = name.trim();
|
||||
|
||||
// 2. 长度校验(2-6位,含少数民族中间点)
|
||||
if (pureName.length < 2 || pureName.length > 6) {
|
||||
return { valid: false, msg: '姓名长度应为2-6位' };
|
||||
}
|
||||
|
||||
// 3. 正则校验:仅允许中文、少数民族中间点(·),且中间点不能在开头/结尾
|
||||
// 中文范围:[\u4e00-\u9fa5],中间点:[\u00b7](Unicode 标准中间点,非小数点)
|
||||
const nameReg = /^[\u4e00-\u9fa5]+([\u00b7][\u4e00-\u9fa5]+)*$/;
|
||||
if (!nameReg.test(pureName)) {
|
||||
return {
|
||||
valid: false,
|
||||
msg: '姓名仅支持中文和少数民族中间点(·),且不能包含数字、字母或特殊符号'
|
||||
};
|
||||
}
|
||||
|
||||
// 4. 额外限制:中间点不能连续(如“李··四”)
|
||||
if (/[\u00b7]{2,}/.test(pureName)) {
|
||||
return { valid: false, msg: '姓名中的中间点(·)不能连续' };
|
||||
}
|
||||
|
||||
// 校验通过
|
||||
return { valid: true, msg: '姓名格式合法' };
|
||||
}
|
||||
|
||||
/**
|
||||
* 身份证号码合法性校验(支持18位/15位)
|
||||
* @param {string} idCard - 待校验的身份证号
|
||||
* @returns {Object} 校验结果:{ valid: boolean, msg: string, info?: Object }
|
||||
* info 可选返回:{ birthDate: string, gender: string }(出生日期、性别)
|
||||
*/
|
||||
export function validateIdCard(idCard) {
|
||||
// 1. 空值校验
|
||||
if (!idCard || idCard.trim() === '') {
|
||||
return { valid: false, msg: '身份证号码不能为空' };
|
||||
}
|
||||
const pureIdCard = idCard.trim().toUpperCase(); // 统一转为大写(处理X)
|
||||
|
||||
// 2. 格式校验(18位或15位)
|
||||
const id18Reg = /^[1-9]\d{5}(19|20)\d{2}((0[1-9])|(1[0-2]))((0[1-9])|([12]\d)|(3[01]))\d{3}([0-9]|X)$/;
|
||||
const id15Reg = /^[1-9]\d{5}\d{2}((0[1-9])|(1[0-2]))((0[1-9])|([12]\d)|(3[01]))\d{3}$/;
|
||||
|
||||
if (!id18Reg.test(pureIdCard) && !id15Reg.test(pureIdCard)) {
|
||||
return {
|
||||
valid: false,
|
||||
msg: '身份证号码格式错误(需18位,最后一位可含X;或15位纯数字)'
|
||||
};
|
||||
}
|
||||
|
||||
// 3. 提取出生日期并校验合法性
|
||||
let birthDateStr, birthDate;
|
||||
if (pureIdCard.length === 18) {
|
||||
// 18位:第7-14位为出生日期(YYYYMMDD)
|
||||
birthDateStr = pureIdCard.slice(6, 14);
|
||||
birthDate = new Date(`${birthDateStr.slice(0,4)}-${birthDateStr.slice(4,6)}-${birthDateStr.slice(6,8)}`);
|
||||
} else {
|
||||
// 15位:第7-12位为出生日期(YYMMDD),补全为YYYYMMDD(19xx或20xx,默认19xx)
|
||||
const year = `19${pureIdCard.slice(6, 8)}`;
|
||||
const month = pureIdCard.slice(8, 10);
|
||||
const day = pureIdCard.slice(10, 12);
|
||||
birthDateStr = `${year}${month}${day}`;
|
||||
birthDate = new Date(`${year}-${month}-${day}`);
|
||||
}
|
||||
|
||||
// 校验出生日期有效性(如20230230 → 日期对象会是Invalid Date)
|
||||
if (
|
||||
isNaN(birthDate.getTime()) ||
|
||||
birthDateStr.slice(0,4) !== birthDate.getFullYear().toString() ||
|
||||
birthDateStr.slice(4,6) !== (birthDate.getMonth() + 1).toString().padStart(2, '0') ||
|
||||
birthDateStr.slice(6,8) !== birthDate.getDate().toString().padStart(2, '0')
|
||||
) {
|
||||
return { valid: false, msg: '身份证中的出生日期无效' };
|
||||
}
|
||||
|
||||
// 4. 18位身份证额外校验:校验码合法性(加权算法)
|
||||
if (pureIdCard.length === 18) {
|
||||
// 加权因子
|
||||
const weightFactors = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
|
||||
// 校验码对应值(0-10 → 10对应X)
|
||||
const checkCodeMap = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'];
|
||||
// 计算前17位与加权因子的乘积和
|
||||
let sum = 0;
|
||||
for (let i = 0; i < 17; i++) {
|
||||
sum += parseInt(pureIdCard[i]) * weightFactors[i];
|
||||
}
|
||||
// 计算预期校验码
|
||||
const expectedCheckCode = checkCodeMap[sum % 11];
|
||||
// 对比实际校验码(最后一位)
|
||||
if (pureIdCard[17] !== expectedCheckCode) {
|
||||
return { valid: false, msg: '身份证校验码错误,可能是无效身份证' };
|
||||
}
|
||||
}
|
||||
|
||||
// 5. 可选:提取性别(18位第17位,15位第15位;奇数=男,偶数=女)
|
||||
let gender = '';
|
||||
if (pureIdCard.length === 18) {
|
||||
const genderCode = parseInt(pureIdCard[16]);
|
||||
gender = genderCode % 2 === 1 ? '男' : '女';
|
||||
} else {
|
||||
const genderCode = parseInt(pureIdCard[14]);
|
||||
gender = genderCode % 2 === 1 ? '男' : '女';
|
||||
}
|
||||
|
||||
// 校验通过,返回额外信息(出生日期、性别)
|
||||
return {
|
||||
valid: true,
|
||||
msg: '身份证号码合法',
|
||||
info: {
|
||||
birthDate: `${birthDate.getFullYear()}-${(birthDate.getMonth() + 1).toString().padStart(2, '0')}-${birthDate.getDate().toString().padStart(2, '0')}`,
|
||||
gender: gender
|
||||
}
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user