mirror of
https://gitee.com/beijing_hongye_huicheng/lilishop-uniapp.git
synced 2026-09-20 20:02:02 +08:00
feat(distribution): 添加分销员状态检查与加载指示
- 在多个分销相关页面中引入分销员状态检查,确保用户在访问前具备有效分销资格。 - 增加加载指示器以改善用户体验,提示用户正在加载数据。 - 更新相关逻辑以处理分销员资格的不同状态,确保用户在不符合条件时获得适当反馈。
This commit is contained in:
@@ -1,5 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="page" :style="themeStyle">
|
<view class="page" :style="themeStyle">
|
||||||
|
<view v-if="!pageReady" class="state-wrap">
|
||||||
|
<text class="state-text">加载中...</text>
|
||||||
|
</view>
|
||||||
|
<template v-else>
|
||||||
<view class="filter-bar">
|
<view class="filter-bar">
|
||||||
<scroll-view scroll-x class="filter-scroll" :show-scrollbar="false">
|
<scroll-view scroll-x class="filter-scroll" :show-scrollbar="false">
|
||||||
<view class="filter-tabs">
|
<view class="filter-tabs">
|
||||||
@@ -126,6 +130,7 @@
|
|||||||
<view class="guide-btn" @click="showGuide = false">知道了</view>
|
<view class="guide-btn" @click="showGuide = false">知道了</view>
|
||||||
</view>
|
</view>
|
||||||
</u-popup>
|
</u-popup>
|
||||||
|
</template>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -135,6 +140,7 @@ import { onShow, onLoad } from '@dcloudio/uni-app'
|
|||||||
import { useStore } from '@/store'
|
import { useStore } from '@/store'
|
||||||
import { getThemeStyle } from '@/utils/theme'
|
import { getThemeStyle } from '@/utils/theme'
|
||||||
import { getDistributionPerformance } from '@/api/distribution'
|
import { getDistributionPerformance } from '@/api/distribution'
|
||||||
|
import { assertActiveDistributor } from '@/utils/distributionStatus'
|
||||||
|
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
||||||
@@ -146,6 +152,7 @@ const rangeTabs = [
|
|||||||
{ label: '近七日', value: 'LAST_7_DAYS' },
|
{ label: '近七日', value: 'LAST_7_DAYS' },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const pageReady = ref(false)
|
||||||
const activeRange = ref('ALL')
|
const activeRange = ref('ALL')
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const customVisible = ref(false)
|
const customVisible = ref(false)
|
||||||
@@ -176,7 +183,13 @@ onLoad((options: Record<string, string>) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
onShow(() => {
|
onShow(() => {
|
||||||
loadPerformance()
|
assertActiveDistributor().then((d) => {
|
||||||
|
if (!d) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pageReady.value = true
|
||||||
|
loadPerformance()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
function formatMoney(val: number | string) {
|
function formatMoney(val: number | string) {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 账户列表 -->
|
<!-- 账户列表 -->
|
||||||
<view v-else-if="accounts.length" class="account-list">
|
<view v-else-if="pageReady && accounts.length" class="account-list">
|
||||||
<view
|
<view
|
||||||
class="account-item"
|
class="account-item"
|
||||||
v-for="item in accounts"
|
v-for="item in accounts"
|
||||||
@@ -39,12 +39,12 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 空状态 -->
|
<!-- 空状态 -->
|
||||||
<view v-else class="empty-wrap">
|
<view v-else-if="pageReady" class="empty-wrap">
|
||||||
<text class="empty-text">暂无银行卡,请添加</text>
|
<text class="empty-text">暂无银行卡,请添加</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 添加账户按钮 -->
|
<!-- 添加账户按钮 -->
|
||||||
<view class="add-btn-wrap">
|
<view v-if="pageReady" class="add-btn-wrap">
|
||||||
<view class="add-btn" @click="openAddPopup">+ 添加账户</view>
|
<view class="add-btn" @click="openAddPopup">+ 添加账户</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -102,6 +102,7 @@ import { onLoad, onShow } from '@dcloudio/uni-app'
|
|||||||
import { useStore } from '@/store'
|
import { useStore } from '@/store'
|
||||||
import { getThemeStyle } from '@/utils/theme'
|
import { getThemeStyle } from '@/utils/theme'
|
||||||
import { getBankCards, addBankCard, deleteBankCard, setDefaultBankCard } from '@/api/distribution'
|
import { getBankCards, addBankCard, deleteBankCard, setDefaultBankCard } from '@/api/distribution'
|
||||||
|
import { assertActiveDistributor } from '@/utils/distributionStatus'
|
||||||
|
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
||||||
@@ -113,7 +114,8 @@ const isSelectMode = ref(false)
|
|||||||
|
|
||||||
const accounts = ref<any[]>([])
|
const accounts = ref<any[]>([])
|
||||||
const selectedId = ref('')
|
const selectedId = ref('')
|
||||||
const loading = ref(false)
|
const pageReady = ref(false)
|
||||||
|
const loading = ref(true)
|
||||||
const addPopupVisible = ref(false)
|
const addPopupVisible = ref(false)
|
||||||
const saveLoading = ref(false)
|
const saveLoading = ref(false)
|
||||||
const form = ref({ holderName: '', bankName: '', cardNo: '' })
|
const form = ref({ holderName: '', bankName: '', cardNo: '' })
|
||||||
@@ -127,7 +129,14 @@ onLoad((options: any) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
onShow(() => {
|
onShow(() => {
|
||||||
loadAccounts()
|
loading.value = true
|
||||||
|
assertActiveDistributor().then((d) => {
|
||||||
|
if (!d) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pageReady.value = true
|
||||||
|
loadAccounts()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
function loadAccounts() {
|
function loadAccounts() {
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import { onLoad, onReachBottom } from '@dcloudio/uni-app'
|
|||||||
import { useStore } from '@/store'
|
import { useStore } from '@/store'
|
||||||
import { getThemeStyle } from '@/utils/theme'
|
import { getThemeStyle } from '@/utils/theme'
|
||||||
import { cashLog } from '@/api/distribution'
|
import { cashLog } from '@/api/distribution'
|
||||||
|
import { assertActiveDistributor } from '@/utils/distributionStatus'
|
||||||
|
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
||||||
@@ -40,13 +41,18 @@ const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
|||||||
const cashList = ref<any[]>([])
|
const cashList = ref<any[]>([])
|
||||||
const cashPage = ref(1)
|
const cashPage = ref(1)
|
||||||
const cashTotal = ref(0)
|
const cashTotal = ref(0)
|
||||||
const cashLoading = ref(false)
|
const cashLoading = ref(true)
|
||||||
const cashLoadingMore = ref(false)
|
const cashLoadingMore = ref(false)
|
||||||
const cashFinished = ref(false)
|
const cashFinished = ref(false)
|
||||||
const PAGE_SIZE = 15
|
const PAGE_SIZE = 15
|
||||||
|
|
||||||
onLoad(() => {
|
onLoad(() => {
|
||||||
loadCashHistory(true)
|
assertActiveDistributor().then((d) => {
|
||||||
|
if (!d) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
loadCashHistory(true)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
onReachBottom(() => {
|
onReachBottom(() => {
|
||||||
|
|||||||
@@ -19,7 +19,10 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<template v-if="detailId">
|
<view v-if="!pageReady" class="state-wrap">
|
||||||
|
<text class="state-text">加载中...</text>
|
||||||
|
</view>
|
||||||
|
<template v-else-if="detailId">
|
||||||
<view v-if="detailLoading" class="state-wrap">
|
<view v-if="detailLoading" class="state-wrap">
|
||||||
<text class="state-text">加载中...</text>
|
<text class="state-text">加载中...</text>
|
||||||
</view>
|
</view>
|
||||||
@@ -62,7 +65,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-else>
|
<template v-else-if="pageReady">
|
||||||
<view class="main-tabs">
|
<view class="main-tabs">
|
||||||
<view
|
<view
|
||||||
v-for="item in mainTabs"
|
v-for="item in mainTabs"
|
||||||
@@ -184,6 +187,7 @@ import {
|
|||||||
updateDistributionCustomerStarred,
|
updateDistributionCustomerStarred,
|
||||||
} from '@/api/distribution'
|
} from '@/api/distribution'
|
||||||
import { parseGoodsImageUrl } from '@/utils/filters.js'
|
import { parseGoodsImageUrl } from '@/utils/filters.js'
|
||||||
|
import { assertActiveDistributor } from '@/utils/distributionStatus'
|
||||||
|
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
||||||
@@ -207,6 +211,7 @@ const rangeTabs = [
|
|||||||
const activeFilter = ref('ALL')
|
const activeFilter = ref('ALL')
|
||||||
const activeRange = ref('ALL')
|
const activeRange = ref('ALL')
|
||||||
const keyword = ref('')
|
const keyword = ref('')
|
||||||
|
const pageReady = ref(false)
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const loadingMore = ref(false)
|
const loadingMore = ref(false)
|
||||||
const finished = ref(false)
|
const finished = ref(false)
|
||||||
@@ -245,9 +250,15 @@ onShow(() => {
|
|||||||
if (current?.options) {
|
if (current?.options) {
|
||||||
applyRouteOptions(current.options)
|
applyRouteOptions(current.options)
|
||||||
}
|
}
|
||||||
if (!detailId.value) {
|
assertActiveDistributor().then((d) => {
|
||||||
resetAndLoad()
|
if (!d) {
|
||||||
}
|
return
|
||||||
|
}
|
||||||
|
pageReady.value = true
|
||||||
|
if (!detailId.value) {
|
||||||
|
resetAndLoad()
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
onReachBottom(() => {
|
onReachBottom(() => {
|
||||||
|
|||||||
@@ -119,7 +119,8 @@ import { onShow } from '@dcloudio/uni-app'
|
|||||||
import { useStore } from '@/store'
|
import { useStore } from '@/store'
|
||||||
import { getThemeStyle } from '@/utils/theme'
|
import { getThemeStyle } from '@/utils/theme'
|
||||||
import config from '@/config/config'
|
import config from '@/config/config'
|
||||||
import { distribution, getDistributionGrades } from '@/api/distribution'
|
import { getDistributionGrades } from '@/api/distribution'
|
||||||
|
import { assertActiveDistributor } from '@/utils/distributionStatus'
|
||||||
import { getUserInfo } from '@/api/members'
|
import { getUserInfo } from '@/api/members'
|
||||||
|
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
@@ -166,18 +167,21 @@ function refreshUserInfo() {
|
|||||||
|
|
||||||
function loadPageData() {
|
function loadPageData() {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
Promise.all([fetchGrades(), fetchDistribution()]).finally(() => {
|
let allowed = false
|
||||||
loading.value = false
|
assertActiveDistributor()
|
||||||
})
|
.then((result) => {
|
||||||
}
|
if (!result) {
|
||||||
|
return
|
||||||
function fetchDistribution() {
|
}
|
||||||
return distribution().then((res) => {
|
allowed = true
|
||||||
if (!res.data?.result) {
|
distributionData.value = result
|
||||||
return
|
return fetchGrades()
|
||||||
}
|
})
|
||||||
distributionData.value = res.data.result
|
.finally(() => {
|
||||||
})
|
if (allowed) {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchGrades() {
|
function fetchGrades() {
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ import { onLoad, onReachBottom } from '@dcloudio/uni-app'
|
|||||||
import { useStore } from '@/store'
|
import { useStore } from '@/store'
|
||||||
import { cashLog, getDistributionOrders } from '@/api/distribution'
|
import { cashLog, getDistributionOrders } from '@/api/distribution'
|
||||||
import { unitPrice } from '@/utils/filters.js'
|
import { unitPrice } from '@/utils/filters.js'
|
||||||
|
import { assertActiveDistributor } from '@/utils/distributionStatus'
|
||||||
|
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
|
|
||||||
@@ -79,7 +80,12 @@ onLoad((option) => {
|
|||||||
uni.setNavigationBarTitle({
|
uni.setNavigationBarTitle({
|
||||||
title: type === 0 ? '分销业绩' : '提现记录',
|
title: type === 0 ? '分销业绩' : '提现记录',
|
||||||
})
|
})
|
||||||
type === 0 ? fetchAchievementList() : fetchWithdrawLog()
|
assertActiveDistributor().then((d) => {
|
||||||
|
if (!d) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
type === 0 ? fetchAchievementList() : fetchWithdrawLog()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
onReachBottom(() => {
|
onReachBottom(() => {
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
<view class="nav-placeholder"></view>
|
<view class="nav-placeholder"></view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<view v-if="checking" class="center-pending">加载中...</view>
|
||||||
|
<template v-else-if="centerReady">
|
||||||
<!-- 顶部用户信息 -->
|
<!-- 顶部用户信息 -->
|
||||||
<view class="header">
|
<view class="header">
|
||||||
<view class="user-row" @click="goGrade">
|
<view class="user-row" @click="goGrade">
|
||||||
@@ -199,6 +201,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
</template>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -209,7 +212,6 @@ import { useStore } from '@/store'
|
|||||||
import config from '@/config/config'
|
import config from '@/config/config'
|
||||||
import { getThemeStyle } from '@/utils/theme'
|
import { getThemeStyle } from '@/utils/theme'
|
||||||
import {
|
import {
|
||||||
distribution,
|
|
||||||
getDistributionFeaturedGoods,
|
getDistributionFeaturedGoods,
|
||||||
getDistributionGrades,
|
getDistributionGrades,
|
||||||
getDistributionCustomers,
|
getDistributionCustomers,
|
||||||
@@ -218,6 +220,7 @@ import {
|
|||||||
getDistributionPerformance,
|
getDistributionPerformance,
|
||||||
} from '@/api/distribution'
|
} from '@/api/distribution'
|
||||||
import { getUserInfo } from '@/api/members'
|
import { getUserInfo } from '@/api/members'
|
||||||
|
import { assertActiveDistributor } from '@/utils/distributionStatus'
|
||||||
|
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
||||||
@@ -226,6 +229,8 @@ const statusBarHeight = ref(20)
|
|||||||
const expanded = ref(false)
|
const expanded = ref(false)
|
||||||
|
|
||||||
const distributionData = ref<Record<string, any>>({})
|
const distributionData = ref<Record<string, any>>({})
|
||||||
|
const checking = ref(true)
|
||||||
|
const centerReady = ref(false)
|
||||||
const gradeList = ref<any[]>([])
|
const gradeList = ref<any[]>([])
|
||||||
const featuredGoods = ref<any[]>([])
|
const featuredGoods = ref<any[]>([])
|
||||||
const todayOrderCount = ref(0)
|
const todayOrderCount = ref(0)
|
||||||
@@ -288,25 +293,38 @@ function refreshUserInfo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function loadPageData() {
|
function loadPageData() {
|
||||||
Promise.all([
|
checking.value = true
|
||||||
fetchDistribution(),
|
centerReady.value = false
|
||||||
fetchGrades(),
|
distributionData.value = {}
|
||||||
fetchTodayOrders(),
|
fetchDistribution()
|
||||||
fetchTodayEarnings(),
|
.then((active) => {
|
||||||
fetchTodayCustomers(),
|
if (!active) {
|
||||||
fetchTodayInvites(),
|
return
|
||||||
fetchFeaturedGoods(),
|
}
|
||||||
])
|
centerReady.value = true
|
||||||
|
Promise.all([
|
||||||
|
fetchGrades(),
|
||||||
|
fetchTodayOrders(),
|
||||||
|
fetchTodayEarnings(),
|
||||||
|
fetchTodayCustomers(),
|
||||||
|
fetchTodayInvites(),
|
||||||
|
fetchFeaturedGoods(),
|
||||||
|
])
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
if (centerReady.value) {
|
||||||
|
checking.value = false
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchDistribution() {
|
function fetchDistribution() {
|
||||||
return distribution().then((res) => {
|
return assertActiveDistributor().then((result) => {
|
||||||
if (!res.data?.result) {
|
if (!result) {
|
||||||
uni.showToast({ title: '您还不是分销员', icon: 'none' })
|
return false
|
||||||
setTimeout(() => goBack(), 1500)
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
distributionData.value = res.data.result
|
distributionData.value = result
|
||||||
|
return true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -497,6 +515,13 @@ function goOrder() {
|
|||||||
width: 72rpx;
|
width: 72rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.center-pending {
|
||||||
|
padding: 120rpx 0;
|
||||||
|
color: #999;
|
||||||
|
font-size: 28rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
background: linear-gradient(180deg, #1f2228 0%, #2a2e36 100%);
|
background: linear-gradient(180deg, #1f2228 0%, #2a2e36 100%);
|
||||||
padding: 24rpx 32rpx 40rpx;
|
padding: 24rpx 32rpx 40rpx;
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="page" :style="themeStyle">
|
<view class="page" :style="themeStyle">
|
||||||
|
<view v-if="!pageReady" class="state-wrap">
|
||||||
|
<text class="state-text">加载中...</text>
|
||||||
|
</view>
|
||||||
|
<template v-else>
|
||||||
<view class="hero">
|
<view class="hero">
|
||||||
<view class="hero-title">邀好友 赚奖励</view>
|
<view class="hero-title">邀好友 赚奖励</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -54,6 +58,7 @@
|
|||||||
|
|
||||||
<view class="view-all" @click="goInviteList">查看我的邀请</view>
|
<view class="view-all" @click="goInviteList">查看我的邀请</view>
|
||||||
</view>
|
</view>
|
||||||
|
</template>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -65,6 +70,7 @@ import config from '@/config/config'
|
|||||||
import { getThemeStyle } from '@/utils/theme'
|
import { getThemeStyle } from '@/utils/theme'
|
||||||
import { getDistributionInvitees } from '@/api/distribution'
|
import { getDistributionInvitees } from '@/api/distribution'
|
||||||
import { parseGoodsImageUrl } from '@/utils/filters.js'
|
import { parseGoodsImageUrl } from '@/utils/filters.js'
|
||||||
|
import { assertActiveDistributor } from '@/utils/distributionStatus'
|
||||||
|
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
||||||
@@ -91,12 +97,19 @@ const flowSteps = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const pageReady = ref(false)
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const inviteTotal = ref(0)
|
const inviteTotal = ref(0)
|
||||||
const inviteList = ref<any[]>([])
|
const inviteList = ref<any[]>([])
|
||||||
|
|
||||||
onShow(() => {
|
onShow(() => {
|
||||||
loadPreview()
|
assertActiveDistributor().then((d) => {
|
||||||
|
if (!d) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pageReady.value = true
|
||||||
|
loadPreview()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
function loadPreview() {
|
function loadPreview() {
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="page" :style="themeStyle">
|
<view class="page" :style="themeStyle">
|
||||||
|
<view v-if="!pageReady" class="state-wrap">
|
||||||
|
<text class="state-text">加载中...</text>
|
||||||
|
</view>
|
||||||
|
<template v-else>
|
||||||
<view class="filter-bar">
|
<view class="filter-bar">
|
||||||
<scroll-view scroll-x class="filter-scroll" :show-scrollbar="false">
|
<scroll-view scroll-x class="filter-scroll" :show-scrollbar="false">
|
||||||
<view class="filter-tabs">
|
<view class="filter-tabs">
|
||||||
@@ -80,6 +84,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</u-popup>
|
</u-popup>
|
||||||
|
</template>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -91,6 +96,7 @@ import config from '@/config/config'
|
|||||||
import { getThemeStyle } from '@/utils/theme'
|
import { getThemeStyle } from '@/utils/theme'
|
||||||
import { getDistributionInvitees } from '@/api/distribution'
|
import { getDistributionInvitees } from '@/api/distribution'
|
||||||
import { parseGoodsImageUrl } from '@/utils/filters.js'
|
import { parseGoodsImageUrl } from '@/utils/filters.js'
|
||||||
|
import { assertActiveDistributor } from '@/utils/distributionStatus'
|
||||||
|
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
||||||
@@ -104,6 +110,7 @@ const rangeTabs = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
const activeRange = ref('ALL')
|
const activeRange = ref('ALL')
|
||||||
|
const pageReady = ref(false)
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const loadingMore = ref(false)
|
const loadingMore = ref(false)
|
||||||
const finished = ref(false)
|
const finished = ref(false)
|
||||||
@@ -138,7 +145,13 @@ onShow(() => {
|
|||||||
if (current?.options) {
|
if (current?.options) {
|
||||||
applyRouteOptions(current.options)
|
applyRouteOptions(current.options)
|
||||||
}
|
}
|
||||||
resetAndLoad()
|
assertActiveDistributor().then((d) => {
|
||||||
|
if (!d) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pageReady.value = true
|
||||||
|
resetAndLoad()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
onReachBottom(() => {
|
onReachBottom(() => {
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ import { onLoad, onReady, onShareAppMessage } from '@dcloudio/uni-app'
|
|||||||
import { useStore } from '@/store'
|
import { useStore } from '@/store'
|
||||||
import { getThemeStyle } from '@/utils/theme'
|
import { getThemeStyle } from '@/utils/theme'
|
||||||
import { getInviteCard } from '@/api/distribution'
|
import { getInviteCard } from '@/api/distribution'
|
||||||
|
import { assertActiveDistributor } from '@/utils/distributionStatus'
|
||||||
import { getMpCode } from '@/api/goods'
|
import { getMpCode } from '@/api/goods'
|
||||||
import { parseGoodsImageUrl } from '@/utils/filters.js'
|
import { parseGoodsImageUrl } from '@/utils/filters.js'
|
||||||
import {
|
import {
|
||||||
@@ -282,6 +283,11 @@ async function loadInviteCardSetting() {
|
|||||||
qrError.value = ''
|
qrError.value = ''
|
||||||
composeError.value = ''
|
composeError.value = ''
|
||||||
|
|
||||||
|
const distributor = await assertActiveDistributor()
|
||||||
|
if (!distributor) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await getInviteCard()
|
const res = await getInviteCard()
|
||||||
if (!res.data?.success || !res.data?.result) {
|
if (!res.data?.success || !res.data?.result) {
|
||||||
|
|||||||
@@ -1,6 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="wrapper" :style="themeStyle">
|
<view class="wrapper" :style="themeStyle">
|
||||||
<view v-if="loading" class="loading">加载中...</view>
|
<view v-if="loading" class="loading">加载中...</view>
|
||||||
|
<view v-else-if="isRetreated" class="page-body">
|
||||||
|
<view class="section result-section">
|
||||||
|
<view class="result-icon retreated">!</view>
|
||||||
|
<view class="result-title">分销资格已清退</view>
|
||||||
|
<view class="result-desc">{{ DISTRIBUTION_RETREAT_MESSAGE }}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
<view v-else-if="!plan">
|
<view v-else-if="!plan">
|
||||||
<view class="empty">暂未开放线上招募</view>
|
<view class="empty">暂未开放线上招募</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -171,6 +178,7 @@ import config from '@/config/config'
|
|||||||
import { parseGoodsImageUrl, tipsToLogin } from '@/utils/filters.js'
|
import { parseGoodsImageUrl, tipsToLogin } from '@/utils/filters.js'
|
||||||
import { resolveRecruitDistributionIdFromScene } from '@/utils/distributionBind.js'
|
import { resolveRecruitDistributionIdFromScene } from '@/utils/distributionBind.js'
|
||||||
import { getRecruitPage, getRecruitProgress, getRecruitInviter, submitRecruitApplication } from '@/api/distribution'
|
import { getRecruitPage, getRecruitProgress, getRecruitInviter, submitRecruitApplication } from '@/api/distribution'
|
||||||
|
import { DISTRIBUTION_RETREAT_MESSAGE, DISTRIBUTION_STATUS } from '@/utils/distributionStatus'
|
||||||
|
|
||||||
const defaultAvatar = config.defaultUserPhoto
|
const defaultAvatar = config.defaultUserPhoto
|
||||||
|
|
||||||
@@ -198,7 +206,12 @@ const fields = computed(() => pageInfo.value.fields || [])
|
|||||||
const recruitGoods = computed(() => plan.value?.recruitGoods || [])
|
const recruitGoods = computed(() => plan.value?.recruitGoods || [])
|
||||||
const agreementContent = computed(() => plan.value?.agreementContent || '')
|
const agreementContent = computed(() => plan.value?.agreementContent || '')
|
||||||
|
|
||||||
|
const distributionStatus = computed(() => pageInfo.value.distributionStatus || '')
|
||||||
|
const currentApplication = computed(() => pageInfo.value.currentApplication || null)
|
||||||
|
const isRetreated = computed(() => distributionStatus.value === DISTRIBUTION_STATUS.RETREAT)
|
||||||
|
|
||||||
const showPoster = computed(() => {
|
const showPoster = computed(() => {
|
||||||
|
if (isRetreated.value) return false
|
||||||
const p = plan.value
|
const p = plan.value
|
||||||
if (!p) return false
|
if (!p) return false
|
||||||
if (p.posterEnabled === false) return false
|
if (p.posterEnabled === false) return false
|
||||||
@@ -211,45 +224,50 @@ const posterRuleText = computed(() => plan.value?.posterRuleText || '')
|
|||||||
const posterContact = computed(() => plan.value?.posterContact || '')
|
const posterContact = computed(() => plan.value?.posterContact || '')
|
||||||
|
|
||||||
const hasJoinCondition = computed(() => {
|
const hasJoinCondition = computed(() => {
|
||||||
|
if (isRetreated.value) return false
|
||||||
const p = plan.value
|
const p = plan.value
|
||||||
if (!p || p.joinConditionType !== 'CONDITIONAL') return false
|
if (!p || p.joinConditionType !== 'CONDITIONAL') return false
|
||||||
return !!(p.requireSelfPurchaseAmount || p.requireConsumeCount || p.requirePurchaseGoods)
|
return !!(p.requireSelfPurchaseAmount || p.requireConsumeCount || p.requirePurchaseGoods)
|
||||||
})
|
})
|
||||||
|
|
||||||
const conditionsMet = computed(() => {
|
const conditionsMet = computed(() => {
|
||||||
|
if (isRetreated.value) return false
|
||||||
if (!hasJoinCondition.value) return true
|
if (!hasJoinCondition.value) return true
|
||||||
return !!progress.value?.satisfied
|
return !!progress.value?.satisfied
|
||||||
})
|
})
|
||||||
|
|
||||||
const distributionStatus = computed(() => pageInfo.value.distributionStatus || '')
|
|
||||||
const currentApplication = computed(() => pageInfo.value.currentApplication || null)
|
|
||||||
|
|
||||||
const isApplyApproved = computed(() => {
|
const isApplyApproved = computed(() => {
|
||||||
if (distributionStatus.value === 'PASS') return true
|
if (isRetreated.value) return false
|
||||||
|
if (distributionStatus.value === DISTRIBUTION_STATUS.PASS) return true
|
||||||
if (submitApplicationStatus.value === 'APPROVED') return true
|
if (submitApplicationStatus.value === 'APPROVED') return true
|
||||||
if (applySubmitted.value && submitAuditMode.value === 'AUTO_PASS') return true
|
if (applySubmitted.value && submitAuditMode.value === 'AUTO_PASS') return true
|
||||||
return currentApplication.value?.applicationStatus === 'APPROVED'
|
return false
|
||||||
})
|
})
|
||||||
|
|
||||||
const isApplyPending = computed(() => {
|
const isApplyPending = computed(() => {
|
||||||
|
if (isRetreated.value) return false
|
||||||
if (isApplyApproved.value) return false
|
if (isApplyApproved.value) return false
|
||||||
if (distributionStatus.value === 'APPLY') return true
|
if (distributionStatus.value === DISTRIBUTION_STATUS.APPLY) return true
|
||||||
if (submitApplicationStatus.value === 'PENDING') return true
|
if (submitApplicationStatus.value === 'PENDING') return true
|
||||||
if (applySubmitted.value && submitAuditMode.value === 'MANUAL') return true
|
if (applySubmitted.value && submitAuditMode.value === 'MANUAL') return true
|
||||||
return currentApplication.value?.applicationStatus === 'PENDING'
|
return currentApplication.value?.applicationStatus === 'PENDING'
|
||||||
})
|
})
|
||||||
|
|
||||||
const showApplyResult = computed(() => isApplyApproved.value || isApplyPending.value)
|
const showApplyResult = computed(() => {
|
||||||
|
if (isRetreated.value) return false
|
||||||
|
return isApplyApproved.value || isApplyPending.value
|
||||||
|
})
|
||||||
|
|
||||||
const isManualApply = computed(() => {
|
const isManualApply = computed(() => {
|
||||||
return (plan.value?.applyMode || 'MANUAL') === 'MANUAL'
|
return (plan.value?.applyMode || 'MANUAL') === 'MANUAL'
|
||||||
})
|
})
|
||||||
|
|
||||||
const showLoginFooter = computed(() => {
|
const showLoginFooter = computed(() => {
|
||||||
return !!plan.value && !isUserLoggedIn.value && !loading.value
|
return !isRetreated.value && !!plan.value && !isUserLoggedIn.value && !loading.value
|
||||||
})
|
})
|
||||||
|
|
||||||
const showInviterHeader = computed(() => {
|
const showInviterHeader = computed(() => {
|
||||||
|
if (isRetreated.value) return false
|
||||||
if (!recruitToken.value) return false
|
if (!recruitToken.value) return false
|
||||||
const info = inviterInfo.value
|
const info = inviterInfo.value
|
||||||
return !!(info?.memberName || info?.memberAvatar)
|
return !!(info?.memberName || info?.memberAvatar)
|
||||||
@@ -259,15 +277,15 @@ const inviterName = computed(() => inviterInfo.value?.memberName || '分销员')
|
|||||||
const inviterAvatar = computed(() => parseGoodsImageUrl(inviterInfo.value?.memberAvatar) || defaultAvatar)
|
const inviterAvatar = computed(() => parseGoodsImageUrl(inviterInfo.value?.memberAvatar) || defaultAvatar)
|
||||||
|
|
||||||
const showManualApply = computed(() => {
|
const showManualApply = computed(() => {
|
||||||
return isUserLoggedIn.value && !showApplyResult.value && conditionsMet.value && isManualApply.value
|
return !isRetreated.value && isUserLoggedIn.value && !showApplyResult.value && conditionsMet.value && isManualApply.value
|
||||||
})
|
})
|
||||||
|
|
||||||
const showAutoApplyTip = computed(() => {
|
const showAutoApplyTip = computed(() => {
|
||||||
return isUserLoggedIn.value && !showApplyResult.value && conditionsMet.value && plan.value?.applyMode === 'AUTO'
|
return !isRetreated.value && isUserLoggedIn.value && !showApplyResult.value && conditionsMet.value && plan.value?.applyMode === 'AUTO'
|
||||||
})
|
})
|
||||||
|
|
||||||
const showApplyForm = computed(() => {
|
const showApplyForm = computed(() => {
|
||||||
return !!plan.value?.requireApplyInfo && fields.value.length > 0
|
return !isRetreated.value && !!plan.value?.requireApplyInfo && fields.value.length > 0
|
||||||
})
|
})
|
||||||
|
|
||||||
const canApply = computed(() => {
|
const canApply = computed(() => {
|
||||||
@@ -445,7 +463,7 @@ function handleApplySuccess(application: any) {
|
|||||||
submitAuditMode.value = auditMode
|
submitAuditMode.value = auditMode
|
||||||
submitApplicationStatus.value = status
|
submitApplicationStatus.value = status
|
||||||
if (auditMode === 'AUTO_PASS' || status === 'APPROVED') {
|
if (auditMode === 'AUTO_PASS' || status === 'APPROVED') {
|
||||||
pageInfo.value.distributionStatus = 'PASS'
|
pageInfo.value.distributionStatus = DISTRIBUTION_STATUS.PASS
|
||||||
if (pageInfo.value.currentApplication) {
|
if (pageInfo.value.currentApplication) {
|
||||||
pageInfo.value.currentApplication.applicationStatus = 'APPROVED'
|
pageInfo.value.currentApplication.applicationStatus = 'APPROVED'
|
||||||
}
|
}
|
||||||
@@ -458,6 +476,10 @@ function submit() {
|
|||||||
if (!tipsToLogin('normal')) {
|
if (!tipsToLogin('normal')) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if (isRetreated.value) {
|
||||||
|
uni.showToast({ title: DISTRIBUTION_RETREAT_MESSAGE, icon: 'none' })
|
||||||
|
return
|
||||||
|
}
|
||||||
if (!showManualApply.value) {
|
if (!showManualApply.value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -738,6 +760,11 @@ function submit() {
|
|||||||
color: #fa8c16;
|
color: #fa8c16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.result-icon.retreated {
|
||||||
|
background: #fff2f0;
|
||||||
|
color: #ff4d4f;
|
||||||
|
}
|
||||||
|
|
||||||
.result-title {
|
.result-title {
|
||||||
font-size: 36rpx;
|
font-size: 36rpx;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="page">
|
<view class="page">
|
||||||
|
<view v-if="!pageReady" class="state-wrap">
|
||||||
|
<text class="state-text">加载中...</text>
|
||||||
|
</view>
|
||||||
|
<template v-else>
|
||||||
<view class="search-bar">
|
<view class="search-bar">
|
||||||
<view class="search-inner">
|
<view class="search-inner">
|
||||||
<u-icon name="search" color="#bbb" size="18" />
|
<u-icon name="search" color="#bbb" size="18" />
|
||||||
@@ -81,6 +85,7 @@
|
|||||||
<text>{{ finished ? '没有更多了' : (loadingMore ? '加载中...' : '上拉加载更多') }}</text>
|
<text>{{ finished ? '没有更多了' : (loadingMore ? '加载中...' : '上拉加载更多') }}</text>
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
|
</template>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -88,6 +93,7 @@
|
|||||||
import { ref, computed } from 'vue'
|
import { ref, computed } from 'vue'
|
||||||
import { onLoad } from '@dcloudio/uni-app'
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
import { distributionGoods, getDistributionGoodsSetting } from '@/api/distribution'
|
import { distributionGoods, getDistributionGoodsSetting } from '@/api/distribution'
|
||||||
|
import { assertActiveDistributor } from '@/utils/distributionStatus'
|
||||||
|
|
||||||
const DEFAULT_SORT_MAP: Record<string, { field: string; order: string }> = {
|
const DEFAULT_SORT_MAP: Record<string, { field: string; order: string }> = {
|
||||||
HIGHEST_COMMISSION: { field: 'COMMISSION', order: 'DESC' },
|
HIGHEST_COMMISSION: { field: 'COMMISSION', order: 'DESC' },
|
||||||
@@ -103,6 +109,7 @@ const sortTabs = [
|
|||||||
{ field: 'PRICE', label: '价格' },
|
{ field: 'PRICE', label: '价格' },
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const pageReady = ref(false)
|
||||||
const routeQuery = ref<Record<string, string>>({})
|
const routeQuery = ref<Record<string, string>>({})
|
||||||
const keyword = ref('')
|
const keyword = ref('')
|
||||||
const sortField = ref('COMMISSION')
|
const sortField = ref('COMMISSION')
|
||||||
@@ -128,6 +135,11 @@ onLoad((options) => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
async function initPage() {
|
async function initPage() {
|
||||||
|
const distributor = await assertActiveDistributor()
|
||||||
|
if (!distributor) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pageReady.value = true
|
||||||
await loadGoodsSetting()
|
await loadGoodsSetting()
|
||||||
resetAndFetch()
|
resetAndFetch()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<view class="nav-placeholder"></view>
|
<view class="nav-placeholder"></view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="hero">
|
<view v-if="!loading && detail.orderItemSn" class="hero">
|
||||||
<view class="hero-status">{{ detail.settlementStatusText || '待结算' }}</view>
|
<view class="hero-status">{{ detail.settlementStatusText || '待结算' }}</view>
|
||||||
<view class="hero-sub">分销订单详情</view>
|
<view class="hero-sub">分销订单详情</view>
|
||||||
</view>
|
</view>
|
||||||
@@ -109,11 +109,12 @@ import { useStore } from '@/store'
|
|||||||
import { getThemeStyle } from '@/utils/theme'
|
import { getThemeStyle } from '@/utils/theme'
|
||||||
import { getDistributionOrderDetail } from '@/api/distribution'
|
import { getDistributionOrderDetail } from '@/api/distribution'
|
||||||
import { parseGoodsImageUrl, formatGoodsSpecs } from '@/utils/filters.js'
|
import { parseGoodsImageUrl, formatGoodsSpecs } from '@/utils/filters.js'
|
||||||
|
import { assertActiveDistributor } from '@/utils/distributionStatus'
|
||||||
|
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
||||||
const statusBarHeight = ref(20)
|
const statusBarHeight = ref(20)
|
||||||
const loading = ref(false)
|
const loading = ref(true)
|
||||||
const detail = ref<Record<string, any>>({})
|
const detail = ref<Record<string, any>>({})
|
||||||
const orderItemSn = ref('')
|
const orderItemSn = ref('')
|
||||||
const orderType = ref('PROMOTION')
|
const orderType = ref('PROMOTION')
|
||||||
@@ -122,7 +123,12 @@ onLoad((options) => {
|
|||||||
statusBarHeight.value = uni.getWindowInfo?.()?.statusBarHeight || 20
|
statusBarHeight.value = uni.getWindowInfo?.()?.statusBarHeight || 20
|
||||||
orderItemSn.value = options?.orderItemSn || ''
|
orderItemSn.value = options?.orderItemSn || ''
|
||||||
orderType.value = options?.orderType || 'PROMOTION'
|
orderType.value = options?.orderType || 'PROMOTION'
|
||||||
loadDetail()
|
assertActiveDistributor().then((d) => {
|
||||||
|
if (!d) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
loadDetail()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
const totalGoodsNum = computed(() => Number(detail.value.totalGoodsNum || detail.value.num || 0))
|
const totalGoodsNum = computed(() => Number(detail.value.totalGoodsNum || detail.value.num || 0))
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="page" :style="themeStyle">
|
<view class="page" :style="themeStyle">
|
||||||
|
<view v-if="!pageReady" class="state-wrap">
|
||||||
|
<text class="state-text">加载中...</text>
|
||||||
|
</view>
|
||||||
|
<template v-else>
|
||||||
<view class="search-bar">
|
<view class="search-bar">
|
||||||
<view class="search-inner">
|
<view class="search-inner">
|
||||||
<u-icon name="search" color="#bbb" size="18" />
|
<u-icon name="search" color="#bbb" size="18" />
|
||||||
@@ -132,6 +136,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</u-popup>
|
</u-popup>
|
||||||
|
</template>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -142,6 +147,7 @@ import { useStore } from '@/store'
|
|||||||
import { getThemeStyle } from '@/utils/theme'
|
import { getThemeStyle } from '@/utils/theme'
|
||||||
import { getDistributionOrders } from '@/api/distribution'
|
import { getDistributionOrders } from '@/api/distribution'
|
||||||
import { parseGoodsImageUrl, formatGoodsSpecs } from '@/utils/filters.js'
|
import { parseGoodsImageUrl, formatGoodsSpecs } from '@/utils/filters.js'
|
||||||
|
import { assertActiveDistributor } from '@/utils/distributionStatus'
|
||||||
|
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
||||||
@@ -161,6 +167,7 @@ const rangeTabs = [
|
|||||||
const activeTab = ref('PROMOTION')
|
const activeTab = ref('PROMOTION')
|
||||||
const activeRange = ref('ALL')
|
const activeRange = ref('ALL')
|
||||||
const keyword = ref('')
|
const keyword = ref('')
|
||||||
|
const pageReady = ref(false)
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const loadingMore = ref(false)
|
const loadingMore = ref(false)
|
||||||
const finished = ref(false)
|
const finished = ref(false)
|
||||||
@@ -202,7 +209,13 @@ onShow(() => {
|
|||||||
if (current?.options) {
|
if (current?.options) {
|
||||||
applyRouteOptions(current.options)
|
applyRouteOptions(current.options)
|
||||||
}
|
}
|
||||||
resetAndLoad()
|
assertActiveDistributor().then((d) => {
|
||||||
|
if (!d) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pageReady.value = true
|
||||||
|
resetAndLoad()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
onReachBottom(() => {
|
onReachBottom(() => {
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ import { onLoad, onReady, onShareAppMessage } from '@dcloudio/uni-app'
|
|||||||
import { useStore } from '@/store'
|
import { useStore } from '@/store'
|
||||||
import { getThemeStyle } from '@/utils/theme'
|
import { getThemeStyle } from '@/utils/theme'
|
||||||
import { getPromotionPoster } from '@/api/distribution'
|
import { getPromotionPoster } from '@/api/distribution'
|
||||||
|
import { assertActiveDistributor } from '@/utils/distributionStatus'
|
||||||
import { getMpCode } from '@/api/goods'
|
import { getMpCode } from '@/api/goods'
|
||||||
import { parseGoodsImageUrl } from '@/utils/filters.js'
|
import { parseGoodsImageUrl } from '@/utils/filters.js'
|
||||||
import {
|
import {
|
||||||
@@ -269,6 +270,11 @@ async function loadPosterSetting() {
|
|||||||
qrError.value = ''
|
qrError.value = ''
|
||||||
composeError.value = ''
|
composeError.value = ''
|
||||||
|
|
||||||
|
const distributor = await assertActiveDistributor()
|
||||||
|
if (!distributor) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await getPromotionPoster()
|
const res = await getPromotionPoster()
|
||||||
if (!res.data?.success || !res.data?.result) {
|
if (!res.data?.success || !res.data?.result) {
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="page">
|
<view class="page">
|
||||||
|
<view v-if="!pageReady" class="state-wrap">
|
||||||
|
<text class="state-text">加载中...</text>
|
||||||
|
</view>
|
||||||
<distribution-goods-share
|
<distribution-goods-share
|
||||||
|
v-else
|
||||||
:sku-id="query.skuId"
|
:sku-id="query.skuId"
|
||||||
:goods-id="query.goodsId"
|
:goods-id="query.goodsId"
|
||||||
:distribution-id="query.distributionId"
|
:distribution-id="query.distributionId"
|
||||||
@@ -12,11 +16,19 @@
|
|||||||
import { ref } from 'vue'
|
import { ref } from 'vue'
|
||||||
import { onLoad } from '@dcloudio/uni-app'
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
import DistributionGoodsShare from '@/components/distribution-goods-share/index.vue'
|
import DistributionGoodsShare from '@/components/distribution-goods-share/index.vue'
|
||||||
|
import { assertActiveDistributor } from '@/utils/distributionStatus'
|
||||||
|
|
||||||
const query = ref<Record<string, string>>({})
|
const query = ref<Record<string, string>>({})
|
||||||
|
const pageReady = ref(false)
|
||||||
|
|
||||||
onLoad((options) => {
|
onLoad((options) => {
|
||||||
query.value = (options || {}) as Record<string, string>
|
query.value = (options || {}) as Record<string, string>
|
||||||
|
assertActiveDistributor().then((d) => {
|
||||||
|
if (!d) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pageReady.value = true
|
||||||
|
})
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -25,4 +37,14 @@ onLoad((options) => {
|
|||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.state-wrap {
|
||||||
|
padding: 120rpx 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.state-text {
|
||||||
|
color: #999;
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ import { onLoad, onReachBottom } from '@dcloudio/uni-app'
|
|||||||
import { useStore } from '@/store'
|
import { useStore } from '@/store'
|
||||||
import { getThemeStyle } from '@/utils/theme'
|
import { getThemeStyle } from '@/utils/theme'
|
||||||
import { getWalletLog } from '@/api/distribution'
|
import { getWalletLog } from '@/api/distribution'
|
||||||
|
import { assertActiveDistributor } from '@/utils/distributionStatus'
|
||||||
|
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
||||||
@@ -39,13 +40,18 @@ const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
|||||||
const walletList = ref<any[]>([])
|
const walletList = ref<any[]>([])
|
||||||
const walletPage = ref(1)
|
const walletPage = ref(1)
|
||||||
const walletTotal = ref(0)
|
const walletTotal = ref(0)
|
||||||
const walletLoading = ref(false)
|
const walletLoading = ref(true)
|
||||||
const walletLoadingMore = ref(false)
|
const walletLoadingMore = ref(false)
|
||||||
const walletFinished = ref(false)
|
const walletFinished = ref(false)
|
||||||
const PAGE_SIZE = 15
|
const PAGE_SIZE = 15
|
||||||
|
|
||||||
onLoad(() => {
|
onLoad(() => {
|
||||||
loadWalletLog(true)
|
assertActiveDistributor().then((d) => {
|
||||||
|
if (!d) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
loadWalletLog(true)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
onReachBottom(() => {
|
onReachBottom(() => {
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="page" :style="themeStyle">
|
<view class="page" :style="themeStyle">
|
||||||
<view class="content">
|
<view v-if="!pageReady" class="state-wrap">
|
||||||
|
<text class="state-text">加载中...</text>
|
||||||
|
</view>
|
||||||
|
<view v-else class="content">
|
||||||
<!-- 到账账户 -->
|
<!-- 到账账户 -->
|
||||||
<view class="section-card">
|
<view class="section-card">
|
||||||
<view class="account-row" @click="openAccountDrawer">
|
<view class="account-row" @click="openAccountDrawer">
|
||||||
@@ -139,11 +142,13 @@ import { ref, computed } from 'vue'
|
|||||||
import { onLoad } from '@dcloudio/uni-app'
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
import { useStore } from '@/store'
|
import { useStore } from '@/store'
|
||||||
import { getThemeStyle } from '@/utils/theme'
|
import { getThemeStyle } from '@/utils/theme'
|
||||||
import { distribution, cash, getBankCards, addBankCard } from '@/api/distribution'
|
import { cash, getBankCards, addBankCard } from '@/api/distribution'
|
||||||
|
import { assertActiveDistributor } from '@/utils/distributionStatus'
|
||||||
|
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
||||||
|
|
||||||
|
const pageReady = ref(false)
|
||||||
const canRebate = ref(0)
|
const canRebate = ref(0)
|
||||||
const amount = ref('')
|
const amount = ref('')
|
||||||
const submitLoading = ref(false)
|
const submitLoading = ref(false)
|
||||||
@@ -161,14 +166,17 @@ const saveLoading = ref(false)
|
|||||||
const form = ref({ holderName: '', bankName: '', cardNo: '' })
|
const form = ref({ holderName: '', bankName: '', cardNo: '' })
|
||||||
|
|
||||||
function loadInfo() {
|
function loadInfo() {
|
||||||
distribution().then((res: any) => {
|
return assertActiveDistributor().then((d) => {
|
||||||
const d = res?.data?.result || {}
|
if (!d) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
canRebate.value = Number(d.canRebate || 0)
|
canRebate.value = Number(d.canRebate || 0)
|
||||||
if (!inited.value) {
|
if (!inited.value) {
|
||||||
const prefill = Math.min(canRebate.value, 9999)
|
const prefill = Math.min(canRebate.value, 9999)
|
||||||
amount.value = prefill > 0 ? prefill.toFixed(2) : ''
|
amount.value = prefill > 0 ? prefill.toFixed(2) : ''
|
||||||
inited.value = true
|
inited.value = true
|
||||||
}
|
}
|
||||||
|
return d
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,8 +196,13 @@ function loadCards() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onLoad(() => {
|
onLoad(() => {
|
||||||
loadInfo()
|
loadInfo().then((d) => {
|
||||||
loadCards()
|
if (!d) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
pageReady.value = true
|
||||||
|
loadCards()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
function openAccountDrawer() {
|
function openAccountDrawer() {
|
||||||
@@ -304,6 +317,16 @@ function maskCard(cardNo: string) {
|
|||||||
|
|
||||||
.content { padding: 24rpx; }
|
.content { padding: 24rpx; }
|
||||||
|
|
||||||
|
.state-wrap {
|
||||||
|
padding: 120rpx 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.state-text {
|
||||||
|
color: #999;
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
.section-card {
|
.section-card {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border-radius: 20rpx;
|
border-radius: 20rpx;
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="wrapper" :style="themeStyle">
|
<view class="wrapper" :style="themeStyle">
|
||||||
|
<view v-if="!pageReady" class="state-wrap">
|
||||||
|
<text class="state-text">加载中...</text>
|
||||||
|
</view>
|
||||||
|
<template v-else>
|
||||||
<view class="feedBack-box">
|
<view class="feedBack-box">
|
||||||
<view class="box-title">提现金额</view>
|
<view class="box-title">提现金额</view>
|
||||||
<view class="amount-row">
|
<view class="amount-row">
|
||||||
@@ -23,13 +27,15 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="submit" @click="submitWithdraw">提现</view>
|
<view class="submit" @click="submitWithdraw">提现</view>
|
||||||
|
</template>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, getCurrentInstance, onMounted } from 'vue'
|
import { ref, computed, getCurrentInstance, onMounted } from 'vue'
|
||||||
import { useStore } from '@/store'
|
import { useStore } from '@/store'
|
||||||
import { distribution, cash } from '@/api/distribution'
|
import { cash } from '@/api/distribution'
|
||||||
|
import { assertActiveDistributor } from '@/utils/distributionStatus'
|
||||||
import { unitPrice } from '@/utils/filters.js'
|
import { unitPrice } from '@/utils/filters.js'
|
||||||
import { getThemeStyle } from '@/utils/theme'
|
import { getThemeStyle } from '@/utils/theme'
|
||||||
|
|
||||||
@@ -38,23 +44,20 @@ const { proxy } = getCurrentInstance()!
|
|||||||
|
|
||||||
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
const themeStyle = computed(() => getThemeStyle(store.state.theme))
|
||||||
const price = ref('')
|
const price = ref('')
|
||||||
|
const pageReady = ref(false)
|
||||||
const distributionData = ref<Record<string, any>>({})
|
const distributionData = ref<Record<string, any>>({})
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
fetchDistributionInfo()
|
fetchDistributionInfo()
|
||||||
})
|
})
|
||||||
|
|
||||||
function hideLoadingIfNeeded() {
|
|
||||||
if (store.state.isShowToast) uni.hideLoading()
|
|
||||||
}
|
|
||||||
|
|
||||||
function fetchDistributionInfo() {
|
function fetchDistributionInfo() {
|
||||||
uni.showLoading({ title: '加载中' })
|
assertActiveDistributor().then((result) => {
|
||||||
distribution().then((res) => {
|
if (!result) {
|
||||||
if (res.data.result) {
|
return
|
||||||
distributionData.value = res.data.result
|
|
||||||
}
|
}
|
||||||
hideLoadingIfNeeded()
|
distributionData.value = result
|
||||||
|
pageReady.value = true
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,6 +101,16 @@ page {
|
|||||||
background: #f8f8f8;
|
background: #f8f8f8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.state-wrap {
|
||||||
|
padding: 120rpx 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.state-text {
|
||||||
|
color: #999;
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
.feedBack-box {
|
.feedBack-box {
|
||||||
background: #fff;
|
background: #fff;
|
||||||
border-radius: 20rpx;
|
border-radius: 20rpx;
|
||||||
|
|||||||
@@ -136,6 +136,7 @@ import { distribution as fetchDistribution } from '@/api/distribution'
|
|||||||
import configs from '@/config/config'
|
import configs from '@/config/config'
|
||||||
import storage from '@/utils/storage'
|
import storage from '@/utils/storage'
|
||||||
import { tipsToLogin, setClipboard } from '@/utils/filters.js'
|
import { tipsToLogin, setClipboard } from '@/utils/filters.js'
|
||||||
|
import { DISTRIBUTION_RETREAT_MESSAGE, DISTRIBUTION_STATUS } from '@/utils/distributionStatus'
|
||||||
|
|
||||||
const sharingShow = ref(false)
|
const sharingShow = ref(false)
|
||||||
const sharingLink = ref('')
|
const sharingLink = ref('')
|
||||||
@@ -194,18 +195,19 @@ function distribution() {
|
|||||||
if (!tipsToLogin('normal')) {
|
if (!tipsToLogin('normal')) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// 入口按 distributionStatus 路由:有对象 ≠ 有效分销员。清退停住,不进 join / home。
|
||||||
fetchDistribution().then((res) => {
|
fetchDistribution().then((res) => {
|
||||||
if (res.data.result) {
|
if (res.data.result) {
|
||||||
const type = res.data.result.distributionStatus
|
const type = res.data.result.distributionStatus
|
||||||
if (type == 'PASS') {
|
if (type == DISTRIBUTION_STATUS.PASS) {
|
||||||
uni.navigateTo({
|
uni.navigateTo({
|
||||||
url: '/pages/mine/distribution/home',
|
url: '/pages/mine/distribution/home',
|
||||||
})
|
})
|
||||||
} else if (type == 'REFUSE') {
|
} else if (type == DISTRIBUTION_STATUS.REFUSE) {
|
||||||
goRecruitJoin()
|
goRecruitJoin()
|
||||||
} else if (type == 'RETREAT') {
|
} else if (type == DISTRIBUTION_STATUS.RETREAT) {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title: '您的分销资格已被清退。请联系管理员!',
|
title: DISTRIBUTION_RETREAT_MESSAGE,
|
||||||
duration: 2000,
|
duration: 2000,
|
||||||
icon: 'none',
|
icon: 'none',
|
||||||
})
|
})
|
||||||
|
|||||||
100
utils/distributionStatus.js
Normal file
100
utils/distributionStatus.js
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
/**
|
||||||
|
* 分销员资格状态(与后端 DistributionStatusEnum 对齐)。
|
||||||
|
*
|
||||||
|
* 入口按 distributionStatus 分支;能力页只有 PASS 才渲染业务。
|
||||||
|
* 有返回 ≠ 有效分销员。
|
||||||
|
*
|
||||||
|
* @author Mike
|
||||||
|
* @date 2026-09-09
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { distribution } from '@/api/distribution'
|
||||||
|
|
||||||
|
export const DISTRIBUTION_STATUS = {
|
||||||
|
PASS: 'PASS',
|
||||||
|
APPLY: 'APPLY',
|
||||||
|
REFUSE: 'REFUSE',
|
||||||
|
RETREAT: 'RETREAT',
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 全端统一清退文案 */
|
||||||
|
export const DISTRIBUTION_RETREAT_MESSAGE = '您的分销资格已被清退。请联系管理员!'
|
||||||
|
|
||||||
|
export const DISTRIBUTION_APPLY_MESSAGE = '您的信息正在审核'
|
||||||
|
|
||||||
|
export const DISTRIBUTION_NOT_MEMBER_MESSAGE = '您还不是分销员'
|
||||||
|
|
||||||
|
const JOIN_PATH = '/pages/mine/distribution/join'
|
||||||
|
const MINE_TAB = '/pages/tabbar/user/my'
|
||||||
|
const TOAST_DURATION = 2000
|
||||||
|
|
||||||
|
export function getDistributionStatus(distribution) {
|
||||||
|
return distribution && distribution.distributionStatus ? distribution.distributionStatus : null
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 能力页:仅在职分销员可看业绩 / 提现 / 等级等 */
|
||||||
|
export function isActiveDistributor(distribution) {
|
||||||
|
return getDistributionStatus(distribution) === DISTRIBUTION_STATUS.PASS
|
||||||
|
}
|
||||||
|
|
||||||
|
function showStatusToast(title) {
|
||||||
|
uni.showToast({ title, duration: TOAST_DURATION, icon: 'none' })
|
||||||
|
}
|
||||||
|
|
||||||
|
function leaveCapabilityPage() {
|
||||||
|
setTimeout(() => {
|
||||||
|
const pages = typeof getCurrentPages === 'function' ? getCurrentPages() : []
|
||||||
|
if (pages.length > 1) {
|
||||||
|
uni.navigateBack({ delta: 1 })
|
||||||
|
} else {
|
||||||
|
uni.switchTab({ url: MINE_TAB })
|
||||||
|
}
|
||||||
|
}, TOAST_DURATION)
|
||||||
|
}
|
||||||
|
|
||||||
|
function goRecruitJoin() {
|
||||||
|
uni.redirectTo({
|
||||||
|
url: JOIN_PATH,
|
||||||
|
fail: () => {
|
||||||
|
uni.navigateTo({ url: JOIN_PATH })
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 能力页非 PASS 提示并退出。RETREAT 用统一清退文案;APPLY / REFUSE 与入口一致。
|
||||||
|
*/
|
||||||
|
export function leaveInactiveDistributor(member) {
|
||||||
|
const status = getDistributionStatus(member)
|
||||||
|
if (status === DISTRIBUTION_STATUS.RETREAT) {
|
||||||
|
showStatusToast(DISTRIBUTION_RETREAT_MESSAGE)
|
||||||
|
leaveCapabilityPage()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (status === DISTRIBUTION_STATUS.REFUSE) {
|
||||||
|
goRecruitJoin()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (status === DISTRIBUTION_STATUS.APPLY) {
|
||||||
|
showStatusToast(DISTRIBUTION_APPLY_MESSAGE)
|
||||||
|
leaveCapabilityPage()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
showStatusToast(DISTRIBUTION_NOT_MEMBER_MESSAGE)
|
||||||
|
leaveCapabilityPage()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 能力页守卫:请求 GET /distribution,仅 PASS 返回对象,否则提示并退出。
|
||||||
|
* @returns {Promise<object|null>}
|
||||||
|
*/
|
||||||
|
export function assertActiveDistributor() {
|
||||||
|
return distribution().then((res) => {
|
||||||
|
const result = res && res.data ? res.data.result : null
|
||||||
|
if (isActiveDistributor(result)) {
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
leaveInactiveDistributor(result)
|
||||||
|
return null
|
||||||
|
})
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user