Bläddra i källkod

feat: 饮食详情小程序端编写

xdd 3 veckor sedan
förälder
incheckning
4acce5cad7

+ 55 - 0
fs-service/src/main/java/com/fs/foods/domain/FsFoodRecord.java

@@ -0,0 +1,55 @@
+package com.fs.foods.domain;
+
+import lombok.Data;
+import lombok.Builder;
+import lombok.NoArgsConstructor;
+import lombok.AllArgsConstructor;
+
+import java.util.Date;
+import java.time.LocalDate;
+import java.time.LocalTime;
+
+/**
+ * 饮食记录实体类
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class FsFoodRecord {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 用户ID
+     */
+    private Long userId;
+
+    /**
+     * 用餐日期
+     */
+    private LocalDate recordDate;
+
+    /**
+     * 记录时间点
+     */
+    private LocalTime recordTime;
+
+    /**
+     * 用餐情况描述
+     */
+    private String mealDescription;
+
+    /**
+     * 创建时间
+     */
+    private Date createdAt;
+
+    /**
+     * 更新时间
+     */
+    private Date updatedAt;
+}

+ 73 - 0
fs-service/src/main/java/com/fs/foods/mapper/FoodRecordMapper.java

@@ -0,0 +1,73 @@
+package com.fs.foods.mapper;
+
+import com.fs.foods.domain.FsFoodRecord;
+import com.fs.foods.param.FoodRecordQueryParam;
+import org.apache.ibatis.annotations.Insert;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Options;
+import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.annotations.Update;
+import org.apache.ibatis.annotations.Param;
+
+import java.time.LocalDate;
+import java.util.List;
+
+/**
+ * 饮食记录数据访问接口
+ */
+@Mapper
+public interface FoodRecordMapper {
+
+    /**
+     * 根据ID查询饮食记录
+     */
+    @Select("SELECT * FROM fs_food_records WHERE id = #{id}")
+    FsFoodRecord getById(@Param("id") Long id);
+
+    /**
+     * 获取用户某日的所有饮食记录
+     */
+    @Select("SELECT * FROM fs_food_records WHERE user_id = #{userId} AND record_date = #{recordDate} ORDER BY record_time")
+    List<FsFoodRecord> getByUserAndDate(@Param("userId") Long userId, @Param("recordDate") LocalDate recordDate);
+
+    /**
+     * 获取用户所有饮食记录
+     */
+    @Select("SELECT * FROM fs_food_records WHERE user_id = #{userId} ORDER BY record_date DESC, record_time DESC")
+    List<FsFoodRecord> getByUser(@Param("userId") Long userId);
+
+    /**
+     * 新增饮食记录
+     */
+    @Insert("INSERT INTO fs_food_records(user_id, record_date, record_time, meal_description) " +
+            "VALUES(#{userId}, #{recordDate}, #{recordTime}, #{mealDescription})")
+    @Options(useGeneratedKeys = true, keyProperty = "id")
+    int insert(FsFoodRecord foodRecord);
+
+    /**
+     * 更新饮食记录
+     */
+    @Update("UPDATE fs_food_records SET record_date = #{recordDate}, record_time = #{recordTime}, " +
+            "meal_description = #{mealDescription} WHERE id = #{id}")
+    int update(FsFoodRecord foodRecord);
+
+    /**
+     * 删除饮食记录
+     */
+    @Update("DELETE FROM fs_food_records WHERE id = #{id}")
+    int deleteById(@Param("id") Long id);
+
+    List<FsFoodRecord> selectFoodRecordList(FoodRecordQueryParam param);
+
+    List<FsFoodRecord> selectFoodRecordsByUserAndDate(FoodRecordQueryParam param);
+
+    int deleteFsFoodRecordByIds(Long[] ids);
+
+    Integer selectFoodRecordCount(FoodRecordQueryParam param);
+
+    Integer selectRecordDays(FoodRecordQueryParam param);
+
+    FsFoodRecord selectLatestRecord(Long userId);
+
+    List<FsFoodRecord> selectRecentFoodRecords(FoodRecordQueryParam param);
+}

+ 42 - 0
fs-service/src/main/java/com/fs/foods/param/FoodRecordAddParam.java

@@ -0,0 +1,42 @@
+package com.fs.foods.param;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import javax.validation.constraints.NotNull;
+import java.time.LocalDate;
+import java.time.LocalTime;
+
+/**
+ * 新增饮食记录参数
+ */
+@Data
+@ApiModel("新增饮食记录参数")
+public class FoodRecordAddParam {
+
+    /**
+     * 用餐日期
+     */
+    @ApiModelProperty("用餐日期")
+    @NotNull(message = "用餐日期不能为空")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate recordDate;
+
+    /**
+     * 记录时间点
+     */
+    @ApiModelProperty("记录时间点")
+    @NotNull(message = "记录时间不能为空")
+    @DateTimeFormat(pattern = "HH:mm:ss")
+    private LocalTime recordTime;
+
+    /**
+     * 用餐情况描述
+     */
+    @ApiModelProperty("用餐情况描述")
+    @NotNull(message = "用餐描述不能为空")
+    private String mealDescription;
+
+}

+ 48 - 0
fs-service/src/main/java/com/fs/foods/param/FoodRecordEditParam.java

@@ -0,0 +1,48 @@
+package com.fs.foods.param;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import javax.validation.constraints.NotNull;
+import java.time.LocalDate;
+import java.time.LocalTime;
+
+/**
+ * 修改饮食记录参数
+ */
+@Data
+@ApiModel("修改饮食记录参数")
+public class FoodRecordEditParam {
+
+    /**
+     * 主键ID
+     */
+    @ApiModelProperty("记录ID")
+    @NotNull(message = "记录ID不能为空")
+    private Long id;
+
+    /**
+     * 用餐日期
+     */
+    @ApiModelProperty("用餐日期")
+    @NotNull(message = "用餐日期不能为空")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate recordDate;
+
+    /**
+     * 记录时间点
+     */
+    @ApiModelProperty("记录时间点")
+    @NotNull(message = "记录时间不能为空")
+    @DateTimeFormat(pattern = "HH:mm:ss")
+    private LocalTime recordTime;
+
+    /**
+     * 用餐情况描述
+     */
+    @ApiModelProperty("用餐情况描述")
+    @NotNull(message = "用餐描述不能为空")
+    private String mealDescription;
+}

+ 51 - 0
fs-service/src/main/java/com/fs/foods/param/FoodRecordQueryParam.java

@@ -0,0 +1,51 @@
+package com.fs.foods.param;
+
+import com.fs.common.core.domain.BaseEntity;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDate;
+
+/**
+ * 饮食记录查询参数
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ApiModel("饮食记录查询参数")
+public class FoodRecordQueryParam extends BaseEntity {
+
+    /**
+     * 用户ID
+     */
+    @ApiModelProperty("用户ID")
+    private Long userId;
+
+    /**
+     * 开始日期
+     */
+    @ApiModelProperty("开始日期")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate startDate;
+
+    /**
+     * 结束日期
+     */
+    @ApiModelProperty("结束日期")
+    @DateTimeFormat(pattern = "yyyy-MM-dd")
+    private LocalDate endDate;
+
+    /**
+     * 页码
+     */
+    @ApiModelProperty("页码")
+    private Integer pageNum = 1;
+
+    /**
+     * 页大小
+     */
+    @ApiModelProperty("页大小")
+    private Integer pageSize = 10;
+}

+ 90 - 0
fs-service/src/main/java/com/fs/foods/service/IFsFoodRecordService.java

@@ -0,0 +1,90 @@
+package com.fs.foods.service;
+
+import com.fs.foods.domain.FsFoodRecord;
+import com.fs.foods.param.FoodRecordQueryParam;
+
+import java.time.LocalDate;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 饮食记录Service接口
+ */
+public interface IFsFoodRecordService {
+
+    /**
+     * 查询饮食记录
+     *
+     * @param id 饮食记录主键
+     * @return 饮食记录
+     */
+    public FsFoodRecord selectFsFoodRecordById(Long id);
+
+    /**
+     * 查询饮食记录列表
+     *
+     * @param param 查询参数
+     * @return 饮食记录集合
+     */
+    public List<FsFoodRecord> selectFoodRecordList(FoodRecordQueryParam param);
+
+    /**
+     * 根据用户ID和日期查询饮食记录
+     *
+     * @param userId 用户ID
+     * @param recordDate 记录日期
+     * @return 饮食记录集合
+     */
+    public List<FsFoodRecord> selectFoodRecordsByUserAndDate(Long userId, LocalDate recordDate);
+
+    /**
+     * 新增饮食记录
+     *
+     * @param fsFoodRecord 饮食记录
+     * @return 结果
+     */
+    public int insertFsFoodRecord(FsFoodRecord fsFoodRecord);
+
+    /**
+     * 修改饮食记录
+     *
+     * @param fsFoodRecord 饮食记录
+     * @return 结果
+     */
+    public int updateFsFoodRecord(FsFoodRecord fsFoodRecord);
+
+    /**
+     * 批量删除饮食记录
+     *
+     * @param ids 需要删除的饮食记录主键集合
+     * @return 结果
+     */
+    public int deleteFsFoodRecordByIds(Long[] ids);
+
+    /**
+     * 删除饮食记录信息
+     *
+     * @param id 饮食记录主键
+     * @return 结果
+     */
+    public int deleteFsFoodRecordById(Long id);
+
+    /**
+     * 获取用户饮食记录统计信息
+     *
+     * @param userId 用户ID
+     * @param startDate 开始日期
+     * @param endDate 结束日期
+     * @return 统计信息
+     */
+    public Map<String, Object> getFoodRecordStats(Long userId, LocalDate startDate, LocalDate endDate);
+
+    /**
+     * 获取用户最近的饮食记录
+     *
+     * @param userId 用户ID
+     * @param limit 限制条数
+     * @return 饮食记录集合
+     */
+    public List<FsFoodRecord> selectRecentFoodRecords(Long userId, Integer limit);
+}

+ 179 - 0
fs-service/src/main/java/com/fs/foods/service/impl/FsFoodRecordServiceImpl.java

@@ -0,0 +1,179 @@
+package com.fs.foods.service.impl;
+
+import com.fs.common.utils.DateUtils;
+import com.fs.common.utils.StringUtils;
+import com.fs.foods.domain.FsFoodRecord;
+import com.fs.foods.mapper.FoodRecordMapper;
+import com.fs.foods.param.FoodRecordQueryParam;
+import com.fs.foods.service.IFsFoodRecordService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDate;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 饮食记录Service业务层处理
+ */
+@Slf4j
+@Service
+public class FsFoodRecordServiceImpl implements IFsFoodRecordService {
+
+    @Autowired
+    private FoodRecordMapper fsFoodRecordMapper;
+
+    /**
+     * 查询饮食记录
+     *
+     * @param id 饮食记录主键
+     * @return 饮食记录
+     */
+    @Override
+    public FsFoodRecord selectFsFoodRecordById(Long id) {
+        return fsFoodRecordMapper.getById(id);
+    }
+
+    /**
+     * 查询饮食记录列表
+     *
+     * @param param 查询参数
+     * @return 饮食记录
+     */
+    @Override
+    public List<FsFoodRecord> selectFoodRecordList(FoodRecordQueryParam param) {
+        return fsFoodRecordMapper.selectFoodRecordList(param);
+    }
+
+    /**
+     * 根据用户ID和日期查询饮食记录
+     *
+     * @param userId 用户ID
+     * @param recordDate 记录日期
+     * @return 饮食记录集合
+     */
+    @Override
+    public List<FsFoodRecord> selectFoodRecordsByUserAndDate(Long userId, LocalDate recordDate) {
+        FoodRecordQueryParam param = new FoodRecordQueryParam();
+        param.setUserId(userId);
+        param.setStartDate(recordDate);
+        param.setEndDate(recordDate);
+        return fsFoodRecordMapper.selectFoodRecordsByUserAndDate(param);
+    }
+
+    /**
+     * 新增饮食记录
+     *
+     * @param fsFoodRecord 饮食记录
+     * @return 结果
+     */
+    @Override
+    public int insertFsFoodRecord(FsFoodRecord fsFoodRecord) {
+        fsFoodRecord.setCreatedAt(DateUtils.getNowDate());
+        return fsFoodRecordMapper.insert(fsFoodRecord);
+    }
+
+    /**
+     * 修改饮食记录
+     *
+     * @param fsFoodRecord 饮食记录
+     * @return 结果
+     */
+    @Override
+    public int updateFsFoodRecord(FsFoodRecord fsFoodRecord) {
+        fsFoodRecord.setUpdatedAt(DateUtils.getNowDate());
+        return fsFoodRecordMapper.update(fsFoodRecord);
+    }
+
+    /**
+     * 批量删除饮食记录
+     *
+     * @param ids 需要删除的饮食记录主键
+     * @return 结果
+     */
+    @Override
+    public int deleteFsFoodRecordByIds(Long[] ids) {
+        return fsFoodRecordMapper.deleteFsFoodRecordByIds(ids);
+    }
+
+    /**
+     * 删除饮食记录信息
+     *
+     * @param id 饮食记录主键
+     * @return 结果
+     */
+    @Override
+    public int deleteFsFoodRecordById(Long id) {
+        return fsFoodRecordMapper.deleteById(id);
+    }
+
+    /**
+     * 获取用户饮食记录统计信息
+     *
+     * @param userId 用户ID
+     * @param startDate 开始日期
+     * @param endDate 结束日期
+     * @return 统计信息
+     */
+    @Override
+    public Map<String, Object> getFoodRecordStats(Long userId, LocalDate startDate, LocalDate endDate) {
+        try {
+            // 如果没有指定日期范围,默认查询最近30天
+            if (startDate == null || endDate == null) {
+                endDate = LocalDate.now();
+                startDate = endDate.minusDays(30);
+            }
+
+            FoodRecordQueryParam param = new FoodRecordQueryParam();
+            param.setUserId(userId);
+            param.setStartDate(startDate);
+            param.setEndDate(endDate);
+
+            // 获取总记录数
+            Integer totalCount = fsFoodRecordMapper.selectFoodRecordCount(param);
+
+            // 获取记录天数
+            Integer recordDays = fsFoodRecordMapper.selectRecordDays(param);
+
+            // 获取平均每日记录数
+            Double avgRecordsPerDay = recordDays > 0 ? (double) totalCount / recordDays : 0.0;
+
+            // 获取最近一次记录时间
+            FsFoodRecord latestRecord = fsFoodRecordMapper.selectLatestRecord(userId);
+
+            Map<String, Object> stats = new HashMap<>();
+            stats.put("totalCount", totalCount);
+            stats.put("recordDays", recordDays);
+            stats.put("avgRecordsPerDay", String.format("%.1f", avgRecordsPerDay));
+            stats.put("latestRecordDate", latestRecord != null ? latestRecord.getRecordDate() : null);
+            stats.put("startDate", startDate);
+            stats.put("endDate", endDate);
+
+            return stats;
+        } catch (Exception e) {
+            log.error("获取饮食记录统计异常:", e);
+            return new HashMap<>();
+        }
+    }
+
+    /**
+     * 获取用户最近的饮食记录
+     *
+     * @param userId 用户ID
+     * @param limit 限制条数
+     * @return 饮食记录集合
+     */
+    @Override
+    public List<FsFoodRecord> selectRecentFoodRecords(Long userId, Integer limit) {
+        FoodRecordQueryParam param = new FoodRecordQueryParam();
+        param.setUserId(userId);
+        if (limit != null && limit > 0) {
+            param.setPageSize(limit);
+        } else {
+            param.setPageSize(10); // 默认10条
+        }
+        return fsFoodRecordMapper.selectRecentFoodRecords(param);
+    }
+}

+ 124 - 0
fs-service/src/main/resources/mapper/foods/FoodRecordMapper.xml

@@ -0,0 +1,124 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.fs.foods.mapper.FoodRecordMapper">
+
+    <!-- 结果映射 -->
+    <resultMap id="BaseResultMap" type="com.fs.foods.domain.FsFoodRecord">
+        <id column="id" jdbcType="BIGINT" property="id" />
+        <result column="user_id" jdbcType="BIGINT" property="userId" />
+        <result column="record_date" jdbcType="DATE" property="recordDate" />
+        <result column="record_time" jdbcType="TIME" property="recordTime" />
+        <result column="meal_description" jdbcType="VARCHAR" property="mealDescription" />
+        <result column="created_at" jdbcType="TIMESTAMP" property="createdAt" />
+        <result column="updated_at" jdbcType="TIMESTAMP" property="updatedAt" />
+    </resultMap>
+
+    <!-- 查询字段 -->
+    <sql id="Base_Column_List">
+        id, user_id, record_date, record_time, meal_description, created_at, updated_at
+    </sql>
+
+    <!-- 通用查询条件 -->
+    <sql id="selectFoodRecordVo">
+        SELECT <include refid="Base_Column_List" /> FROM fs_food_records
+    </sql>
+
+    <!-- 条件查询饮食记录列表 -->
+    <select id="selectFoodRecordList" parameterType="com.fs.foods.param.FoodRecordQueryParam" resultMap="BaseResultMap">
+        SELECT
+        <include refid="Base_Column_List" />
+        FROM fs_food_records
+        <where>
+            <if test="userId != null">
+                AND user_id = #{userId}
+            </if>
+            <if test="startDate != null">
+                AND record_date &gt;= #{startDate}
+            </if>
+            <if test="endDate != null">
+                AND record_date &lt;= #{endDate}
+            </if>
+            <if test="keyword != null and keyword != ''">
+                AND meal_description LIKE CONCAT('%', #{keyword}, '%')
+            </if>
+        </where>
+        ORDER BY record_date DESC, record_time DESC
+    </select>
+    <!-- 根据用户和日期查询饮食记录 -->
+    <select id="selectFoodRecordsByUserAndDate" parameterType="com.fs.foods.param.FoodRecordQueryParam" resultMap="BaseResultMap">
+        <include refid="selectFoodRecordVo"/>
+        <where>
+            <if test="userId != null">
+                AND user_id = #{userId}
+            </if>
+            <if test="startDate != null">
+                AND record_date &gt;= #{startDate}
+            </if>
+            <if test="endDate != null">
+                AND record_date &lt;= #{endDate}
+            </if>
+        </where>
+        ORDER BY record_date DESC, record_time DESC
+    </select>
+    <!-- 批量删除饮食记录 -->
+    <delete id="deleteFsFoodRecordByIds" parameterType="Long">
+        DELETE FROM fs_food_records WHERE id IN
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+    <!-- 查询饮食记录总数 -->
+    <select id="selectFoodRecordCount" parameterType="com.fs.foods.param.FoodRecordQueryParam" resultType="java.lang.Integer">
+        SELECT COUNT(*) FROM fs_food_records
+        <where>
+            <if test="userId != null">
+                AND user_id = #{userId}
+            </if>
+            <if test="startDate != null">
+                AND record_date &gt;= #{startDate}
+            </if>
+            <if test="endDate != null">
+                AND record_date &lt;= #{endDate}
+            </if>
+        </where>
+    </select>
+    <!-- 查询记录天数 -->
+    <select id="selectRecordDays" parameterType="com.fs.foods.param.FoodRecordQueryParam" resultType="java.lang.Integer">
+        SELECT COUNT(DISTINCT record_date) FROM fs_food_records
+        <where>
+            <if test="userId != null">
+                AND user_id = #{userId}
+            </if>
+            <if test="startDate != null">
+                AND record_date &gt;= #{startDate}
+            </if>
+            <if test="endDate != null">
+                AND record_date &lt;= #{endDate}
+            </if>
+        </where>
+    </select>
+    <!-- 查询用户最新记录 -->
+    <select id="selectLatestRecord" parameterType="java.lang.Long" resultMap="BaseResultMap">
+        <include refid="selectFoodRecordVo"/>
+        WHERE user_id = #{userId}
+        ORDER BY record_date DESC, record_time DESC
+        LIMIT 1
+    </select>
+    <!-- 查询最近的饮食记录 -->
+    <select id="selectRecentFoodRecords" parameterType="com.fs.foods.param.FoodRecordQueryParam" resultMap="BaseResultMap">
+        <include refid="selectFoodRecordVo"/>
+        <where>
+            <if test="userId != null">
+                AND user_id = #{userId}
+            </if>
+            <if test="startDate != null">
+                AND record_date &gt;= #{startDate}
+            </if>
+            <if test="endDate != null">
+                AND record_date &lt;= #{endDate}
+            </if>
+        </where>
+        ORDER BY record_date DESC, record_time DESC
+    </select>
+
+</mapper>

+ 216 - 0
fs-user-app/src/main/java/com/fs/app/controller/FoodRecordController.java

@@ -0,0 +1,216 @@
+package com.fs.app.controller;
+
+import com.fs.app.annotation.Login;
+import com.fs.foods.param.FoodRecordAddParam;
+import com.fs.foods.param.FoodRecordEditParam;
+import com.fs.foods.param.FoodRecordQueryParam;
+import com.fs.common.core.domain.R;
+import com.fs.common.core.page.TableDataInfo;
+import com.fs.common.utils.StringUtils;
+import com.fs.foods.domain.FsFoodRecord;
+import com.fs.foods.service.IFsFoodRecordService;
+import com.github.pagehelper.PageHelper;
+import com.github.pagehelper.PageInfo;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.format.annotation.DateTimeFormat;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.validation.Valid;
+import java.time.LocalDate;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 饮食记录控制器
+ */
+@Api("饮食记录管理")
+@RestController
+@Slf4j
+@RequestMapping(value = "/app/food-record")
+public class FoodRecordController extends AppBaseController {
+
+    @Autowired
+    private IFsFoodRecordService foodRecordService;
+
+    /**
+     * 获取用户饮食记录详情
+     */
+    @Login
+    @ApiOperation("获取饮食记录详情")
+    @GetMapping("/getRecordInfo/{id}")
+    public R getRecordInfo(@PathVariable Long id, HttpServletRequest request) {
+        try {
+            FsFoodRecord record = foodRecordService.selectFsFoodRecordById(id);
+            if (record == null || !record.getUserId().equals(Long.parseLong(getUserId()))) {
+                return R.error("记录不存在或无权限访问");
+            }
+            Map<String, Object> map = new HashMap<>();
+            map.put("record", record);
+            return R.ok(map);
+        } catch (Exception e) {
+            log.error("获取饮食记录详情异常:", e);
+            return R.error("操作异常");
+        }
+    }
+
+    /**
+     * 获取用户某日的饮食记录列表
+     */
+    @Login
+    @ApiOperation("获取某日饮食记录列表")
+    @GetMapping("/getDayRecords")
+    public R getDayRecords(@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate recordDate,
+                          HttpServletRequest request) {
+        try {
+            Long userId = Long.parseLong(getUserId());
+            List<FsFoodRecord> list = foodRecordService.selectFoodRecordsByUserAndDate(userId, recordDate);
+            Map<String, Object> map = new HashMap<>();
+            map.put("records", list);
+            map.put("recordDate", recordDate);
+            return R.ok(map);
+        } catch (Exception e) {
+            log.error("获取某日饮食记录异常:", e);
+            return R.error("操作异常");
+        }
+    }
+
+    /**
+     * 获取用户饮食记录分页列表
+     */
+    @Login
+    @ApiOperation("获取用户饮食记录列表")
+    @GetMapping("/getMyRecordList")
+    public R getMyRecordList(FoodRecordQueryParam param, HttpServletRequest request) {
+        try {
+            PageHelper.startPage(param.getPageNum(), param.getPageSize());
+            param.setUserId(Long.parseLong(getUserId()));
+            List<FsFoodRecord> list = foodRecordService.selectFoodRecordList(param);
+            PageInfo<FsFoodRecord> listPageInfo = new PageInfo<>(list);
+            return R.ok().put("data", listPageInfo);
+        } catch (Exception e) {
+            log.error("获取饮食记录列表异常:", e);
+            return R.error("操作异常");
+        }
+    }
+
+    /**
+     * 新增饮食记录
+     */
+    @Login
+    @ApiOperation("新增饮食记录")
+    @PostMapping("/addRecord")
+    public R addRecord(@RequestBody @Valid FoodRecordAddParam param, HttpServletRequest request) {
+        try {
+            log.info("【新增饮食记录】:{}", param);
+
+            if (StringUtils.isEmpty(param.getMealDescription())) {
+                return R.error("用餐描述不能为空");
+            }
+
+            FsFoodRecord record = new FsFoodRecord();
+            BeanUtils.copyProperties(param, record);
+            record.setUserId(Long.parseLong(getUserId()));
+
+            if (foodRecordService.insertFsFoodRecord(record) > 0) {
+                return R.ok("添加成功");
+            } else {
+                return R.error("添加失败");
+            }
+        } catch (Exception e) {
+            log.error("新增饮食记录异常:", e);
+            return R.error("操作异常");
+        }
+    }
+
+    /**
+     * 修改饮食记录
+     */
+    @Login
+    @ApiOperation("修改饮食记录")
+    @PostMapping("/editRecord")
+    public R editRecord(@RequestBody @Valid FoodRecordEditParam param, HttpServletRequest request) {
+        try {
+            log.info("【修改饮食记录】:{}", param);
+
+            // 验证记录是否存在且属于当前用户
+            FsFoodRecord existRecord = foodRecordService.selectFsFoodRecordById(param.getId());
+            if (existRecord == null || !existRecord.getUserId().equals(Long.parseLong(getUserId()))) {
+                return R.error("记录不存在或无权限修改");
+            }
+
+            FsFoodRecord record = new FsFoodRecord();
+            BeanUtils.copyProperties(param, record);
+            record.setUserId(Long.parseLong(getUserId()));
+
+            if (foodRecordService.updateFsFoodRecord(record) > 0) {
+                return R.ok("修改成功");
+            } else {
+                return R.error("修改失败");
+            }
+        } catch (Exception e) {
+            log.error("修改饮食记录异常:", e);
+            return R.error("操作异常");
+        }
+    }
+
+    /**
+     * 删除饮食记录
+     */
+    @Login
+    @ApiOperation("删除饮食记录")
+    @PostMapping("/deleteRecord/{id}")
+    public R deleteRecord(@PathVariable("id") Long id, HttpServletRequest request) {
+        try {
+            // 验证记录是否存在且属于当前用户
+            FsFoodRecord existRecord = foodRecordService.selectFsFoodRecordById(id);
+            if (existRecord == null || !existRecord.getUserId().equals(Long.parseLong(getUserId()))) {
+                return R.error("记录不存在或无权限删除");
+            }
+
+            if (foodRecordService.deleteFsFoodRecordById(id) > 0) {
+                return R.ok("删除成功");
+            } else {
+                return R.error("删除失败");
+            }
+        } catch (Exception e) {
+            log.error("删除饮食记录异常:", e);
+            return R.error("操作异常");
+        }
+    }
+
+    /**
+     * 获取用户饮食记录统计
+     */
+    @Login
+    @ApiOperation("获取饮食记录统计")
+    @GetMapping("/getRecordStats")
+    public R getRecordStats(@RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate startDate,
+                           @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate endDate,
+                           HttpServletRequest request) {
+        try {
+            Long userId = Long.parseLong(getUserId());
+            Map<String, Object> stats = foodRecordService.getFoodRecordStats(userId, startDate, endDate);
+            return R.ok().put("data", stats);
+        } catch (Exception e) {
+            log.error("获取饮食记录统计异常:", e);
+            return R.error("操作异常");
+        }
+    }
+
+    /**
+     * 管理端查询饮食记录列表
+     */
+    @ApiOperation("管理端查询饮食记录")
+    @GetMapping("/admin/list")
+    public TableDataInfo adminList(FoodRecordQueryParam param) {
+        startPage();
+        List<FsFoodRecord> list = foodRecordService.selectFoodRecordList(param);
+        return getDataTable(list);
+    }
+}