From 3f2de012ecdf280df6d9ef5f9508df7990ecfd50 Mon Sep 17 00:00:00 2001 From: menxipeng Date: Thu, 21 Aug 2025 12:29:41 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BF=A1=E6=81=AF=E5=8F=8D?= =?UTF-8?q?=E9=A6=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../back/UserFeedbackController.java | 98 ++++++ .../client/ClientFeedbackController.java | 85 +++++ .../controller/client/MusicController.java | 5 +- .../client/UserHistoryController.java | 6 +- .../core/domain/entity/UserFeedback.java | 191 +++++++++++ .../system/mapper/UserFeedbackMapper.java | 62 ++++ .../system/service/IUserFeedbackService.java | 62 ++++ .../service/impl/UserFeedbackServiceImpl.java | 94 ++++++ .../mapper/system/UserFeedbackMapper.xml | 101 ++++++ ruoyi-ui/src/api/feedback/feedback.js | 44 +++ ruoyi-ui/src/views/feedback/index.vue | 302 ++++++++++++++++++ 11 files changed, 1046 insertions(+), 4 deletions(-) create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/back/UserFeedbackController.java create mode 100644 ruoyi-admin/src/main/java/com/ruoyi/web/controller/client/ClientFeedbackController.java create mode 100644 ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/UserFeedback.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/mapper/UserFeedbackMapper.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/IUserFeedbackService.java create mode 100644 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/UserFeedbackServiceImpl.java create mode 100644 ruoyi-system/src/main/resources/mapper/system/UserFeedbackMapper.xml create mode 100644 ruoyi-ui/src/api/feedback/feedback.js create mode 100644 ruoyi-ui/src/views/feedback/index.vue diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/back/UserFeedbackController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/back/UserFeedbackController.java new file mode 100644 index 0000000..3eb7d66 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/back/UserFeedbackController.java @@ -0,0 +1,98 @@ +package com.ruoyi.web.controller.back; + +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.UserFeedback; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.system.service.IUserFeedbackService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * 用户反馈Controller + * + * @author ruoyi + * @date 2025-08-21 + */ +@RestController +@RequestMapping("/back/feedback") +public class UserFeedbackController extends BaseController +{ + @Autowired + private IUserFeedbackService userFeedbackService; + + /** + * 查询用户反馈列表 + */ + @PreAuthorize("@ss.hasPermi('system:feedback:list')") + @GetMapping("/list") + public TableDataInfo list(UserFeedback userFeedback) + { + startPage(); + List list = userFeedbackService.selectUserFeedbackList(userFeedback); + return getDataTable(list); + } + + /** + * 导出用户反馈列表 + */ + @PreAuthorize("@ss.hasPermi('system:feedback:export')") + @Log(title = "用户反馈", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(HttpServletResponse response, UserFeedback userFeedback) + { + List list = userFeedbackService.selectUserFeedbackList(userFeedback); + ExcelUtil util = new ExcelUtil<>(UserFeedback.class); + util.exportExcel(response, list, "用户反馈数据"); + } + + /** + * 获取用户反馈详细信息 + */ + @PreAuthorize("@ss.hasPermi('system:feedback:query')") + @GetMapping(value = "/{id}") + public AjaxResult getInfo(@PathVariable("id") String id) + { + return success(userFeedbackService.selectUserFeedbackById(id)); + } + + /** + * 新增用户反馈 + */ + @PreAuthorize("@ss.hasPermi('system:feedback:add')") + @Log(title = "用户反馈", businessType = BusinessType.INSERT) + @PostMapping + public AjaxResult add(@RequestBody UserFeedback userFeedback) + { + return toAjax(userFeedbackService.insertUserFeedback(userFeedback)); + } + + /** + * 修改用户反馈 + */ + @PreAuthorize("@ss.hasPermi('system:feedback:edit')") + @Log(title = "用户反馈", businessType = BusinessType.UPDATE) + @PutMapping + public AjaxResult edit(@RequestBody UserFeedback userFeedback) + { + return toAjax(userFeedbackService.updateUserFeedback(userFeedback)); + } + + /** + * 删除用户反馈 + */ + @PreAuthorize("@ss.hasPermi('system:feedback:remove')") + @Log(title = "用户反馈", businessType = BusinessType.DELETE) + @DeleteMapping("/{ids}") + public AjaxResult remove(@PathVariable String[] ids) + { + return toAjax(userFeedbackService.deleteUserFeedbackByIds(ids)); + } +} diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/client/ClientFeedbackController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/client/ClientFeedbackController.java new file mode 100644 index 0000000..0eb2a83 --- /dev/null +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/client/ClientFeedbackController.java @@ -0,0 +1,85 @@ +package com.ruoyi.web.controller.client; + +import com.ruoyi.common.annotation.Log; +import com.ruoyi.common.core.controller.BaseController; +import com.ruoyi.common.core.domain.AjaxResult; +import com.ruoyi.common.core.domain.entity.UserFeedback; +import com.ruoyi.common.core.page.TableDataInfo; +import com.ruoyi.common.enums.BusinessType; +import com.ruoyi.common.utils.ServletUtils; +import com.ruoyi.common.utils.StringUtils; +import com.ruoyi.common.utils.ip.IpUtils; +import com.ruoyi.common.utils.poi.ExcelUtil; +import com.ruoyi.system.service.IUserFeedbackService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.web.bind.annotation.*; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Date; +import java.util.List; +import java.util.UUID; + +/** + * 用户反馈Controller + * + * @author ruoyi + * @date 2025-08-21 + */ +@RestController +@RequestMapping("/client/feedback") +public class ClientFeedbackController extends BaseController +{ + @Autowired + private IUserFeedbackService userFeedbackService; + + /** + * 提交用户反馈 + */ + @PostMapping("/submit") + public AjaxResult submit(@RequestBody UserFeedback userFeedback, HttpServletRequest request) + { + // 验证必填字段 + if (StringUtils.isEmpty(userFeedback.getFeedbackContent())) { + return AjaxResult.error("反馈内容不能为空"); + } + + // 设置ID + userFeedback.setId(UUID.randomUUID().toString().replaceAll("-", "")); + + // 设置IP地址 + userFeedback.setIpAddress(IpUtils.getIpAddr(request)); + + // 设置用户浏览器信息 + userFeedback.setUserAgent(request.getHeader("User-Agent")); + + // 设置状态,如果未提供则默认为pending + if (StringUtils.isEmpty(userFeedback.getStatus())) { + userFeedback.setStatus("pending"); + } else { + // 验证状态值是否合法 + String status = userFeedback.getStatus(); + if (!status.equals("pending") && !status.equals("processing") && + !status.equals("resolved") && !status.equals("closed")) { + return AjaxResult.error("状态值无效,必须是 pending、processing、resolved 或 closed"); + } + } + + // 设置创建时间和更新时间 + Date now = new Date(); + userFeedback.setCreatedAt(now); + userFeedback.setUpdatedAt(now); + + return toAjax(userFeedbackService.insertUserFeedback(userFeedback)); + } + + /** + * 查询用户反馈详情 + */ + @GetMapping("/detail/{id}") + public AjaxResult getInfo(@PathVariable("id") String id) + { + return AjaxResult.success(userFeedbackService.selectUserFeedbackById(id)); + } +} \ No newline at end of file diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/client/MusicController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/client/MusicController.java index 3bb658f..28f4b8d 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/client/MusicController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/client/MusicController.java @@ -17,6 +17,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -73,10 +74,10 @@ public class MusicController extends BaseController { int count = musicService.findLikeNumsByUserId(userId); // 获取一张音乐图片 String imgUrl = musicService.findLikeMusicImageByUserId(userId); - AjaxResult ajax = AjaxResult.success(); + Map ajax = new HashMap<>(); ajax.put("count", count); ajax.put("imgUrl", imgUrl); - return ajax; + return AjaxResult.success(ajax); } // 删除我喜欢的音乐 cancel/like diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/client/UserHistoryController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/client/UserHistoryController.java index 41fad2c..cb71775 100644 --- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/client/UserHistoryController.java +++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/client/UserHistoryController.java @@ -14,7 +14,9 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletResponse; +import java.util.HashMap; import java.util.List; +import java.util.Map; /** * 用户播放历史Controller @@ -118,10 +120,10 @@ public class UserHistoryController extends BaseController // 获取一张音乐图片 String imgUrl = userHistoryService.findHistoryMusicImageByUserId(userId); - AjaxResult ajax = AjaxResult.success(); + Map ajax = new HashMap<>(); ajax.put("count", count); ajax.put("imgUrl", imgUrl); - return ajax; + return AjaxResult.success(ajax); } } diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/UserFeedback.java b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/UserFeedback.java new file mode 100644 index 0000000..1ec74f8 --- /dev/null +++ b/ruoyi-common/src/main/java/com/ruoyi/common/core/domain/entity/UserFeedback.java @@ -0,0 +1,191 @@ +package com.ruoyi.common.core.domain.entity; + +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; +import com.ruoyi.common.annotation.Excel; +import com.ruoyi.common.core.domain.BaseEntity; + +/** + * 用户反馈对象 user_feedback + * + * @author ruoyi + * @date 2025-08-21 + */ +public class UserFeedback extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + /** 唯一标识符 */ + private String id; + + /** 反馈内容 */ + @Excel(name = "反馈内容") + private String feedbackContent; + + /** 用户姓名 */ + @Excel(name = "用户姓名") + private String userName; + + /** 联系方式类型 */ + @Excel(name = "联系方式类型") + private String contactType; + + /** 联系方式信息 */ + @Excel(name = "联系方式信息") + private String contactInfo; + + /** 处理状态 */ + @Excel(name = "处理状态") + private String status; + + /** 创建时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date createdAt; + + /** 更新时间 */ + @JsonFormat(pattern = "yyyy-MM-dd") + @Excel(name = "更新时间", width = 30, dateFormat = "yyyy-MM-dd") + private Date updatedAt; + + /** 用户IP地址 */ + @Excel(name = "用户IP地址") + private String ipAddress; + + /** 用户浏览器信息 */ + @Excel(name = "用户浏览器信息") + private String userAgent; + + /** 附件路径(如果有) */ + @Excel(name = "附件路径", readConverterExp = "如=果有") + private String attachmentPath; + + public void setId(String id) + { + this.id = id; + } + + public String getId() + { + return id; + } + + public void setFeedbackContent(String feedbackContent) + { + this.feedbackContent = feedbackContent; + } + + public String getFeedbackContent() + { + return feedbackContent; + } + + public void setUserName(String userName) + { + this.userName = userName; + } + + public String getUserName() + { + return userName; + } + + public void setContactType(String contactType) + { + this.contactType = contactType; + } + + public String getContactType() + { + return contactType; + } + + public void setContactInfo(String contactInfo) + { + this.contactInfo = contactInfo; + } + + public String getContactInfo() + { + return contactInfo; + } + + public void setStatus(String status) + { + this.status = status; + } + + public String getStatus() + { + return status; + } + + public void setCreatedAt(Date createdAt) + { + this.createdAt = createdAt; + } + + public Date getCreatedAt() + { + return createdAt; + } + + public void setUpdatedAt(Date updatedAt) + { + this.updatedAt = updatedAt; + } + + public Date getUpdatedAt() + { + return updatedAt; + } + + public void setIpAddress(String ipAddress) + { + this.ipAddress = ipAddress; + } + + public String getIpAddress() + { + return ipAddress; + } + + public void setUserAgent(String userAgent) + { + this.userAgent = userAgent; + } + + public String getUserAgent() + { + return userAgent; + } + + public void setAttachmentPath(String attachmentPath) + { + this.attachmentPath = attachmentPath; + } + + public String getAttachmentPath() + { + return attachmentPath; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("id", getId()) + .append("feedbackContent", getFeedbackContent()) + .append("userName", getUserName()) + .append("contactType", getContactType()) + .append("contactInfo", getContactInfo()) + .append("status", getStatus()) + .append("createdAt", getCreatedAt()) + .append("updatedAt", getUpdatedAt()) + .append("ipAddress", getIpAddress()) + .append("userAgent", getUserAgent()) + .append("attachmentPath", getAttachmentPath()) + .toString(); + } +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/UserFeedbackMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/UserFeedbackMapper.java new file mode 100644 index 0000000..81904d7 --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/UserFeedbackMapper.java @@ -0,0 +1,62 @@ +package com.ruoyi.system.mapper; + +import com.ruoyi.common.core.domain.entity.UserFeedback; + +import java.util.List; + +/** + * 用户反馈Mapper接口 + * + * @author ruoyi + * @date 2025-08-21 + */ +public interface UserFeedbackMapper +{ + /** + * 查询用户反馈 + * + * @param id 用户反馈主键 + * @return 用户反馈 + */ + public UserFeedback selectUserFeedbackById(String id); + + /** + * 查询用户反馈列表 + * + * @param userFeedback 用户反馈 + * @return 用户反馈集合 + */ + public List selectUserFeedbackList(UserFeedback userFeedback); + + /** + * 新增用户反馈 + * + * @param userFeedback 用户反馈 + * @return 结果 + */ + public int insertUserFeedback(UserFeedback userFeedback); + + /** + * 修改用户反馈 + * + * @param userFeedback 用户反馈 + * @return 结果 + */ + public int updateUserFeedback(UserFeedback userFeedback); + + /** + * 删除用户反馈 + * + * @param id 用户反馈主键 + * @return 结果 + */ + public int deleteUserFeedbackById(String id); + + /** + * 批量删除用户反馈 + * + * @param ids 需要删除的数据主键集合 + * @return 结果 + */ + public int deleteUserFeedbackByIds(String[] ids); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/IUserFeedbackService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/IUserFeedbackService.java new file mode 100644 index 0000000..ee32cfc --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/IUserFeedbackService.java @@ -0,0 +1,62 @@ +package com.ruoyi.system.service; + +import com.ruoyi.common.core.domain.entity.UserFeedback; + +import java.util.List; + +/** + * 用户反馈Service接口 + * + * @author ruoyi + * @date 2025-08-21 + */ +public interface IUserFeedbackService +{ + /** + * 查询用户反馈 + * + * @param id 用户反馈主键 + * @return 用户反馈 + */ + public UserFeedback selectUserFeedbackById(String id); + + /** + * 查询用户反馈列表 + * + * @param userFeedback 用户反馈 + * @return 用户反馈集合 + */ + public List selectUserFeedbackList(UserFeedback userFeedback); + + /** + * 新增用户反馈 + * + * @param userFeedback 用户反馈 + * @return 结果 + */ + public int insertUserFeedback(UserFeedback userFeedback); + + /** + * 修改用户反馈 + * + * @param userFeedback 用户反馈 + * @return 结果 + */ + public int updateUserFeedback(UserFeedback userFeedback); + + /** + * 批量删除用户反馈 + * + * @param ids 需要删除的用户反馈主键集合 + * @return 结果 + */ + public int deleteUserFeedbackByIds(String[] ids); + + /** + * 删除用户反馈信息 + * + * @param id 用户反馈主键 + * @return 结果 + */ + public int deleteUserFeedbackById(String id); +} diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/UserFeedbackServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/UserFeedbackServiceImpl.java new file mode 100644 index 0000000..a99cf6c --- /dev/null +++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/UserFeedbackServiceImpl.java @@ -0,0 +1,94 @@ +package com.ruoyi.system.service.impl; + +import com.ruoyi.common.core.domain.entity.UserFeedback; +import com.ruoyi.system.mapper.UserFeedbackMapper; +import com.ruoyi.system.service.IUserFeedbackService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.List; + +/** + * 用户反馈Service业务层处理 + * + * @author ruoyi + * @date 2025-08-21 + */ +@Service +public class UserFeedbackServiceImpl implements IUserFeedbackService +{ + @Autowired + private UserFeedbackMapper userFeedbackMapper; + + /** + * 查询用户反馈 + * + * @param id 用户反馈主键 + * @return 用户反馈 + */ + @Override + public UserFeedback selectUserFeedbackById(String id) + { + return userFeedbackMapper.selectUserFeedbackById(id); + } + + /** + * 查询用户反馈列表 + * + * @param userFeedback 用户反馈 + * @return 用户反馈 + */ + @Override + public List selectUserFeedbackList(UserFeedback userFeedback) + { + return userFeedbackMapper.selectUserFeedbackList(userFeedback); + } + + /** + * 新增用户反馈 + * + * @param userFeedback 用户反馈 + * @return 结果 + */ + @Override + public int insertUserFeedback(UserFeedback userFeedback) + { + return userFeedbackMapper.insertUserFeedback(userFeedback); + } + + /** + * 修改用户反馈 + * + * @param userFeedback 用户反馈 + * @return 结果 + */ + @Override + public int updateUserFeedback(UserFeedback userFeedback) + { + return userFeedbackMapper.updateUserFeedback(userFeedback); + } + + /** + * 批量删除用户反馈 + * + * @param ids 需要删除的用户反馈主键 + * @return 结果 + */ + @Override + public int deleteUserFeedbackByIds(String[] ids) + { + return userFeedbackMapper.deleteUserFeedbackByIds(ids); + } + + /** + * 删除用户反馈信息 + * + * @param id 用户反馈主键 + * @return 结果 + */ + @Override + public int deleteUserFeedbackById(String id) + { + return userFeedbackMapper.deleteUserFeedbackById(id); + } +} diff --git a/ruoyi-system/src/main/resources/mapper/system/UserFeedbackMapper.xml b/ruoyi-system/src/main/resources/mapper/system/UserFeedbackMapper.xml new file mode 100644 index 0000000..fe743c2 --- /dev/null +++ b/ruoyi-system/src/main/resources/mapper/system/UserFeedbackMapper.xml @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + select id, feedback_content, user_name, contact_type, contact_info, status, created_at, updated_at, ip_address, user_agent, attachment_path from user_feedback + + + + + + + + insert into user_feedback + + feedback_content, + user_name, + contact_type, + contact_info, + status, + created_at, + updated_at, + ip_address, + user_agent, + attachment_path, + + + #{feedbackContent}, + #{userName}, + #{contactType}, + #{contactInfo}, + #{status}, + #{createdAt}, + #{updatedAt}, + #{ipAddress}, + #{userAgent}, + #{attachmentPath}, + + + + + update user_feedback + + feedback_content = #{feedbackContent}, + user_name = #{userName}, + contact_type = #{contactType}, + contact_info = #{contactInfo}, + status = #{status}, + created_at = #{createdAt}, + updated_at = #{updatedAt}, + ip_address = #{ipAddress}, + user_agent = #{userAgent}, + attachment_path = #{attachmentPath}, + + where id = #{id} + + + + delete from user_feedback where id = #{id} + + + + delete from user_feedback where id in + + #{id} + + + \ No newline at end of file diff --git a/ruoyi-ui/src/api/feedback/feedback.js b/ruoyi-ui/src/api/feedback/feedback.js new file mode 100644 index 0000000..edae105 --- /dev/null +++ b/ruoyi-ui/src/api/feedback/feedback.js @@ -0,0 +1,44 @@ +import request from '@/utils/request' + +// 查询用户反馈列表 +export function listFeedback(query) { + return request({ + url: '/back/feedback/list', + method: 'get', + params: query + }) +} + +// 查询用户反馈详细 +export function getFeedback(id) { + return request({ + url: '/back/feedback/' + id, + method: 'get' + }) +} + +// 新增用户反馈 +export function addFeedback(data) { + return request({ + url: '/back/feedback', + method: 'post', + data: data + }) +} + +// 修改用户反馈 +export function updateFeedback(data) { + return request({ + url: '/back/feedback', + method: 'put', + data: data + }) +} + +// 删除用户反馈 +export function delFeedback(id) { + return request({ + url: '/back/feedback/' + id, + method: 'delete' + }) +} diff --git a/ruoyi-ui/src/views/feedback/index.vue b/ruoyi-ui/src/views/feedback/index.vue new file mode 100644 index 0000000..cbe30d7 --- /dev/null +++ b/ruoyi-ui/src/views/feedback/index.vue @@ -0,0 +1,302 @@ + + + + + \ No newline at end of file