signin+userlevelsystem

Change-Id: I4d2b2660b23521817ae2ed6a55c6c322a20385ec
diff --git a/src/main/java/com/example/g8backend/controller/UserController.java b/src/main/java/com/example/g8backend/controller/UserController.java
index 121bc1a..8019967 100644
--- a/src/main/java/com/example/g8backend/controller/UserController.java
+++ b/src/main/java/com/example/g8backend/controller/UserController.java
@@ -8,6 +8,7 @@
 import org.springframework.security.core.Authentication;
 import org.springframework.security.core.context.SecurityContextHolder;
 import org.springframework.web.bind.annotation.*;
+import com.example.g8backend.service.ISigningService;
 
 import java.util.List;
 import java.util.Map;
@@ -90,4 +91,14 @@
         Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
         return (Long) authentication.getPrincipal();
     }
+
+    @Autowired
+    private ISigningService signingService; // 修改接口名称
+
+    @PostMapping("/signin")
+    public String signIn() {
+        Long userId = getCurrentUserId(); // 假设从安全上下文中获取用户ID
+        boolean success = signingService.signIn(userId);
+        return success ? "签到成功" : "今日已签到";
+    }
 }
diff --git a/src/main/java/com/example/g8backend/entity/User.java b/src/main/java/com/example/g8backend/entity/User.java
index 64f4f10..4c4a465 100644
--- a/src/main/java/com/example/g8backend/entity/User.java
+++ b/src/main/java/com/example/g8backend/entity/User.java
@@ -6,6 +6,8 @@
 import lombok.Data;
 import lombok.experimental.Accessors;
 
+import java.time.LocalDate;
+
 @Data
 @TableName("users")
 @Accessors(chain = true)
@@ -17,6 +19,9 @@
     private String password;
     private String userName;
     private String email;
+    private String userLevel;      // 用户等级(lv1/lv2/lv3/vip)
+    private Integer signinCount;
+    private LocalDate lastSigninDate;
 
     @Override
     public String toString() {
diff --git a/src/main/java/com/example/g8backend/entity/UserSignin.java b/src/main/java/com/example/g8backend/entity/UserSignin.java
new file mode 100644
index 0000000..1af4b6c
--- /dev/null
+++ b/src/main/java/com/example/g8backend/entity/UserSignin.java
@@ -0,0 +1,17 @@
+package com.example.g8backend.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+import java.time.LocalDate;
+
+@Data
+@TableName("user_signin")
+public class UserSignin {
+    @TableId(type = IdType.AUTO)
+    private Long signinId;
+    private Long userId;
+    private LocalDate signinDate;
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/g8backend/mapper/UserMapper.java b/src/main/java/com/example/g8backend/mapper/UserMapper.java
index 0a9e562..98e6c67 100644
--- a/src/main/java/com/example/g8backend/mapper/UserMapper.java
+++ b/src/main/java/com/example/g8backend/mapper/UserMapper.java
@@ -4,10 +4,18 @@
 import com.example.g8backend.entity.User;
 import org.apache.ibatis.annotations.Mapper;
 import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.annotations.Update;
 
 @Mapper
 public interface UserMapper extends BaseMapper<User> {
     User getUserByName(@Param("userName") String userName);
     User getUserByEmail(@Param("email") String email);
     User getUserByPasskey(@Param("passkey") String passkey);
+
+    @Select("SELECT * FROM users WHERE user_name = #{name}")
+    User selectByUserName(@Param("name") String name);
+
+    @Update("UPDATE users SET user_level = #{userLevel} WHERE user_id = #{userId}")
+    int updateUserLevel(@Param("userId") Long userId, @Param("userLevel") String userLevel);
 }
diff --git a/src/main/java/com/example/g8backend/mapper/UserSigninMapper.java b/src/main/java/com/example/g8backend/mapper/UserSigninMapper.java
new file mode 100644
index 0000000..42a4736
--- /dev/null
+++ b/src/main/java/com/example/g8backend/mapper/UserSigninMapper.java
@@ -0,0 +1,14 @@
+package com.example.g8backend.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.example.g8backend.entity.UserSignin;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+
+@Mapper
+public interface UserSigninMapper extends BaseMapper<UserSignin> {
+
+    @Select("SELECT COUNT(*) FROM user_signin WHERE user_id = #{userId} AND signin_date = #{date}")
+    boolean existsByUserIdAndDate(@Param("userId") Long userId, @Param("date") String date);
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/g8backend/service/ISigningService.java b/src/main/java/com/example/g8backend/service/ISigningService.java
new file mode 100644
index 0000000..e408e6c
--- /dev/null
+++ b/src/main/java/com/example/g8backend/service/ISigningService.java
@@ -0,0 +1,7 @@
+package com.example.g8backend.service;
+
+import com.example.g8backend.dto.ApiResponse;
+
+public interface ISigningService {
+    boolean signIn(Long userId);
+}
\ No newline at end of file
diff --git a/src/main/java/com/example/g8backend/service/impl/SigninServiceImpl.java b/src/main/java/com/example/g8backend/service/impl/SigninServiceImpl.java
new file mode 100644
index 0000000..1f70520
--- /dev/null
+++ b/src/main/java/com/example/g8backend/service/impl/SigninServiceImpl.java
@@ -0,0 +1,52 @@
+package com.example.g8backend.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.example.g8backend.entity.User;
+import com.example.g8backend.entity.UserSignin;
+import com.example.g8backend.mapper.UserMapper;
+import com.example.g8backend.mapper.UserSigninMapper;
+import com.example.g8backend.service.ISigningService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import java.time.LocalDate;
+
+@Service
+@RequiredArgsConstructor
+public class SigninServiceImpl implements ISigningService{
+    private final UserMapper userMapper;
+    private final UserSigninMapper userSigninMapper;
+
+    @Override
+    @Transactional
+    public boolean signIn(Long userId) {
+        LocalDate today = LocalDate.now();
+        String todayStr = today.toString();
+
+        // 检查今日是否已签到
+        if (userSigninMapper.existsByUserIdAndDate(userId, todayStr)) {
+            return false; // 已签到
+        }
+
+        // 插入签到记录
+        UserSignin signin = new UserSignin();
+        signin.setUserId(userId);
+        signin.setSigninDate(today);
+        userSigninMapper.insert(signin);
+
+        // 更新用户信息
+        User user = userMapper.selectById(userId);
+        user.setSigninCount(user.getSigninCount() + 1);
+        user.setLastSigninDate(today);
+
+        // 根据签到次数升级等级 默认lv1 三次签到lv2 十次签到lv3
+        if (user.getSigninCount() >= 10) {
+            user.setUserLevel("lv3");
+        } else if (user.getSigninCount() >= 3) {
+            user.setUserLevel("lv2");
+        }
+
+        userMapper.updateById(user);
+        return true;
+    }
+}
\ No newline at end of file