caiyuqin 2 месяцев назад
Родитель
Сommit
3878089c0a

+ 1 - 0
.gitignore

@@ -20,6 +20,7 @@ dist
 *.sln
 *.sw?
 .hbuilderx
+.trae
 
 .stylelintcache
 .eslintcache

+ 41 - 0
src/api/my.ts

@@ -0,0 +1,41 @@
+import { http } from '@/http/alova'
+
+//我的-收益统计数据
+export function getMyDataStatistics() {
+    return http.Get('/couponCenter/APP/mine/getMyDataStatistics')
+}
+
+
+// 分享收益
+export function getProfitList(params:any) {
+    return http.Get('/couponCenter/APP/couponIssuerAccountDetail/getProfitList', {
+        params
+    })
+}
+// 邀新收益
+export function getNewInvitationList(params:any) {
+    return http.Get('/couponCenter/APP/couponIssuerAccountDetail/getNewInvitationList', {
+        params
+    })
+}
+// 核销收益
+export function getWriteOffIncomeList(params:any) {
+    return http.Get('/couponCenter/APP/couponIssuerAccountDetail/getWriteOffIncomeList', {
+        params
+    })
+}
+
+
+//获取团员数量统计
+export function getTeamStatistics(params:any) {
+    return http.Get('/couponCenter/APP/mine/getTeamStatistics', {
+        params
+    })
+}
+
+//获取团员收益金额统计
+export function getTeamAmountStatistics(params:any) {
+    return http.Get('/couponCenter/APP/mine/getTeamAmountStatistics', {
+        params
+    })
+}

+ 30 - 6
src/components/dateRangePicker/index.vue

@@ -9,7 +9,7 @@
           </view>
         </view>
 
-        <view class="selected-range">
+        <view v-if="currentMode === 'range'" class="selected-range">
           <view class="range-box" :class="{ active: activePicker === 'start', empty: !hasStartDate }"
             @click="switchPicker('start')">
             <text class="range-value">{{ startDateStr }}</text>
@@ -54,7 +54,8 @@
         </view>
 
         <view class="picker-footer">
-          <button class="reset-btn" @click="handleReset">重置</button>
+          <button class="reset-btn" @click="handleReset" v-if="currentMode === 'range'">重置</button>
+          <button class="reset-btn" @click="handleCancel" v-else>取消</button>
           <button class="confirm-btn" @click="handleConfirm">确定</button>
         </view>
       </view>
@@ -74,10 +75,13 @@ type DateParts = {
 
 const props = defineProps<{
   show: boolean;
-  startDate?: string;
-  endDate?: string;
+  mode?: 'single' | 'range'; //单选 / 默认是双选择
+  startDate?: string;  //单个时间如果有默认值,用这个字段
+  endDate?: string; //结束时间
 }>();
 
+const currentMode = computed(() => props.mode || 'range');
+
 const emit = defineEmits<{
   (e: "update:show", value: boolean): void;
   (e: "confirm", value: { startDate: string; endDate: string }): void;
@@ -410,6 +414,7 @@ const selectCurrentPickerDate = () => {
 };
 
 const switchPicker = (picker: PickerType) => {
+  if (currentMode.value === 'single') return;
   if (activePicker.value === picker) return;
   activePicker.value = picker;
   forceUpdatePicker();
@@ -433,15 +438,26 @@ const handleReset = () => {
   forceUpdatePicker();
 };
 
+
 const handleCancel = () => {
   emit("cancel");
   emit("update:show", false);
 };
 
 const handleConfirm = () => {
+  if (currentMode.value === 'single') {
+    // if (!hasStartDate.value) {
+    //   return showToast("请选择时间");
+    // }
+    const date = formatDateValue(getStartDate());
+    emit("confirm", { dateTime: date });
+    emit("update:show", false);
+    return;
+  }
+
   if (!validateDateRange()) return;
-  if (!hasStartDate.value || !hasEndDate.value) {
-    return showToast("请选择时间");
+  if (hasStartDate.value !== hasEndDate.value) {
+    return showToast("请选择日期");
   }
 
   emit("confirm", {
@@ -496,6 +512,14 @@ const initDates = () => {
     end || { year: defaultYear, month: defaultMonth, day: defaultDay };
   activePicker.value = start ? "start" : end ? "end" : "start";
   setPickerValue(displayDate);
+
+  // 单模式:默认选中当天,打开即可点确定
+  if (currentMode.value === 'single' && !hasStartDate.value) {
+    hasStartDate.value = true;
+    startYear.value = displayDate.year;
+    startMonth.value = displayDate.month;
+    startDay.value = displayDate.day;
+  }
 };
 
 watch(

+ 2 - 2
src/components/exchangeCoupon.vue

@@ -106,8 +106,8 @@ function goDetail(){
         <view class="discount-coupon-content">
             <view class="discount-coupon-info-container">
                 <view class="discount-coupon-info-content">
-                    <view class="discount-coupon-info-desc" @click='goDetail'>
-                        <view class="desc-text">
+                    <view class="discount-coupon-info-desc" >
+                        <view class="desc-text" @click='goDetail'>
                             {{ coupon.name }}
                         </view>
                         <view class="desc-type" @tap="isExpand = !isExpand">

+ 49 - 20
src/components/filter/filter.vue

@@ -4,7 +4,7 @@
       <view class="filter-bar">
         <view class="filter-tabs">
           <view class='filter-list' v-for="(item, index) in matchedDataList" :key="index"
-            @click="handleTabClick(item,index)">
+            @click="handleTabClick(item, index)">
             <view class='filter-name'>
               <text class="filter-tab">{{ item.name }}</text>
               <text class="caret" />
@@ -18,7 +18,7 @@
       <view class="classification-cont">
         <view class='classification-list' v-for='(item, index) in filterData' :key='index'
           @click='classClick(index, item)'>
-          <view class='classification-label' :class='{active:item.isSelected}'>{{ item.label }}</view>
+          <view class='classification-label' :class='{ active: item.isSelected }'>{{ item.label }}</view>
           <u--image class='selected-icon' v-show='item.isSelected' :src="getImageUrl('@img/income/selected.png')"
             mode="aspectFit" width="32rpx" height="32rpx">
           </u--image>
@@ -37,6 +37,13 @@ import { ref, computed, nextTick } from "vue";
 import { getImageUrl } from "@/utils/imageUtil";
 import PopupLayer from "@/components/popupLayer/index.vue";
 import DateRangePicker from "@/components/dateRangePicker/index.vue";
+import {
+  usePagination,
+  useRequest,
+  actionDelegationMiddleware,
+} from "alova/client";
+import { getCategoryList } from "@/api/home";
+
 const emit = defineEmits(["selectValue"]);
 const props = defineProps({
   filter: {
@@ -77,10 +84,10 @@ const tabListFilter = ref({
 });
 
 //结算状态
-const tabListSettlement = ref(
+const tabListSettlement = ref([
   { label: "待结算", type: "1", isSelected: false },
-  { label: "已结算", type: "2", isSelected: false }
-);
+  { label: "已结算", type: "2", isSelected: false },
+]);
 
 // 分组配置
 const groupConfig = ref([
@@ -116,7 +123,8 @@ const groupConfig = ref([
   },
 ]);
 
-const matchedDataList = computed(() => {
+const matchedDataList = ref([]);
+const setValue = (value) => {
   const filterArray = props.filter;
   if (!Array.isArray(filterArray) || filterArray.length === 0) {
     return [];
@@ -128,7 +136,6 @@ const matchedDataList = computed(() => {
 
     if (matched) {
       const rawData = matched.data;
-      let listData = [];
 
       result.push({
         key: matched.key,
@@ -138,9 +145,8 @@ const matchedDataList = computed(() => {
       });
     }
   }
-
-  return result;
-});
+  matchedDataList.value = result;
+};
 
 const filterData = ref([]);
 const isOpen = ref(false);
@@ -149,10 +155,11 @@ const popupRef = ref();
 // 当前选中的tab
 const currentTab = ref(0);
 const handleTabClick = (value, index) => {
+  isOpen.value = !isOpen.value;
   if (value.key == "dataFilter") {
     showPicker.value = true;
+    popupRef.value?.close();
   } else {
-    isOpen.value = !isOpen.value;
     nextTick(() => {
       isOpen.value ? popupRef.value?.show() : popupRef.value?.close();
       filterData.value = value.data;
@@ -173,11 +180,7 @@ function classClick(index, item) {
     item.isSelected = true;
     selectedValues.value[currentGroup.key] = item;
 
-    // 将选中项的 label 赋值给 matchedDataList 对应的 name
-    const configItem = groupConfig.value.find(g => g.key === currentGroup.key);
-    if (configItem) {
-      configItem.name = item.label;
-    }
+    matchedDataList.value[currentTab.value].name = item.label;
 
     emit("selectValue", selectedValues.value);
   }
@@ -195,10 +198,9 @@ const defaultEnd = "";
 const handleConfirm = (value: { startDate: string; endDate: string }) => {
   const currentGroup = matchedDataList.value[currentTab.value];
   selectedValues.value[currentGroup.key] = value;
-  const configItem = groupConfig.value.find(g => g.key === currentGroup.key);
-    if (configItem) {
-      configItem.name = `${value.startDate} - ${value.endDate}`
-    }
+  matchedDataList.value[
+    currentTab.value
+  ].name = `${value.startDate} - ${value.endDate}`;
   emit("selectValue", selectedValues.value);
 };
 
@@ -206,6 +208,25 @@ const handleCancel = () => {
   console.log("取消选择");
 };
 
+const {
+  send: sendCategoryList,
+  data: categoryList,
+  loading: categoryLoading,
+} = useRequest(getCategoryList, {
+  immediate: false,
+});
+
+onShow(async () => {
+  await sendCategoryList();
+  tabListType.value = categoryList.value?.map((item) => ({
+    ...item,
+    label: item.name,
+    isSelected: false,
+    type: item.value,
+  }));
+  setValue();
+});
+
 // 暴露方法
 defineExpose({
   selectedValues,
@@ -240,18 +261,22 @@ defineExpose({
       box-sizing: border-box;
       overflow-x: auto; // 让外层滚动
       white-space: nowrap;
+
       // 隐藏滚动条
       &::-webkit-scrollbar {
         display: none;
       }
+
       .filter-tabs {
         display: flex;
         gap: 28rpx;
         min-width: max-content; // 内容撑开宽度
+
         .filter-list {
           display: flex;
           flex-shrink: 0; // 防止被压缩
         }
+
         .caret {
           width: 0;
           height: 0;
@@ -260,12 +285,14 @@ defineExpose({
           border-right: 7rpx solid transparent;
           border-top: 9rpx solid #333333;
         }
+
         .filter-name {
           display: flex;
           align-items: center;
           height: 44rpx;
           line-height: 44rpx;
         }
+
         .filter-tab {
           font-weight: 400;
           font-size: 26rpx;
@@ -274,6 +301,7 @@ defineExpose({
       }
     }
   }
+
   .classification-cont {
     padding: 0 32rpx;
     box-sizing: border-box;
@@ -289,6 +317,7 @@ defineExpose({
       font-size: 26rpx;
       padding-bottom: 32rpx;
     }
+
     .active {
       color: #ff536b;
     }

+ 2 - 2
src/components/templateCoupon.vue

@@ -117,8 +117,8 @@ function goDetail(){
                             {{ coupon.type === '2' ? '折' : '元' }}
                         </view>
                     </view>
-                    <view class="discount-coupon-info-desc"  @click='goDetail'>
-                        <view class="desc-text">
+                    <view class="discount-coupon-info-desc"  >
+                        <view class="desc-text" @click='goDetail'>
                             {{ coupon.name }}
                         </view>
                         <view class="desc-type" @tap="isExpand = !isExpand">

+ 1 - 0
src/pages-C/home/browse.vue

@@ -209,6 +209,7 @@ function selectValue(item) {
     }
   }
 
+
   .classification-cont {
     padding: 0 32rpx;
     box-sizing: border-box;

+ 77 - 77
src/pages-C/my/myNewUsers.vue

@@ -1,8 +1,8 @@
 <script setup lang="ts">
-import { ref } from "vue";
-import { safeAreaInsets, menuButtonInfo } from "@/utils";
-import CustomNavigationBar from "@/components/CustomNavigationBar.vue";
+import { computed, ref } from "vue";
 import { getImageUrl } from "@/utils/imageUtil";
+import LsvList from "@/components/listScrollView/index.vue";
+import { getNewInvitationList } from "@/api/my";
 
 definePage({
   style: {
@@ -11,73 +11,64 @@ definePage({
   },
 });
 
-const totalIncome = ref("38.00");
+const totalAmount = ref();
 
-const shareList = ref([
-  {
-    id: 1,
-    couponName: "某某某某某优惠券",
-    income: "2.00",
-    receiveTime: "2026-05-18 19:00:00",
-    receiver: "林雨欣",
-  },
-  {
-    id: 2,
-    couponName: "某某某某某优惠券",
-    income: "17.00",
-    receiveTime: "2026-05-18 19:00:00",
-    receiver: "吴雨桐",
-  },
-  {
-    id: 3,
-    couponName: "某某某某某优惠券",
-    income: "18.00",
-    receiveTime: "2026-05-18 19:00:00",
-    receiver: "周昭宁",
-  },
-  {
-    id: 4,
-    couponName: "某某某某某优惠券",
-    income: "8.00",
-    receiveTime: "2026-05-18 19:00:00",
-    receiver: "周宇轩",
-  },
+const tabList = ref([
+  { label: "今天", value: "1" },
+  { label: "近30天", value: "2" },
 ]);
+const currentTab = ref("1");
 
-function handleViewDetail(item) {
-  uni.showToast({
-    title: `查看 ${item.couponName} 详情`,
-    icon: "none",
-  });
-}
+const showPicker = ref(false);
+const defaultStart = ref();
+const defaultEnd = ref();
 
-// 定义tab列表
-const tabList = ref([
-  { label: "今天", value: "0" },
-  { label: "近30天", value: "1" },
-]);
-// 当前选中的tab
-const currentTab = ref("0");
+const listRef = ref();
 
-// 点击tab事件
 const handleTabClick = (value) => {
   currentTab.value = value;
-  console.log("选中tab:", value);
+  reloadListRef();
 };
 
-const showPicker = ref(false);
-const defaultStart = "";
-const defaultEnd = "";
-
 const handleConfirm = (value: { startDate: string; endDate: string }) => {
-  console.log("选中的日期范围:", value);
-  // 处理业务逻辑
+  defaultStart.value = value.startDate;
+  defaultEnd.value = value.endDate;
+  reloadListRef();
+};
+
+const reloadListRef = () => {
+  listRef.value.reloadList({
+    startTime: defaultStart.value ? defaultStart.value + " 00:00:00" : "",
+    endTime: defaultEnd.value ? defaultEnd.value + " 23:59:59" : "",
+    timeType: currentTab.value,
+  });
 };
 
 const handleCancel = () => {
   console.log("取消选择");
 };
 
+const getCouponListApi = (params) => {
+  return getNewInvitationList({
+    pageNo: params.pageNo,
+    pageSize: params.pageSize,
+    timeType: params.timeType ?? 1,
+    startTime: params.startTime || "",
+    endTime: params.endTime || "",
+  });
+};
+
+const afterFetch = (item) => {
+  totalAmount.value = item.totalAmount;
+};
+
+const dateRangeText = computed(() => {
+  if (defaultStart.value && defaultEnd.value) {
+    return `${defaultStart.value} - ${defaultEnd.value}`;
+  }
+  return "日期筛选";
+});
+
 function goDetails(item) {
   uni.navigateTo({
     url: `/pages-C/my/myNewUsersDetails`,
@@ -98,7 +89,7 @@ function goDetails(item) {
                     backgroundPosition: 'center'
                 }">
         <text class="income-label">邀新累计收益(元)</text>
-        <text class="income-amount">3859.00</text>
+        <text class="income-amount">{{totalAmount || 0}}</text>
       </view>
 
       <view class="filter-box">
@@ -113,8 +104,7 @@ function goDetails(item) {
         <view class="income-line"></view>
         <view class='income-select'>
           <view class='income-time' @click='showPicker=true'>
-            <!-- <view class='income-time-name'>2026 05.10-2026 05.12 </view> -->
-            <view class='income-time-name'>日期筛选 </view>
+            <view class='income-time-name'>{{ dateRangeText }}</view>
             <view class="caret" />
           </view>
         </view>
@@ -128,31 +118,35 @@ function goDetails(item) {
             <text class="total-label">总收益</text>
             <view>
               <!-- <text class="total-symbol">¥</text> -->
-              <text class="total-amount">{{ totalIncome }}</text>
+              <text class="total-amount">{{ totalAmount || 0 }}</text>
             </view>
           </view>
         </view>
 
-        <view class="records-list">
-          <view v-for="(item, index) in shareList" :key="item.id" class="record-item">
-            <view class="record-bottom" @click='goDetails'>
-              <view class="info-row">
-                <text class="info-label">获得佣金</text>
-                <text class="income-value">¥{{ item.income }}</text>
-              </view>
-              <view class="info-row">
-                <text class="info-label">邀请人数</text>
-                <text class="info-value">{{ item.receiver }}</text>
-              </view>
-              <view class="info-row">
-                <text class="info-label">邀请日期</text>
-                <text class="info-value">{{ item.receiveTime }}</text>
+        <LsvList ref="listRef" :api="getCouponListApi" key-name="detailList" @afterFetch='afterFetch'>
+          <template #list="{ data }">
+            <view class="records-list">
+              <view v-for="(item, index) in data" :key="item.id" class="record-item">
+                <view class="record-bottom" @click='goDetails'>
+                  <view class="info-row">
+                    <text class="info-label">获得佣金</text>
+                    <text class="income-value">¥{{ item.earnings }}</text>
+                  </view>
+                  <view class="info-row">
+                    <text class="info-label">邀请人数</text>
+                    <text class="info-value">{{ item.shareCount }}</text>
+                  </view>
+                  <view class="info-row">
+                    <text class="info-label">邀请日期</text>
+                    <text class="info-value">{{ item.receiveTime }}</text>
+                  </view>
+                </view>
+
+                <view v-if="index < data.length - 1" class="record-divider"></view>
               </view>
             </view>
-
-            <view v-if="index < shareList.length - 1" class="record-divider"></view>
-          </view>
-        </view>
+          </template>
+        </LsvList>
       </view>
     </view>
 
@@ -166,11 +160,16 @@ function goDetails(item) {
 .share-info-container {
   min-height: 100vh;
   background: #f8f8fa;
+  display: flex;
+  flex-direction: column;
 
   .share-info-content {
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+    padding: 32rpx 0;
     overflow: auto;
     box-sizing: border-box;
-    padding: 32rpx 0;
   }
 
   .income-card {
@@ -276,6 +275,7 @@ function goDetails(item) {
     border-radius: 32rpx;
     padding: 32rpx 32rpx 0 32rpx;
     margin: 0 32rpx;
+    flex: 1;
     .card-header {
       display: flex;
       justify-content: space-between;

+ 98 - 87
src/pages-C/my/myShare.vue

@@ -1,8 +1,8 @@
 <script setup lang="ts">
 import { ref } from "vue";
-import { safeAreaInsets, menuButtonInfo } from "@/utils";
-import CustomNavigationBar from "@/components/CustomNavigationBar.vue";
 import { getImageUrl } from "@/utils/imageUtil";
+import LsvList from "@/components/listScrollView/index.vue";
+import { getProfitList } from "@/api/my";
 
 definePage({
   style: {
@@ -13,37 +13,6 @@ definePage({
 
 const totalIncome = ref("38.00");
 
-const shareList = ref([
-  {
-    id: 1,
-    couponName: "某某某某某优惠券",
-    income: "2.00",
-    receiveTime: "2026-05-18 19:00:00",
-    receiver: "林雨欣",
-  },
-  {
-    id: 2,
-    couponName: "某某某某某优惠券",
-    income: "17.00",
-    receiveTime: "2026-05-18 19:00:00",
-    receiver: "吴雨桐",
-  },
-  {
-    id: 3,
-    couponName: "某某某某某优惠券",
-    income: "18.00",
-    receiveTime: "2026-05-18 19:00:00",
-    receiver: "周昭宁",
-  },
-  {
-    id: 4,
-    couponName: "某某某某某优惠券",
-    income: "8.00",
-    receiveTime: "2026-05-18 19:00:00",
-    receiver: "周宇轩",
-  },
-]);
-
 function handleViewDetail(item) {
   uni.showToast({
     title: `查看 ${item.couponName} 详情`,
@@ -53,30 +22,62 @@ function handleViewDetail(item) {
 
 // 定义tab列表
 const tabList = ref([
-  { label: "今天", value: "0" },
-  { label: "近30天", value: "1" },
+  { label: "今天", value: "1" },
+  { label: "近30天", value: "2" },
 ]);
 // 当前选中的tab
-const currentTab = ref("0");
+const currentTab = ref("1");
 
+const showPicker = ref(false);
+const defaultStart = ref();
+const defaultEnd = ref();
 // 点击tab事件
+const listRef = ref();
 const handleTabClick = (value) => {
   currentTab.value = value;
-  console.log("选中tab:", value);
+  reloadListRef();
 };
 
-const showPicker = ref(false);
-const defaultStart = "";
-const defaultEnd = "";
-
 const handleConfirm = (value: { startDate: string; endDate: string }) => {
-  console.log("选中的日期范围:", value);
-  // 处理业务逻辑
+  defaultStart.value = value.startDate;
+  defaultEnd.value = value.endDate;
+  reloadListRef();
+};
+
+const reloadListRef = (value) => {
+  listRef.value.reloadList({
+    startTime: defaultStart.value ? defaultStart.value + " 00:00:00" : "",
+    endTime: defaultEnd.value ? defaultEnd.value + " 23:59:59" : "",
+    timeType: currentTab.value,
+  });
 };
 
 const handleCancel = () => {
   console.log("取消选择");
 };
+
+const getCouponListApi = (params) => {
+  return getProfitList({
+    pageNo: params.pageNo,
+    pageSize: params.pageSize,
+    timeType: params.timeType ?? 1,
+    startTime: params.startTime || "",
+    endTime: params.endTime || "",
+  });
+};
+
+const totalAmount = ref();
+
+const afterFetch = (item) => {
+  totalAmount.value = item.totalAmount;
+};
+
+const dateRangeText = computed(() => {
+  if (defaultStart.value && defaultEnd.value) {
+    return `${defaultStart.value} - ${defaultEnd.value}`;
+  }
+  return "日期筛选";
+});
 </script>
 
 <template>
@@ -85,31 +86,32 @@ const handleCancel = () => {
       :title-style="{ fontWeight: 'bold', color: '#000' }" leftIconColor='#000'></u-navbar>
 
     <view class="share-info-content">
-      <view class="income-card" :style="{
+      <view>
+        <view class="income-card" :style="{
                     backgroundImage: `url(${getImageUrl('@img/me/share-bg.png')})`,
                     backgroundSize: 'cover',
                     backgroundRepeat: 'no-repeat',
                     backgroundPosition: 'center'
                 }">
-        <text class="income-label">分享累计收益(元)</text>
-        <text class="income-amount">3859.00</text>
-      </view>
+          <text class="income-label">分享累计收益(元)</text>
+          <text class="income-amount">{{totalAmount || 0}}</text>
+        </view>
 
-      <view class="filter-box">
-        <view class="filter-bar">
-          <view class="filter-tabs">
-            <view v-for="(item, index) in tabList" :key="index" class="filter-tab"
-              :class="{ active: currentTab === item.value }" @click="handleTabClick(item.value)">
-              <text class="tab-text">{{ item.label }}</text>
+        <view class="filter-box">
+          <view class="filter-bar">
+            <view class="filter-tabs">
+              <view v-for="(item, index) in tabList" :key="index" class="filter-tab"
+                :class="{ active: currentTab === item.value }" @click="handleTabClick(item.value)">
+                <text class="tab-text">{{ item.label }}</text>
+              </view>
             </view>
           </view>
-        </view>
-        <view class="income-line"></view>
-        <view class='income-select'>
-          <view class='income-time' @click='showPicker=true'>
-            <!-- <view class='income-time-name'>2026 05.10-2026 05.12 </view> -->
-            <view class='income-time-name'>日期筛选 </view>
-            <view class="caret" />
+          <view class="income-line"></view>
+          <view class='income-select'>
+            <view class='income-time' @click='showPicker=true'>
+              <view class='income-time-name'>{{dateRangeText}} </view>
+              <view class="caret" />
+            </view>
           </view>
         </view>
       </view>
@@ -126,36 +128,39 @@ const handleCancel = () => {
             </view>
           </view>
         </view>
-
-        <view class="records-list">
-          <view v-for="(item, index) in shareList" :key="item.id" class="record-item">
-            <view class="record-bottom">
-              <view class="info-row">
-                <text class="info-label">用户名称</text>
-                <view class="income-person">
-                  <u--image class='income-phone' :src="getImageUrl('@img/me/head.png')" width="42rpx" height="42rpx"
-                    shape="circle">
-                  </u--image>
-                  <view>林雨欣</view>
+        <LsvList ref="listRef" :api="getCouponListApi" key-name="detailList" @afterFetch='afterFetch'>
+          <template #list="{ data }">
+            <view class="records-list">
+              <view v-for="(item, index) in data" :key="item.id" class="record-item">
+                <view class="record-bottom">
+                  <view class="info-row">
+                    <text class="info-label">用户名称</text>
+                    <view class="income-person">
+                      <u--image class='income-phone' :src="item.receiveUserAvatar || getImageUrl('@img/me/head.png')"
+                        width="42rpx" height="42rpx" shape="circle">
+                      </u--image>
+                      <view>{{item.receiveUserName}}</view>
+                    </view>
+                  </view>
+                  <view class="info-row">
+                    <text class="info-label">获得佣金</text>
+                    <text class="income-value">¥{{ item.earnings }}</text>
+                  </view>
+                  <view class="info-row">
+                    <text class="info-label">联系方式</text>
+                    <text class="info-value">{{ item.receiveUserPhone }}</text>
+                  </view>
+                  <view class="info-row">
+                    <text class="info-label">邀请日期</text>
+                    <text class="info-value">{{ item.receiveTime }}</text>
+                  </view>
                 </view>
-              </view>
-              <view class="info-row">
-                <text class="info-label">获得佣金</text>
-                <text class="income-value">¥{{ item.income }}</text>
-              </view>
-              <view class="info-row">
-                <text class="info-label">联系方式</text>
-                <text class="info-value">{{ item.receiver }}</text>
-              </view>
-              <view class="info-row">
-                <text class="info-label">邀请日期</text>
-                <text class="info-value">{{ item.receiveTime }}</text>
+
+                <view v-if="index < data.length - 1" class="record-divider"></view>
               </view>
             </view>
-
-            <view v-if="index < shareList.length - 1" class="record-divider"></view>
-          </view>
-        </view>
+          </template>
+        </LsvList>
       </view>
     </view>
 
@@ -169,8 +174,13 @@ const handleCancel = () => {
 .share-info-container {
   min-height: 100vh;
   background: #f8f8fa;
+  display: flex;
+  flex-direction: column;
 
   .share-info-content {
+    flex: 1;
+    display: flex;
+    flex-direction: column;
     padding: 32rpx 0;
     overflow: auto;
     box-sizing: border-box;
@@ -278,6 +288,7 @@ const handleCancel = () => {
     border-radius: 32rpx;
     padding: 32rpx 32rpx 0 32rpx;
     margin: 0 32rpx;
+    flex: 1;
     .card-header {
       display: flex;
       justify-content: space-between;

+ 104 - 105
src/pages-C/my/myWriteOff.vue

@@ -1,8 +1,8 @@
 <script setup lang="ts">
-import { ref } from "vue";
-import { safeAreaInsets, menuButtonInfo } from "@/utils";
-import CustomNavigationBar from "@/components/CustomNavigationBar.vue";
+import { computed, ref } from "vue";
 import { getImageUrl } from "@/utils/imageUtil";
+import LsvList from "@/components/listScrollView/index.vue";
+import { getWriteOffIncomeList } from "@/api/my";
 
 definePage({
   style: {
@@ -11,72 +11,63 @@ definePage({
   },
 });
 
-const totalIncome = ref("38.00");
+const totalAmount = ref();
 
-const shareList = ref([
-  {
-    id: 1,
-    couponName: "某某某某某优惠券",
-    income: "2.00",
-    receiveTime: "2026-05-18 19:00:00",
-    receiver: "林雨欣",
-  },
-  {
-    id: 2,
-    couponName: "某某某某某优惠券",
-    income: "17.00",
-    receiveTime: "2026-05-18 19:00:00",
-    receiver: "吴雨桐",
-  },
-  {
-    id: 3,
-    couponName: "某某某某某优惠券",
-    income: "18.00",
-    receiveTime: "2026-05-18 19:00:00",
-    receiver: "周昭宁",
-  },
-  {
-    id: 4,
-    couponName: "某某某某某优惠券",
-    income: "8.00",
-    receiveTime: "2026-05-18 19:00:00",
-    receiver: "周宇轩",
-  },
+const tabList = ref([
+  { label: "今天", value: "1" },
+  { label: "近30天", value: "2" },
 ]);
+const currentTab = ref("1");
 
-function handleViewDetail(item) {
-  uni.showToast({
-    title: `查看 ${item.couponName} 详情`,
-    icon: "none",
-  });
-}
+const showPicker = ref(false);
+const defaultStart = ref();
+const defaultEnd = ref();
 
-// 定义tab列表
-const tabList = ref([
-  { label: "今天", value: "0" },
-  { label: "近30天", value: "1" },
-]);
-// 当前选中的tab
-const currentTab = ref("0");
+const listRef = ref();
 
-// 点击tab事件
 const handleTabClick = (value) => {
   currentTab.value = value;
-  console.log("选中tab:", value);
+  reloadListRef();
 };
 
-const showPicker = ref(false);
-const defaultStart = "";
-const defaultEnd = "";
-
 const handleConfirm = (value: { startDate: string; endDate: string }) => {
-  console.log("选中的日期范围:", value);
-  // 处理业务逻辑
+  defaultStart.value = value.startDate;
+  defaultEnd.value = value.endDate;
+  reloadListRef();
+};
+
+const reloadListRef = () => {
+  listRef.value.reloadList({
+    startTime: defaultStart.value ? defaultStart.value + " 00:00:00" : "",
+    endTime: defaultEnd.value ? defaultEnd.value + " 23:59:59" : "",
+    timeType: currentTab.value,
+  });
 };
 
 const handleCancel = () => {
   console.log("取消选择");
 };
+
+const getCouponListApi = (params) => {
+  return getWriteOffIncomeList({
+    pageNo: params.pageNo,
+    pageSize: params.pageSize,
+    timeType: params.timeType ?? 1,
+    startTime: params.startTime || "",
+    endTime: params.endTime || "",
+  });
+};
+
+const afterFetch = (item) => {
+  totalAmount.value = item.totalAmount;
+};
+
+const dateRangeText = computed(() => {
+  if (defaultStart.value && defaultEnd.value) {
+    return `${defaultStart.value} - ${defaultEnd.value}`;
+  }
+  return "日期筛选";
+});
 </script>
 
 <template>
@@ -92,7 +83,7 @@ const handleCancel = () => {
                     backgroundPosition: 'center'
                 }">
         <text class="income-label">核销累计收益(元)</text>
-        <text class="income-amount">3859.00</text>
+        <text class="income-amount">{{totalAmount || 0}}</text>
       </view>
 
       <view class="filter-box">
@@ -107,8 +98,7 @@ const handleCancel = () => {
         <view class="income-line"></view>
         <view class='income-select'>
           <view class='income-time' @click='showPicker=true'>
-            <!-- <view class='income-time-name'>2026 05.10-2026 05.12 </view> -->
-            <view class='income-time-name'>日期筛选 </view>
+            <view class='income-time-name'>{{ dateRangeText }}</view>
             <view class="caret" />
           </view>
         </view>
@@ -123,61 +113,64 @@ const handleCancel = () => {
             <text class="total-label">总收益</text>
             <view>
               <text class="total-symbol">¥</text>
-              <text class="total-amount">{{ totalIncome }}</text>
+              <text class="total-amount">{{ totalAmount || 0 }}</text>
             </view>
           </view>
         </view>
 
-        <view class="records-list">
-          <view v-for="(item, index) in shareList" :key="item.id" class="record-item">
-
-            <view class="record-bottom">
-              <view class="info-row">
-                <text class="info-label">优惠券名称</text>
-                <text class="info-value">¥{{ item.income }}</text>
-              </view>
-              <view class="info-row">
-                <text class="info-label">核销时间</text>
-                <text class="info-value">{{ item.receiver }}</text>
-              </view>
-              <view class="info-row">
-                <text class="info-label">核销用户</text>
-                <view class="income-person">
-                  <u--image class='income-phone' :src="getImageUrl('@img/me/head.png')" width="42rpx" height="42rpx"
-                    shape="circle">
-                  </u--image>
-                  <view>林雨欣</view>
+        <LsvList ref="listRef" :api="getCouponListApi" key-name="detailList" @afterFetch='afterFetch'>
+          <template #list="{ data }">
+            <view class="records-list">
+              <view v-for="(item, index) in data" :key="item.id" class="record-item">
+                <view class="record-bottom">
+                  <view class="info-row">
+                    <text class="info-label">优惠券名称</text>
+                    <text class="info-value">{{ item.couponName }}</text>
+                  </view>
+                  <view class="info-row">
+                    <text class="info-label">核销时间</text>
+                    <text class="info-value">{{ item.writeOffTime }}</text>
+                  </view>
+                  <view class="info-row">
+                    <text class="info-label">核销用户</text>
+                    <view class="income-person">
+                      <u--image class='income-phone' :src="item.writeOffUserUrl || getImageUrl('@img/me/head.png')" width="42rpx" height="42rpx"
+                        shape="circle">
+                      </u--image>
+                      <view>{{ item.writeOffUserNickName }}</view>
+                    </view>
+                  </view>
+                  <view class="info-row">
+                    <text class="info-label">联系方式</text>
+                    <text class="info-value">{{ item.writeOffUserPhone }}</text>
+                  </view>
+                  <view class="info-row">
+                    <text class="info-label">商品类目</text>
+                    <text class="info-value">{{ item.commodityCategory }}</text>
+                  </view>
+                  <view class="info-row">
+                    <text class="info-label">商品名称</text>
+                    <text class="info-value">{{ item.productName }}</text>
+                  </view>
+                  <view class="info-row">
+                    <text class="info-label">核销商家</text>
+                    <text class="info-value">{{ item.writeOffMerchant }}</text>
+                  </view>
+                  <view class="info-row">
+                    <text class="info-label">实付金额</text>
+                    <text class="info-value">¥{{ item.actualPaymentAmount }}</text>
+                  </view>
+                  <view class="info-row">
+                    <text class="info-label">获得佣金</text>
+                    <text class="income-value">¥{{ item.commission }}</text>
+                  </view>
                 </view>
-              </view>
-              <view class="info-row">
-                <text class="info-label">联系方式</text>
-                <text class="info-value">{{ item.receiveTime }}</text>
-              </view>
-              <view class="info-row">
-                <text class="info-label">核销类型</text>
-                <text class="info-value">{{ item.receiveTime }}</text>
-              </view>
-              <view class="info-row">
-                <text class="info-label">商品名称</text>
-                <text class="info-value">{{ item.receiveTime }}</text>
-              </view>
-              <view class="info-row">
-                <text class="info-label">核销商家</text>
-                <text class="info-value">{{ item.receiveTime }}</text>
-              </view>
-              <view class="info-row">
-                <text class="info-label">实付金额</text>
-                <text class="info-value">{{ item.receiveTime }}</text>
-              </view>
-              <view class="info-row">
-                <text class="info-label">获得佣金</text>
-                <text class="income-value">{{ item.receiveTime }}</text>
+
+                <view v-if="index < data.length - 1" class="record-divider"></view>
               </view>
             </view>
-
-            <view v-if="index < shareList.length - 1" class="record-divider"></view>
-          </view>
-        </view>
+          </template>
+        </LsvList>
       </view>
     </view>
 
@@ -191,8 +184,13 @@ const handleCancel = () => {
 .share-info-container {
   min-height: 100vh;
   background: #f8f8fa;
+  display: flex;
+  flex-direction: column;
 
   .share-info-content {
+    flex: 1;
+    display: flex;
+    flex-direction: column;
     padding: 32rpx 0;
   }
 
@@ -294,6 +292,7 @@ const handleCancel = () => {
     border-radius: 32rpx;
     padding: 32rpx 32rpx 0 32rpx;
     margin: 0 32rpx;
+    flex: 1;
     .card-header {
       display: flex;
       justify-content: space-between;

+ 27 - 10
src/pages-C/share/shareInfo.vue

@@ -1,5 +1,5 @@
 <script setup lang="ts">
-import { onLoad } from '@dcloudio/uni-app'
+import { onLoad } from "@dcloudio/uni-app";
 import { ref } from "vue";
 import { getImageUrl } from "@/utils/imageUtil";
 import Upopup from "@/components/popup/index.vue";
@@ -7,13 +7,14 @@ import StarRating from "@/components/start/start.vue";
 import { storeToRefs } from "pinia";
 import { useTokenStore } from "@/store/token";
 import { toLoginPage } from "@/utils/toLoginPage";
+import { useCouponShare } from '@/hooks/useCouponShare'
 
 const tokenStore = useTokenStore();
 const { hasLogin } = storeToRefs(tokenStore);
 
 // 接收分享卡片传入的参数
 onLoad((options: any) => {
-  console.log('onLoad options:', options);
+  console.log("onLoad options:", options);
   // 例如:options.couponId, options.from 等
 });
 definePage({
@@ -57,15 +58,15 @@ const shopShow = ref(false);
 function navigateToMiniProgram() {
   // #ifdef MP-WEIXIN
   uni.navigateToMiniProgram({
-    appId: 'wxab9634bf98628a03',   // TODO: 替换为目标小程序的 AppId
-    path: 'pages/home/home',                     // TODO: 替换为目标小程序的页面路径
-    envVersion: 'trial',
+    appId: "wxab9634bf98628a03", // TODO: 替换为目标小程序的 AppId
+    path: "pages/home/home", // TODO: 替换为目标小程序的页面路径
+    envVersion: "trial",
     success: () => {
-      console.log('跳转其他小程序成功');
+      console.log("跳转其他小程序成功");
     },
     fail: (err) => {
-      console.error('跳转失败', JSON.stringify(err));
-      uni.showToast({ title: err.errMsg || '跳转失败', icon: 'none' });
+      console.error("跳转失败", JSON.stringify(err));
+      uni.showToast({ title: err.errMsg || "跳转失败", icon: "none" });
     },
   });
   // #endif
@@ -84,6 +85,22 @@ function receive() {
   // 已登录 → 跳转其他小程序领券
   navigateToMiniProgram();
 }
+
+const { shareCoupon, ...shareHooks } = useCouponShare()
+function clickShare() {
+  try {
+    // const shareLink = await shareCoupon(couponTemplateId.value);
+    // if (shareLink) {
+    //   couponShareLink.value = shareLink;
+    //   showShareModal.value = true;
+    //   if (props.enableCustomShare) {
+    //     emit("shareClick", couponShareLink.value, shareHooks);
+    //   }
+    // }
+  } finally {
+    // uni.hideLoading()
+  }
+}
 </script>
 
 <template>
@@ -267,8 +284,8 @@ function receive() {
     </view>
 
     <view class="share-info">
-      <!-- <view class="share-btn">去分享</view> -->
-      <view class="share-btn" @click='receive'>去领取</view>
+      <view class="share-btn" @click='clickShare'>去分享</view>
+      <!-- <view class="share-btn" @click='receive'>去领取</view> -->
     </view>
   </view>
 

+ 32 - 15
src/pages/income/income.vue

@@ -9,6 +9,12 @@ import { getImageUrl } from "@/utils/imageUtil";
 import Classification from "./classification.vue";
 import Upopup from "@/components/popup/index.vue";
 import DateRangePicker from "@/components/dateRangePicker/index.vue";
+import {
+  usePagination,
+  useRequest,
+  actionDelegationMiddleware,
+} from "alova/client";
+import { getCategoryList } from "@/api/home";
 
 definePage({
   style: {
@@ -126,16 +132,10 @@ const tabs = ref([
 function tabClick(index) {
   tabsIndex.value = index;
 }
-const rewardTabs = ref([
-  { label: "全部", type: "0" },
-  { label: "分享奖励", type: "1" },
-  { label: "核销奖励", type: "2" },
-  { label: "邀新奖励", type: "3" },
-]);
 
 const settlementTabs = ref([
-  { label: "待结算", type: "1" },
-  { label: "已结算", type: "2" },
+  { name: "待结算", value: "1" },
+  { name: "已结算", value: "2" },
 ]);
 
 function classClick(e, item, tabName) {
@@ -166,15 +166,29 @@ const openPicker = () => {
 const showPicker = ref(false);
 const defaultStart = "";
 const defaultEnd = "";
-
+const dateValue = ref();
 const handleConfirm = (value: { startDate: string; endDate: string }) => {
   console.log("选中的日期范围:", value);
+  dateValue.value = `${value.startDate} - ${value.endDate}`;
+
   // 处理业务逻辑
 };
 
 const handleCancel = () => {
   console.log("取消选择");
 };
+
+const {
+  send: sendCategoryList,
+  data: categoryList,
+  loading: categoryLoading,
+} = useRequest(getCategoryList, {
+  immediate: false,
+});
+
+onShow(async () => {
+  await sendCategoryList();
+});
 </script>
 
 <template>
@@ -230,17 +244,17 @@ const handleCancel = () => {
           <view class="stat-divider"></view>
         </view>
         <view class='income-time' @click='showPicker=true'>
-          <view class='income-time-name'>日期筛选 </view>
+          <view class='income-time-name'>{{dateValue?dateValue:'日期筛选'}} </view>
           <text class="caret" />
           <view class="stat-divider"></view>
         </view>
         <view class='income-time' @click='showMap.type=true'>
-          <view class='income-time-name'>{{classItem.type.label?classItem.type.label:'选择分类'}} </view>
+          <view class='income-time-name'>{{classItem.type.name?classItem.type.name:'选择分类'}} </view>
           <text class="caret" />
           <view class="stat-divider"></view>
         </view>
         <view class='income-time' @click='showMap.set=true'>
-          <view class='income-time-name'>{{classItem.set.label?classItem.set.label:'结算状态'}} </view>
+          <view class='income-time-name'>{{classItem.set.name?classItem.set.name:'结算状态'}} </view>
           <text class="caret" />
         </view>
       </view>
@@ -291,9 +305,9 @@ const handleCancel = () => {
   <!-- 选择分类 -->
   <Upopup :isShow="showMap.type" title='选择分类' @close='showMap.type=false' :isFooter='false'>
     <view class="classification-cont">
-      <view class='classification-list' v-for='(item,index) in rewardTabs' :key='index'
+      <view class='classification-list' v-for='(item,index) in categoryList' :key='index'
         @click='classClick(index,item,"type")'>
-        <view class='classification-label'>{{ item.label }}</view>
+        <view class='classification-label' :class='{active:indexMap.type==index}'>{{ item.name }}</view>
         <u--image class='selected-icon' v-show='indexMap.type==index' :src="getImageUrl('@img/income/selected.png')"
           mode="aspectFit" width="32rpx" height="32rpx">
         </u--image>
@@ -306,7 +320,7 @@ const handleCancel = () => {
     <view class="classification-cont">
       <view class='classification-list' v-for='(item,index) in settlementTabs' :key='index'
         @click='classClick(index,item,"set")'>
-        <view class='classification-label'>{{ item.label }}</view>
+        <view class='classification-label' :class='{active:indexMap.set==index}'>{{ item.name }}</view>
         <u--image class='selected-icon' v-show='indexMap.set==index' :src="getImageUrl('@img/income/selected.png')"
           mode="aspectFit" width="32rpx" height="32rpx">
         </u--image>
@@ -650,5 +664,8 @@ const handleCancel = () => {
     font-size: 26rpx;
     padding-bottom: 32rpx;
   }
+  .active{
+    color:#FF536B;
+  }
 }
 </style>

+ 19 - 50
src/pages/my/my.vue

@@ -9,6 +9,7 @@ import { useInviterStore } from "@/store/inviter";
 import { useTokenStore } from "@/store/token";
 
 import { getCouponSituation } from "@/api/home";
+import { getMyDataStatistics } from "@/api/my";
 
 definePage({
   style: {
@@ -32,7 +33,7 @@ onPageScroll((e) => {
 
 const form = ref({});
 const visibleNoticeList = computed(() => {
-  const data = form.value || {};
+  const data = dataStatistics.value || {};
   return [
     {
       title: "分享收益(元)",
@@ -41,74 +42,32 @@ const visibleNoticeList = computed(() => {
     },
     {
       title: "邀新收益(元)",
-      content: data.totalWithdraw || 0,
+      content: data.inviteNewIncome || 0,
       page: "/pages-C/my/myNewUsers",
     },
     {
       title: "核销收益(元)",
-      content: data.bankCards || 0,
+      content: data.writeOffIncome || 0,
       page: "/pages-C/my/myWriteOff",
     },
     {
       title: "团队收益(元)",
-      content: data.inviteIncome || 0,
+      content: data.memberIncome || 0,
       page: "/pages-C/my/myGroup",
     },
   ];
 });
 
-const inviteStatsList = computed(() => {
-  const data = form.value || {};
-  return [
-    {
-      title: "今日邀请",
-      content: data.totalIncome || 0,
-      page: "/pages-C/my/myTodayInvitation",
-    },
-    {
-      title: "累计邀请",
-      content: data.totalWithdraw || 0,
-      page: "/pages-C/my/myCumulativeGroup",
-    },
-    {
-      title: "累计团员",
-      content: data.bankCards || 0,
-      page: "/pages-C/my/myCumulativeInvitation",
-    },
-  ];
-});
 
-const inviteLineList = computed(() => {
-  const data = form.value || {};
-  return [
-    {
-      title: "累计发券",
-      content: data.totalIncome || 0,
-      page: "/pages-C/my/sendCoupon",
-    },
-    {
-      title: "累计核销",
-      content: data.totalWithdraw || 0,
-      page: "/pages-C/my/sendWriteOff",
-    },
-    {
-      title: "累计未核销",
-      content: data.bankCards || 0,
-      page: "/pages-C/my/sendCancelWriteOff",
-    },
-    {
-      title: "累计领取人数",
-      content: data.bankCards || 0,
-      page: "/pages-C/my/sendRecipientsNumber",
-    },
-  ];
-});
 
 onLoad(async () => {
   // 登录后查询收益数据
   if (hasLogin.value) {
     await getCouponSituationRequest({ queryType: "time" });
     deadline.value = Date.now();
+
+    //我的统计
+    await getMyData();
   }
 });
 
@@ -120,6 +79,16 @@ onShow(async () => {
   }
 });
 
+ //我的统计
+const {
+  send: getMyData,
+  data: dataStatistics,
+  loading:statisticsLoading ,
+} = useRequest(getMyDataStatistics, {
+  immediate: false,
+  middleware: delayLoadingMiddleware(0, 500),
+});
+
 // 用户优惠券统计数据
 const {
   send: getCouponSituationRequest,
@@ -228,7 +197,7 @@ function listInfo(item) {
       <view class="stats-card">
         <view class="stats-main">
           <text class="stats-label">累计收益(元)</text>
-          <text class="stats-value">222</text>
+          <text class="stats-value">{{ dataStatistics?.cumulativeIncome || 0 }}</text>
         </view>
         <view class="stats-grid">
           <view v-for="(item, index) in visibleNoticeList" :key="index" class="stats-item" @click='listInfo(item)'>