3 コミット f7bc35186a ... 9ced072dbf

作者 SHA1 メッセージ 日付
  caojp 9ced072dbf 浏览器标签页的标题栏区域进行修改 2 週間 前
  李思佳 639bd1a938 Merge branch 'test_dev' into lisijia 3 週間 前
  李思佳 3d41715eb9 feat(matchmaker): 实现红娘签到信息获取与展示功能 3 週間 前

+ 28 - 67
LiangZhiYUMao/pages/matchmaker-workbench/mine.vue

@@ -394,6 +394,15 @@ export default {
         // 获取签到统计
         const stats = await api.matchmaker.checkinStats(makerId)
         console.log('获取签到统计返回结果:', stats)
+        
+        // 获取当前年月
+        const today = new Date()
+        const year = today.getFullYear()
+        const month = today.getMonth() + 1
+        
+        // 获取本月所有签到日期
+        const checkinInfo = await api.matchmaker.checkinInfo(makerId, year, month)
+        console.log('获取签到信息返回结果:', checkinInfo)
 
         // 初始化签到记录数组
         this.signedDays = []
@@ -401,75 +410,27 @@ export default {
         if (stats) {
           this.continuousDays = stats.continuousDays || 0
           this.totalDays = stats.totalDays || 0
-
-          // 检查stats中是否包含本月的签到记录
+          
+          // 从checkinInfo中获取已签到日期列表
           let signedDays = []
-
-          // 情况1: stats直接包含signedDays数组
-          if (stats.signedDays && Array.isArray(stats.signedDays)) {
-            signedDays = stats.signedDays
-          }
-          // 情况2: stats.data包含signedDays数组
-          else if (stats.data && stats.data.signedDays && Array.isArray(stats.data.signedDays)) {
-            signedDays = stats.data.signedDays
-          }
-          // 情况3: stats是对象,直接包含日期属性
-          else if (typeof stats === 'object') {
-            // 处理stats对象
-            const processStats = (obj) => {
-              const days = []
-              // 遍历对象,寻找日期相关的属性
-              for (const key in obj) {
-                if (obj.hasOwnProperty(key)) {
-                  // 检查是否是日期相关的属性
-                  const value = obj[key]
-                  // 检查是否是日期格式
-                  if (typeof value === 'object' && value !== null && typeof value.isChecked === 'boolean') {
-                    // 如果是包含isChecked属性的对象,且isChecked为true
-                    if (value.isChecked && typeof value.date === 'number') {
-                      days.push(value.date)
-                    }
-                  }
-                }
-              }
-              return days
-            }
-
-            // 先处理stats对象本身
-            signedDays = processStats(stats)
-
-            // 如果stats.data存在,也处理一下
-            if (stats.data && typeof stats.data === 'object') {
-              signedDays = [...signedDays, ...processStats(stats.data)]
-            }
-          }
-
-          // 检查签到状态响应中是否包含签到记录
-          if (signedDays.length === 0 && res && typeof res === 'object') {
-            const processRes = (obj) => {
-              const days = []
-              if (obj.signedDays && Array.isArray(obj.signedDays)) {
-                days.push(...obj.signedDays)
-              }
-              return days
-            }
-
-            signedDays = processRes(res)
-
-            if (res.data && typeof res.data === 'object') {
-              signedDays = [...signedDays, ...processRes(res.data)]
-            }
+          if (checkinInfo && checkinInfo.checkedDates) {
+            // 将日期字符串转换为日期的日部分(数字)
+            signedDays = checkinInfo.checkedDates.map(dateStr => {
+              const date = new Date(dateStr)
+              return date.getDate()
+            })
           }
 
           // 检查今日是否已签到,如果已签到但不在signedDays中,添加进去
-          const today = new Date().getDate()
-          if (this.isSignedToday && !signedDays.includes(today)) {
-            signedDays.push(today)
+          const todayDate = today.getDate()
+          if (this.isSignedToday && !signedDays.includes(todayDate)) {
+            signedDays.push(todayDate)
           }
 
           // 去重并排序
           this.signedDays = [...new Set(signedDays)].sort((a, b) => a - b)
         }
+        console.log('最终的signedDays:', this.signedDays)
 
         console.log('最终的signedDays:', this.signedDays)
       } catch (error) {
@@ -1212,19 +1173,19 @@ export default {
           }
 
           &.today {
-            background: #FFF3E0;
-            color: #FF9800;
+            background: #E1BEE7;
+            color: #6A1B9A;
             font-weight: bold;
           }
 
           &.checked {
-            background: #FFCDD2;
-            color: #E91E63;
+            background: #F3E5F5;
+            color: #9C27B0;
             font-weight: bold;
           }
 
           &.today-checked {
-            background: #E91E63;
+            background: #9C27B0;
             color: #FFFFFF;
             font-weight: bold;
           }
@@ -1235,7 +1196,7 @@ export default {
             right: 5rpx;
             font-size: 18rpx;
             color: #FFFFFF;
-            background: #E91E63;
+            background: #9C27B0;
             border-radius: 50%;
             width: 24rpx;
             height: 24rpx;
@@ -1246,7 +1207,7 @@ export default {
 
           .today-checked .check-mark {
             background: #FFFFFF;
-            color: #E91E63;
+            color: #9C27B0;
           }
         }
       }

+ 20 - 3
LiangZhiYUMao/pages/matchmaker-workbench/sign-in.vue

@@ -12,13 +12,13 @@
 		<scroll-view scroll-y class="content">
 			<!-- 签到日历标题 -->
 			<view class="calendar-header">
-				<text class="calendar-title">11月签到日历</text>
+				<text class="calendar-title">{{ currentMonthText }}签到日历</text>
 				<text class="calendar-subtitle">红线相系,良缘成就一生欢喜。</text>
 			</view>
 
 			<!-- 月份选择 -->
 			<view class="month-selector">
-				<text class="month-text">2025年 11月</text>
+				<text class="month-text">{{ currentMonthText }}</text>
 				<view class="streak-badge">
 					<text class="streak-text">红线季良缘</text>
 				</view>
@@ -173,31 +173,43 @@ export default {
 				
 				// 获取本月所有签到日期
 				const checkinInfoRes = await api.matchmaker.checkinInfo(this.makerId, this.currentYear, this.currentMonth)
+				console.log('签到信息API响应:', JSON.stringify(checkinInfoRes, null, 2))
 				let checkinInfo = checkinInfoRes
 				if (checkinInfoRes && checkinInfoRes.data) {
 					checkinInfo = checkinInfoRes.data
 				}
+				console.log('处理后的签到信息:', JSON.stringify(checkinInfo, null, 2))
 				
 				// 获取已签到日期列表
 				this.signedDates = checkinInfo.checkedDates || []
+				console.log('已签到日期列表:', JSON.stringify(this.signedDates, null, 2))
+				console.log('已签到日期数量:', this.signedDates.length)
 				
 				// 检查今日签到状态
 				const statusRes = await api.matchmaker.checkinStatus(this.makerId)
+				console.log('签到状态API响应:', statusRes)
 				let statusData = statusRes
 				if (statusRes && statusRes.data !== undefined) {
 					statusData = statusRes.data
 				}
 				this.isSigned = statusData === true || statusData?.isCheckedIn === true || statusData?.checked === true
+				console.log('今日签到状态:', this.isSigned)
+				
+				// 更新日历,显示所有已签到日期
+				this.generateCalendar()
 			} catch (e) {
 				console.error('加载签到数据失败:', e)
 			}
 		},
 		generateCalendar() {
+			console.log('开始生成日历,已签到日期:', this.signedDates)
 			const year = this.currentYear
 			const month = this.currentMonth
+			console.log('当前年月:', year, month)
 			
 			// 更新月份显示文本
 			this.currentMonthText = `${year}年${month}月`
+			console.log('月份显示文本:', this.currentMonthText)
 			
 			// 获取当月第一天是星期几
 			const firstDay = new Date(year, month - 1, 1).getDay()
@@ -205,10 +217,12 @@ export default {
 			const daysInMonth = new Date(year, month, 0).getDate()
 			// 获取上月天数
 			const prevMonthDays = new Date(year, month - 1, 0).getDate()
+			console.log('日历参数: 第一天星期几:', firstDay, '当月天数:', daysInMonth, '上月天数:', prevMonthDays)
 			
 			// 获取今天的日期字符串
 			const today = new Date()
 			const todayStr = this.formatDate(today)
+			console.log('今天日期:', todayStr)
 			
 			const days = []
 			
@@ -227,11 +241,13 @@ export default {
 				const date = new Date(year, month - 1, i)
 				const dateStr = this.formatDate(date)
 				const isToday = dateStr === todayStr
+				const isSigned = this.signedDates.includes(dateStr)
+				console.log('生成日期:', dateStr, '是否已签到:', isSigned, '是否今天:', isToday)
 				
 				days.push({
 					day: i,
 					isOtherMonth: false,
-					isSigned: this.signedDates.includes(dateStr),
+					isSigned: isSigned,
 					isToday: isToday
 				})
 			}
@@ -248,6 +264,7 @@ export default {
 			}
 			
 			this.calendarDays = days
+			console.log('生成的日历数据:', this.calendarDays)
 		},
 		// 格式化日期为YYYY-MM-DD
 		formatDate(date) {

+ 101 - 82
LiangZhiYUMao/pages/mine/index.vue

@@ -244,6 +244,8 @@
 </template>
 
 <script>
+import api from '@/utils/api.js'
+
 export default {
   data() {
     return {
@@ -671,48 +673,64 @@ export default {
     },
 
     // 加载签到信息
-    loadCheckinInfo() {
+    async loadCheckinInfo() {
       // 确保有用户ID
       if (!this.userInfo.userId) {
         console.error('用户ID不存在,无法加载签到信息')
         return
       }
 
-      uni.request({
-        url: this.gatewayURL + '/api/checkin/info',
-        method: 'GET',
-        data: {
-          userId: this.userInfo.userId
-        },
-        success: (res) => {
-          console.log('签到信息:', res.data)
-
-          if (res.data.code === 200) {
-            const data = res.data.data
-
-            // 更新签到数据
-            this.checkinData = {
-              continuousDays: data.continuousDays,
-              totalDays: data.totalDays,
-              todayChecked: data.todayChecked,
-              checkedDates: data.checkedDates
-            }
-
-            // 更新奖励列表
-            this.checkinRewards = data.rewards
-
-            // 生成日历
-            this.generateCalendarFromBackend(data.checkedDates)
+      try {
+        // 检查用户是否为红娘
+        const matchmakerStatusRes = await api.user.getMatchmakerStatus(this.userInfo.userId)
+        console.log('用户红娘状态:', matchmakerStatusRes)
+        
+        if (matchmakerStatusRes && matchmakerStatusRes.isMatchmaker) {
+          // 是红娘,使用红娘签到接口
+          console.log('用户是红娘,使用红娘签到接口')
+          
+          // 获取当前年月
+          const today = new Date()
+          const year = today.getFullYear()
+          const month = today.getMonth() + 1
+          
+          // 调用红娘签到信息接口
+          const checkinInfoRes = await api.matchmaker.checkinInfo(
+            matchmakerStatusRes.matchmakerId, 
+            year, 
+            month
+          )
+          
+          console.log('红娘签到信息:', checkinInfoRes)
+          
+          // 更新签到数据
+          this.checkinData = {
+            continuousDays: checkinInfoRes.continuousDays,
+            totalDays: checkinInfoRes.totalDays,
+            todayChecked: checkinInfoRes.todayChecked,
+            checkedDates: checkinInfoRes.checkedDates
           }
-        },
-        fail: (err) => {
-          console.error('获取签到信息失败:', err)
-          uni.showToast({
-            title: '加载签到信息失败',
-            icon: 'none'
-          })
+          
+          // 生成日历
+          this.generateCalendarFromBackend(checkinInfoRes.checkedDates)
+          
+          // 简单的奖励列表
+          this.checkinRewards = [
+            { day: 7, icon: '👑', reward: '积分+10', received: checkinInfoRes.continuousDays >= 7, isCurrent: checkinInfoRes.continuousDays < 7 },
+            { day: 14, icon: '💎', reward: '积分+20', received: checkinInfoRes.continuousDays >= 14, isCurrent: checkinInfoRes.continuousDays >= 7 && checkinInfoRes.continuousDays < 14 },
+            { day: 30, icon: '🏆', reward: '积分+50', received: checkinInfoRes.continuousDays >= 30, isCurrent: checkinInfoRes.continuousDays >= 14 && checkinInfoRes.continuousDays < 30 }
+          ]
+        } else {
+          // 不是红娘,普通用户签到功能暂未实现
+          console.log('用户不是红娘,普通用户签到功能暂未实现')
         }
-      })
+      } catch (err) {
+        console.error('加载签到信息失败:', err)
+        uni.showToast({
+          title: '加载签到信息失败',
+          icon: 'none'
+        })
+      }
     },
 
     // 根据后端数据生成日历(修复版本)
@@ -781,7 +799,7 @@ export default {
       this.$refs.checkinPopup.close()
     },
     // 处理签到(通过网关)
-    handleCheckin() {
+    async handleCheckin() {
       if (this.checkinData.todayChecked) {
         uni.showToast({
           title: '今日已签到',
@@ -792,61 +810,62 @@ export default {
 
       // 确保有用户ID
       if (!this.userInfo.userId) {
-        uni.showToast({
-          title: '请先登录',
-          icon: 'none'
-        })
+        uni.showToast({ title: '请先登录', icon: 'none' })
         return
       }
 
-      // 调用后端签到接口(通过网关)
-      uni.request({
-        url: this.gatewayURL + '/api/checkin/sign?userId=' + this.userInfo.userId,
-        method: 'POST',
-        success: (res) => {
-          console.log('签到结果:', res.data)
-
-          if (res.data.code === 200) {
-            // 显示签到成功提示
-            uni.showToast({
-              title: res.data.message,
-              icon: 'success',
-              duration: 2500
-            })
-
-            const data = res.data.data
-
-            // 更新签到数据
-            this.checkinData = {
-              continuousDays: data.continuousDays,
-              totalDays: data.totalDays,
-              todayChecked: data.todayChecked,
-              checkedDates: data.checkedDates
-            }
-
-            // 更新奖励列表
-            this.checkinRewards = data.rewards
-
-            // 重新生成日历
-            this.generateCalendarFromBackend(data.checkedDates)
-
-          } else {
-            // 签到失败
-            uni.showToast({
-              title: res.data.message,
-              icon: 'none',
-              duration: 2000
-            })
+      try {
+        // 检查用户是否为红娘
+        const matchmakerStatusRes = await api.user.getMatchmakerStatus(this.userInfo.userId)
+        console.log('用户红娘状态:', matchmakerStatusRes)
+        
+        if (matchmakerStatusRes && matchmakerStatusRes.isMatchmaker) {
+          // 是红娘,使用红娘签到接口
+          console.log('用户是红娘,使用红娘签到接口')
+          
+          // 调用红娘签到接口
+          const signRes = await api.matchmaker.doCheckin(matchmakerStatusRes.matchmakerId)
+          
+          // 签到成功后更新状态
+          this.checkinData.todayChecked = true
+          this.checkinData.totalDays++
+          this.checkinData.continuousDays++
+          
+          // 获取当前日期字符串
+          const today = new Date()
+          const todayStr = this.formatDate(today)
+          
+          // 更新签到日期列表
+          if (!this.checkinData.checkedDates.includes(todayStr)) {
+            this.checkinData.checkedDates.push(todayStr)
           }
-        },
-        fail: (err) => {
-          console.error('签到失败:', err)
+          
+          // 重新生成日历
+          this.generateCalendarFromBackend(this.checkinData.checkedDates)
+          
           uni.showToast({
-            title: '签到失败,请稍后重试',
+            title: '签到成功 +5积分',
+            icon: 'success',
+            duration: 2500
+          })
+          
+          // 重新加载签到信息,确保数据最新
+          await this.loadCheckinInfo()
+        } else {
+          // 不是红娘,普通用户签到功能暂未实现
+          console.log('用户不是红娘,普通用户签到功能暂未实现')
+          uni.showToast({
+            title: '功能开发中,敬请期待',
             icon: 'none'
           })
         }
-      })
+      } catch (err) {
+        console.error('签到失败:', err)
+        uni.showToast({
+          title: err.message || '签到失败,请稍后重试',
+          icon: 'none'
+        })
+      }
     },
     goVerify() {
       uni.showToast({

+ 5 - 0
LiangZhiYUMao/utils/api.js

@@ -487,6 +487,11 @@ export default {
             url: `/matchmaker/checkin/do?makerId=${makerId}`, 
             method: 'POST' 
         }),
+        
+        // 获取签到信息,包括当月已签到日期
+        checkinInfo: (makerId, year, month) => request({ 
+            url: `/matchmaker/checkin/info?makerId=${makerId}&year=${year}&month=${month}` 
+        }),
 
         // 更新红娘资料(编辑资料页使用)
         updateProfile: (matchmakerId, data) => request({

+ 1 - 1
marriageAdmin-vue/index.html

@@ -2,7 +2,7 @@
 <html lang="">
   <head>
     <meta charset="UTF-8">
-    <link rel="icon" href="/favicon.ico">
+    <link rel="icon" type="image/png" href="/src/assets/qingluan.png">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>Vite App</title>
   </head>

+ 50 - 0
service/homePage/src/main/java/com/zhentao/controller/MatchmakerCheckinController.java

@@ -6,6 +6,7 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
 /**
@@ -116,4 +117,53 @@ public class MatchmakerCheckinController {
             return errorResult;
         }
     }
+
+    /**
+     * 获取签到信息,包括当月已签到日期
+     *
+     * @param makerId 用户ID(兼容旧参数名)
+     * @param userId 用户ID
+     * @param year 年份
+     * @param month 月份
+     * @return 签到信息
+     */
+    @GetMapping("/info")
+    public Result<Map<String, Object>> getCheckinInfo(@RequestParam(required = false) Long makerId, 
+                                                    @RequestParam(required = false) Long userId, 
+                                                    @RequestParam Integer year, 
+                                                    @RequestParam Integer month) {
+        try {
+            // 优先使用 userId,如果没有则使用 makerId(兼容旧参数名)
+            Long finalUserId = userId != null ? userId : makerId;
+            System.out.println("📥 接收到签到信息请求: finalUserId=" + finalUserId + ", year=" + year + ", month=" + month);
+
+            // 获取已签到日期列表
+            List<String> checkedDates = matchmakerCheckinService.getCheckedDates(finalUserId, year, month);
+            
+            // 获取签到统计信息
+            Integer continuousDays = matchmakerCheckinService.getContinuousDays(finalUserId);
+            Integer totalDays = matchmakerCheckinService.getTotalDays(finalUserId);
+            boolean isCheckedIn = matchmakerCheckinService.isCheckedIn(finalUserId);
+
+            // 构建返回数据
+            Map<String, Object> data = new HashMap<>();
+            data.put("continuousDays", continuousDays);
+            data.put("totalDays", totalDays);
+            data.put("todayChecked", isCheckedIn);
+            data.put("checkedDates", checkedDates);
+
+            Result<Map<String, Object>> infoResult = new Result<>();
+            infoResult.setCode(200);
+            infoResult.setMsg("查询成功");
+            infoResult.setData(data);
+            return infoResult;
+        } catch (Exception e) {
+            e.printStackTrace();
+            Result<Map<String, Object>> errorResult = new Result<>();
+            errorResult.setCode(500);
+            errorResult.setMsg("获取签到信息失败:" + e.getMessage());
+            errorResult.setData(null);
+            return errorResult;
+        }
+    }
 }

+ 11 - 0
service/homePage/src/main/java/com/zhentao/mapper/MatchmakerCheckinMapper.java

@@ -6,6 +6,7 @@ import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
 
 import java.time.LocalDate;
+import java.util.List;
 
 /**
  * 红娘签到记录Mapper
@@ -40,4 +41,14 @@ public interface MatchmakerCheckinMapper extends BaseMapper<MatchmakerCheckin> {
      * @return 累计签到天数
      */
     Integer selectTotalDaysByMakerId(@Param("makerId") Long makerId);
+
+    /**
+     * 查询红娘在指定年月的已签到日期列表
+     *
+     * @param makerId 红娘ID
+     * @param year    年份
+     * @param month   月份
+     * @return 已签到日期列表,格式:YYYY-MM-DD
+     */
+    List<String> selectCheckedDatesByMakerIdAndMonth(@Param("makerId") Long makerId, @Param("year") Integer year, @Param("month") Integer month);
 }

+ 16 - 9
service/homePage/src/main/java/com/zhentao/service/MatchmakerCheckinService.java

@@ -3,43 +3,50 @@ package com.zhentao.service;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.zhentao.entity.MatchmakerCheckin;
 
+import java.time.LocalDate;
+import java.util.List;
+
 /**
- * 红娘签到记录Service
+ * 红娘签到记录服务接口
  *
  * @author zhentao
  * @since 2025-12-10
  */
 public interface MatchmakerCheckinService extends IService<MatchmakerCheckin> {
-
     /**
      * 执行红娘签到
-     *
      * @param makerId 红娘ID
      * @return 签到结果
      */
     boolean checkin(Long makerId);
-
+    
     /**
      * 检查红娘是否已经签到
-     *
      * @param makerId 红娘ID
      * @return 是否已签到
      */
     boolean isCheckedIn(Long makerId);
-
+    
     /**
      * 获取红娘的累计签到天数
-     *
      * @param makerId 红娘ID
      * @return 累计签到天数
      */
     Integer getTotalDays(Long makerId);
-
+    
     /**
      * 获取红娘的连续签到天数
-     *
      * @param makerId 红娘ID
      * @return 连续签到天数
      */
     Integer getContinuousDays(Long makerId);
+    
+    /**
+     * 获取红娘当月已签到日期列表
+     * @param makerId 红娘ID
+     * @param year 年份
+     * @param month 月份
+     * @return 已签到日期列表
+     */
+    List<String> getCheckedDates(Long makerId, Integer year, Integer month);
 }

+ 24 - 0
service/homePage/src/main/java/com/zhentao/service/impl/MatchmakerCheckinServiceImpl.java

@@ -13,6 +13,8 @@ import org.springframework.transaction.annotation.Transactional;
 
 import java.time.LocalDate;
 import java.time.temporal.ChronoUnit;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * 红娘签到记录Service实现类
@@ -169,4 +171,26 @@ public class MatchmakerCheckinServiceImpl extends ServiceImpl<MatchmakerCheckinM
         
         return 0;
     }
+
+    @Override
+    public List<String> getCheckedDates(Long idParam, Integer year, Integer month) {
+        // idParam 可能是 userId 或 matchmakerId,需要兼容处理
+        Long matchmakerId = idParam;
+        
+        // 先尝试直接用 idParam 作为 matchmakerId 查询
+        List<String> checkedDates = matchmakerCheckinMapper.selectCheckedDatesByMakerIdAndMonth(idParam, year, month);
+        if (checkedDates != null && !checkedDates.isEmpty()) {
+            return checkedDates;
+        }
+        
+        // 如果没找到,尝试把 idParam 当作 userId 来查询 matchmaker
+        MatchmakerVO matchmaker = matchmakerService.getMatchmakerByUserId(idParam);
+        if (matchmaker != null && matchmaker.getMatchmakerId() != null) {
+            matchmakerId = matchmaker.getMatchmakerId().longValue();
+            checkedDates = matchmakerCheckinMapper.selectCheckedDatesByMakerIdAndMonth(matchmakerId, year, month);
+            return checkedDates != null ? checkedDates : new ArrayList<>();
+        }
+        
+        return new ArrayList<>();
+    }
 }

+ 9 - 0
service/homePage/src/main/resources/mapper/MatchmakerCheckinMapper.xml

@@ -23,4 +23,13 @@
         WHERE maker_id = #{makerId}
     </select>
     
+    <!-- 查询指定年月的已签到日期列表 -->
+    <select id="selectCheckedDatesByMakerIdAndMonth" resultType="java.lang.String">
+        SELECT DATE_FORMAT(checkin_date, '%Y-%m-%d') AS checked_date FROM matchmaker_checkin 
+        WHERE maker_id = #{makerId}
+        AND YEAR(checkin_date) = #{year}
+        AND MONTH(checkin_date) = #{month}
+        ORDER BY checkin_date ASC
+    </select>
+    
 </mapper>