improve the functions related to commenting on images

This commit is contained in:
landaiqing
2024-09-23 00:53:43 +08:00
parent 8d5d918a7d
commit 7aae53e533
32 changed files with 1004 additions and 86 deletions

View File

@@ -2,7 +2,7 @@ package client_api
import (
"github.com/gin-gonic/gin"
uuid "github.com/satori/go.uuid"
"github.com/google/uuid"
"schisandra-cloud-album/common/constant"
"schisandra-cloud-album/common/redis"
"schisandra-cloud-album/common/result"
@@ -31,12 +31,16 @@ func (ClientAPI) GenerateClientId(c *gin.Context) {
return
}
// 生成新的客户端ID
v1 := uuid.NewV1()
err := redis.Set(constant.UserLoginClientRedisKey+ip, v1.String(), time.Hour*24*7).Err()
uid, err := uuid.NewUUID()
if err != nil {
global.LOG.Error(err)
return
}
result.OkWithData(v1.String(), c)
err = redis.Set(constant.UserLoginClientRedisKey+ip, uid, time.Hour*24*7).Err()
if err != nil {
global.LOG.Error(err)
return
}
result.OkWithData(uid, c)
return
}

View File

@@ -1,7 +1,30 @@
package comment_api
import "schisandra-cloud-album/service"
import (
"schisandra-cloud-album/model"
"schisandra-cloud-album/service"
)
type CommentAPI struct{}
var commentReplyService = service.Service.CommentReplyService
type CommentImages struct {
TopicId string `json:"topic_id" bson:"topic_id" required:"true"`
CommentId int64 `json:"comment_id" bson:"comment_id" required:"true"`
UserId string `json:"user_id" bson:"user_id" required:"true"`
Images []string `json:"image_url" bson:"images" required:"true"`
CreatedAt string `json:"created_at" bson:"created_at" required:"true"`
}
type CommentData struct {
Comment model.ScaCommentReply `json:"comment"`
Images []string `json:"images,omitempty"`
}
type CommentResponse struct {
Size int `json:"size"`
Total int64 `json:"total"`
Current int `json:"current"`
Comments []CommentData `json:"comments"`
}

View File

@@ -1,28 +1,235 @@
package comment_api
import (
"context"
"errors"
"github.com/acmestack/gorm-plus/gplus"
ginI18n "github.com/gin-contrib/i18n"
"github.com/gin-gonic/gin"
"github.com/mssola/useragent"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"schisandra-cloud-album/api/comment_api/dto"
"schisandra-cloud-album/common/enum"
"schisandra-cloud-album/common/result"
"schisandra-cloud-album/global"
"schisandra-cloud-album/model"
"schisandra-cloud-album/utils"
"time"
)
// CommentSubmit 提交评论
// @Summary 提交评论
// @Description 提交评论
// @Tags 评论
// @Accept json
// @Produce json
// @Param comment_request body dto.CommentRequest true "评论请求"
// @Router /auth/comment/submit [post]
func (CommentAPI) CommentSubmit(c *gin.Context) {
commentRequest := dto.CommentRequest{}
err := c.ShouldBindJSON(&commentRequest)
if err := c.ShouldBindJSON(&commentRequest); err != nil {
result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c)
return
}
if commentRequest.Content == "" || commentRequest.UserID == "" || commentRequest.TopicId == "" {
result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c)
return
}
if len(commentRequest.Images) > 3 {
result.FailWithMessage(ginI18n.MustGetMessage(c, "TooManyImages"), c)
return
}
userAgent := c.GetHeader("User-Agent")
if userAgent == "" {
global.LOG.Errorln("user-agent is empty")
return
}
ua := useragent.New(userAgent)
ip := utils.GetClientIP(c)
location, err := global.IP2Location.SearchByStr(ip)
if err != nil {
global.LOG.Errorln(err)
return
}
location = utils.RemoveZeroAndAdjust(location)
browser, _ := ua.Browser()
operatingSystem := ua.OS()
isAuthor := 0
if commentRequest.UserID == commentRequest.Author {
isAuthor = 1
}
commentReply := model.ScaCommentReply{
Content: commentRequest.Content,
UserId: commentRequest.UserID,
TopicId: commentRequest.TopicId,
TopicType: enum.CommentTopicType,
CommentType: enum.COMMENT,
Author: isAuthor,
CommentIp: ip,
Location: location,
Browser: browser,
OperatingSystem: operatingSystem,
}
if err = commentReplyService.CreateCommentReply(&commentReply); err != nil {
result.FailWithMessage(ginI18n.MustGetMessage(c, "CommentSubmitFailed"), c)
return
}
if len(commentRequest.Images) > 0 {
commentImages := CommentImages{
TopicId: commentRequest.TopicId,
CommentId: commentReply.Id,
UserId: commentRequest.UserID,
Images: commentRequest.Images,
CreatedAt: time.Now().Format("2006-01-02 15:04:05"),
}
if _, err = global.MongoDB.Database(global.CONFIG.MongoDB.DB).Collection("comment_images").InsertOne(context.Background(), commentImages); err != nil {
global.LOG.Errorln(err)
result.FailWithMessage(ginI18n.MustGetMessage(c, "CommentSubmitFailed"), c)
return
}
}
result.OkWithMessage(ginI18n.MustGetMessage(c, "CommentSubmitSuccess"), c)
return
}
// ReplySubmit 提交回复
// @Summary 提交回复
// @Description 提交回复
// @Tags 评论
// @Accept json
// @Produce json
// @Param reply_comment_request body dto.ReplyCommentRequest true "回复评论请求"
// @Router /auth/reply/submit [post]
func (CommentAPI) ReplySubmit(c *gin.Context) {
replyCommentRequest := dto.ReplyCommentRequest{}
if err := c.ShouldBindJSON(&replyCommentRequest); err != nil {
result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c)
return
}
if replyCommentRequest.Content == "" ||
replyCommentRequest.UserID == "" ||
replyCommentRequest.TopicId == "" ||
replyCommentRequest.ReplyId == "" ||
replyCommentRequest.ReplyUser == "" {
result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c)
return
}
if len(replyCommentRequest.Images) > 3 {
result.FailWithMessage(ginI18n.MustGetMessage(c, "TooManyImages"), c)
return
}
userAgent := c.GetHeader("User-Agent")
if userAgent == "" {
global.LOG.Errorln("user-agent is empty")
return
}
ua := useragent.New(userAgent)
ip := utils.GetClientIP(c)
location, err := global.IP2Location.SearchByStr(ip)
if err != nil {
global.LOG.Errorln(err)
return
}
location = utils.RemoveZeroAndAdjust(location)
browser, _ := ua.Browser()
operatingSystem := ua.OS()
isAuthor := 0
if replyCommentRequest.UserID == replyCommentRequest.Author {
isAuthor = 1
}
commentReply := model.ScaCommentReply{
Content: replyCommentRequest.Content,
UserId: replyCommentRequest.UserID,
TopicId: replyCommentRequest.TopicId,
TopicType: enum.CommentTopicType,
CommentType: enum.REPLY,
ReplyId: replyCommentRequest.ReplyId,
ReplyUser: replyCommentRequest.ReplyUser,
Author: isAuthor,
CommentIp: ip,
Location: location,
Browser: browser,
OperatingSystem: operatingSystem,
}
if err = commentReplyService.CreateCommentReply(&commentReply); err != nil {
result.FailWithMessage(ginI18n.MustGetMessage(c, "CommentSubmitFailed"), c)
return
}
if len(replyCommentRequest.Images) > 0 {
commentImages := CommentImages{
TopicId: replyCommentRequest.TopicId,
CommentId: commentReply.Id,
UserId: replyCommentRequest.UserID,
Images: replyCommentRequest.Images,
CreatedAt: time.Now().Format("2006-01-02 15:04:05"),
}
if _, err = global.MongoDB.Database(global.CONFIG.MongoDB.DB).Collection("comment_images").InsertOne(context.Background(), commentImages); err != nil {
global.LOG.Errorln(err)
result.FailWithMessage(ginI18n.MustGetMessage(c, "CommentSubmitFailed"), c)
return
}
}
result.OkWithMessage(ginI18n.MustGetMessage(c, "CommentSubmitSuccess"), c)
return
}
// CommentList 获取评论列表
// @Summary 获取评论列表
// @Description 获取评论列表
// @Tags 评论
// @Accept json
// @Produce json
// @Param comment_list_request body dto.CommentListRequest true "评论列表请求"
// @Router /auth/comment/list [post]
func (CommentAPI) CommentList(c *gin.Context) {
commentListRequest := dto.CommentListRequest{}
err := c.ShouldBindJSON(&commentListRequest)
if err != nil {
result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c)
return
}
content := commentRequest.Content
images := commentRequest.Images
if content == "" {
result.FailWithMessage(ginI18n.MustGetMessage(c, "RequestParamsNotEmpty"), c)
if commentListRequest.TopicId == "" {
result.FailWithMessage(ginI18n.MustGetMessage(c, "ParamsError"), c)
return
}
if len(images) > 5 {
result.FailWithMessage(ginI18n.MustGetMessage(c, "TooManyImages"), c)
return
query, u := gplus.NewQuery[model.ScaCommentReply]()
page := gplus.NewPage[model.ScaCommentReply](commentListRequest.Page, commentListRequest.Size)
query.Eq(&u.TopicId, commentListRequest.TopicId).OrderByDesc(&u.Likes)
page, _ = gplus.SelectPage(page, query)
var commentsWithImages []CommentData
for _, user := range page.Records {
// 获取评论图片
commentImages := CommentImages{}
wrong := global.MongoDB.Database(global.CONFIG.MongoDB.DB).Collection("comment_images").FindOne(context.Background(), bson.M{"comment_id": user.Id}).Decode(&commentImages)
if wrong != nil && !errors.Is(wrong, mongo.ErrNoDocuments) {
global.LOG.Errorln(wrong)
}
commentsWithImages = append(commentsWithImages, CommentData{
Comment: *user,
Images: commentImages.Images,
})
}
response := CommentResponse{
Comments: commentsWithImages,
Size: page.Size,
Current: page.Current,
Total: page.Total,
}
result.OkWithData(response, c)
return
}

View File

@@ -3,4 +3,21 @@ package dto
type CommentRequest struct {
Content string `json:"content"`
Images []string `json:"images"`
UserID string `json:"user_id"`
TopicId string `json:"topic_id"`
Author string `json:"author"`
}
type ReplyCommentRequest struct {
Content string `json:"content"`
Images []string `json:"images"`
UserID string `json:"user_id"`
TopicId string `json:"topic_id"`
ReplyId string `json:"reply_id"`
ReplyUser string `json:"reply_user"`
Author string `json:"author"`
}
type CommentListRequest struct {
TopicId string `json:"topic_id"`
Page int `json:"page" default:"1"`
Size int `json:"size" default:"10"`
}

View File

@@ -9,7 +9,6 @@ import (
"github.com/ArtisanCloud/PowerWeChat/v3/src/kernel/messages"
models2 "github.com/ArtisanCloud/PowerWeChat/v3/src/kernel/models"
"github.com/ArtisanCloud/PowerWeChat/v3/src/officialAccount/server/handlers/models"
"github.com/DanPlayer/randomname"
ginI18n "github.com/gin-contrib/i18n"
"github.com/gin-gonic/gin"
"github.com/yitter/idgenerator-go/idgen"
@@ -18,6 +17,7 @@ import (
"schisandra-cloud-album/api/websocket_api"
"schisandra-cloud-album/common/constant"
"schisandra-cloud-album/common/enum"
"schisandra-cloud-album/common/randomname"
"schisandra-cloud-album/common/redis"
"schisandra-cloud-album/common/result"
"schisandra-cloud-album/global"

View File

@@ -2,7 +2,6 @@ package user_api
import (
"errors"
"github.com/DanPlayer/randomname"
ginI18n "github.com/gin-contrib/i18n"
"github.com/gin-gonic/gin"
"github.com/mssola/useragent"
@@ -12,6 +11,7 @@ import (
"schisandra-cloud-album/api/user_api/dto"
"schisandra-cloud-album/common/constant"
"schisandra-cloud-album/common/enum"
"schisandra-cloud-album/common/randomname"
"schisandra-cloud-album/common/redis"
"schisandra-cloud-album/common/result"
"schisandra-cloud-album/global"

View File

@@ -0,0 +1,6 @@
package enum
var (
COMMENT = 0
REPLY = 1
)

View File

@@ -0,0 +1,5 @@
package enum
var (
CommentTopicType = 0
)

View File

@@ -0,0 +1,8 @@
package randomname
// ActSomethingSlice 做什么事情
var ActSomethingSlice = []string{
"打豆豆", "吃爆米花", "走向人生巅峰", "大力出奇迹", "得到了金球奖", "爆射世界杯", "有亿点点忧伤", "完成了梅开二度", "完成了帽子戏法", "完成了大四喜", "完成了五子登科",
"望穿秋水", "掐指一算", "横扫千军", "一眼定情", "会发财", "求而不得", "舞力四射", "横扫六合", "救了一个美女", "使出了佛怒火莲", "在巴黎徒步", "心花怒放", "在武汉看电影",
}
var ActSomethingSliceCount = len(ActSomethingSlice)

View File

@@ -0,0 +1,31 @@
package randomname
// AdjectiveSlice 形容词
var AdjectiveSlice = []string{
"帅气的", "迷人的", "大汗淋漓的", "朝气蓬勃的", "隐身的", "天神下凡的", "快乐的", "冷静的", "醉熏的", "潇洒的", "糊涂的", "积极的",
"冷酷的", "深情的", "粗暴的", "温柔的", "可爱的", "愉快的", "义气的", "认真的", "威武的", "传统的", "潇洒的", "漂亮的", "自然的",
"专一的", "听话的", "昏睡的", "狂野的", "等待的", "搞怪的", "幽默的", "魁梧的", "活泼的", "开心的", "高兴的", "超帅的", "留胡子的",
"坦率的", "直率的", "轻松的", "痴情的", "完美的", "精明的", "无聊的", "有魅力的", "丰富的", "高挑的", "傻傻的", "冷艳的", "爱听歌的",
"繁荣的", "饱满的", "炙热的", "暴躁的", "碧蓝的", "俊逸的", "英勇的", "健忘的", "故意的", "无心的", "土豪的", "朴实的", "兴奋的",
"幸福的", "淡定的", "不安的", "阔达的", "孤独的", "独特的", "疯狂的", "时尚的", "落后的", "风趣的", "忧伤的", "大胆的", "爱笑的", "矮小的",
"健康的", "合适的", "玩命的", "沉默的", "斯文的", "香蕉的", "苹果的", "鲤鱼的", "鳗鱼的", "任性的", "细心的", "粗心的", "大意的", "甜甜的",
"酷酷的", "健壮的", "英俊的", "霸气的", "阳光的", "默默的", "大力的", "孝顺的", "忧虑的", "着急的", "紧张的", "善良的", "凶狠的", "害怕的",
"重要的", "危机的", "欢喜的", "欣慰的", "满意的", "跳跃的", "诚心的", "称心的", "如意的", "怡然的", "娇气的", "无奈的", "无语的", "激动的",
"愤怒的", "美好的", "感动的", "激情的", "激昂的", "震动的", "虚拟的", "超级的", "寒冷的", "精明的", "明理的", "犹豫的", "忧郁的", "寂寞的",
"奋斗的", "勤奋的", "现代的", "过时的", "稳重的", "热情的", "含蓄的", "开放的", "无辜的", "多情的", "纯真的", "拉长的", "热心的", "从容的",
"体贴的", "风中的", "曾经的", "追寻的", "儒雅的", "优雅的", "开朗的", "外向的", "内向的", "清爽的", "文艺的", "长情的", "平常的", "单身的",
"伶俐的", "高大的", "懦弱的", "柔弱的", "爱笑的", "乐观的", "耍酷的", "酷炫的", "神勇的", "年轻的", "唠叨的", "瘦瘦的", "无情的", "包容的",
"顺心的", "畅快的", "舒适的", "靓丽的", "负责的", "背后的", "简单的", "谦让的", "彩色的", "缥缈的", "欢呼的", "生动的", "复杂的", "慈祥的",
"仁爱的", "魔幻的", "虚幻的", "淡然的", "受伤的", "雪白的", "高高的", "糟糕的", "顺利的", "闪闪的", "羞涩的", "缓慢的", "迅速的", "优秀的",
"聪明的", "含糊的", "俏皮的", "淡淡的", "坚强的", "平淡的", "欣喜的", "能干的", "灵巧的", "友好的", "机智的", "机灵的", "正直的", "谨慎的",
"俭朴的", "殷勤的", "虚心的", "辛勤的", "自觉的", "无私的", "无限的", "踏实的", "老实的", "现实的", "可靠的", "务实的", "拼搏的", "个性的",
"粗犷的", "活力的", "成就的", "勤劳的", "单纯的", "落寞的", "朴素的", "悲凉的", "忧心的", "洁净的", "清秀的", "自由的", "小巧的", "单薄的",
"贪玩的", "刻苦的", "干净的", "壮观的", "和谐的", "文静的", "调皮的", "害羞的", "安详的", "自信的", "端庄的", "坚定的", "美满的", "舒心的",
"温暖的", "专注的", "勤恳的", "美丽的", "腼腆的", "优美的", "甜美的", "甜蜜的", "整齐的", "动人的", "典雅的", "尊敬的", "舒服的", "妩媚的",
"秀丽的", "喜悦的", "甜美的", "彪壮的", "强健的", "大方的", "俊秀的", "聪慧的", "陶醉的", "悦耳的", "动听的", "明亮的", "结实的", "魁梧的",
"标致的", "清脆的", "敏感的", "光亮的", "大气的", "老迟到的", "知性的", "冷傲的", "呆萌的", "野性的", "隐形的", "笑点低的", "微笑的", "笨笨的",
"难过的", "沉静的", "火星上的", "失眠的", "安静的", "纯情的", "要减肥的", "迷路的", "烂漫的", "哭泣的", "贤惠的", "苗条的", "温婉的", "发嗲的",
"会撒娇的", "贪玩的", "执着的", "眯眯眼的", "花痴的", "想人陪的", "眼睛大的", "高贵的", "傲娇的", "心灵美的", "爱撒娇的", "细腻的", "天真的",
"怕黑的", "感性的", "飘逸的", "怕孤独的", "忐忑的", "还单身的", "怕孤单的", "懵懂的",
}
var AdjectiveSliceCount = len(AdjectiveSlice)

View File

@@ -0,0 +1,11 @@
package randomname
// PersonSlice 人物
var PersonSlice = []string{
"梅西", "罗纳尔多", "内马尔", "贝克汉姆", "姆巴佩", "苏牙", "小罗", "大罗", "鲁尼", "本泽马", "贝利", "约翰", "柯南", "米老鼠",
"弗朗茨", "普拉蒂尼", "迪斯蒂法诺", "普斯卡什", "乔治·贝斯特", "范巴斯滕", "尤西比奥", "列夫·雅辛", "博比", "博比·摩尔", "盖德·穆勒",
"巴乔", "斯坦利", "济科", "弗兰科", "加林查", "保罗", "肯尼", "巴蒂斯图塔", "坎通纳", "哈吉", "罗马里奥",
"齐达內", "古利特", "约翰·查尔斯", "卡卡", "哈维", "伊布", "莫德里奇", "欧文", "巴乔", "萧炎", "鸣人", "佐助", "盖茨比", "乔布斯", "索尔",
"宙斯", "雅典娜", "星矢", "托尼", "科比", "乔丹", "西瓜太郎", "一休", "莫甘娜", "永恩", "爱因斯坦", "肖申克", "摩尔",
}
var PersonSliceCount = len(PersonSlice)

View File

@@ -0,0 +1,20 @@
package randomname
import (
"math/rand"
"time"
)
// GenerateName 生成随机昵称
func GenerateName() string {
var name string
rand.New(rand.NewSource(time.Now().UnixNano()))
selectedType := RandomType(rand.Intn(2))
switch selectedType {
case AdjectiveAndPerson:
name = AdjectiveSlice[rand.Intn(AdjectiveSliceCount)] + PersonSlice[rand.Intn(PersonSliceCount)]
case PersonActSomething:
name = PersonSlice[rand.Intn(PersonSliceCount)] + ActSomethingSlice[rand.Intn(ActSomethingSliceCount)]
}
return name
}

View File

@@ -0,0 +1,8 @@
package randomname
type RandomType int
const (
AdjectiveAndPerson RandomType = iota // 形容词+人物 例如:帅气的罗纳尔多
PersonActSomething // 人物+做事情 例如:梅西吃爆米花
)

View File

@@ -13,8 +13,8 @@ type Response struct {
}
const (
SUCCESS = 0
FAIL = -1
SUCCESS = 200
FAIL = 500
)
func Result(code int, msg string, data any, success bool, c *gin.Context) {

18
config/conf_mongodb.go Normal file
View File

@@ -0,0 +1,18 @@
package config
import "strconv"
type MongoDB struct {
Host string `yaml:"host"`
Port int `yaml:"port"`
AuthSource string `yaml:"auth-source"`
DB string `yaml:"db"`
User string `yaml:"user"`
Password string `yaml:"password"`
MaxOpenConn int `yaml:"max-open-conn"`
MaxIdleConn int `yaml:"max-idle-conn"`
}
func (m *MongoDB) MongoDsn() string {
return "mongodb://" + m.Host + ":" + strconv.Itoa(m.Port)
}

View File

@@ -12,4 +12,5 @@ type Config struct {
OAuth OAuth `yaml:"oauth"`
Swagger Swagger `yaml:"swagger"`
Casbin Casbin `yaml:"casbin"`
MongoDB MongoDB `yaml:"mongodb"`
}

View File

@@ -2,6 +2,7 @@ package core
import (
"fmt"
"github.com/acmestack/gorm-plus/gplus"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/logger"
@@ -61,5 +62,7 @@ func MySQlConnect() *gorm.DB {
sqlDB.SetMaxIdleConns(global.CONFIG.MySQL.MaxIdleConnes)
sqlDB.SetMaxOpenConns(global.CONFIG.MySQL.MaxOpenConnes)
sqlDB.SetConnMaxLifetime(time.Hour * 4) //连接最大复用时间
// 初始化gplus
gplus.Init(db)
return db
}

40
core/mongodb.go Normal file
View File

@@ -0,0 +1,40 @@
package core
import (
"context"
"fmt"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
"schisandra-cloud-album/global"
"time"
)
// InitMongoDB initializes the MongoDB connection
func InitMongoDB() {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
clientOptions := options.Client().ApplyURI(global.CONFIG.MongoDB.MongoDsn())
clientOptions.SetAuth(options.Credential{
AuthMechanism: "SCRAM-SHA-256",
AuthMechanismProperties: nil,
AuthSource: global.CONFIG.MongoDB.AuthSource,
Username: global.CONFIG.MongoDB.User,
Password: global.CONFIG.MongoDB.Password,
PasswordSet: true,
})
connect, err := mongo.Connect(ctx, clientOptions)
if err != nil {
global.LOG.Fatalf(err.Error())
return
}
// Check the connection
err = connect.Ping(context.TODO(), nil)
if err != nil {
global.LOG.Fatalf(err.Error())
return
}
global.MongoDB = connect
fmt.Println("Connected to MongoDB!")
}

View File

@@ -42,6 +42,33 @@ const docTemplate = `{
"responses": {}
}
},
"/api/auth/permission/assign": {
"post": {
"description": "给指定角色分配权限",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"权限管理"
],
"summary": "给指定角色分配权限",
"parameters": [
{
"description": "权限列表",
"name": "permissions",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.AddPermissionToRoleRequestDto"
}
}
],
"responses": {}
}
},
"/api/auth/role/add_role_to_user": {
"post": {
"description": "给指定用户添加角色",
@@ -137,6 +164,22 @@ const docTemplate = `{
}
}
},
"/api/auth/user/logout": {
"post": {
"tags": [
"用户模块"
],
"summary": "退出登录",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
}
}
}
},
"/api/auth/user/query_by_phone": {
"get": {
"tags": [
@@ -405,6 +448,60 @@ const docTemplate = `{
}
}
},
"/api/comment/reply": {
"post": {
"description": "提交回复",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"评论"
],
"summary": "提交回复",
"parameters": [
{
"description": "回复评论请求",
"name": "reply_comment_request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.ReplyCommentRequest"
}
}
],
"responses": {}
}
},
"/api/comment/submit": {
"post": {
"description": "提交评论",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"评论"
],
"summary": "提交评论",
"parameters": [
{
"description": "评论请求",
"name": "comment_request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.CommentRequest"
}
}
],
"responses": {}
}
},
"/api/oauth/callback_notify": {
"post": {
"description": "微信回调",
@@ -762,16 +859,6 @@ const docTemplate = `{
"summary": "创建websocket服务",
"responses": {}
}
},
"/api/ws/socket": {
"get": {
"description": "创建websocket服务",
"tags": [
"websocket"
],
"summary": "创建websocket服务(gorilla)",
"responses": {}
}
}
},
"definitions": {
@@ -800,6 +887,20 @@ const docTemplate = `{
}
}
},
"dto.AddPermissionToRoleRequestDto": {
"type": "object",
"properties": {
"method": {
"type": "string"
},
"permission": {
"type": "string"
},
"role_key": {
"type": "string"
}
}
},
"dto.AddRoleToUserRequestDto": {
"type": "object",
"properties": {
@@ -811,6 +912,26 @@ const docTemplate = `{
}
}
},
"dto.CommentRequest": {
"type": "object",
"properties": {
"content": {
"type": "string"
},
"images": {
"type": "array",
"items": {
"type": "string"
}
},
"topic_id": {
"type": "string"
},
"user_id": {
"type": "string"
}
}
},
"dto.PhoneLoginRequest": {
"type": "object",
"properties": {
@@ -825,6 +946,32 @@ const docTemplate = `{
}
}
},
"dto.ReplyCommentRequest": {
"type": "object",
"properties": {
"content": {
"type": "string"
},
"images": {
"type": "array",
"items": {
"type": "string"
}
},
"reply_id": {
"type": "string"
},
"reply_user": {
"type": "string"
},
"topic_id": {
"type": "string"
},
"user_id": {
"type": "string"
}
}
},
"dto.ResetPasswordRequest": {
"type": "object",
"properties": {
@@ -913,7 +1060,6 @@ const docTemplate = `{
"type": "integer"
},
"update_by": {
"description": "更新人",
"type": "string"
},
"update_time": {

View File

@@ -31,6 +31,33 @@
"responses": {}
}
},
"/api/auth/permission/assign": {
"post": {
"description": "给指定角色分配权限",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"权限管理"
],
"summary": "给指定角色分配权限",
"parameters": [
{
"description": "权限列表",
"name": "permissions",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.AddPermissionToRoleRequestDto"
}
}
],
"responses": {}
}
},
"/api/auth/role/add_role_to_user": {
"post": {
"description": "给指定用户添加角色",
@@ -126,6 +153,22 @@
}
}
},
"/api/auth/user/logout": {
"post": {
"tags": [
"用户模块"
],
"summary": "退出登录",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
}
}
}
},
"/api/auth/user/query_by_phone": {
"get": {
"tags": [
@@ -394,6 +437,60 @@
}
}
},
"/api/comment/reply": {
"post": {
"description": "提交回复",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"评论"
],
"summary": "提交回复",
"parameters": [
{
"description": "回复评论请求",
"name": "reply_comment_request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.ReplyCommentRequest"
}
}
],
"responses": {}
}
},
"/api/comment/submit": {
"post": {
"description": "提交评论",
"consumes": [
"application/json"
],
"produces": [
"application/json"
],
"tags": [
"评论"
],
"summary": "提交评论",
"parameters": [
{
"description": "评论请求",
"name": "comment_request",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/dto.CommentRequest"
}
}
],
"responses": {}
}
},
"/api/oauth/callback_notify": {
"post": {
"description": "微信回调",
@@ -751,16 +848,6 @@
"summary": "创建websocket服务",
"responses": {}
}
},
"/api/ws/socket": {
"get": {
"description": "创建websocket服务",
"tags": [
"websocket"
],
"summary": "创建websocket服务(gorilla)",
"responses": {}
}
}
},
"definitions": {
@@ -789,6 +876,20 @@
}
}
},
"dto.AddPermissionToRoleRequestDto": {
"type": "object",
"properties": {
"method": {
"type": "string"
},
"permission": {
"type": "string"
},
"role_key": {
"type": "string"
}
}
},
"dto.AddRoleToUserRequestDto": {
"type": "object",
"properties": {
@@ -800,6 +901,26 @@
}
}
},
"dto.CommentRequest": {
"type": "object",
"properties": {
"content": {
"type": "string"
},
"images": {
"type": "array",
"items": {
"type": "string"
}
},
"topic_id": {
"type": "string"
},
"user_id": {
"type": "string"
}
}
},
"dto.PhoneLoginRequest": {
"type": "object",
"properties": {
@@ -814,6 +935,32 @@
}
}
},
"dto.ReplyCommentRequest": {
"type": "object",
"properties": {
"content": {
"type": "string"
},
"images": {
"type": "array",
"items": {
"type": "string"
}
},
"reply_id": {
"type": "string"
},
"reply_user": {
"type": "string"
},
"topic_id": {
"type": "string"
},
"user_id": {
"type": "string"
}
}
},
"dto.ResetPasswordRequest": {
"type": "object",
"properties": {
@@ -902,7 +1049,6 @@
"type": "integer"
},
"update_by": {
"description": "更新人",
"type": "string"
},
"update_time": {

View File

@@ -15,6 +15,15 @@ definitions:
$ref: '#/definitions/model.ScaAuthPermission'
type: array
type: object
dto.AddPermissionToRoleRequestDto:
properties:
method:
type: string
permission:
type: string
role_key:
type: string
type: object
dto.AddRoleToUserRequestDto:
properties:
role_key:
@@ -22,6 +31,19 @@ definitions:
uid:
type: string
type: object
dto.CommentRequest:
properties:
content:
type: string
images:
items:
type: string
type: array
topic_id:
type: string
user_id:
type: string
type: object
dto.PhoneLoginRequest:
properties:
auto_login:
@@ -31,6 +53,23 @@ definitions:
phone:
type: string
type: object
dto.ReplyCommentRequest:
properties:
content:
type: string
images:
items:
type: string
type: array
reply_id:
type: string
reply_user:
type: string
topic_id:
type: string
user_id:
type: string
type: object
dto.ResetPasswordRequest:
properties:
captcha:
@@ -94,7 +133,6 @@ definitions:
description: 类型 0 菜单 1 目录 2 按钮 -1其他
type: integer
update_by:
description: 更新人
type: string
update_time:
description: 更新时间
@@ -121,6 +159,24 @@ paths:
summary: 批量添加权限
tags:
- 权限管理
/api/auth/permission/assign:
post:
consumes:
- application/json
description: 给指定角色分配权限
parameters:
- description: 权限列表
in: body
name: permissions
required: true
schema:
$ref: '#/definitions/dto.AddPermissionToRoleRequestDto'
produces:
- application/json
responses: {}
summary: 给指定角色分配权限
tags:
- 权限管理
/api/auth/role/add_role_to_user:
post:
consumes:
@@ -183,6 +239,16 @@ paths:
summary: 删除用户
tags:
- 用户模块
/api/auth/user/logout:
post:
responses:
"200":
description: OK
schema:
type: string
summary: 退出登录
tags:
- 用户模块
/api/auth/user/query_by_phone:
get:
parameters:
@@ -358,6 +424,42 @@ paths:
summary: 生成基础文字验证码
tags:
- 基础文字验证码
/api/comment/reply:
post:
consumes:
- application/json
description: 提交回复
parameters:
- description: 回复评论请求
in: body
name: reply_comment_request
required: true
schema:
$ref: '#/definitions/dto.ReplyCommentRequest'
produces:
- application/json
responses: {}
summary: 提交回复
tags:
- 评论
/api/comment/submit:
post:
consumes:
- application/json
description: 提交评论
parameters:
- description: 评论请求
in: body
name: comment_request
required: true
schema:
$ref: '#/definitions/dto.CommentRequest'
produces:
- application/json
responses: {}
summary: 提交评论
tags:
- 评论
/api/oauth/callback_notify:
post:
description: 微信回调
@@ -595,11 +697,4 @@ paths:
summary: 创建websocket服务
tags:
- websocket
/api/ws/socket:
get:
description: 创建websocket服务
responses: {}
summary: 创建websocket服务(gorilla)
tags:
- websocket
swagger: "2.0"

View File

@@ -9,6 +9,7 @@ import (
"github.com/wenlng/go-captcha/v2/click"
"github.com/wenlng/go-captcha/v2/rotate"
"github.com/wenlng/go-captcha/v2/slide"
"go.mongodb.org/mongo-driver/mongo"
"gorm.io/gorm"
"schisandra-cloud-album/config"
)
@@ -28,4 +29,5 @@ var (
Wechat *officialAccount.OfficialAccount // 微信公众号
Casbin *casbin.CachedEnforcer // casbin权限管理器
IP2Location *xdb.Searcher // IP地址定位
MongoDB *mongo.Client
)

32
go.mod
View File

@@ -1,11 +1,13 @@
module schisandra-cloud-album
go 1.22.5
go 1.23
toolchain go1.23.1
require (
github.com/ArtisanCloud/PowerLibs/v3 v3.2.5
github.com/ArtisanCloud/PowerLibs/v3 v3.2.6
github.com/ArtisanCloud/PowerWeChat/v3 v3.2.38
github.com/BurntSushi/toml v1.3.2
github.com/BurntSushi/toml v1.4.0
github.com/casbin/casbin/v2 v2.98.0
github.com/casbin/gorm-adapter/v3 v3.28.0
github.com/gin-contrib/cors v1.7.2
@@ -13,13 +15,13 @@ require (
github.com/gin-gonic/gin v1.10.0
github.com/golang-jwt/jwt/v5 v5.2.1
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
github.com/google/uuid v1.6.0
github.com/juju/ratelimit v1.0.2
github.com/lionsoul2014/ip2region/binding/golang v0.0.0-20240510055607-89e20ab7b6c6
github.com/lxzan/gws v1.8.5
github.com/mssola/useragent v1.0.0
github.com/pkg6/go-sms v0.1.2
github.com/redis/go-redis/v9 v9.6.1
github.com/satori/go.uuid v1.2.0
github.com/sirupsen/logrus v1.9.3
github.com/swaggo/files v1.0.1
github.com/swaggo/gin-swagger v1.6.0
@@ -28,8 +30,9 @@ require (
github.com/wenlng/go-captcha/v2 v2.0.0
github.com/wumansgy/goEncrypt v1.1.0
github.com/yitter/idgenerator-go v1.3.3
golang.org/x/crypto v0.25.0
golang.org/x/text v0.16.0
go.mongodb.org/mongo-driver v1.17.0
golang.org/x/crypto v0.27.0
golang.org/x/text v0.18.0
gopkg.in/yaml.v3 v3.0.1
gorm.io/driver/mysql v1.5.7
gorm.io/gen v0.3.26
@@ -39,8 +42,8 @@ require (
require (
filippo.io/edwards25519 v1.1.0 // indirect
github.com/ArtisanCloud/PowerSocialite/v3 v3.0.7 // indirect
github.com/DanPlayer/randomname v1.0.1 // indirect
github.com/KyleBanks/depth v1.2.1 // indirect
github.com/acmestack/gorm-plus v0.1.5 // indirect
github.com/bytedance/sonic v1.12.0 // indirect
github.com/bytedance/sonic/loader v0.2.0 // indirect
github.com/casbin/govaluate v1.2.0 // indirect
@@ -66,7 +69,7 @@ require (
github.com/goccy/go-json v0.10.3 // indirect
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
github.com/golang-sql/sqlexp v0.1.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect
github.com/jackc/pgx/v5 v5.5.5 // indirect
@@ -75,7 +78,7 @@ require (
github.com/jinzhu/now v1.1.5 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.17.5 // indirect
github.com/klauspost/compress v1.17.9 // indirect
github.com/klauspost/cpuid/v2 v2.2.8 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
@@ -83,6 +86,7 @@ require (
github.com/microsoft/go-mssqldb v1.6.0 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/montanaflynn/stats v0.7.1 // indirect
github.com/nicksnyder/go-i18n/v2 v2.4.0 // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
@@ -91,14 +95,20 @@ require (
github.com/remyoudompheng/bigfft v0.0.0-20230126093431-47fa9a501578 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.12 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.1.2 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
go.opentelemetry.io/otel v1.4.0 // indirect
go.opentelemetry.io/otel/trace v1.4.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/arch v0.8.0 // indirect
golang.org/x/image v0.18.0 // indirect
golang.org/x/mod v0.19.0 // indirect
golang.org/x/net v0.27.0 // indirect
golang.org/x/sync v0.7.0 // indirect
golang.org/x/sys v0.22.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.25.0 // indirect
golang.org/x/tools v0.23.0 // indirect
google.golang.org/protobuf v1.34.2 // indirect
gorm.io/datatypes v1.2.1 // indirect

64
go.sum
View File

@@ -1,7 +1,7 @@
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/ArtisanCloud/PowerLibs/v3 v3.2.5 h1:W3NKBTnh4d5RBzondNo++QdZ99HPYs5TQKMH2gngKvk=
github.com/ArtisanCloud/PowerLibs/v3 v3.2.5/go.mod h1:XFRnJA+D0b0IoeSk2ceZzBp9qxatMHOGtWdZCa/r/3U=
github.com/ArtisanCloud/PowerLibs/v3 v3.2.6 h1:xNDXBJ1VNYAEgs4UG/lSygzU66/XG3mTA7mm/qE//NY=
github.com/ArtisanCloud/PowerLibs/v3 v3.2.6/go.mod h1:xFGsskCnzAu+6rFEJbGVAlwhrwZPXAny6m7j71S/B5k=
github.com/ArtisanCloud/PowerSocialite/v3 v3.0.7 h1:P+erNlErr+X2v7Et+yTWaTfIRhw+HfpAPdvNIEwk9Gw=
github.com/ArtisanCloud/PowerSocialite/v3 v3.0.7/go.mod h1:VZQNCvcK/rldF3QaExiSl1gJEAkyc5/I8RLOd3WFZq4=
github.com/ArtisanCloud/PowerWeChat/v3 v3.2.38 h1:f2gDqq4s3FR3wEdaMJM/Cr3gRhSG3usjQhhbM3Tj+eU=
@@ -24,12 +24,12 @@ github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v0.8.0/go.mod h
github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o=
github.com/AzureAD/microsoft-authentication-library-for-go v1.1.0 h1:HCc0+LpPfpCKs6LGGLAhwBARt9632unrVcI6i8s/8os=
github.com/AzureAD/microsoft-authentication-library-for-go v1.1.0/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/DanPlayer/randomname v1.0.1 h1:BY7WkgB0gsjESNsqG7NADD5KSlWYAglCiRDKMJ9Q1Zo=
github.com/DanPlayer/randomname v1.0.1/go.mod h1:3baqzjkyc22BGUIAGK+maXF8I6vTcO+XF/tvXaZAU3E=
github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0=
github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho=
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
github.com/acmestack/gorm-plus v0.1.5 h1:8FhGeZ1fQpebtT8vgL0Gkt2sJkGjDFitYWnU/Ym2Xwo=
github.com/acmestack/gorm-plus v0.1.5/go.mod h1:qGJTQQkQ7ttaov5lIKLshyGaPdtVvJab0Td8iI08XLA=
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
@@ -81,6 +81,10 @@ github.com/glebarez/go-sqlite v1.20.3/go.mod h1:u3N6D/wftiAzIOJtZl6BmedqxmmkDfH3
github.com/glebarez/sqlite v1.7.0 h1:A7Xj/KN2Lvie4Z4rrgQHY8MsbebX3NyWsL3n2i82MVI=
github.com/glebarez/sqlite v1.7.0/go.mod h1:PkeevrRlF/1BhQBCnzcMWzgrIk7IOop+qS2jUYLfHhk=
github.com/go-bindata/go-bindata v3.1.2+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo=
github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ=
@@ -115,13 +119,17 @@ github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF0
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc=
github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4=
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
@@ -150,8 +158,8 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/juju/ratelimit v1.0.2 h1:sRxmtRiajbvrcLQT7S+JbqU0ntsb9W2yhSdNN8tWfaI=
github.com/juju/ratelimit v1.0.2/go.mod h1:qapgC/Gy+xNh9UxzV13HGGl/6UXNN+ct+vwSgWNm/qk=
github.com/klauspost/compress v1.17.5 h1:d4vBd+7CHydUqpFBgUEKkSdtSugf9YFmSkvUYPquI5E=
github.com/klauspost/compress v1.17.5/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM=
github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
@@ -186,6 +194,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8=
github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/mssola/useragent v1.0.0 h1:WRlDpXyxHDNfvZaPEut5Biveq86Ze4o4EMffyMxmH5o=
github.com/mssola/useragent v1.0.0/go.mod h1:hz9Cqz4RXusgg1EdI4Al0INR62kP7aPSRNHnpU+b85Y=
github.com/nicksnyder/go-i18n/v2 v2.4.0 h1:3IcvPOAvnCKwNm0TB0dLDTuawWEj+ax/RERNC+diLMM=
@@ -211,8 +221,6 @@ github.com/remyoudompheng/bigfft v0.0.0-20230126093431-47fa9a501578 h1:VstopitMQ
github.com/remyoudompheng/bigfft v0.0.0-20230126093431-47fa9a501578/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
@@ -247,9 +255,25 @@ github.com/wenlng/go-captcha/v2 v2.0.0 h1:7Z4Zy09SIHgvj9e8ZxP4VhYOwg7IHt8kGlVrE5
github.com/wenlng/go-captcha/v2 v2.0.0/go.mod h1:5hac1em3uXoyC5ipZ0xFv9umNM/waQvYAQdr0cx/h34=
github.com/wumansgy/goEncrypt v1.1.0 h1:Krr2FJL4GEsMTBvLfsnoTmgWb7rkGnL4siJ9K2cxMs0=
github.com/wumansgy/goEncrypt v1.1.0/go.mod h1:dWgF7mi5Ujmt8V5EoyRqjH6XtZ8wmNQyT4u2uvH8Pyg=
github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
github.com/yitter/idgenerator-go v1.3.3 h1:i6rzmpbCL0vlmr/tuW5+lSQzNuDG9vYBjIYRvnRcHE8=
github.com/yitter/idgenerator-go v1.3.3/go.mod h1:VVjbqFjGUsIkaXVkXEdmx1LiXUL3K1NvyxWPJBPbBpE=
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM=
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.mongodb.org/mongo-driver v1.17.0 h1:Hp4q2MCjvY19ViwimTs00wHi7G4yzxh4/2+nTx8r40k=
go.mongodb.org/mongo-driver v1.17.0/go.mod h1:wwWm/+BuOddhcq3n68LKRmgk2wXzmF6s0SFOa0GINL4=
go.opentelemetry.io/otel v1.4.0 h1:7ESuKPq6zpjRaY5nvVDGiuwK7VAJ8MwkKnmNJ9whNZ4=
go.opentelemetry.io/otel v1.4.0/go.mod h1:jeAqMFKy2uLIxCtKxoFj0FAL5zAPKQagc3+GtBWakzk=
go.opentelemetry.io/otel/sdk v1.4.0 h1:LJE4SW3jd4lQTESnlpQZcBhQ3oci0U2MLR5uhicfTHQ=
go.opentelemetry.io/otel/sdk v1.4.0/go.mod h1:71GJPNJh4Qju6zJuYl1CrYtXbrgfau/M9UAggqiy1UE=
go.opentelemetry.io/otel/trace v1.4.0 h1:4OOUrPZdVFQkbzl/JSdvGCWIdw5ONXXxzHlaLlWppmo=
go.opentelemetry.io/otel/trace v1.4.0/go.mod h1:uc3eRsqDfWs9R7b92xbQbU42/eTNz4N+gLP8qJCi4aE=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
@@ -265,8 +289,8 @@ golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
golang.org/x/image v0.16.0/go.mod h1:ugSZItdV4nOxyqp56HmXwH0Ry0nBCpjnZdpDaIHdoPs=
golang.org/x/image v0.18.0 h1:jGzIakQa/ZXI1I0Fxvaa9W7yP25TqT6cHIHn+6CqvSQ=
golang.org/x/image v0.18.0/go.mod h1:4yyo5vMFQjVjUcVk4jEQcU9MGy/rulF5WvUILseCM2E=
@@ -291,8 +315,8 @@ golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -307,8 +331,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@@ -318,13 +342,14 @@ golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224=
golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@@ -333,6 +358,7 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg=
golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg=
google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View File

@@ -64,4 +64,9 @@ RequestLimit = "request limit!"
PermissionVerifyFailed = "permission verify failed!"
IllegalRequests = "illegal requests!"
RequestParamsNotEmpty = "request params can not be empty!"
TooManyImages = "too many images!"
TooManyImages = "too many images!"
CommentSubmitFailed = "comment submit failed!"
CommentSubmitSuccess = "comment submit successfully!"
ImageStorageError = "image storage error!"
ImageDecodeError = "image decode error!"
ImageSaveError = "image save error!"

View File

@@ -64,4 +64,9 @@ RequestLimit = "请求频率过高!"
PermissionVerifyFailed = "权限验证失败!"
IllegalRequests = "非法请求!"
RequestParamsNotEmpty = "请求参数不能为空!"
TooManyImages = "最多只能上传5张图片!"
TooManyImages = "最多只能上传3张图片!"
CommentSubmitFailed = "评论提交失败!"
CommentSubmitSuccess = "评论提交成功!"
ImageStorageError = "图片存储错误!"
ImageDecodeError = "图片解码错误!"
ImageSaveError = "图片保存错误!"

View File

@@ -13,6 +13,7 @@ func main() {
core.InitConfig() // 读取配置文件
core.InitLogger() // 初始化日志
core.InitGorm() // 初始化数据库
core.InitMongoDB() // 初始化MongoDB
core.InitRedis() // 初始化redis
core.InitCaptcha() // 初始化验证码
core.InitIDGenerator() // 初始化ID生成器

View File

@@ -6,7 +6,8 @@ const ScaCommentLikesTableName = "sca_comment_likes"
type ScaCommentLikes struct {
Id int64 `gorm:"column:id;type:bigint(20);primary_key" json:"id"`
UserId string `gorm:"column:user_id;type:varchar(20);comment:用户ID;NOT NULL" json:"user_id"`
CommentId int64 `gorm:"column:comment_id;type:bigint(20);comment:评论ID" json:"comment_id"`
CommentId int64 `gorm:"column:comment_id;type:bigint(20);comment:评论ID;NOT NULL" json:"comment_id"`
Type int `gorm:"column:type;type:int(11);comment:类型0 点赞 1 踩;NOT NULL" json:"type"`
}
func (like *ScaCommentLikes) TableName() string {

View File

@@ -17,21 +17,20 @@ type ScaCommentReply struct {
CommentType int `gorm:"column:comment_type;type:int(11);comment:评论类型 0评论 1 回复" json:"comment_type"`
ReplyId string `gorm:"column:reply_id;type:varchar(20);comment:回复目标id" json:"reply_id"`
ReplyUser string `gorm:"column:reply_user;type:varchar(20);comment:回复人id" json:"reply_user"`
Author int `gorm:"column:author;type:int(11);comment:评论回复是否作者 0否 1是" json:"author"`
Likes int64 `gorm:"column:likes;type:bigint(20);comment:点赞数" json:"likes"`
ReplyCount int64 `gorm:"column:reply_count;type:bigint(20);comment:回复数量" json:"reply_count"`
PicUrls string `gorm:"column:pic_urls;type:longtext;comment:图片链接" json:"pic_urls"`
Author int `gorm:"column:author;type:int(11);default:0;comment:评论回复是否作者 0否 1是" json:"author"`
Likes int64 `gorm:"column:likes;type:bigint(20);default:0;comment:点赞数" json:"likes"`
ReplyCount int64 `gorm:"column:reply_count;type:bigint(20);default:0;comment:回复数量" json:"reply_count"`
CreatedTime time.Time `gorm:"column:created_time;type:datetime;default:CURRENT_TIMESTAMP;comment:创建时间" json:"created_time"`
UpdateTime time.Time `gorm:"column:update_time;type:datetime;default:CURRENT_TIMESTAMP;comment:更新时间" json:"update_time"`
Deleted int `gorm:"column:deleted;type:int(11);default:0;comment:是否删除 0未删除 1 已删除" json:"deleted"`
CreatedBy string `gorm:"column:created_by;type:varchar(32);comment:创建人" json:"created_by"`
UpdateBy string `gorm:"column:update_by;type:varchar(32);comment:更新人" json:"update_by"`
Dislikes int64 `gorm:"column:dislikes;type:bigint(20);comment:踩数" json:"dislikes"`
Dislikes int64 `gorm:"column:dislikes;type:bigint(20);default:0;comment:踩数" json:"dislikes"`
CommentIp string `gorm:"column:comment_ip;type:varchar(20);comment:评论ip" json:"comment_ip"`
Location string `gorm:"column:location;type:varchar(20);comment:评论地址" json:"location"`
Browser string `gorm:"column:browser;type:varchar(20);comment:评论浏览器" json:"browser"`
OperatingSystem string `gorm:"column:operating_system;type:varchar(20);comment:评论操作系统" json:"operating_system"`
Order int64 `gorm:"column:order;type:bigint(20);comment:评论排序" json:"order"`
CommentOrder int64 `gorm:"column:comment_order;type:bigint(20);default:0;comment:评论排序" json:"comment_order"`
}
func (comment *ScaCommentReply) TableName() string {

View File

@@ -9,4 +9,6 @@ var commonApi = api.Api.CommonApi
func CommentRouter(router *gin.RouterGroup) {
router.POST("/auth/comment/submit", commonApi.CommentSubmit)
router.POST("/auth/reply/submit", commonApi.ReplySubmit)
router.POST("/auth/comment/list", commonApi.CommentList)
}

View File

@@ -12,3 +12,29 @@ func (CommentReplyService) CreateCommentReply(comment *model.ScaCommentReply) er
}
return nil
}
// GetCommentListOrderByCreatedTimeDesc 通过topic_id获取评论列表
func (CommentReplyService) GetCommentListOrderByCreatedTimeDesc(topicID uint, page, pageSize int) ([]model.ScaCommentReply, error) {
var comments []model.ScaCommentReply
// 计算偏移量
offset := (page - 1) * pageSize
if err := global.DB.Where("topic_id =? and deleted = 0", topicID).Order("created_time desc").
Offset(offset).Limit(pageSize).Find(&comments).Error; err != nil {
return nil, err
}
return comments, nil
}
// GetCommentListOrderByLikesDesc 通过topic_id获取评论列表
func (CommentReplyService) GetCommentListOrderByLikesDesc(topicID uint, page, pageSize int) ([]model.ScaCommentReply, error) {
var comments []model.ScaCommentReply
// 计算偏移量
offset := (page - 1) * pageSize
if err := global.DB.Where("topic_id =? and deleted = 0", topicID).Order("likes desc").
Offset(offset).Limit(pageSize).Find(&comments).Error; err != nil {
return nil, err
}
return comments, nil
}

52
utils/paginator.go Normal file
View File

@@ -0,0 +1,52 @@
package utils
import (
"gorm.io/gorm"
)
// 标准分页结构体接收最原始的DO
// 建议在外部再建一个字段一样的结构体用以将DO转换成DTO或VO
type Page[T any] struct {
CurrentPage int64 `json:"currentPage"`
PageSize int64 `json:"pageSize"`
Total int64 `json:"total"`
Pages int64 `json:"pages"`
Data []T `json:"data"`
}
// 各种查询条件先在query设置好后再放进来
func (page *Page[T]) SelectPages(query *gorm.DB) (e error) {
var model T
query.Model(&model).Count(&page.Total)
if page.Total == 0 {
page.Data = []T{}
return
}
e = query.Model(&model).Scopes(Paginate(page)).Find(&page.Data).Error
return
}
func Paginate[T any](page *Page[T]) func(db *gorm.DB) *gorm.DB {
return func(db *gorm.DB) *gorm.DB {
if page.CurrentPage <= 0 {
page.CurrentPage = 1
}
switch {
case page.PageSize > 10000:
page.PageSize = 10000 // 限制一下分页大小
case page.PageSize <= 0:
page.PageSize = 10
}
page.Pages = page.Total / page.PageSize
if page.Total%page.PageSize != 0 {
page.Pages++
}
p := page.CurrentPage
if page.CurrentPage > page.Pages {
p = page.Pages
}
size := page.PageSize
offset := int((p - 1) * size)
return db.Offset(offset).Limit(int(size))
}
}