feat():learning后台管理项目初始化

This commit is contained in:
yuj
2025-12-04 16:23:46 +08:00
parent 39886d50d2
commit 88e048f4d1
154 changed files with 28966 additions and 6 deletions

View File

@@ -0,0 +1,195 @@
package handlers
import (
"strconv"
"goalfymax-admin/internal/models"
"goalfymax-admin/internal/services"
"goalfymax-admin/pkg/utils"
"github.com/gin-gonic/gin"
)
// UserFeedbackHandler 用户反馈处理器
type UserFeedbackHandler struct {
service *services.UserFeedbackService
response *utils.Response
}
// NewUserFeedbackHandler 创建用户反馈处理器
func NewUserFeedbackHandler(service *services.UserFeedbackService) *UserFeedbackHandler {
return &UserFeedbackHandler{
service: service,
response: utils.NewResponse(),
}
}
// List 获取用户反馈列表
func (h *UserFeedbackHandler) List(c *gin.Context) {
var req models.UserFeedbackListRequest
if err := c.ShouldBindQuery(&req); err != nil {
h.response.ValidateError(c, err)
return
}
result, err := h.service.List(c.Request.Context(), &req)
if err != nil {
h.response.InternalServerError(c, err.Error())
return
}
h.response.Success(c, result)
}
// GetByID 根据ID获取用户反馈
func (h *UserFeedbackHandler) GetByID(c *gin.Context) {
idStr := c.Param("id")
id, err := strconv.ParseInt(idStr, 10, 64)
if err != nil {
h.response.BadRequest(c, "无效的反馈ID")
return
}
feedbackItem, err := h.service.GetByID(c.Request.Context(), id)
if err != nil {
if err.Error() == "反馈不存在" {
h.response.NotFound(c, "反馈不存在")
return
}
h.response.InternalServerError(c, err.Error())
return
}
h.response.Success(c, feedbackItem)
}
// MarkHandled 标记为已处理
func (h *UserFeedbackHandler) MarkHandled(c *gin.Context) {
idStr := c.Param("id")
id, err := strconv.ParseInt(idStr, 10, 64)
if err != nil {
h.response.BadRequest(c, "无效的反馈ID")
return
}
var req models.UserFeedbackMarkRequest
if err := c.ShouldBindJSON(&req); err != nil {
h.response.ValidateError(c, err)
return
}
// 获取当前用户ID从JWT token中解析
userID, exists := c.Get("user_id")
if !exists {
h.response.Unauthorized(c, "无法获取用户信息")
return
}
// 处理用户ID支持多种类型
var handledBy int
switch v := userID.(type) {
case int:
handledBy = v
case uint:
handledBy = int(v)
case string:
var err error
handledBy, err = strconv.Atoi(v)
if err != nil {
h.response.InternalServerError(c, "用户ID格式错误")
return
}
default:
h.response.InternalServerError(c, "用户ID格式错误")
return
}
// 获取当前状态以确定切换后的状态
feedback, err := h.service.GetByID(c.Request.Context(), id)
if err != nil {
if err.Error() == "反馈不存在" {
h.response.NotFound(c, "反馈不存在")
return
}
h.response.InternalServerError(c, err.Error())
return
}
newStatus := 0
message := "标记为未处理成功"
if feedback.Status == 0 {
// 当前是未处理,切换为已处理
newStatus = 1
message = "标记为已处理成功"
}
err = h.service.MarkHandled(c.Request.Context(), id, handledBy, req.Note)
if err != nil {
if err.Error() == "反馈不存在" {
h.response.NotFound(c, "反馈不存在")
return
}
if err.Error() == "处理人ID无效" {
h.response.BadRequest(c, err.Error())
return
}
h.response.InternalServerError(c, err.Error())
return
}
// 返回处理结果
result := map[string]interface{}{
"id": id,
"status": newStatus,
"message": message,
}
if newStatus == 1 {
result["handled_by"] = handledBy
}
h.response.Success(c, result)
}
// Delete 删除用户反馈
func (h *UserFeedbackHandler) Delete(c *gin.Context) {
idStr := c.Param("id")
id, err := strconv.ParseInt(idStr, 10, 64)
if err != nil {
h.response.BadRequest(c, "无效的反馈ID")
return
}
err = h.service.Delete(c.Request.Context(), id)
if err != nil {
if err.Error() == "反馈不存在" {
h.response.NotFound(c, "反馈不存在")
return
}
h.response.InternalServerError(c, err.Error())
return
}
h.response.Success(c, gin.H{"message": "删除成功"})
}
// GetStatistics 获取反馈统计信息
func (h *UserFeedbackHandler) GetStatistics(c *gin.Context) {
stats, err := h.service.GetStatistics(c.Request.Context())
if err != nil {
h.response.InternalServerError(c, err.Error())
return
}
h.response.Success(c, stats)
}
// hasHTTPPrefix 判断字符串是否为 http/https URL
func hasHTTPPrefix(s string) bool {
if len(s) < 7 {
return false
}
if len(s) >= 8 && (s[:8] == "https://") {
return true
}
return len(s) >= 7 && (s[:7] == "http://")
}