Browse Source

意见反馈模块功能开发(未完成)

panzhilin 6 days ago
parent
commit
87cc7c0a45

+ 87 - 0
alien-entity/src/main/java/shop/alien/entity/store/LifeFeedback.java

@@ -0,0 +1,87 @@
+package shop.alien.entity.store;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 意见反馈表
+ */
+@Data
+@JsonInclude
+@TableName("life_feedback")
+@ApiModel(value = "LifeFeedback对象", description = "意见反馈")
+public class LifeFeedback implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "主键ID")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "用户ID")
+    @TableField("user_id")
+    private Integer userId;
+
+    @ApiModelProperty(value = "反馈来源:1-用户端,2-商家端")
+    @TableField("feedback_source")
+    private Integer feedbackSource;
+
+    @ApiModelProperty(value = "反馈方式:1-主动反馈,2-平台回复")
+    @TableField("feedback_way")
+    private Integer feedbackWay;
+
+    @ApiModelProperty(value = "反馈类型:1-优化建议,2-问题")
+    @TableField("feedback_type")
+    private Integer feedbackType;
+
+    @ApiModelProperty(value = "反馈内容")
+    @TableField("content")
+    private String content;
+
+    @ApiModelProperty(value = "联系方式(手机号或邮箱)")
+    @TableField("contact_way")
+    private String contactWay;
+
+    @ApiModelProperty(value = "反馈时间")
+    @TableField("feedback_time")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date feedbackTime;
+
+    @ApiModelProperty(value = "跟进工作人员ID(关联life_sys)")
+    @TableField("follow_up_staff")
+    private Integer followUpStaff;
+
+    @ApiModelProperty(value = "处理状态:0-待处理,1-处理中,2-已完成")
+    @TableField("handle_status")
+    private Integer handleStatus;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+}
+

+ 62 - 0
alien-entity/src/main/java/shop/alien/entity/store/LifeImg.java

@@ -0,0 +1,62 @@
+package shop.alien.entity.store;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 反馈图片表
+ */
+@Data
+@JsonInclude
+@TableName("life_img")
+@ApiModel(value = "LifeImg对象", description = "反馈图片")
+public class LifeImg implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "主键ID")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "反馈ID(关联life_feedback)")
+    @TableField("feedback_id")
+    private Integer feedbackId;
+
+    @ApiModelProperty(value = "图片URL")
+    @TableField("img_url")
+    private String imgUrl;
+
+    @ApiModelProperty(value = "图片排序")
+    @TableField("img_sort")
+    private Integer imgSort;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+}
+

+ 26 - 0
alien-entity/src/main/java/shop/alien/entity/store/dto/FeedbackReplyDto.java

@@ -0,0 +1,26 @@
+package shop.alien.entity.store.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 平台回复反馈DTO
+ */
+@Data
+@ApiModel(value = "FeedbackReplyDto对象", description = "平台回复反馈DTO")
+public class FeedbackReplyDto implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "原始反馈ID")
+    private Integer feedbackId;
+
+    @ApiModelProperty(value = "平台工作人员ID")
+    private Integer staffId;
+
+    @ApiModelProperty(value = "回复内容")
+    private String content;
+}
+

+ 39 - 0
alien-entity/src/main/java/shop/alien/entity/store/dto/LifeFeedbackDto.java

@@ -0,0 +1,39 @@
+package shop.alien.entity.store.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 意见反馈提交DTO
+ */
+@Data
+@ApiModel(value = "LifeFeedbackDto对象", description = "意见反馈提交DTO")
+public class LifeFeedbackDto implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "用户ID")
+    private Integer userId;
+
+    @ApiModelProperty(value = "反馈来源:1-用户端,2-商家端")
+    private Integer feedbackSource;
+
+    @ApiModelProperty(value = "反馈方式:1-主动反馈,2-平台回复")
+    private Integer feedbackWay;
+
+    @ApiModelProperty(value = "反馈类型:1-优化建议,2-问题")
+    private Integer feedbackType;
+
+    @ApiModelProperty(value = "反馈内容")
+    private String content;
+
+    @ApiModelProperty(value = "联系方式(手机号或邮箱)")
+    private String contactWay;
+
+    @ApiModelProperty(value = "图片URL列表")
+    private List<String> imgUrlList;
+}
+

+ 57 - 0
alien-entity/src/main/java/shop/alien/entity/store/vo/LifeFeedbackVo.java

@@ -0,0 +1,57 @@
+package shop.alien.entity.store.vo;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 意见反馈展示VO
+ */
+@Data
+@ApiModel(value = "LifeFeedbackVo对象", description = "意见反馈展示VO")
+public class LifeFeedbackVo implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "反馈ID")
+    private Integer id;
+
+    @ApiModelProperty(value = "用户ID")
+    private Integer userId;
+
+    @ApiModelProperty(value = "反馈来源:1-用户端,2-商家端")
+    private Integer feedbackSource;
+
+    @ApiModelProperty(value = "反馈方式:1-主动反馈,2-平台回复")
+    private Integer feedbackWay;
+
+    @ApiModelProperty(value = "反馈类型:1-优化建议,2-问题")
+    private Integer feedbackType;
+
+    @ApiModelProperty(value = "反馈内容")
+    private String content;
+
+    @ApiModelProperty(value = "联系方式")
+    private String contactWay;
+
+    @ApiModelProperty(value = "反馈时间")
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
+    private Date feedbackTime;
+
+    @ApiModelProperty(value = "处理状态:0-待处理,1-处理中,2-已完成")
+    private Integer handleStatus;
+
+    @ApiModelProperty(value = "跟进工作人员姓名")
+    private String staffName;
+
+    @ApiModelProperty(value = "附件图片列表")
+    private List<String> imgUrlList;
+
+    @ApiModelProperty(value = "平台反馈建议列表")
+    private List<LifeFeedbackVo> platformReplies;
+}
+

+ 64 - 0
alien-entity/src/main/java/shop/alien/mapper/LifeFeedbackMapper.java

@@ -0,0 +1,64 @@
+package shop.alien.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import shop.alien.entity.store.LifeFeedback;
+import shop.alien.entity.store.vo.LifeFeedbackVo;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 意见反馈 Mapper 接口
+ */
+@Mapper
+public interface LifeFeedbackMapper extends BaseMapper<LifeFeedback> {
+
+    /**
+     * 查询用户反馈列表(带工作人员名称)
+     * @param page 分页对象
+     * @param userId 用户ID
+     * @param feedbackSource 反馈来源
+     * @param feedbackWay 反馈方式
+     * @param handleStatus 处理状态
+     * @return 反馈列表
+     */
+    IPage<LifeFeedbackVo> selectFeedbackListWithStaff(
+            Page<LifeFeedbackVo> page,
+            @Param("userId") Integer userId,
+            @Param("feedbackSource") Integer feedbackSource,
+            @Param("feedbackWay") Integer feedbackWay,
+            @Param("handleStatus") Integer handleStatus
+    );
+
+    /**
+     * 查询反馈详情(带工作人员名称)
+     * @param feedbackId 反馈ID
+     * @return 反馈详情
+     */
+    LifeFeedbackVo selectFeedbackDetail(@Param("feedbackId") Integer feedbackId);
+
+    /**
+     * 统计待处理反馈数量
+     * @param feedbackSource 反馈来源
+     * @return 待处理数量
+     */
+    Integer countPendingFeedback(@Param("feedbackSource") Integer feedbackSource);
+
+    /**
+     * 查询平台回复列表
+     * @param userId 用户ID
+     * @param feedbackSource 反馈来源
+     * @param startTime 开始时间
+     * @return 平台回复列表
+     */
+    List<LifeFeedbackVo> selectPlatformReplies(
+            @Param("userId") Integer userId,
+            @Param("feedbackSource") Integer feedbackSource,
+            @Param("startTime") Date startTime
+    );
+}
+

+ 44 - 0
alien-entity/src/main/java/shop/alien/mapper/LifeImgMapper.java

@@ -0,0 +1,44 @@
+package shop.alien.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import shop.alien.entity.store.LifeImg;
+
+import java.util.List;
+
+/**
+ * 反馈图片 Mapper 接口
+ */
+@Mapper
+public interface LifeImgMapper extends BaseMapper<LifeImg> {
+
+    /**
+     * 根据反馈ID查询图片列表
+     * @param feedbackId 反馈ID
+     * @return 图片列表
+     */
+    List<LifeImg> selectByFeedbackId(@Param("feedbackId") Integer feedbackId);
+
+    /**
+     * 批量插入图片
+     * @param list 图片列表
+     * @return 插入数量
+     */
+    Integer batchInsert(@Param("list") List<LifeImg> list);
+
+    /**
+     * 根据反馈ID删除图片(逻辑删除)
+     * @param feedbackId 反馈ID
+     * @return 删除数量
+     */
+    Integer deleteByFeedbackId(@Param("feedbackId") Integer feedbackId);
+
+    /**
+     * 查询反馈的图片URL列表
+     * @param feedbackId 反馈ID
+     * @return 图片URL列表
+     */
+    List<String> selectImgUrlsByFeedbackId(@Param("feedbackId") Integer feedbackId);
+}
+

+ 86 - 0
alien-store/src/main/java/shop/alien/store/controller/LifeFeedbackController.java

@@ -0,0 +1,86 @@
+package shop.alien.store.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import io.swagger.annotations.*;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.dto.FeedbackReplyDto;
+import shop.alien.entity.store.dto.LifeFeedbackDto;
+import shop.alien.entity.store.vo.LifeFeedbackVo;
+import shop.alien.store.service.LifeFeedbackService;
+
+/**
+ * 意见反馈 Controller
+ */
+@Api(tags = {"意见反馈模块"})
+@Slf4j
+@CrossOrigin
+@RestController
+@RequestMapping("/feedback")
+@RequiredArgsConstructor
+public class LifeFeedbackController {
+
+    private final LifeFeedbackService lifeFeedbackService;
+
+    @ApiOperation(value = "提交反馈", httpMethod = "POST")
+    @PostMapping("/submit")
+    public R<String> submitFeedback(@RequestBody LifeFeedbackDto dto) {
+        log.info("LifeFeedbackController.submitFeedback, dto={}", dto);
+        return lifeFeedbackService.submitFeedback(dto);
+    }
+
+    @ApiOperation(value = "平台回复反馈", httpMethod = "POST")
+    @PostMapping("/reply")
+    public R<String> replyFeedback(@RequestBody FeedbackReplyDto dto) {
+        log.info("LifeFeedbackController.replyFeedback, dto={}", dto);
+        return lifeFeedbackService.replyFeedback(dto);
+    }
+
+    @ApiOperation(value = "查询用户历史反馈列表", httpMethod = "GET")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "userId", value = "用户ID", dataType = "Integer", paramType = "query", required = true),
+            @ApiImplicitParam(name = "feedbackSource", value = "反馈来源:1-用户端,2-商家端", dataType = "Integer", paramType = "query", required = true),
+            @ApiImplicitParam(name = "page", value = "页码", dataType = "int", paramType = "query", required = true),
+            @ApiImplicitParam(name = "size", value = "每页数量", dataType = "int", paramType = "query", required = true)
+    })
+    @GetMapping("/list")
+    public R<IPage<LifeFeedbackVo>> getFeedbackList(
+            @RequestParam("userId") Integer userId,
+            @RequestParam("feedbackSource") Integer feedbackSource,
+            @RequestParam(value = "page", defaultValue = "1") int page,
+            @RequestParam(value = "size", defaultValue = "10") int size) {
+        log.info("LifeFeedbackController.getFeedbackList, userId={}, feedbackSource={}, page={}, size={}", 
+                userId, feedbackSource, page, size);
+        IPage<LifeFeedbackVo> result = lifeFeedbackService.getFeedbackList(userId, feedbackSource, page, size);
+        return R.data(result);
+    }
+
+    @ApiOperation(value = "查询反馈详情", httpMethod = "GET")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "feedbackId", value = "反馈ID", dataType = "Integer", paramType = "query", required = true)
+    })
+    @GetMapping("/detail")
+    public R<LifeFeedbackVo> getFeedbackDetail(@RequestParam("feedbackId") Integer feedbackId) {
+        log.info("LifeFeedbackController.getFeedbackDetail, feedbackId={}", feedbackId);
+        return lifeFeedbackService.getFeedbackDetail(feedbackId);
+    }
+
+    @ApiOperation(value = "更新反馈处理状态", httpMethod = "POST")
+    @ApiImplicitParams({
+            @ApiImplicitParam(name = "feedbackId", value = "反馈ID", dataType = "Integer", paramType = "query", required = true),
+            @ApiImplicitParam(name = "handleStatus", value = "处理状态:0-待处理,1-处理中,2-已完成", dataType = "Integer", paramType = "query", required = true),
+            @ApiImplicitParam(name = "staffId", value = "跟进工作人员ID", dataType = "Integer", paramType = "query", required = false)
+    })
+    @PostMapping("/updateStatus")
+    public R<String> updateHandleStatus(
+            @RequestParam("feedbackId") Integer feedbackId,
+            @RequestParam("handleStatus") Integer handleStatus,
+            @RequestParam(value = "staffId", required = false) Integer staffId) {
+        log.info("LifeFeedbackController.updateHandleStatus, feedbackId={}, handleStatus={}, staffId={}", 
+                feedbackId, handleStatus, staffId);
+        return lifeFeedbackService.updateHandleStatus(feedbackId, handleStatus, staffId);
+    }
+}
+

+ 56 - 0
alien-store/src/main/java/shop/alien/store/service/LifeFeedbackService.java

@@ -0,0 +1,56 @@
+package shop.alien.store.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.IService;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.LifeFeedback;
+import shop.alien.entity.store.dto.FeedbackReplyDto;
+import shop.alien.entity.store.dto.LifeFeedbackDto;
+import shop.alien.entity.store.vo.LifeFeedbackVo;
+
+/**
+ * 意见反馈 Service
+ */
+public interface LifeFeedbackService extends IService<LifeFeedback> {
+
+    /**
+     * 提交反馈
+     * @param dto 反馈信息
+     * @return 反馈结果
+     */
+    R<String> submitFeedback(LifeFeedbackDto dto);
+
+    /**
+     * 平台回复反馈
+     * @param dto 回复信息
+     * @return 回复结果
+     */
+    R<String> replyFeedback(FeedbackReplyDto dto);
+
+    /**
+     * 查询用户历史反馈列表
+     * @param userId 用户ID
+     * @param feedbackSource 反馈来源
+     * @param page 页码
+     * @param size 每页数量
+     * @return 反馈列表
+     */
+    IPage<LifeFeedbackVo> getFeedbackList(Integer userId, Integer feedbackSource, int page, int size);
+
+    /**
+     * 查询反馈详情
+     * @param feedbackId 反馈ID
+     * @return 反馈详情
+     */
+    R<LifeFeedbackVo> getFeedbackDetail(Integer feedbackId);
+
+    /**
+     * 更新反馈处理状态
+     * @param feedbackId 反馈ID
+     * @param handleStatus 处理状态
+     * @param staffId 跟进人员ID
+     * @return 更新结果
+     */
+    R<String> updateHandleStatus(Integer feedbackId, Integer handleStatus, Integer staffId);
+}
+

+ 240 - 0
alien-store/src/main/java/shop/alien/store/service/impl/LifeFeedbackServiceImpl.java

@@ -0,0 +1,240 @@
+package shop.alien.store.service.impl;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+import shop.alien.entity.result.R;
+import shop.alien.entity.store.LifeFeedback;
+import shop.alien.entity.store.LifeImg;
+import shop.alien.entity.store.LifeLog;
+import shop.alien.entity.store.dto.FeedbackReplyDto;
+import shop.alien.entity.store.dto.LifeFeedbackDto;
+import shop.alien.entity.store.vo.LifeFeedbackVo;
+import shop.alien.mapper.LifeFeedbackMapper;
+import shop.alien.mapper.LifeLogMapper;
+import shop.alien.store.service.LifeFeedbackService;
+import shop.alien.store.service.LifeImgService;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 意见反馈 Service实现类
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+@Transactional(rollbackFor = Exception.class)
+public class LifeFeedbackServiceImpl extends ServiceImpl<LifeFeedbackMapper, LifeFeedback> implements LifeFeedbackService {
+
+    private final LifeFeedbackMapper lifeFeedbackMapper;
+    private final LifeImgService lifeImgService;
+    private final LifeLogMapper lifeLogMapper;
+
+    @Override
+    public R<String> submitFeedback(LifeFeedbackDto dto) {
+        try {
+            // 1. 参数校验
+            if (dto.getUserId() == null) {
+                return R.fail("用户ID不能为空");
+            }
+            if (dto.getFeedbackSource() == null) {
+                return R.fail("反馈来源不能为空");
+            }
+            if (dto.getFeedbackType() == null) {
+                return R.fail("反馈类型不能为空");
+            }
+            if (dto.getContent() == null || dto.getContent().trim().isEmpty()) {
+                return R.fail("反馈内容不能为空");
+            }
+
+            // 2. 创建反馈记录(使用MyBatis Plus的save方法)
+            LifeFeedback feedback = new LifeFeedback();
+            BeanUtils.copyProperties(dto, feedback);
+            feedback.setFeedbackTime(new Date());
+            feedback.setHandleStatus(0); // 待处理
+            feedback.setCreatedTime(new Date());
+            feedback.setCreatedUserId(dto.getUserId());
+
+            boolean saveResult = this.save(feedback);
+            if (!saveResult) {
+                return R.fail("提交反馈失败");
+            }
+
+            // 3. 保存附件图片(使用批量插入)
+            if (!CollectionUtils.isEmpty(dto.getImgUrlList())) {
+                List<LifeImg> imgList = new java.util.ArrayList<>();
+                int sort = 1;
+                for (String imgUrl : dto.getImgUrlList()) {
+                    LifeImg img = new LifeImg();
+                    img.setFeedbackId(feedback.getId());
+                    img.setImgUrl(imgUrl);
+                    img.setImgSort(sort++);
+                    img.setCreatedTime(new Date());
+                    img.setCreatedUserId(dto.getUserId());
+                    imgList.add(img);
+                }
+                lifeImgService.batchSave(imgList);
+            }
+
+            // 4. 记录日志
+            saveLog("用户提交反馈,ID:" + feedback.getId());
+
+            return R.success("提交成功");
+        } catch (Exception e) {
+            log.error("提交反馈失败", e);
+            return R.fail("提交反馈失败:" + e.getMessage());
+        }
+    }
+
+    @Override
+    public R<String> replyFeedback(FeedbackReplyDto dto) {
+        try {
+            // 1. 参数校验
+            if (dto.getFeedbackId() == null) {
+                return R.fail("反馈ID不能为空");
+            }
+            if (dto.getStaffId() == null) {
+                return R.fail("工作人员ID不能为空");
+            }
+            if (dto.getContent() == null || dto.getContent().trim().isEmpty()) {
+                return R.fail("回复内容不能为空");
+            }
+
+            // 2. 查询原始反馈
+            LifeFeedback originalFeedback = lifeFeedbackMapper.selectById(dto.getFeedbackId());
+            if (originalFeedback == null) {
+                return R.fail("反馈记录不存在");
+            }
+
+            // 3. 创建平台回复记录(使用MyBatis Plus的save方法)
+            LifeFeedback reply = new LifeFeedback();
+            reply.setUserId(originalFeedback.getUserId());
+            reply.setFeedbackSource(originalFeedback.getFeedbackSource());
+            reply.setFeedbackWay(2); // 平台回复
+            reply.setFeedbackType(originalFeedback.getFeedbackType());
+            reply.setContent(dto.getContent());
+            reply.setFeedbackTime(new Date());
+            reply.setFollowUpStaff(dto.getStaffId());
+            reply.setHandleStatus(2); // 已完成
+            reply.setCreatedTime(new Date());
+            reply.setCreatedUserId(dto.getStaffId());
+
+            boolean saveResult = this.save(reply);
+            if (!saveResult) {
+                return R.fail("回复失败");
+            }
+
+            // 4. 更新原始反馈的处理状态和跟进人员(使用MyBatis Plus的updateById方法)
+            LifeFeedback updateFeedback = new LifeFeedback();
+            updateFeedback.setId(dto.getFeedbackId());
+            updateFeedback.setHandleStatus(1); // 处理中
+            updateFeedback.setFollowUpStaff(dto.getStaffId());
+            updateFeedback.setUpdatedTime(new Date());
+            updateFeedback.setUpdatedUserId(dto.getStaffId());
+            this.updateById(updateFeedback);
+
+            // 5. 记录日志
+            saveLog("平台回复反馈,原始反馈ID:" + dto.getFeedbackId() + ",回复ID:" + reply.getId());
+
+            return R.success("回复成功");
+        } catch (Exception e) {
+            log.error("回复反馈失败", e);
+            return R.fail("回复反馈失败:" + e.getMessage());
+        }
+    }
+
+    @Override
+    public IPage<LifeFeedbackVo> getFeedbackList(Integer userId, Integer feedbackSource, int page, int size) {
+        try {
+            // 使用自定义SQL查询(已包含工作人员名称)
+            Page<LifeFeedbackVo> pageParam = new Page<>(page, size);
+            IPage<LifeFeedbackVo> voPage = lifeFeedbackMapper.selectFeedbackListWithStaff(
+                    pageParam, userId, feedbackSource, 1, null
+            );
+
+            // 为每条记录查询附件图片
+            voPage.getRecords().forEach(vo -> {
+                List<String> imgUrls = lifeImgService.getImgUrlsByFeedbackId(vo.getId());
+                vo.setImgUrlList(imgUrls);
+            });
+
+            return voPage;
+        } catch (Exception e) {
+            log.error("查询反馈列表失败", e);
+            return new Page<>(page, size);
+        }
+    }
+
+    @Override
+    public R<LifeFeedbackVo> getFeedbackDetail(Integer feedbackId) {
+        try {
+            // 1. 使用自定义SQL查询反馈详情(已包含工作人员名称)
+            LifeFeedbackVo vo = lifeFeedbackMapper.selectFeedbackDetail(feedbackId);
+            if (vo == null) {
+                return R.fail("反馈记录不存在");
+            }
+
+            // 2. 查询附件图片
+            List<String> imgUrls = lifeImgService.getImgUrlsByFeedbackId(feedbackId);
+            vo.setImgUrlList(imgUrls);
+
+            // 3. 查询平台回复列表(如果是主动反馈)
+            if (vo.getFeedbackWay() == 1) {
+                List<LifeFeedbackVo> replyList = lifeFeedbackMapper.selectPlatformReplies(
+                        vo.getUserId(), vo.getFeedbackSource(), vo.getFeedbackTime()
+                );
+                vo.setPlatformReplies(replyList);
+            }
+
+            return R.data(vo);
+        } catch (Exception e) {
+            log.error("查询反馈详情失败", e);
+            return R.fail("查询反馈详情失败:" + e.getMessage());
+        }
+    }
+
+    @Override
+    public R<String> updateHandleStatus(Integer feedbackId, Integer handleStatus, Integer staffId) {
+        try {
+            // 使用MyBatis Plus的updateById方法
+            LifeFeedback feedback = new LifeFeedback();
+            feedback.setId(feedbackId);
+            feedback.setHandleStatus(handleStatus);
+            feedback.setFollowUpStaff(staffId);
+            feedback.setUpdatedTime(new Date());
+            feedback.setUpdatedUserId(staffId);
+
+            boolean result = this.updateById(feedback);
+            if (result) {
+                saveLog("更新反馈处理状态,反馈ID:" + feedbackId + ",状态:" + handleStatus);
+                return R.success("更新成功");
+            }
+            return R.fail("更新失败");
+        } catch (Exception e) {
+            log.error("更新反馈处理状态失败", e);
+            return R.fail("更新失败:" + e.getMessage());
+        }
+    }
+
+    /**
+     * 保存操作日志
+     */
+    private void saveLog(String context) {
+        try {
+            LifeLog log = new LifeLog();
+            log.setContext(context);
+            log.setCreatedTime(new Date());
+            lifeLogMapper.insert(log);
+        } catch (Exception e) {
+            log.error("保存日志失败", e);
+        }
+    }
+}
+