Przeglądaj źródła

优化团队成员页面统计逻辑

wilhelm wong 2 miesięcy temu
rodzic
commit
b0ff0bc052
2 zmienionych plików z 184 dodań i 15 usunięć
  1. 9 0
      src/services/api.js
  2. 175 15
      src/views/TeamMembersView.vue

+ 9 - 0
src/services/api.js

@@ -393,6 +393,15 @@ export const getMemberStatisticsDetail = async (teamMemberId, startDate, endDate
   return response.data
 }
 
+// 获取团队统计数据(仅限团队用户)
+export const getTeamLeaderStats = async (teamId) => {
+  const params = {}
+  if (teamId) params.teamId = teamId
+  
+  const response = await api.get('/team-members/statistics/team-leader', { params })
+  return response.data
+}
+
 // ==================== 推广链接相关API ====================
 
 // 创建推广链接

+ 175 - 15
src/views/TeamMembersView.vue

@@ -1,5 +1,6 @@
 <template>
   <div class="rounded-lg p-4 bg-[var(--p-content-background)]">
+
     <DataTable
       :value="tableData.content"
       :paginator="true"
@@ -45,6 +46,12 @@
           <Button icon="pi pi-refresh" @click="handleRefresh" label="刷新" size="small" />
           <Button icon="pi pi-plus" @click="openAddDialog" label="新增成员" size="small" severity="success" />
           <div class="flex-1"></div>
+          <!-- 团队用户统计信息提示 -->
+          <div v-if="isTeam" class="text-sm text-gray-600">
+            <span class="font-medium">团队统计:</span>
+            <span v-if="teamStats" class="text-green-600 ml-1">已加载</span>
+            <span v-else class="text-orange-600 ml-1">未加载</span>
+          </div>
         </div>
       </template>
 
@@ -80,42 +87,75 @@
         </template>
       </Column>
 
-      <!-- <Column field="totalRevenue" header="总收入" style="min-width: 120px">
+      <Column field="commissionRate" header="分成比例" style="min-width: 120px">
         <template #body="slotProps">
-          <span class="total-revenue-text font-semibold"> {{ formatAmount(slotProps.data.totalRevenue) }} </span>
+          <span class="commission-rate-text font-semibold">
+            {{ slotProps.data.commissionRate || 0 }}%
+          </span>
         </template>
       </Column>
 
-      <Column field="todayRevenue" header="今日收入" style="min-width: 120px">
+      <!-- 团队用户可见的收入统计列 -->
+      <Column v-if="isTeam" field="totalRevenue" header="总收入" style="min-width: 120px">
         <template #body="slotProps">
-          <span class="today-revenue-text font-semibold"> {{ formatAmount(slotProps.data.todayRevenue) }} </span>
+          <span class="total-revenue-text font-semibold text-blue-600">
+            ¥{{ formatAmount(getMemberTotalRevenue(slotProps.data.id)) }}
+          </span>
         </template>
-      </Column> -->
+      </Column>
 
-      <Column field="commissionRate" header="分成比例" style="min-width: 120px">
+      <Column v-if="isTeam" field="todayRevenue" header="今日收入" style="min-width: 120px">
         <template #body="slotProps">
-          <span class="commission-rate-text font-semibold">
-            {{ slotProps.data.commissionRate || 0 }}%
+          <span class="today-revenue-text font-semibold text-green-600">
+            ¥{{ formatAmount(getMemberTodayRevenue(slotProps.data.id)) }}
           </span>
         </template>
       </Column>
 
-      <Column field="totalRevenue" header="总分成" style="min-width: 120px">
+      <!-- 团队用户可见的销售额统计列 -->
+      <Column v-if="isTeam" field="totalSales" header="总销售额" style="min-width: 120px">
         <template #body="slotProps">
-          <span class="total-revenue-text font-semibold">
-            ¥{{ formatAmount(slotProps.data.totalRevenue) }}
+          <span class="total-sales-text font-semibold text-purple-600">
+            ¥{{ formatAmount(getMemberTotalSales(slotProps.data.id)) }}
           </span>
         </template>
       </Column>
 
-      <Column field="todayRevenue" header="今日分成" style="min-width: 120px">
+      <Column v-if="isTeam" field="todaySales" header="今日销售额" style="min-width: 120px">
         <template #body="slotProps">
-          <span class="today-revenue-text font-semibold">
-            ¥{{ formatAmount(slotProps.data.todayRevenue) }}
+          <span class="today-sales-text font-semibold text-orange-600">
+            ¥{{ formatAmount(getMemberTodaySales(slotProps.data.id)) }}
           </span>
         </template>
       </Column>
 
+      <!-- 实际收入(比例)列 -->
+      <Column v-if="isTeam" field="actualIncome" header="队长收入(比例)" style="min-width: 150px">
+        <template #body="slotProps">
+          <div class="flex flex-col">
+            <span v-if="isTeamLeader(slotProps.data.id)" class="team-leader-income-text font-semibold text-red-600">
+              ¥{{ formatAmount(getTeamLeaderTotalIncome(slotProps.data.id)) }}({{ getMemberActualRate(slotProps.data.id) }}%)
+            </span>
+            <span v-else class="actual-rate-text font-semibold text-blue-600">
+              ¥{{ formatAmount(getMemberTotalRevenue(slotProps.data.id)) }}({{ getMemberActualRate(slotProps.data.id) }}%)
+            </span>
+          </div>
+        </template>
+      </Column>
+
+      <!-- 今日实际收入(比例)列 -->
+      <Column v-if="isTeam" field="todayActualIncome" header="队长今日收入(比例)" style="min-width: 150px">
+        <template #body="slotProps">
+          <div class="flex flex-col">
+            <span v-if="isTeamLeader(slotProps.data.id)" class="team-leader-today-income-text font-semibold text-red-600">
+              ¥{{ formatAmount(getTeamLeaderTodayIncome(slotProps.data.id)) }}({{ getMemberActualRate(slotProps.data.id) }}%)
+            </span>
+            <span v-else class="today-revenue-text font-semibold text-green-600">
+              ¥{{ formatAmount(getMemberTodayRevenue(slotProps.data.id)) }}({{ getMemberActualRate(slotProps.data.id) }}%)
+            </span>
+          </div>
+        </template>
+      </Column>
 
       <Column field="createdAt" header="创建时间" style="min-width: 150px">
         <template #body="slotProps">
@@ -255,7 +295,7 @@ import InputNumber from 'primevue/inputnumber'
 import Password from 'primevue/password'
 import { useConfirm } from 'primevue/useconfirm'
 import { useToast } from 'primevue/usetoast'
-import { listMembers, createMember, updateMember, deleteMember } from '@/services/api'
+import { listMembers, createMember, updateMember, deleteMember, getTeamLeaderStats } from '@/services/api'
 import { useTeamStore } from '@/stores/team'
 
 const toast = useToast()
@@ -307,6 +347,10 @@ const tableData = ref({
 
 // 加载状态
 const loading = ref(false)
+const statsLoading = ref(false)
+
+// 团队统计数据
+const teamStats = ref(null)
 
 // 编辑相关
 const editDialog = ref(false)
@@ -347,6 +391,63 @@ const formatDateTime = (dateString) => {
   return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
 }
 
+
+// 获取成员的实际比例
+const getMemberActualRate = (memberId) => {
+  if (!teamStats.value?.membersStats) return 0
+  const member = teamStats.value.membersStats.find(m => m.memberId === memberId)
+  return member?.actualRate || 0
+}
+
+// 获取成员的总收入
+const getMemberTotalRevenue = (memberId) => {
+  if (!teamStats.value?.membersStats) return 0
+  const member = teamStats.value.membersStats.find(m => m.memberId === memberId)
+  return member?.totalRevenue || 0
+}
+
+// 获取成员的今日收入
+const getMemberTodayRevenue = (memberId) => {
+  if (!teamStats.value?.membersStats) return 0
+  const member = teamStats.value.membersStats.find(m => m.memberId === memberId)
+  return member?.todayRevenue || 0
+}
+
+// 获取成员的总销售额
+const getMemberTotalSales = (memberId) => {
+  if (!teamStats.value?.membersStats) return 0
+  const member = teamStats.value.membersStats.find(m => m.memberId === memberId)
+  return member?.totalSales || 0
+}
+
+// 获取成员的今日销售额
+const getMemberTodaySales = (memberId) => {
+  if (!teamStats.value?.membersStats) return 0
+  const member = teamStats.value.membersStats.find(m => m.memberId === memberId)
+  return member?.todaySales || 0
+}
+
+// 判断是否为队长
+const isTeamLeader = (memberId) => {
+  if (!teamStats.value?.membersStats) return false
+  const member = teamStats.value.membersStats.find(m => m.memberId === memberId)
+  return member?.teamLeaderTotalIncome !== undefined || member?.teamLeaderTodayIncome !== undefined
+}
+
+// 获取队长的实际总收入
+const getTeamLeaderTotalIncome = (memberId) => {
+  if (!teamStats.value?.membersStats) return 0
+  const member = teamStats.value.membersStats.find(m => m.memberId === memberId)
+  return member?.teamLeaderTotalIncome || 0
+}
+
+// 获取队长的实际今日收入
+const getTeamLeaderTodayIncome = (memberId) => {
+  if (!teamStats.value?.membersStats) return 0
+  const member = teamStats.value.membersStats.find(m => m.memberId === memberId)
+  return member?.teamLeaderTodayIncome || 0
+}
+
 // 获取数据
 const fetchData = async () => {
   loading.value = true
@@ -370,6 +471,36 @@ const fetchData = async () => {
   }
 }
 
+// 获取团队统计数据
+const fetchTeamStats = async () => {
+  if (!isTeam.value) return
+  
+  statsLoading.value = true
+  try {
+    const response = await getTeamLeaderStats()
+    teamStats.value = response
+  } catch (error) {
+    console.error('获取团队统计数据失败:', error)
+    if (error.status === 403) {
+      toast.add({
+        severity: 'warn',
+        summary: '权限不足',
+        detail: '只有团队用户才能访问统计数据',
+        life: 3000
+      })
+    } else {
+      toast.add({
+        severity: 'error',
+        summary: '错误',
+        detail: '获取团队统计数据失败',
+        life: 3000
+      })
+    }
+  } finally {
+    statsLoading.value = false
+  }
+}
+
 // 分页处理
 const handlePageChange = (event) => {
   tableData.value.metadata.page = event.page
@@ -513,6 +644,10 @@ const saveEdit = async () => {
 
 onMounted(() => {
   fetchData()
+  // 如果是团队用户,预加载统计数据
+  if (isTeam.value) {
+    fetchTeamStats()
+  }
 })
 </script>
 
@@ -584,6 +719,31 @@ onMounted(() => {
   font-weight: 600;
 }
 
+.actual-rate-text {
+  color: #2563eb;
+  font-weight: 600;
+}
+
+.total-sales-text {
+  color: #7c3aed;
+  font-weight: 600;
+}
+
+.today-sales-text {
+  color: #ea580c;
+  font-weight: 600;
+}
+
+.team-leader-income-text {
+  color: #dc2626;
+  font-weight: 600;
+}
+
+.team-leader-today-income-text {
+  color: #dc2626;
+  font-weight: 600;
+}
+
 
 .font-medium {
   font-weight: 500;