|
|
@@ -6,7 +6,7 @@
|
|
|
</view>
|
|
|
|
|
|
<view class="content-area">
|
|
|
- <view v-if="isLoading" class="loading-indicator">
|
|
|
+ <view v-if="loading" class="loading-indicator">
|
|
|
<image class="loading-avatar" src="/static/images/avatar_default.png" mode="aspectFill"></image>
|
|
|
<text class="loading-text">加载中...</text>
|
|
|
</view>
|
|
|
@@ -25,51 +25,50 @@
|
|
|
</view>
|
|
|
</view>
|
|
|
|
|
|
+ <!-- 空状态 -->
|
|
|
+ <view class="no-data" v-if="filteredCustomers.length === 0">
|
|
|
+ <view class="empty-state">
|
|
|
+ <image src="/static/images/icon_empty_state.png" class="empty-icon" mode="aspectFit"></image>
|
|
|
+ <text>暂无客户数据</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+
|
|
|
<!-- 列表区域 -->
|
|
|
- <view v-else>
|
|
|
- <view class="no-data" v-if="filteredCustomers.length === 0">
|
|
|
- <view class="empty-state">
|
|
|
- <image src="/static/images/icon_empty_state.png" class="empty-icon" mode="aspectFit"></image>
|
|
|
- <text>暂无客户数据</text>
|
|
|
- </view>
|
|
|
+ <view class="customer-item" v-for="customer in filteredCustomers" :key="customer.id">
|
|
|
+ <view class="customer-avatar-wrap">
|
|
|
+ <image
|
|
|
+ v-if="customer.avatar"
|
|
|
+ class="customer-avatar-img"
|
|
|
+ :src="customer.avatar"
|
|
|
+ mode="aspectFill"></image>
|
|
|
+ <text v-else class="customer-avatar-icon">👤</text>
|
|
|
</view>
|
|
|
|
|
|
- <view class="customer-item" v-for="customer in filteredCustomers" :key="customer.id">
|
|
|
- <view class="customer-avatar-wrap">
|
|
|
- <image
|
|
|
- v-if="customer.avatar"
|
|
|
- class="customer-avatar-img"
|
|
|
- :src="customer.avatar"
|
|
|
- mode="aspectFill"></image>
|
|
|
- <text v-else class="customer-avatar-icon">👤</text>
|
|
|
+ <view class="customer-info">
|
|
|
+ <view class="customer-name">{{ customer.familyName || customer.buyerNickname || '微信用户' }}</view>
|
|
|
+ <view class="customer-meta">
|
|
|
+ <text class="member-type">{{ customer.memberType === 'login' ? '登录用户' : '本地用户' }}</text>
|
|
|
+ <text class="join-time">{{ formatJoinTime(customer.createdAt) }}</text>
|
|
|
</view>
|
|
|
+ </view>
|
|
|
|
|
|
- <view class="customer-info">
|
|
|
- <view class="customer-name">{{ customer.nickname || '微信用户' }}</view>
|
|
|
- <view class="customer-meta">
|
|
|
- <text class="member-type">{{ customer.memberType || '本地用户' }}</text>
|
|
|
- <text class="join-time">{{ formatJoinTime(customer.joinTime) }}</text>
|
|
|
- </view>
|
|
|
+ <view class="customer-right">
|
|
|
+ <view class="order-count">
|
|
|
+ <text>{{ customer.loginMemberCount || 0 }}</text>
|
|
|
+ <text>成员</text>
|
|
|
</view>
|
|
|
|
|
|
- <view class="customer-right">
|
|
|
- <view class="order-count">
|
|
|
- <text>{{ customer.orderCount || 0 }}</text>
|
|
|
- <text>订单</text>
|
|
|
- </view>
|
|
|
-
|
|
|
- <view class="source-tag" :class="'tag-' + (customer.source || 'default')">
|
|
|
- <text>{{ getSourceTagLabel(customer.source) }}</text>
|
|
|
- </view>
|
|
|
+ <view class="source-tag" :class="'tag-' + (customer.source || 'default')">
|
|
|
+ <text>{{ getSourceTagLabel(customer.source) }}</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
+ </view>
|
|
|
|
|
|
- <!-- 加载更多 -->
|
|
|
- <view class="load-more" v-if="hasMore && !loading">
|
|
|
- <view @click="loadMore" class="load-more-btn">
|
|
|
- <text>加载更多</text>
|
|
|
- <image v-if="loadingMore" src="/static/images/arrow_down.png" class="spinner" mode="aspectFit"></image>
|
|
|
- </view>
|
|
|
+ <!-- 加载更多 -->
|
|
|
+ <view class="load-more" v-if="hasMore && !loading">
|
|
|
+ <view @click="loadMore" class="load-more-btn">
|
|
|
+ <text>加载更多</text>
|
|
|
+ <image v-if="loadingMore" src="/static/images/arrow_down.png" class="spinner" mode="aspectFit"></image>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
@@ -79,15 +78,18 @@
|
|
|
|
|
|
<script>
|
|
|
import fontScaleMixin from '@/mixins/font-scale.js'
|
|
|
+import { getVendorTeamCustomers } from '@/utils/api.js'
|
|
|
+import { parseDate } from '@/utils/format.js'
|
|
|
export default {
|
|
|
mixins: [fontScaleMixin],
|
|
|
data() {
|
|
|
return {
|
|
|
// 页面状态
|
|
|
- status: 'all', // all | referred | order | manual
|
|
|
+ status: 'all', // all | referral | order | manual
|
|
|
page: 1,
|
|
|
hasMore: true,
|
|
|
loading: false,
|
|
|
+ loadingMore: false,
|
|
|
refreshing: false,
|
|
|
|
|
|
// 数据
|
|
|
@@ -95,7 +97,7 @@ export default {
|
|
|
filteredCustomers: [], // 筛选后的客户列表
|
|
|
statusOptions: [ // 筛选选项
|
|
|
{ key: 'all', label: '全部' },
|
|
|
- { key: 'referred', label: '推荐人' },
|
|
|
+ { key: 'referral', label: '推荐码' },
|
|
|
{ key: 'order', label: '下单' },
|
|
|
{ key: 'manual', label: '人工' }
|
|
|
],
|
|
|
@@ -135,7 +137,7 @@ export default {
|
|
|
|
|
|
try {
|
|
|
// 并发请求:获取客户列表 + 获取统计概览
|
|
|
- var res = await this.$http.getTeamCustomers({
|
|
|
+ var res = await getVendorTeamCustomers({
|
|
|
systemId: this.systemId,
|
|
|
parentId: this.parentId,
|
|
|
page: this.page,
|
|
|
@@ -143,8 +145,11 @@ export default {
|
|
|
})
|
|
|
|
|
|
if (res && res.data) {
|
|
|
- this.customers = this.page === 1 ? res.data.records || [] : this.customers.concat(res.data.records || [])
|
|
|
- this.hasMore = (res.data.records || []).length >= 20
|
|
|
+ // 后端返回 { list, total }(Map),兼容旧版数组形状
|
|
|
+ var data = res.data
|
|
|
+ var list = data instanceof Array ? data : (data.list || data.records || [])
|
|
|
+ this.customers = this.page === 1 ? list : this.customers.concat(list)
|
|
|
+ this.hasMore = (list || []).length >= 20
|
|
|
this.page++
|
|
|
|
|
|
// 计算筛选后的列表
|
|
|
@@ -190,7 +195,8 @@ export default {
|
|
|
// 格式化加入时间
|
|
|
formatJoinTime(timeStr) {
|
|
|
if (!timeStr) return '-'
|
|
|
- var d = this.parseDate(timeStr)
|
|
|
+ var d = parseDate(timeStr)
|
|
|
+ if (!d) return '-'
|
|
|
return d.getFullYear() + '-' + String(d.getMonth() + 1).padStart(2, '0') + '-' + String(d.getDate()).padStart(2, '0')
|
|
|
},
|
|
|
|
|
|
@@ -201,7 +207,7 @@ export default {
|
|
|
'order': '下单自动',
|
|
|
'referral': '推荐码'
|
|
|
}
|
|
|
- return labels[source] || source
|
|
|
+ return labels[source] || source || '未标注'
|
|
|
}
|
|
|
}
|
|
|
}
|