diff --git a/api/controller/Article.go b/api/controller/Article.go new file mode 100644 index 0000000..ba1bf85 --- /dev/null +++ b/api/controller/Article.go @@ -0,0 +1,333 @@ +package controller + +import ( + "fmt" + "github.com/gin-gonic/gin" + "strconv" + "vote-admin-api/api/dao" + "vote-admin-api/api/dto" + "vote-admin-api/api/model" + "vote-admin-api/api/requests" + "vote-admin-api/api/responses" + "vote-admin-api/global" + "vote-admin-api/utils" +) + +type Article struct{} + +// GetArticlePage 获取图文列表-分页 +func (r *Article) GetArticlePage(c *gin.Context) { + articleRequest := requests.ArticleRequest{} + req := articleRequest.GetArticlePage + if err := c.ShouldBindJSON(&req); err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 参数验证 + if err := global.Validate.Struct(req); err != nil { + responses.FailWithMessage(utils.Translate(err), c) + return + } + + if req.Page == 0 { + req.Page = 1 + } + + if req.PageSize == 0 { + req.PageSize = 20 + } + + if req.Order != nil { + if req.Order.VoteNum != "" { + if req.Order.VoteNum != "desc" && req.Order.VoteNum != "asc" { + responses.FailWithMessage("排序字段错误", c) + return + } + } + } + + // 获取数据 + articleDao := dao.ArticleDao{} + articles, total, err := articleDao.GetArticlePageSearch(req, req.Page, req.PageSize) + if err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 处理返回值 + g := dto.GetArticleListDto(articles) + + result := make(map[string]interface{}) + result["page"] = req.Page + result["page_size"] = req.PageSize + result["total"] = total + result["data"] = g + responses.OkWithData(result, c) +} + +// GetArticle 获取图文详情 +func (r *Article) GetArticle(c *gin.Context) { + id := c.Param("article_id") + if id == "" { + responses.FailWithMessage("缺少参数", c) + return + } + + // 将 id 转换为 int64 类型 + articleId, err := strconv.ParseInt(id, 10, 64) + if err != nil { + responses.Fail(c) + return + } + + // 获取数据 + articleDao := dao.ArticleDao{} + article, err := articleDao.GetArticleById(articleId) + if err != nil { + responses.FailWithMessage("文章错误", c) + return + } + + // 获取作者数据 + articleAuthorDao := dao.ArticleAuthorDao{} + maps := make(map[string]interface{}) + maps["article_id"] = articleId + articleAuthors, err := articleAuthorDao.GetArticleAuthorPreloadList(maps) + if err != nil { + responses.FailWithMessage("文章错误", c) + return + } + + // 获取排名 + rank, _ := articleDao.GetArticleRank(article.ArticleId) + + // 处理返回值 + g := dto.GetArticleDto(article) + + // 加载数据-作者 + g.LoadArticleAuthor(articleAuthors) + + // 加载数据-作者排名 + g.LoadRank(rank) + + responses.OkWithData(g, c) +} + +// PutArticle 修改图文详情 +func (r *Article) PutArticle(c *gin.Context) { + articleRequest := requests.ArticleRequest{} + req := articleRequest.PutArticle + if err := c.ShouldBindJSON(&req); err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 参数验证 + if err := global.Validate.Struct(req); err != nil { + responses.FailWithMessage(utils.Translate(err), c) + return + } + + id := c.Param("article_id") + if id == "" { + responses.FailWithMessage("缺少参数", c) + return + } + + // 将 id 转换为 int64 类型 + articleId, err := strconv.ParseInt(id, 10, 64) + if err != nil { + responses.Fail(c) + return + } + + // 获取订单数据 + articleDao := dao.ArticleDao{} + article, err := articleDao.GetArticleById(articleId) + if err != nil { + responses.FailWithMessage("图文异常", c) + return + } + + // 开始事务 + tx := global.Db.Begin() + defer func() { + if r := recover(); r != nil { + tx.Rollback() + fmt.Println(r) + } + }() + + articleData := make(map[string]interface{}) + + // 文章标题 + if article.ArticleTitle != req.ArticleTitle { + articleData["article_title"] = req.ArticleTitle + } + + // 文章状态 + if article.ArticleStatus != req.ArticleStatus { + articleData["article_status"] = req.ArticleStatus + } + + // 文章内容 + if article.ArticleContent != req.ArticleContent { + articleData["article_content"] = req.ArticleContent + } + + // 修改 + if len(articleData) > 0 { + err = articleDao.EditArticleById(tx, articleId, articleData) + if err != nil { + tx.Rollback() + responses.FailWithMessage(err.Error(), c) + return + } + } + + // 删除作者 + articleAuthorDao := dao.ArticleAuthorDao{} + maps := make(map[string]interface{}) + maps["article_id"] = articleId + err = articleAuthorDao.DeleteArticleAuthor(tx, maps) + if err != nil { + tx.Rollback() + responses.FailWithMessage(err.Error(), c) + return + } + + baseHospitalDao := dao.BaseHospitalDao{} + // 新增作者 + for _, author := range req.ArticleAuthor { + if author.HospitalId == "" { + tx.Rollback() + responses.FailWithMessage("请选择作者所属医院", c) + return + } + + if author.AuthorName == "" { + tx.Rollback() + responses.FailWithMessage("请输入作者名称", c) + return + } + + // 检测医院 + hospitalId, err := strconv.ParseInt(author.HospitalId, 10, 64) + if err != nil { + tx.Rollback() + responses.FailWithMessage(err.Error(), c) + return + } + + baseHospital, err := baseHospitalDao.GetBaseHospitalById(hospitalId) + if err != nil || baseHospital == nil { + tx.Rollback() + responses.FailWithMessage("医院错误", c) + return + } + + ArticleAuthor := &model.ArticleAuthor{ + ArticleId: articleId, + AuthorName: author.AuthorName, + HospitalId: hospitalId, + } + ArticleAuthor, err = articleAuthorDao.AddArticleAuthor(tx, ArticleAuthor) + if err != nil { + tx.Rollback() + responses.FailWithMessage(err.Error(), c) + return + } + } + + tx.Commit() + responses.Ok(c) +} + +// AddArticle 新增图文详情 +func (r *Article) AddArticle(c *gin.Context) { + articleRequest := requests.ArticleRequest{} + req := articleRequest.AddArticle + if err := c.ShouldBindJSON(&req); err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 参数验证 + if err := global.Validate.Struct(req); err != nil { + responses.FailWithMessage(utils.Translate(err), c) + return + } + + // 开始事务 + tx := global.Db.Begin() + defer func() { + if r := recover(); r != nil { + tx.Rollback() + responses.FailWithMessage("操作失败", c) + return + } + }() + + article := &model.Article{ + ArticleTitle: req.ArticleTitle, + ArticleStatus: req.ArticleStatus, + VoteNum: 0, + ArticleContent: req.ArticleContent, + } + + articleDao := dao.ArticleDao{} + article, err := articleDao.AddArticle(tx, article) + if err != nil { + tx.Rollback() + responses.FailWithMessage(err.Error(), c) + return + } + + // 新增作者 + baseHospitalDao := dao.BaseHospitalDao{} + articleAuthorDao := dao.ArticleAuthorDao{} + for _, author := range req.ArticleAuthor { + if author.HospitalId == "" { + tx.Rollback() + responses.FailWithMessage("请选择作者所属医院", c) + return + } + + if author.AuthorName == "" { + tx.Rollback() + responses.FailWithMessage("请输入作者名称", c) + return + } + + // 检测医院 + hospitalId, err := strconv.ParseInt(author.HospitalId, 10, 64) + if err != nil { + tx.Rollback() + responses.FailWithMessage(err.Error(), c) + return + } + + baseHospital, err := baseHospitalDao.GetBaseHospitalById(hospitalId) + if err != nil || baseHospital == nil { + tx.Rollback() + responses.FailWithMessage("医院错误", c) + return + } + + ArticleAuthor := &model.ArticleAuthor{ + ArticleId: article.ArticleId, + AuthorName: author.AuthorName, + HospitalId: hospitalId, + } + ArticleAuthor, err = articleAuthorDao.AddArticleAuthor(tx, ArticleAuthor) + if err != nil { + tx.Rollback() + responses.FailWithMessage(err.Error(), c) + return + } + } + + tx.Commit() + responses.Ok(c) +} diff --git a/api/controller/Base.go b/api/controller/Base.go index 9b28f06..9bc954b 100644 --- a/api/controller/Base.go +++ b/api/controller/Base.go @@ -2,5 +2,12 @@ package controller // Api api接口 type Api struct { - Public // 公共方法 + Public // 公共方法 + Article // 图文 + Video // 视频 + BaseAgreement // 基础数据-协议 + User // 用户 + UserVoteDay // 投票记录 + System // 配置 + BaseHospital // 基础数据-医院 } diff --git a/api/controller/BaseAgreement.go b/api/controller/BaseAgreement.go new file mode 100644 index 0000000..58414ff --- /dev/null +++ b/api/controller/BaseAgreement.go @@ -0,0 +1,198 @@ +package controller + +import ( + "github.com/gin-gonic/gin" + "strconv" + "vote-admin-api/api/dao" + "vote-admin-api/api/dto" + "vote-admin-api/api/model" + "vote-admin-api/api/requests" + "vote-admin-api/api/responses" + "vote-admin-api/global" + "vote-admin-api/utils" +) + +type BaseAgreement struct{} + +// GetBaseAgreementPage 获取协议列表-分页 +func (b *BaseAgreement) GetBaseAgreementPage(c *gin.Context) { + baseAgreementRequest := requests.BaseAgreementRequest{} + req := baseAgreementRequest.GetBaseAgreementPage + if err := c.ShouldBind(&req); err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 参数验证 + if err := global.Validate.Struct(req); err != nil { + responses.FailWithMessage(utils.Translate(err), c) + return + } + + if req.Page == 0 { + req.Page = 1 + } + + if req.PageSize == 0 { + req.PageSize = 20 + } + + // 获取分类数据 + baseAgreementDao := dao.BaseAgreementDao{} + baseAgreement, total, err := baseAgreementDao.GetBaseAgreementPageSearch(req.Page, req.PageSize) + if err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 处理返回值 + g := dto.GetBaseAgreementListDto(baseAgreement) + + result := make(map[string]interface{}) + result["page"] = req.Page + result["page_size"] = req.PageSize + result["total"] = total + result["data"] = g + responses.OkWithData(result, c) +} + +// GetBaseAgreement 获取协议详情 +func (b *BaseAgreement) GetBaseAgreement(c *gin.Context) { + id := c.Param("agreement_id") + if id == "" { + responses.FailWithMessage("缺少参数", c) + return + } + + // 将 id 转换为 int64 类型 + agreementId, err := strconv.ParseInt(id, 10, 64) + if err != nil { + responses.Fail(c) + return + } + + // 获取协议数据 + baseAgreementDao := dao.BaseAgreementDao{} + baseAgreement, err := baseAgreementDao.GetBaseAgreementById(agreementId) + if err != nil { + responses.FailWithMessage("分类异常", c) + return + } + + // 处理返回值 + g := dto.GetBaseAgreementDto(baseAgreement) + + responses.OkWithData(g, c) +} + +// PutBaseAgreement 修改协议 +func (b *BaseAgreement) PutBaseAgreement(c *gin.Context) { + BaseAgreementRequest := requests.BaseAgreementRequest{} + req := BaseAgreementRequest.PutBaseAgreement + if err := c.ShouldBind(&req); err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 参数验证 + if err := global.Validate.Struct(req); err != nil { + responses.FailWithMessage(utils.Translate(err), c) + return + } + + id := c.Param("agreement_id") + if id == "" { + responses.FailWithMessage("缺少参数", c) + return + } + + // 将 id 转换为 int64 类型 + agreementId, err := strconv.ParseInt(id, 10, 64) + if err != nil { + responses.Fail(c) + return + } + + // 获取协议数据 + baseAgreementDao := dao.BaseAgreementDao{} + baseAgreement, err := baseAgreementDao.GetBaseAgreementById(agreementId) + if err != nil { + responses.FailWithMessage("分类异常", c) + return + } + + // 修改值 + baseAgreementData := make(map[string]interface{}) + + // 协议标题 + if req.AgreementTitle != baseAgreement.AgreementTitle { + baseAgreementData["agreement_title"] = req.AgreementTitle + } + + // 协议内容 + if req.AgreementContent != baseAgreement.AgreementContent { + baseAgreementData["agreement_content"] = req.AgreementContent + } + + if len(baseAgreementData) > 0 { + // 开始事务 + tx := global.Db.Begin() + defer func() { + if r := recover(); r != nil { + tx.Rollback() + } + }() + + err = baseAgreementDao.EditBaseAgreementById(tx, agreementId, baseAgreementData) + if err != nil { + tx.Rollback() + responses.FailWithMessage("操作失败", c) + return + } + + tx.Commit() + } + + responses.Ok(c) +} + +// AddBaseAgreement 新增协议 +func (b *BaseAgreement) AddBaseAgreement(c *gin.Context) { + BaseAgreementRequest := requests.BaseAgreementRequest{} + req := BaseAgreementRequest.AddBaseAgreement + if err := c.ShouldBind(&req); err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 参数验证 + if err := global.Validate.Struct(req); err != nil { + responses.FailWithMessage(utils.Translate(err), c) + return + } + + // 开始事务 + tx := global.Db.Begin() + defer func() { + if r := recover(); r != nil { + tx.Rollback() + } + }() + + baseAgreement := &model.BaseAgreement{ + AgreementTitle: req.AgreementTitle, + AgreementType: req.AgreementType, + AgreementContent: req.AgreementContent, + } + + baseAgreementDao := dao.BaseAgreementDao{} + baseAgreement, err := baseAgreementDao.AddBaseAgreement(tx, baseAgreement) + if err != nil { + tx.Rollback() + responses.FailWithMessage(err.Error(), c) + return + } + + tx.Commit() + responses.Ok(c) +} diff --git a/api/controller/BaseHospital.go b/api/controller/BaseHospital.go new file mode 100644 index 0000000..b80a202 --- /dev/null +++ b/api/controller/BaseHospital.go @@ -0,0 +1,41 @@ +// Package controller 科室管理 +package controller + +import ( + "github.com/gin-gonic/gin" + "vote-admin-api/api/dao" + "vote-admin-api/api/dto" + "vote-admin-api/api/requests" + "vote-admin-api/api/responses" + "vote-admin-api/global" + "vote-admin-api/utils" +) + +type BaseHospital struct{} + +// GetHospitalList 获取医院列表 +func (b *BaseHospital) GetHospitalList(c *gin.Context) { + baseHospitalRequest := requests.BaseHospitalRequest{} + req := baseHospitalRequest.GetBaseHospitalList + if err := c.ShouldBind(&req); err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 参数验证 + if err := global.Validate.Struct(req); err != nil { + responses.FailWithMessage(utils.Translate(err), c) + return + } + + baseHospitalDao := dao.BaseHospitalDao{} + baseHospitals, err := baseHospitalDao.GetBaseHospitalLimitByMaps(req) + if err != nil { + responses.Ok(c) + return + } + + // 处理返回值 + getHospitalLimitResponse := dto.GetBaseHospitalListDto(baseHospitals) + responses.OkWithData(getHospitalLimitResponse, c) +} diff --git a/api/controller/Public.go b/api/controller/Public.go index aad4961..2eb95b9 100644 --- a/api/controller/Public.go +++ b/api/controller/Public.go @@ -5,6 +5,7 @@ import ( "encoding/hex" "fmt" "github.com/gin-gonic/gin" + "time" "vote-admin-api/api/dao" "vote-admin-api/api/dto" "vote-admin-api/api/requests" @@ -102,6 +103,7 @@ func (b *Public) GetCaptcha(c *gin.Context) { id, b64s, err := utils.GenerateCaptcha() if err != nil { responses.FailWithMessage("验证码获取失败", c) + return } responses.OkWithData(gin.H{ @@ -109,3 +111,116 @@ func (b *Public) GetCaptcha(c *gin.Context) { "b64s": b64s, }, c) } + +// GetIndex 首页 +func (b *Public) GetIndex(c *gin.Context) { + dataDao := dao.DataDao{} + data, err := dataDao.GetDataById(1) + if err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + g := dto.IndexDto{ + ViewNum: data.ViewNum, + VoteNum: data.VoteNum, + } + + responses.OkWithData(g, c) +} + +// GetIndexData 首页动态统计数据 +func (b *Public) GetIndexData(c *gin.Context) { + publicRequest := requests.PublicRequest{} + req := publicRequest.GetIndexData + if err := c.ShouldBind(&req); err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 参数验证 + if err := global.Validate.Struct(req); err != nil { + responses.FailWithMessage(utils.Translate(err), c) + return + } + + if err := c.ShouldBind(&req); err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 返回值 + var g []*dto.IndexDataDto + results := make(map[string]int64) + + // 分类(1:新增用户数 2:图文投票数 3:视频投票数) + if req.Type == 1 { + // 新增用户数 + endTime, _ := time.Parse("2006-01-02", req.EndTime) + req.EndTime = endTime.Add(23*time.Hour + 59*time.Minute + 59*time.Second).Format("2006-01-02 15:04:05") + + userDao := dao.UserDao{} + maps := make(map[string]interface{}) + users, err := userDao.GetUserListByTime(maps, req.StartTime, req.EndTime, "created_at") + if err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + for _, user := range users { + date := time.Time(user.CreatedAt).Format("2006-01-02") + results[date]++ + } + } + + // 图文投票数 + if req.Type == 2 { + endTime, _ := time.Parse("2006-01-02", req.EndTime) + req.EndTime = endTime.Format("2006-01-02") + + articleVoteDayDao := dao.ArticleVoteDayDao{} + maps := make(map[string]interface{}) + articleVoteDays, err := articleVoteDayDao.GetArticleVoteDayListByTime(maps, req.StartTime, req.EndTime, "voted_at") + if err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + for _, articleVoteDay := range articleVoteDays { + votedAt := time.Time(*articleVoteDay.VotedAt) + date := votedAt.Format("2006-01-02") + results[date]++ + } + } + + // 视频投票数 + if req.Type == 3 { + endTime, _ := time.Parse("2006-01-02", req.EndTime) + req.EndTime = endTime.Format("2006-01-02") + + videoVoteDayDao := dao.VideoVoteDayDao{} + maps := make(map[string]interface{}) + videoVoteDays, err := videoVoteDayDao.GetVideoVoteDayListByTime(maps, req.StartTime, req.EndTime, "voted_at") + if err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + for _, videoVoteDay := range videoVoteDays { + votedAt := time.Time(*videoVoteDay.VotedAt) + date := votedAt.Format("2006-01-02") + results[date]++ + } + } + + for k, v := range results { + response := &dto.IndexDataDto{ + Date: k, + Count: v, + } + + g = append(g, response) + } + + responses.OkWithData(g, c) +} diff --git a/api/controller/System.go b/api/controller/System.go new file mode 100644 index 0000000..0c0ab8b --- /dev/null +++ b/api/controller/System.go @@ -0,0 +1,40 @@ +package controller + +import ( + "github.com/gin-gonic/gin" + "strconv" + "vote-admin-api/api/dao" + "vote-admin-api/api/dto" + "vote-admin-api/api/responses" +) + +type System struct{} + +// GetSystemTime 获取投票时间详情 +func (r *System) GetSystemTime(c *gin.Context) { + id := c.Param("system_time_id") + if id == "" { + responses.FailWithMessage("缺少参数", c) + return + } + + // 将 id 转换为 int64 类型 + systemTimeId, err := strconv.ParseInt(id, 10, 64) + if err != nil { + responses.Fail(c) + return + } + + // 获取数据 + systemTimeDao := dao.SystemTimeDao{} + systemTime, err := systemTimeDao.GetSystemTimeById(systemTimeId) + if err != nil { + responses.FailWithMessage("数据异常", c) + return + } + + // 处理返回值 + g := dto.GetSystemTimeDto(systemTime) + + responses.OkWithData(g, c) +} diff --git a/api/controller/User.go b/api/controller/User.go new file mode 100644 index 0000000..cce8d37 --- /dev/null +++ b/api/controller/User.go @@ -0,0 +1,147 @@ +package controller + +import ( + "github.com/gin-gonic/gin" + "strconv" + "vote-admin-api/api/dao" + "vote-admin-api/api/dto" + "vote-admin-api/api/requests" + "vote-admin-api/api/responses" + "vote-admin-api/global" + "vote-admin-api/utils" +) + +type User struct{} + +// GetUserPage 获取用户列表-分页 +func (r *User) GetUserPage(c *gin.Context) { + userRequest := requests.UserRequest{} + req := userRequest.GetUserPage + if err := c.ShouldBind(&req); err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 参数验证 + if err := global.Validate.Struct(req); err != nil { + responses.FailWithMessage(utils.Translate(err), c) + return + } + + if req.Page == 0 { + req.Page = 1 + } + + if req.PageSize == 0 { + req.PageSize = 20 + } + + // 获取数据 + userDao := dao.UserDao{} + user, total, err := userDao.GetUserPageSearch(req, req.Page, req.PageSize) + if err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 处理返回值 + g := dto.GetUserListDto(user) + + result := make(map[string]interface{}) + result["page"] = req.Page + result["page_size"] = req.PageSize + result["total"] = total + result["data"] = g + responses.OkWithData(result, c) +} + +// GetUser 获取用户详情 +func (r *User) GetUser(c *gin.Context) { + id := c.Param("user_id") + if id == "" { + responses.FailWithMessage("缺少参数", c) + return + } + + // 将 id 转换为 int64 类型 + userId, err := strconv.ParseInt(id, 10, 64) + if err != nil { + responses.Fail(c) + return + } + + // 获取数据 + userDao := dao.UserDao{} + user, err := userDao.GetUserById(userId) + if err != nil { + responses.FailWithMessage("用户异常", c) + return + } + + // 处理返回值 + g := dto.GetUserDto(user) + + responses.OkWithData(g, c) +} + +// PutUserStatus 操作用户状态 +func (r *User) PutUserStatus(c *gin.Context) { + userRequest := requests.UserRequest{} + req := userRequest.PutUserStatus + if err := c.ShouldBind(&req); err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 参数验证 + if err := global.Validate.Struct(req); err != nil { + responses.FailWithMessage(utils.Translate(err), c) + return + } + + id := c.Param("user_id") + if id == "" { + responses.FailWithMessage("缺少参数", c) + return + } + + // 将 id 转换为 int64 类型 + userId, err := strconv.ParseInt(id, 10, 64) + if err != nil { + responses.Fail(c) + return + } + + // 获取数据 + userDao := dao.UserDao{} + user, err := userDao.GetUserById(userId) + if err != nil { + responses.FailWithMessage("用户异常", c) + return + } + + if req.UserStatus == user.UserStatus { + responses.Ok(c) + return + } + + // 开始事务 + tx := global.Db.Begin() + defer func() { + if r := recover(); r != nil { + tx.Rollback() + } + }() + + userData := make(map[string]interface{}) + userData["user_status"] = req.UserStatus + err = userDao.EditUserById(tx, userId, userData) + if err != nil { + tx.Rollback() + responses.FailWithMessage("操作失败", c) + return + } + + tx.Commit() + responses.Ok(c) +} diff --git a/api/controller/UserVoteDay.go b/api/controller/UserVoteDay.go new file mode 100644 index 0000000..a70d7a8 --- /dev/null +++ b/api/controller/UserVoteDay.go @@ -0,0 +1,260 @@ +package controller + +import ( + "fmt" + "github.com/gin-gonic/gin" + "strconv" + "time" + "vote-admin-api/api/dao" + "vote-admin-api/api/dto" + "vote-admin-api/api/requests" + "vote-admin-api/api/responses" + "vote-admin-api/global" + "vote-admin-api/utils" +) + +type UserVoteDay struct{} + +// GetUserArticleVotePage 用户投票记录列表-图文-分页 +func (r *UserVoteDay) GetUserArticleVotePage(c *gin.Context) { + userVoteDayRequest := requests.UserVoteDayRequest{} + req := userVoteDayRequest.GetArticleUserVoteDayPage + if err := c.ShouldBind(&req); err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 参数验证 + if err := global.Validate.Struct(req); err != nil { + responses.FailWithMessage(utils.Translate(err), c) + return + } + + if req.Page == 0 { + req.Page = 1 + } + + if req.PageSize == 0 { + req.PageSize = 20 + } + + userId, err := strconv.ParseInt(req.UserId, 10, 64) + if err != nil { + responses.Fail(c) + return + } + + var total int64 + + articleVoteDayDao := dao.ArticleVoteDayDao{} + articleVoteDay, total, err := articleVoteDayDao.GetArticleVoteDayByUserIdPageSearch(userId, req.Page, req.PageSize) + if err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 处理返回值 + g := make([]*dto.UserVoteDto, len(articleVoteDay)) + for i, v := range articleVoteDay { + createdAt := time.Time(v.CreatedAt).Format("2006-01-02 15:04:05") + + response := &dto.UserVoteDto{ + Id: fmt.Sprintf("%d", v.ArticleId), + Title: v.Article.ArticleTitle, + VotedAt: createdAt, + } + + // 将转换后的结构体添加到新切片中 + g[i] = response + } + + result := make(map[string]interface{}) + result["page"] = req.Page + result["page_size"] = req.PageSize + result["total"] = total + result["data"] = g + responses.OkWithData(result, c) +} + +// GetUserVideoVotePage 用户投票记录列表-视频-分页 +func (r *UserVoteDay) GetUserVideoVotePage(c *gin.Context) { + userVoteDayRequest := requests.UserVoteDayRequest{} + req := userVoteDayRequest.GetVideoUserVoteDayPage + if err := c.ShouldBind(&req); err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 参数验证 + if err := global.Validate.Struct(req); err != nil { + responses.FailWithMessage(utils.Translate(err), c) + return + } + + if req.Page == 0 { + req.Page = 1 + } + + if req.PageSize == 0 { + req.PageSize = 20 + } + + userId, err := strconv.ParseInt(req.UserId, 10, 64) + if err != nil { + responses.Fail(c) + return + } + + var total int64 + + videoVoteDayDao := dao.VideoVoteDayDao{} + videoVoteDay, total, err := videoVoteDayDao.GetVideoVoteDayByUserIdPageSearch(userId, req.Page, req.PageSize) + if err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 处理返回值 + g := make([]*dto.UserVoteDto, len(videoVoteDay)) + for i, v := range videoVoteDay { + createdAt := time.Time(v.CreatedAt).Format("2006-01-02 15:04:05") + + response := &dto.UserVoteDto{ + Id: fmt.Sprintf("%d", v.VideoId), + Title: v.Video.VideoTitle, + VotedAt: createdAt, + } + + // 将转换后的结构体添加到新切片中 + g[i] = response + } + + result := make(map[string]interface{}) + result["page"] = req.Page + result["page_size"] = req.PageSize + result["total"] = total + result["data"] = g + responses.OkWithData(result, c) +} + +// GetArticleVotePage 投票记录列表-图文-分页 +func (r *UserVoteDay) GetArticleVotePage(c *gin.Context) { + userVoteDayRequest := requests.UserVoteDayRequest{} + req := userVoteDayRequest.GetArticleVoteDayPage + if err := c.ShouldBind(&req); err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 参数验证 + if err := global.Validate.Struct(req); err != nil { + responses.FailWithMessage(utils.Translate(err), c) + return + } + + if req.Page == 0 { + req.Page = 1 + } + + if req.PageSize == 0 { + req.PageSize = 20 + } + + articleId, err := strconv.ParseInt(req.ArticleId, 10, 64) + if err != nil { + responses.Fail(c) + return + } + + var total int64 + + articleVoteDayDao := dao.ArticleVoteDayDao{} + articleVoteDay, total, err := articleVoteDayDao.GetArticleVoteDayByArticleIdPageSearch(articleId, req.Page, req.PageSize) + if err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 处理返回值 + g := make([]*dto.UserVoteDto, len(articleVoteDay)) + for i, v := range articleVoteDay { + createdAt := time.Time(v.CreatedAt).Format("2006-01-02 15:04:05") + + response := &dto.UserVoteDto{ + Id: fmt.Sprintf("%d", v.ArticleId), + AppIden: v.User.AppIden, + VotedAt: createdAt, + } + + // 将转换后的结构体添加到新切片中 + g[i] = response + } + + result := make(map[string]interface{}) + result["page"] = req.Page + result["page_size"] = req.PageSize + result["total"] = total + result["data"] = g + responses.OkWithData(result, c) +} + +// GetVideoVotePage 投票记录列表-视频-分页 +func (r *UserVoteDay) GetVideoVotePage(c *gin.Context) { + userVoteDayRequest := requests.UserVoteDayRequest{} + req := userVoteDayRequest.GetVideoVoteDayPage + if err := c.ShouldBind(&req); err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 参数验证 + if err := global.Validate.Struct(req); err != nil { + responses.FailWithMessage(utils.Translate(err), c) + return + } + + if req.Page == 0 { + req.Page = 1 + } + + if req.PageSize == 0 { + req.PageSize = 20 + } + + videoId, err := strconv.ParseInt(req.VideoId, 10, 64) + if err != nil { + responses.Fail(c) + return + } + + var total int64 + + videoVoteDayDao := dao.VideoVoteDayDao{} + videoVoteDay, total, err := videoVoteDayDao.GetVideoVoteDayByVideoIdPageSearch(videoId, req.Page, req.PageSize) + if err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 处理返回值 + g := make([]*dto.UserVoteDto, len(videoVoteDay)) + for i, v := range videoVoteDay { + createdAt := time.Time(v.CreatedAt).Format("2006-01-02 15:04:05") + + response := &dto.UserVoteDto{ + Id: fmt.Sprintf("%d", v.VideoId), + AppIden: v.User.AppIden, + VotedAt: createdAt, + } + + // 将转换后的结构体添加到新切片中 + g[i] = response + } + + result := make(map[string]interface{}) + result["page"] = req.Page + result["page_size"] = req.PageSize + result["total"] = total + result["data"] = g + responses.OkWithData(result, c) +} diff --git a/api/controller/Video.go b/api/controller/Video.go new file mode 100644 index 0000000..abbf325 --- /dev/null +++ b/api/controller/Video.go @@ -0,0 +1,344 @@ +package controller + +import ( + "fmt" + "github.com/gin-gonic/gin" + "strconv" + "vote-admin-api/api/dao" + "vote-admin-api/api/dto" + "vote-admin-api/api/model" + "vote-admin-api/api/requests" + "vote-admin-api/api/responses" + "vote-admin-api/global" + "vote-admin-api/utils" +) + +type Video struct{} + +// GetVideoPage 获取视频列表-分页 +func (r *Video) GetVideoPage(c *gin.Context) { + VideoRequest := requests.VideoRequest{} + req := VideoRequest.GetVideoPage + if err := c.ShouldBindJSON(&req); err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 参数验证 + if err := global.Validate.Struct(req); err != nil { + responses.FailWithMessage(utils.Translate(err), c) + return + } + + if req.Page == 0 { + req.Page = 1 + } + + if req.PageSize == 0 { + req.PageSize = 20 + } + + if req.Order != nil { + if req.Order.VoteNum != "" { + if req.Order.VoteNum != "desc" && req.Order.VoteNum != "asc" { + responses.FailWithMessage("排序字段错误", c) + return + } + } + } + + // 获取数据 + VideoDao := dao.VideoDao{} + Videos, total, err := VideoDao.GetVideoPageSearch(req, req.Page, req.PageSize) + if err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 处理返回值 + g := dto.GetVideoListDto(Videos) + + result := make(map[string]interface{}) + result["page"] = req.Page + result["page_size"] = req.PageSize + result["total"] = total + result["data"] = g + responses.OkWithData(result, c) +} + +// GetVideo 获取视频详情 +func (r *Video) GetVideo(c *gin.Context) { + id := c.Param("video_id") + if id == "" { + responses.FailWithMessage("缺少参数", c) + return + } + + // 将 id 转换为 int64 类型 + videoId, err := strconv.ParseInt(id, 10, 64) + if err != nil { + responses.Fail(c) + return + } + + // 获取数据 + VideoDao := dao.VideoDao{} + video, err := VideoDao.GetVideoById(videoId) + if err != nil { + responses.FailWithMessage("视频错误", c) + return + } + + // 获取作者数据 + VideoAuthorDao := dao.VideoAuthorDao{} + maps := make(map[string]interface{}) + maps["video_id"] = videoId + VideoAuthors, err := VideoAuthorDao.GetVideoAuthorPreloadList(maps) + if err != nil { + responses.FailWithMessage("视频错误", c) + return + } + + // 获取排名 + rank, _ := VideoDao.GetVideoRank(video.VideoId) + + // 处理返回值 + g := dto.GetVideoDto(video) + + // 加载数据-作者 + g.LoadVideoAuthor(VideoAuthors) + + // 加载数据-作者排名 + g.LoadRank(rank) + + responses.OkWithData(g, c) +} + +// PutVideo 修改视频详情 +func (r *Video) PutVideo(c *gin.Context) { + VideoRequest := requests.VideoRequest{} + req := VideoRequest.PutVideo + if err := c.ShouldBindJSON(&req); err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 参数验证 + if err := global.Validate.Struct(req); err != nil { + responses.FailWithMessage(utils.Translate(err), c) + return + } + + id := c.Param("video_id") + if id == "" { + responses.FailWithMessage("缺少参数", c) + return + } + + // 将 id 转换为 int64 类型 + videoId, err := strconv.ParseInt(id, 10, 64) + if err != nil { + responses.Fail(c) + return + } + + // 获取订单数据 + videoDao := dao.VideoDao{} + video, err := videoDao.GetVideoById(videoId) + if err != nil { + responses.FailWithMessage("视频异常", c) + return + } + + // 开始事务 + tx := global.Db.Begin() + defer func() { + if r := recover(); r != nil { + tx.Rollback() + fmt.Println(r) + } + }() + + videoData := make(map[string]interface{}) + + // 视频标题 + if video.VideoTitle != req.VideoTitle { + videoData["video_title"] = req.VideoTitle + } + + // 视频状态 + if video.VideoStatus != req.VideoStatus { + videoData["video_status"] = req.VideoStatus + } + + // 总票数 + if video.VoteNum != req.VoteNum { + videoData["vote_num"] = req.VoteNum + } + + // 视频编号 + if video.VideoNo != req.VideoNo { + videoData["video_no"] = req.VideoNo + } + + // 视频内容 + if video.VideoContent != req.VideoContent { + videoData["video_content"] = req.VideoContent + } + + // 修改 + if len(videoData) > 0 { + err = videoDao.EditVideoById(tx, videoId, videoData) + if err != nil { + tx.Rollback() + responses.FailWithMessage(err.Error(), c) + return + } + } + + // 删除作者 + VideoAuthorDao := dao.VideoAuthorDao{} + maps := make(map[string]interface{}) + maps["video_id"] = videoId + err = VideoAuthorDao.DeleteVideoAuthor(tx, maps) + if err != nil { + tx.Rollback() + responses.FailWithMessage(err.Error(), c) + return + } + + baseHospitalDao := dao.BaseHospitalDao{} + // 新增作者 + for _, author := range req.VideoAuthor { + if author.HospitalId == "" { + tx.Rollback() + responses.FailWithMessage("请选择作者所属医院", c) + return + } + + if author.AuthorName == "" { + tx.Rollback() + responses.FailWithMessage("请输入作者名称", c) + return + } + + // 检测医院 + hospitalId, err := strconv.ParseInt(author.HospitalId, 10, 64) + if err != nil { + tx.Rollback() + responses.FailWithMessage(err.Error(), c) + return + } + + baseHospital, err := baseHospitalDao.GetBaseHospitalById(hospitalId) + if err != nil || baseHospital == nil { + tx.Rollback() + responses.FailWithMessage("医院错误", c) + return + } + + videoAuthor := &model.VideoAuthor{ + VideoId: videoId, + AuthorName: author.AuthorName, + HospitalId: hospitalId, + } + videoAuthor, err = VideoAuthorDao.AddVideoAuthor(tx, videoAuthor) + if err != nil { + tx.Rollback() + responses.FailWithMessage(err.Error(), c) + return + } + } + + tx.Commit() + responses.Ok(c) +} + +// AddVideo 新增视频详情 +func (r *Video) AddVideo(c *gin.Context) { + videoRequest := requests.VideoRequest{} + req := videoRequest.AddVideo + if err := c.ShouldBindJSON(&req); err != nil { + responses.FailWithMessage(err.Error(), c) + return + } + + // 参数验证 + if err := global.Validate.Struct(req); err != nil { + responses.FailWithMessage(utils.Translate(err), c) + return + } + + // 开始事务 + tx := global.Db.Begin() + defer func() { + if r := recover(); r != nil { + tx.Rollback() + responses.FailWithMessage("操作失败", c) + return + } + }() + + video := &model.Video{ + VideoTitle: req.VideoTitle, + VideoStatus: req.VideoStatus, + VideoNo: req.VideoNo, + VoteNum: req.VoteNum, + VideoContent: req.VideoContent, + } + + videoDao := dao.VideoDao{} + video, err := videoDao.AddVideo(tx, video) + if err != nil { + tx.Rollback() + responses.FailWithMessage(err.Error(), c) + return + } + + // 新增作者 + baseHospitalDao := dao.BaseHospitalDao{} + videoAuthorDao := dao.VideoAuthorDao{} + for _, author := range req.VideoAuthor { + if author.HospitalId == "" { + tx.Rollback() + responses.FailWithMessage("请选择作者所属医院", c) + return + } + + if author.AuthorName == "" { + tx.Rollback() + responses.FailWithMessage("请输入作者名称", c) + return + } + + // 检测医院 + hospitalId, err := strconv.ParseInt(author.HospitalId, 10, 64) + if err != nil { + tx.Rollback() + responses.FailWithMessage(err.Error(), c) + return + } + + baseHospital, err := baseHospitalDao.GetBaseHospitalById(hospitalId) + if err != nil || baseHospital == nil { + tx.Rollback() + responses.FailWithMessage("医院错误", c) + return + } + + videoAuthor := &model.VideoAuthor{ + VideoId: video.VideoId, + AuthorName: author.AuthorName, + HospitalId: hospitalId, + } + videoAuthor, err = videoAuthorDao.AddVideoAuthor(tx, videoAuthor) + if err != nil { + tx.Rollback() + responses.FailWithMessage(err.Error(), c) + return + } + } + + tx.Commit() + responses.Ok(c) +} diff --git a/api/dao/Article.go b/api/dao/Article.go index 849b1c2..94557e2 100644 --- a/api/dao/Article.go +++ b/api/dao/Article.go @@ -133,42 +133,26 @@ func (r *ArticleDao) GetArticlePageSearch(req requests.GetArticlePage, page, pag // 构建查询条件 query := global.Db.Model(&model.Article{}) - // 作者 - query = query.Preload("ArticleAuthor") + // 文章标题 + if req.ArticleTitle != "" { + query = query.Where("article_title LIKE ?", "%"+req.ArticleTitle+"%") + } - // 作者关联医院 - query = query.Preload("ArticleAuthor.BaseHospital") + // 文章内容 + if req.ArticleContent != "" { + query = query.Where("article_content LIKE ?", "%"+req.ArticleContent+"%") + } - // 文章状态(1:正常 2:禁用) - query = query.Where("article_status = ?", 1) + // 文章状态 + if req.ArticleStatus != nil { + query = query.Where("article_status = ?", req.ArticleStatus) + } - // 搜索关键字 - if req.Keyword != "" { - keyword := "%" + req.Keyword + "%" // - - // 标题 - orQuery := global.Db.Model(&model.Article{}).Or("article_title LIKE ?", keyword) - - // 医院名称 - hospitalSubQuery := global.Db.Model(&model.BaseHospital{}). - Select("hospital_id"). - Where("hospital_name LIKE ?", keyword) - - articleAuthorSubQuery := global.Db.Model(&model.ArticleAuthor{}). - Select("article_id"). - Where(gorm.Expr("hospital_id IN (?)", hospitalSubQuery)) - - orQuery = orQuery.Or(gorm.Expr("article_id IN (?)", articleAuthorSubQuery)) - - // 作者姓名 - subQuery := global.Db.Model(&model.ArticleAuthor{}). - Select("article_id"). - Where("author_name LIKE ?", keyword) - - orQuery = orQuery.Or(gorm.Expr("article_id IN (?)", subQuery)) - - // 执行组建 - query = query.Where(orQuery) + // 排序 + if req.Order != nil { + if req.Order.VoteNum != "" { + query = query.Order("vote_num " + req.Order.VoteNum) + } } // 排序 diff --git a/api/dao/ArticleAuthor.go b/api/dao/ArticleAuthor.go index 432d0c9..e1b1b9e 100644 --- a/api/dao/ArticleAuthor.go +++ b/api/dao/ArticleAuthor.go @@ -72,6 +72,15 @@ func (r *ArticleAuthorDao) GetArticleAuthorList(maps interface{}) (m []*model.Ar return m, nil } +// GetArticleAuthorPreloadList 获取列表-加载全部关联 +func (r *ArticleAuthorDao) GetArticleAuthorPreloadList(maps interface{}) (m []*model.ArticleAuthor, err error) { + err = global.Db.Preload(clause.Associations).Where(maps).Find(&m).Error + if err != nil { + return nil, err + } + return m, nil +} + // GetArticleAuthorCount 获取数量 func (r *ArticleAuthorDao) GetArticleAuthorCount(maps interface{}) (total int64, err error) { err = global.Db.Model(&model.ArticleAuthor{}).Where(maps).Count(&total).Error diff --git a/api/dao/ArticleVoteDay.go b/api/dao/ArticleVoteDay.go index cf1a4b9..94481e1 100644 --- a/api/dao/ArticleVoteDay.go +++ b/api/dao/ArticleVoteDay.go @@ -124,3 +124,64 @@ func (r *ArticleVoteDayDao) Dec(tx *gorm.DB, voteDayId int64, field string, nume } return nil } + +// GetArticleVoteDayByUserIdPageSearch 获取列表-分页-用户id +func (r *ArticleVoteDayDao) GetArticleVoteDayByUserIdPageSearch(userId int64, page, pageSize int) (m []*model.ArticleVoteDay, total int64, err error) { + var totalRecords int64 + + // 构建查询条件 + query := global.Db.Model(&model.ArticleVoteDay{}) + + // 图文 + query = query.Preload("Article") + + query = query.Where("user_id = ?", userId) + + query = query.Order("created_at desc") + + // 查询总数量 + if err := query.Count(&totalRecords).Error; err != nil { + return nil, 0, err + } + + err = query.Scopes(model.Paginate(page, pageSize)).Find(&m).Error + if err != nil { + return nil, 0, err + } + return m, totalRecords, nil +} + +// GetArticleVoteDayByArticleIdPageSearch 获取列表-分页-文章id +func (r *ArticleVoteDayDao) GetArticleVoteDayByArticleIdPageSearch(articleId int64, page, pageSize int) (m []*model.ArticleVoteDay, total int64, err error) { + var totalRecords int64 + + // 构建查询条件 + query := global.Db.Model(&model.ArticleVoteDay{}) + + // 用户 + query = query.Preload("User") + + query = query.Where("article_id = ?", articleId) + + query = query.Order("created_at desc") + + // 查询总数量 + if err := query.Count(&totalRecords).Error; err != nil { + return nil, 0, err + } + + err = query.Scopes(model.Paginate(page, pageSize)).Find(&m).Error + if err != nil { + return nil, 0, err + } + return m, totalRecords, nil +} + +// GetArticleVoteDayListByTime 获取列表-开始时间/过期时间 +func (r *ArticleVoteDayDao) GetArticleVoteDayListByTime(maps interface{}, startTime, endTime, field string) (m []*model.ArticleVoteDay, err error) { + err = global.Db.Where(maps).Where(field+" BETWEEN ? AND ?", startTime, endTime).Find(&m).Error + if err != nil { + return nil, err + } + return m, nil +} diff --git a/api/dao/BaseAgreement.go b/api/dao/BaseAgreement.go index bb73c85..4974268 100644 --- a/api/dao/BaseAgreement.go +++ b/api/dao/BaseAgreement.go @@ -124,3 +124,25 @@ func (r *BaseAgreementDao) Dec(tx *gorm.DB, AgreementId int64, field string, num } return nil } + +// GetBaseAgreementPageSearch 获取列表-分页 +func (r *BaseAgreementDao) GetBaseAgreementPageSearch(page, pageSize int) (m []*model.BaseAgreement, total int64, err error) { + var totalRecords int64 + + // 构建查询条件 + query := global.Db.Model(&model.BaseAgreement{}) + + // 排序 + query = query.Order("created_at desc") + + // 查询总数量 + if err := query.Count(&totalRecords).Error; err != nil { + return nil, 0, err + } + + err = query.Scopes(model.Paginate(page, pageSize)).Find(&m).Error + if err != nil { + return nil, 0, err + } + return m, totalRecords, nil +} diff --git a/api/dao/BaseHospital.go b/api/dao/BaseHospital.go new file mode 100644 index 0000000..01579f8 --- /dev/null +++ b/api/dao/BaseHospital.go @@ -0,0 +1,145 @@ +package dao + +import ( + "gorm.io/gorm" + "gorm.io/gorm/clause" + "vote-admin-api/api/model" + "vote-admin-api/api/requests" + "vote-admin-api/global" +) + +type BaseHospitalDao struct { +} + +// GetBaseHospitalById 获取数据-id +func (r *BaseHospitalDao) GetBaseHospitalById(HospitalId int64) (m *model.BaseHospital, err error) { + err = global.Db.First(&m, HospitalId).Error + if err != nil { + return nil, err + } + return m, nil +} + +// GetBaseHospitalPreloadById 获取数据-加载全部关联-id +func (r *BaseHospitalDao) GetBaseHospitalPreloadById(HospitalId int64) (m *model.BaseHospital, err error) { + err = global.Db.Preload(clause.Associations).First(&m, HospitalId).Error + if err != nil { + return nil, err + } + return m, nil +} + +// DeleteBaseHospital 删除 +func (r *BaseHospitalDao) DeleteBaseHospital(tx *gorm.DB, maps interface{}) error { + err := tx.Where(maps).Delete(&model.BaseHospital{}).Error + if err != nil { + return err + } + return nil +} + +// DeleteBaseHospitalById 删除-id +func (r *BaseHospitalDao) DeleteBaseHospitalById(tx *gorm.DB, HospitalId int64) error { + if err := tx.Delete(&model.BaseHospital{}, HospitalId).Error; err != nil { + return err + } + return nil +} + +// EditBaseHospital 修改 +func (r *BaseHospitalDao) EditBaseHospital(tx *gorm.DB, maps interface{}, data interface{}) error { + err := tx.Model(&model.BaseHospital{}).Where(maps).Updates(data).Error + if err != nil { + return err + } + return nil +} + +// EditBaseHospitalById 修改-id +func (r *BaseHospitalDao) EditBaseHospitalById(tx *gorm.DB, HospitalId int64, data interface{}) error { + err := tx.Model(&model.BaseHospital{}).Where("hospital_id = ?", HospitalId).Updates(data).Error + if err != nil { + return err + } + return nil +} + +// GetBaseHospitalList 获取列表 +func (r *BaseHospitalDao) GetBaseHospitalList(maps interface{}) (m []*model.BaseHospital, err error) { + err = global.Db.Where(maps).Find(&m).Error + if err != nil { + return nil, err + } + return m, nil +} + +// GetBaseHospitalCount 获取数量 +func (r *BaseHospitalDao) GetBaseHospitalCount(maps interface{}) (total int64, err error) { + err = global.Db.Model(&model.BaseHospital{}).Where(maps).Count(&total).Error + if err != nil { + return 0, err + } + return total, nil +} + +// GetBaseHospitalListRand 获取列表-随机 +func (r *BaseHospitalDao) GetBaseHospitalListRand(maps interface{}, limit int) (m []*model.BaseHospital, err error) { + err = global.Db.Where(maps).Order("rand()").Limit(limit).Find(&m).Error + if err != nil { + return nil, err + } + return m, nil +} + +// AddBaseHospital 新增 +func (r *BaseHospitalDao) AddBaseHospital(tx *gorm.DB, model *model.BaseHospital) (*model.BaseHospital, error) { + if err := tx.Create(model).Error; err != nil { + return nil, err + } + return model, nil +} + +// GetBaseHospital 获取 +func (r *BaseHospitalDao) GetBaseHospital(maps interface{}) (m *model.BaseHospital, err error) { + err = global.Db.Where(maps).First(&m).Error + if err != nil { + return nil, err + } + return m, nil +} + +// Inc 自增 +func (r *BaseHospitalDao) Inc(tx *gorm.DB, HospitalId int64, field string, numeral int) error { + err := tx.Model(&model.BaseHospital{}).Where("hospital_id = ?", HospitalId).UpdateColumn(field, gorm.Expr(field+" + ?", numeral)).Error + if err != nil { + return err + } + return nil +} + +// Dec 自减 +func (r *BaseHospitalDao) Dec(tx *gorm.DB, HospitalId int64, field string, numeral int) error { + err := tx.Model(&model.BaseHospital{}).Where("hospital_id = ?", HospitalId).UpdateColumn(field, gorm.Expr(field+" - ?", numeral)).Error + if err != nil { + return err + } + return nil +} + +// GetBaseHospitalLimitByMaps 获取医院列表-限制条数 +func (r *BaseHospitalDao) GetBaseHospitalLimitByMaps(hospitalRequest requests.GetBaseHospitalList) (m []*model.BaseHospital, err error) { + result := global.Db + if hospitalRequest.HospitalName != "" { + result = result.Where("hospital_name like ?", "%"+hospitalRequest.HospitalName+"%") + } + + if hospitalRequest.HospitalLevelName != "" { + result = result.Where("hospital_level_name like ?", "%"+hospitalRequest.HospitalLevelName+"%") + } + + err = result.Limit(10).Find(&m).Error + if err != nil { + return nil, err + } + return m, nil +} diff --git a/api/dao/User.go b/api/dao/User.go index 46a3540..3578751 100644 --- a/api/dao/User.go +++ b/api/dao/User.go @@ -4,6 +4,7 @@ import ( "gorm.io/gorm" "gorm.io/gorm/clause" "vote-admin-api/api/model" + "vote-admin-api/api/requests" "vote-admin-api/global" ) @@ -124,3 +125,53 @@ func (r *UserDao) Dec(tx *gorm.DB, UserId int64, field string, numeral int) erro } return nil } + +// GetUserPageSearch 获取列表-分页 +func (r *UserDao) GetUserPageSearch(req requests.GetUserPage, page, pageSize int) (m []*model.User, total int64, err error) { + var totalRecords int64 + + // 构建查询条件 + query := global.Db.Model(&model.User{}) + + // 用户id + if req.UserId != "" { + query = query.Where("user_id = ?", req.UserId) + } + + // app唯一标识 + if req.AppIden != "" { + query = query.Where("app_iden = ?", req.AppIden) + } + + // 状态 + if req.UserStatus != 0 { + query = query.Where("user_status = ?", req.UserStatus) + } + + // 用户微信标识 + if req.OpenId != "" { + query = query.Where("open_id LIKE ?", "%"+req.OpenId+"%") + } + + query = query.Order("created_at desc") + + // 查询总数量 + if err := query.Count(&totalRecords).Error; err != nil { + return nil, 0, err + } + + err = query.Scopes(model.Paginate(page, pageSize)).Find(&m).Error + if err != nil { + return nil, 0, err + } + return m, totalRecords, nil +} + +// GetUserListByTime 获取列表-今天开始时间/过期时间 +func (r *UserDao) GetUserListByTime(maps interface{}, startTime, endTime, field string) (m []*model.User, err error) { + err = global.Db.Where(maps).Where(field+" BETWEEN ? AND ?", startTime, endTime).Find(&m).Error + if err != nil { + return nil, err + } + return m, nil +} diff --git a/api/dao/Video.go b/api/dao/Video.go index 0460e49..f9b7bbe 100644 --- a/api/dao/Video.go +++ b/api/dao/Video.go @@ -126,49 +126,38 @@ func (r *VideoDao) Dec(tx *gorm.DB, VideoId int64, field string, numeral int) er return nil } -// GetVideoPageSearch 获取视频列表-分页 +// GetVideoPageSearch 获取列表-分页 func (r *VideoDao) GetVideoPageSearch(req requests.GetVideoPage, page, pageSize int) (m []*model.Video, total int64, err error) { var totalRecords int64 // 构建查询条件 query := global.Db.Model(&model.Video{}) - // 作者 - query = query.Preload("VideoAuthor") + // 文章标题 + if req.VideoTitle != "" { + query = query.Where("video_title LIKE ?", "%"+req.VideoTitle+"%") + } - // 作者关联医院 - query = query.Preload("VideoAuthor.BaseHospital") + // 视频编号 + if req.VideoNo != "" { + query = query.Where("video_no LIKE ?", "%"+req.VideoNo+"%") + } - // 文章状态(1:正常 2:禁用) - query = query.Where("video_status = ?", 1) + // 文章内容 + if req.VideoContent != "" { + query = query.Where("video_content LIKE ?", "%"+req.VideoContent+"%") + } - // 搜索关键字 - if req.Keyword != "" { - keyword := "%" + req.Keyword + "%" // + // 文章状态 + if req.VideoStatus != nil { + query = query.Where("video_status = ?", req.VideoStatus) + } - // 标题 - orQuery := global.Db.Model(&model.Video{}).Or("video_title LIKE ?", keyword) - - // 医院名称 - hospitalSubQuery := global.Db.Model(&model.BaseHospital{}). - Select("hospital_id"). - Where("hospital_name LIKE ?", keyword) - - articleAuthorSubQuery := global.Db.Model(&model.VideoAuthor{}). - Select("video_id"). - Where(gorm.Expr("hospital_id IN (?)", hospitalSubQuery)) - - orQuery = orQuery.Or(gorm.Expr("video_id IN (?)", articleAuthorSubQuery)) - - // 作者姓名 - subQuery := global.Db.Model(&model.VideoAuthor{}). - Select("video_id"). - Where("author_name LIKE ?", keyword) - - orQuery = orQuery.Or(gorm.Expr("video_id IN (?)", subQuery)) - - // 执行组建 - query = query.Where(orQuery) + // 排序 + if req.Order != nil { + if req.Order.VoteNum != "" { + query = query.Order("vote_num " + req.Order.VoteNum) + } } // 排序 diff --git a/api/dao/VideoAuthor.go b/api/dao/VideoAuthor.go index 2524dcd..1bff7fe 100644 --- a/api/dao/VideoAuthor.go +++ b/api/dao/VideoAuthor.go @@ -72,6 +72,15 @@ func (r *VideoAuthorDao) GetVideoAuthorList(maps interface{}) (m []*model.VideoA return m, nil } +// GetVideoAuthorPreloadList 获取列表-加载全部关联 +func (r *VideoAuthorDao) GetVideoAuthorPreloadList(maps interface{}) (m []*model.VideoAuthor, err error) { + err = global.Db.Preload(clause.Associations).Where(maps).Find(&m).Error + if err != nil { + return nil, err + } + return m, nil +} + // GetVideoAuthorCount 获取数量 func (r *VideoAuthorDao) GetVideoAuthorCount(maps interface{}) (total int64, err error) { err = global.Db.Model(&model.VideoAuthor{}).Where(maps).Count(&total).Error diff --git a/api/dao/VideoVoteDay.go b/api/dao/VideoVoteDay.go index fda03d6..cc9220c 100644 --- a/api/dao/VideoVoteDay.go +++ b/api/dao/VideoVoteDay.go @@ -124,3 +124,63 @@ func (r *VideoVoteDayDao) Dec(tx *gorm.DB, voteDayId int64, field string, numera } return nil } + +// GetVideoVoteDayByUserIdPageSearch 获取列表-分页-用户id +func (r *VideoVoteDayDao) GetVideoVoteDayByUserIdPageSearch(userId int64, page, pageSize int) (m []*model.VideoVoteDay, total int64, err error) { + var totalRecords int64 + + // 构建查询条件 + query := global.Db.Model(&model.VideoVoteDay{}) + + query = query.Preload("video") + + query = query.Where("user_id = ?", userId) + + query = query.Order("created_at desc") + + // 查询总数量 + if err := query.Count(&totalRecords).Error; err != nil { + return nil, 0, err + } + + err = query.Scopes(model.Paginate(page, pageSize)).Find(&m).Error + if err != nil { + return nil, 0, err + } + return m, totalRecords, nil +} + +// GetVideoVoteDayByVideoIdPageSearch 获取列表-分页-视频id +func (r *VideoVoteDayDao) GetVideoVoteDayByVideoIdPageSearch(videoId int64, page, pageSize int) (m []*model.VideoVoteDay, total int64, err error) { + var totalRecords int64 + + // 构建查询条件 + query := global.Db.Model(&model.VideoVoteDay{}) + + // 用户 + query = query.Preload("User") + + query = query.Where("video_id = ?", videoId) + + query = query.Order("created_at desc") + + // 查询总数量 + if err := query.Count(&totalRecords).Error; err != nil { + return nil, 0, err + } + + err = query.Scopes(model.Paginate(page, pageSize)).Find(&m).Error + if err != nil { + return nil, 0, err + } + return m, totalRecords, nil +} + +// GetVideoVoteDayListByTime 获取列表-开始时间/过期时间 +func (r *VideoVoteDayDao) GetVideoVoteDayListByTime(maps interface{}, startTime, endTime, field string) (m []*model.VideoVoteDay, err error) { + err = global.Db.Where(maps).Where(field+" BETWEEN ? AND ?", startTime, endTime).Find(&m).Error + if err != nil { + return nil, err + } + return m, nil +} diff --git a/api/dto/Article.go b/api/dto/Article.go index ec0b8c5..4318b35 100644 --- a/api/dto/Article.go +++ b/api/dto/Article.go @@ -16,7 +16,6 @@ type ArticleDto struct { UpdatedAt model.LocalTime `json:"updated_at"` // 更新时间 ArticleAuthor []*ArticleAuthorDto `json:"article_author"` // 作者 Rank *int `json:"rank"` // 排名 - IsVote bool `json:"is_vote"` // 是否已投票(false:否 true:是) } // GetArticleListDto 列表-分页 @@ -76,9 +75,3 @@ func (r *ArticleDto) LoadRank(m int) *ArticleDto { } return r } - -// LoadVoteStatus 加载数据-投票状态 -func (r *ArticleDto) LoadVoteStatus(m bool) *ArticleDto { - r.IsVote = m - return r -} diff --git a/api/dto/ArticleAuthor.go b/api/dto/ArticleAuthor.go index 208f6cb..a6e7d1b 100644 --- a/api/dto/ArticleAuthor.go +++ b/api/dto/ArticleAuthor.go @@ -1,11 +1,15 @@ package dto import ( + "fmt" "vote-admin-api/api/model" ) type ArticleAuthorDto struct { + AuthorId string `json:"author_id"` // 主键id + ArticleId string `json:"article_id"` // 文章id AuthorName string `json:"author_name"` // 作者姓名 + HospitalId string `json:"hospital_id"` // 作者所属id HospitalName string `json:"hospital_name"` // 作者所属医院 } @@ -17,12 +21,15 @@ func GetArticleAuthorListDto(m []*model.ArticleAuthor) []*ArticleAuthorDto { if len(m) > 0 { for i, v := range m { response := &ArticleAuthorDto{ + AuthorId: fmt.Sprintf("%d", v.AuthorId), + ArticleId: fmt.Sprintf("%d", v.ArticleId), AuthorName: v.AuthorName, + HospitalId: fmt.Sprintf("%d", v.HospitalId), } // 加载数据-医院属性 if v.BaseHospital != nil { - response = response.LoadBaseHospitalAttr(v.BaseHospital) + response = response.LoadBaseHospital(v.BaseHospital) } // 将转换后的结构体添加到新切片中 @@ -33,8 +40,8 @@ func GetArticleAuthorListDto(m []*model.ArticleAuthor) []*ArticleAuthorDto { return responses } -// LoadBaseHospitalAttr 加载数据-医院属性 -func (r *ArticleAuthorDto) LoadBaseHospitalAttr(m *model.BaseHospital) *ArticleAuthorDto { +// LoadBaseHospital 加载数据-医院 +func (r *ArticleAuthorDto) LoadBaseHospital(m *model.BaseHospital) *ArticleAuthorDto { if m != nil { r.HospitalName = m.HospitalName } diff --git a/api/dto/BaseAgreement.go b/api/dto/BaseAgreement.go index 4177b62..7d284f6 100644 --- a/api/dto/BaseAgreement.go +++ b/api/dto/BaseAgreement.go @@ -8,6 +8,7 @@ import ( // BaseAgreementDto 基础-协议 type BaseAgreementDto struct { AgreementId string `json:"agreement_id"` // 主键id + AgreementTitle string `json:"agreement_title"` // 协议名称 AgreementType int `json:"agreement_type"` // 协议类型(1:大赛介绍 2:投票规则) AgreementContent string `json:"agreement_content"` // 协议内容 CreatedAt model.LocalTime `json:"created_at"` // 创建时间 @@ -18,9 +19,34 @@ type BaseAgreementDto struct { func GetBaseAgreementDto(m *model.BaseAgreement) *BaseAgreementDto { return &BaseAgreementDto{ AgreementId: fmt.Sprintf("%d", m.AgreementId), + AgreementTitle: m.AgreementTitle, AgreementType: m.AgreementType, AgreementContent: m.AgreementContent, CreatedAt: m.CreatedAt, UpdatedAt: m.UpdatedAt, } } + +// GetBaseAgreementListDto 列表-基础数据-协议 +func GetBaseAgreementListDto(m []*model.BaseAgreement) []*BaseAgreementDto { + // 处理返回值 + responses := make([]*BaseAgreementDto, len(m)) + + if len(m) > 0 { + for i, v := range m { + response := &BaseAgreementDto{ + AgreementId: fmt.Sprintf("%d", v.AgreementId), + AgreementTitle: v.AgreementTitle, + AgreementType: v.AgreementType, + AgreementContent: v.AgreementContent, + CreatedAt: v.CreatedAt, + UpdatedAt: v.UpdatedAt, + } + + // 将转换后的结构体添加到新切片中 + responses[i] = response + } + } + + return responses +} diff --git a/api/dto/BaseHospital.go b/api/dto/BaseHospital.go new file mode 100644 index 0000000..7f63dd8 --- /dev/null +++ b/api/dto/BaseHospital.go @@ -0,0 +1,85 @@ +package dto + +import ( + "fmt" + "vote-admin-api/api/model" +) + +type BaseHospitalDto struct { + HospitalID string `json:"hospital_id"` // 主键id + HospitalName string `json:"hospital_name"` // 医院名称 + HospitalStatus int `json:"hospital_status"` // 状态(0:禁用 1:正常 2:删除) + HospitalLevelName string `json:"hospital_level_name"` // 医院等级名称 + PostCode string `json:"post_code"` // 邮政编码 + Telephone string `json:"telephone"` // 电话 + ProvinceID int `json:"province_id"` // 省份id + Province string `json:"province"` // 省份 + CityID int `json:"city_id"` // 城市id + City string `json:"city"` // 城市 + CountyID int `json:"county_id"` // 区县id + County string `json:"county"` // 区县 + Address string `json:"address"` // 地址 + Latitude string `json:"latitude"` // 纬度 + Longitude string `json:"longitude"` // 经度 + Description string `json:"description"` // 简介 + CreatedAt model.LocalTime `json:"created_at"` // 创建时间 + UpdatedAt model.LocalTime `json:"updated_at"` // 修改时间 +} + +func GetBaseHospitalDto(m *model.BaseHospital) *BaseHospitalDto { + return &BaseHospitalDto{ + HospitalID: fmt.Sprintf("%d", m.HospitalId), + HospitalName: m.HospitalName, + HospitalStatus: m.HospitalStatus, + HospitalLevelName: m.HospitalLevelName, + PostCode: m.PostCode, + Telephone: m.HospitalName, + ProvinceID: m.ProvinceId, + Province: m.Province, + CityID: m.CityId, + City: m.City, + CountyID: m.CountyId, + County: m.County, + Address: m.Address, + Latitude: m.Lat, + Longitude: m.HospitalName, + Description: m.Desc, + CreatedAt: m.CreatedAt, + UpdatedAt: m.UpdatedAt, + } +} + +func GetBaseHospitalListDto(m []*model.BaseHospital) []BaseHospitalDto { + // 处理返回值 + responses := make([]BaseHospitalDto, len(m)) + + if len(m) > 0 { + for i, v := range m { + response := BaseHospitalDto{ + HospitalID: fmt.Sprintf("%d", v.HospitalId), + HospitalName: v.HospitalName, + HospitalStatus: v.HospitalStatus, + HospitalLevelName: v.HospitalLevelName, + PostCode: v.PostCode, + Telephone: v.HospitalName, + ProvinceID: v.ProvinceId, + Province: v.Province, + CityID: v.CityId, + City: v.City, + CountyID: v.CountyId, + County: v.County, + Address: v.Address, + Latitude: v.Lat, + Longitude: v.HospitalName, + Description: v.Desc, + CreatedAt: v.CreatedAt, + UpdatedAt: v.UpdatedAt, + } + + // 将转换后的结构体添加到新切片中 + responses[i] = response + } + } + + return responses +} diff --git a/api/dto/Public.go b/api/dto/Public.go index ac58e72..2ad7d80 100644 --- a/api/dto/Public.go +++ b/api/dto/Public.go @@ -16,15 +16,8 @@ type LoginDto struct { // IndexDto 首页 type IndexDto struct { - QuestionCount int64 `json:"question_count"` // 问题数量 - UserCount int64 `json:"user_count"` // 用户数量 - ValidMemberCount int64 `json:"valid_member_count"` // 有效会员数 - QuestionSubmitCount int64 `json:"question_submit_count"` // 问题总提交次数 - QuestionPayCount int64 `json:"question_pay_count"` // 问题总支付次数 - MemberBuyCount int64 `json:"member_buy_count"` // 会员购买次数 - MemberAmountTotal float64 `json:"member_amount_total"` // 会员购买总金额 - SingleAmountTotal float64 `json:"single_amount_total"` // 单项购买总金额 - AmountTotal float64 `json:"amount_total"` // 会员+单项购买总金额 + ViewNum uint `json:"view_num"` // 浏览数量 + VoteNum uint `json:"vote_num"` // 投票数量 } // IndexDataDto 首页动态统计数据 diff --git a/api/dto/SystemTime.go b/api/dto/SystemTime.go new file mode 100644 index 0000000..94b63af --- /dev/null +++ b/api/dto/SystemTime.go @@ -0,0 +1,26 @@ +package dto + +import ( + "fmt" + "vote-admin-api/api/model" +) + +// SystemTimeDto 配置-时间 +type SystemTimeDto struct { + SystemTimeId string `json:"system_time_id"` // 主键id + StartTime *model.LocalTime `json:"start_time"` // 开始投票时间 + EndTime *model.LocalTime `json:"end_time"` // 结束投票时间 + CreatedAt model.LocalTime `json:"created_at"` // 创建时间 + UpdatedAt model.LocalTime `json:"updated_at"` // 修改时间 +} + +// GetSystemTimeDto 详情 +func GetSystemTimeDto(m *model.SystemTime) *SystemTimeDto { + return &SystemTimeDto{ + SystemTimeId: fmt.Sprintf("%d", m.SystemTimeId), + StartTime: m.StartTime, + EndTime: m.EndTime, + CreatedAt: m.CreatedAt, + UpdatedAt: m.UpdatedAt, + } +} diff --git a/api/dto/User.go b/api/dto/User.go index 63f549e..7c52912 100644 --- a/api/dto/User.go +++ b/api/dto/User.go @@ -1,6 +1,7 @@ package dto import ( + "fmt" "vote-admin-api/api/model" ) @@ -9,8 +10,57 @@ type UserDto struct { UserId string `json:"user_id"` // 用户id UserStatus int `json:"user_status"` // 状态(1:正常 2:禁用) OpenId string `json:"open_id"` // 用户微信标识 + AppIden string `json:"app_iden"` // app唯一标识 LoginAt *model.LocalTime `json:"login_at"` // 登陆时间 LoginIp string `json:"login_ip"` // 登陆ip CreatedAt model.LocalTime `json:"created_at"` // 创建时间 UpdatedAt model.LocalTime `json:"updated_at"` // 更新时间 } + +// UserVoteDto 用户投票记录 +type UserVoteDto struct { + Id string `json:"id"` // 图文/视频标识 + AppIden string `json:"app_iden"` // app唯一标识 + Title string `json:"title"` // 标题 + VotedAt string `json:"voted_at"` // 投票时间 +} + +// GetUserListDto 列表 +func GetUserListDto(m []*model.User) []*UserDto { + // 处理返回值 + responses := make([]*UserDto, len(m)) + + if len(m) > 0 { + for i, v := range m { + response := &UserDto{ + UserId: fmt.Sprintf("%d", v.UserId), + UserStatus: v.UserStatus, + OpenId: v.OpenId, + AppIden: v.AppIden, + LoginAt: v.LoginAt, + LoginIp: v.LoginIp, + CreatedAt: v.CreatedAt, + UpdatedAt: v.UpdatedAt, + } + + // 将转换后的结构体添加到新切片中 + responses[i] = response + } + } + + return responses +} + +// GetUserDto 详情-问题 +func GetUserDto(m *model.User) *UserDto { + return &UserDto{ + UserId: fmt.Sprintf("%d", m.UserId), + UserStatus: m.UserStatus, + OpenId: m.OpenId, + AppIden: m.AppIden, + LoginAt: m.LoginAt, + LoginIp: m.LoginIp, + CreatedAt: m.CreatedAt, + UpdatedAt: m.UpdatedAt, + } +} diff --git a/api/dto/Video.go b/api/dto/Video.go index 18b38ef..e36300f 100644 --- a/api/dto/Video.go +++ b/api/dto/Video.go @@ -7,16 +7,16 @@ import ( // VideoDto 视频表 type VideoDto struct { - VideoId string `json:"video_id"` // 主键id - VideoTitle string `json:"video_title"` // 视频标题 - VideoStatus int `json:"article_status"` // 视频状态(1:正常 2:禁用) - VoteNum uint `json:"vote_num"` // 总票数 - VideoUrl string `json:"video_url"` // 视频地址 - CreatedAt model.LocalTime `json:"created_at"` // 创建时间 - UpdatedAt model.LocalTime `json:"updated_at"` // 更新时间 - VideoAuthor []*VideoAuthorDto `json:"video_author"` // 作者 - Rank *int `json:"rank"` // 排名 - IsVote bool `json:"is_vote"` // 是否已投票(false:否 true:是) + VideoId string `json:"video_id"` // 主键id + VideoTitle string `json:"video_title"` // 视频标题 + VideoStatus int `json:"video_status"` // 视频状态(1:正常 2:禁用) + VideoNo string `json:"video_no"` // 视频编号 + VoteNum uint `json:"vote_num"` // 总票数 + VideoContent string `json:"video_content"` // 视频内容 + CreatedAt model.LocalTime `json:"created_at"` // 创建时间 + UpdatedAt model.LocalTime `json:"updated_at"` // 更新时间 + VideoAuthor []*VideoAuthorDto `json:"video_author"` // 作者 + Rank *int `json:"rank"` // 排名 } // GetVideoListDto 列表-分页 @@ -27,13 +27,14 @@ func GetVideoListDto(m []*model.Video) []*VideoDto { if len(m) > 0 { for i, v := range m { response := &VideoDto{ - VideoId: fmt.Sprintf("%d", v.VideoId), - VideoTitle: v.VideoTitle, - VideoStatus: v.VideoStatus, - VoteNum: v.VoteNum, - VideoUrl: v.VideoUrl, - CreatedAt: v.CreatedAt, - UpdatedAt: v.UpdatedAt, + VideoId: fmt.Sprintf("%d", v.VideoId), + VideoTitle: v.VideoTitle, + VideoStatus: v.VideoStatus, + VideoNo: v.VideoNo, + VoteNum: v.VoteNum, + VideoContent: v.VideoContent, + CreatedAt: v.CreatedAt, + UpdatedAt: v.UpdatedAt, } // 加载数据-作者 @@ -52,13 +53,14 @@ func GetVideoListDto(m []*model.Video) []*VideoDto { // GetVideoDto 详情 func GetVideoDto(m *model.Video) *VideoDto { return &VideoDto{ - VideoId: fmt.Sprintf("%d", m.VideoId), - VideoTitle: m.VideoTitle, - VideoStatus: m.VideoStatus, - VoteNum: m.VoteNum, - VideoUrl: m.VideoUrl, - CreatedAt: m.CreatedAt, - UpdatedAt: m.UpdatedAt, + VideoId: fmt.Sprintf("%d", m.VideoId), + VideoTitle: m.VideoTitle, + VideoStatus: m.VideoStatus, + VideoNo: m.VideoNo, + VoteNum: m.VoteNum, + VideoContent: m.VideoContent, + CreatedAt: m.CreatedAt, + UpdatedAt: m.UpdatedAt, } } @@ -77,9 +79,3 @@ func (r *VideoDto) LoadRank(m int) *VideoDto { } return r } - -// LoadVoteStatus 加载数据-投票状态 -func (r *VideoDto) LoadVoteStatus(m bool) *VideoDto { - r.IsVote = m - return r -} diff --git a/api/model/Article.go b/api/model/Article.go index ef50707..c1b6bb5 100644 --- a/api/model/Article.go +++ b/api/model/Article.go @@ -15,7 +15,6 @@ type Article struct { ArticleContent string `gorm:"column:article_content;type:text;comment:文章内容" json:"article_content"` Model ArticleAuthor []*ArticleAuthor `gorm:"foreignKey:ArticleId;references:article_id" json:"article_author"` - Rank *int `gorm:"column:rank;type:tinyint(1) unsigned;comment:排名" json:"rank"` } func (m *Article) TableName() string { diff --git a/api/model/ArticleVoteDay.go b/api/model/ArticleVoteDay.go index 203b7c0..d9128ec 100644 --- a/api/model/ArticleVoteDay.go +++ b/api/model/ArticleVoteDay.go @@ -13,6 +13,8 @@ type ArticleVoteDay struct { UserId int64 `gorm:"column:user_id;type:bigint(19);comment:用户id;NOT NULL" json:"user_id"` VotedAt *LocalTime `gorm:"column:voted_at;type:date;comment:投票时间(日)" json:"voted_at"` Model + Article *Article `gorm:"foreignKey:ArticleId;references:article_id" json:"article"` + User *User `gorm:"foreignKey:UserId;references:user_id" json:"user"` } func (m *ArticleVoteDay) TableName() string { diff --git a/api/model/BaseAgreement.go b/api/model/BaseAgreement.go index 6894088..4237b06 100644 --- a/api/model/BaseAgreement.go +++ b/api/model/BaseAgreement.go @@ -9,6 +9,7 @@ import ( // BaseAgreement 基础-协议 type BaseAgreement struct { AgreementId int64 `gorm:"column:agreement_id;type:bigint(19);primary_key;comment:主键id" json:"agreement_id"` + AgreementTitle string `gorm:"column:agreement_title;type:varchar(255);comment:协议标题" json:"agreement_title"` AgreementType int `gorm:"column:agreement_type;type:tinyint(1);comment:协议类型(1:大赛介绍 2:投票规则);NOT NULL" json:"agreement_type"` AgreementContent string `gorm:"column:agreement_content;type:text;comment:协议内容" json:"agreement_content"` Model diff --git a/api/model/Video.go b/api/model/Video.go index a4d2513..d9bff48 100644 --- a/api/model/Video.go +++ b/api/model/Video.go @@ -8,11 +8,12 @@ import ( // Video 视频表 type Video struct { - VideoId int64 `gorm:"column:video_id;type:bigint(19);primary_key;comment:主键id" json:"video_id"` - VideoTitle string `gorm:"column:video_title;type:varchar(200);comment:视频标题" json:"video_title"` - VideoStatus int `gorm:"column:video_status;type:tinyint(1);default:1;comment:视频状态(1:正常 2:禁用)" json:"video_status"` - VoteNum uint `gorm:"column:vote_num;type:int(10) unsigned;default:0;comment:总票数" json:"vote_num"` - VideoUrl string `gorm:"column:video_url;type:varchar(255);comment:视频地址" json:"video_url"` + VideoId int64 `gorm:"column:video_id;type:bigint(19);primary_key;comment:主键id" json:"video_id"` + VideoTitle string `gorm:"column:video_title;type:varchar(200);comment:视频标题" json:"video_title"` + VideoStatus int `gorm:"column:video_status;type:tinyint(1);default:1;comment:视频状态(1:正常 2:禁用)" json:"video_status"` + VoteNum uint `gorm:"column:vote_num;type:int(10) unsigned;default:0;comment:总票数" json:"vote_num"` + VideoNo string `gorm:"column:video_no;type:varchar(255);comment:视频编号(保利)" json:"video_no"` + VideoContent string `gorm:"column:video_content;type:text;comment:视频内容" json:"video_content"` Model VideoAuthor []*VideoAuthor `gorm:"foreignKey:VideoId;references:video_id" json:"video_author"` } diff --git a/api/model/VideoVoteDay.go b/api/model/VideoVoteDay.go index 700bc59..195c2bc 100644 --- a/api/model/VideoVoteDay.go +++ b/api/model/VideoVoteDay.go @@ -13,6 +13,8 @@ type VideoVoteDay struct { UserId int64 `gorm:"column:user_id;type:bigint(19);comment:用户id;NOT NULL" json:"user_id"` VotedAt *LocalTime `gorm:"column:voted_at;type:date;comment:投票时间(日)" json:"voted_at"` Model + Video *Video `gorm:"foreignKey:VideoId;references:video_id" json:"video"` + User *User `gorm:"foreignKey:UserId;references:user_id" json:"user"` } func (m *VideoVoteDay) TableName() string { diff --git a/api/requests/Article.go b/api/requests/Article.go index 07df0c0..8a1e7d7 100644 --- a/api/requests/Article.go +++ b/api/requests/Article.go @@ -2,11 +2,49 @@ package requests type ArticleRequest struct { GetArticlePage // 获取图文列表-分页 + PutArticle // 修改图文详情 + AddArticle // 新增图文详情 } // GetArticlePage 获取图文列表-分页 type GetArticlePage struct { - Page int `json:"page" form:"page" label:"页码"` - PageSize int `json:"page_size" form:"page_size" label:"每页个数"` - Keyword string `json:"keyword" form:"keyword" label:"搜索关键字"` + Page int `json:"page" form:"page" label:"页码"` + PageSize int `json:"page_size" form:"page_size" label:"每页个数"` + ArticleTitle string `json:"article_title" form:"article_title" label:"文章标题"` + ArticleStatus *int `json:"article_status" form:"article_status" label:"文章状态"` // (1:正常 2:禁用) + ArticleContent string `json:"article_content" form:"article_content" label:"文章内容"` + Order *GetArticlePageOrder `json:"order" form:"order" label:"排序"` +} + +// GetArticlePageOrder 获取图文列表-分页-排序条件 +type GetArticlePageOrder struct { + VoteNum string `json:"vote_num" form:"vote_num" label:"排序"` // 总票数 +} + +// PutArticle 修改图文详情 +type PutArticle struct { + ArticleTitle string `json:"article_title" form:"article_title" label:"文章标题" validate:"required"` + ArticleStatus int `json:"article_status" form:"article_status" label:"文章状态" validate:"required,oneof=1 2"` // (1:正常 2:禁用) + ArticleContent string `json:"article_content" form:"article_content" label:"文章内容" validate:"required"` + ArticleAuthor []*PutArticleAuthor `json:"article_author" form:"article_author" label:"作者" validate:"required"` +} + +// PutArticleAuthor 修改图文详情-作者 +type PutArticleAuthor struct { + AuthorName string `json:"author_name" form:"author_name" label:"作者姓名" validate:"required"` + HospitalId string `json:"hospital_id" form:"hospital_id" label:"作者所属医院id" validate:"required"` +} + +// AddArticle 新增图文详情 +type AddArticle struct { + ArticleTitle string `json:"article_title" form:"article_title" label:"文章标题" validate:"required"` + ArticleStatus int `json:"article_status" form:"article_status" label:"文章状态" validate:"required,oneof=1 2"` // (1:正常 2:禁用) + ArticleContent string `json:"article_content" form:"article_content" label:"文章内容" validate:"required"` + ArticleAuthor []*PutArticleAuthor `json:"article_author" form:"article_author" label:"作者" validate:"required"` +} + +// AddArticleAuthor 新增图文详情-作者 +type AddArticleAuthor struct { + AuthorName string `json:"author_name" form:"author_name" label:"作者姓名" validate:"required"` + HospitalId string `json:"hospital_id" form:"hospital_id" label:"作者所属医院id" validate:"required"` } diff --git a/api/requests/BaseAgreement.go b/api/requests/BaseAgreement.go new file mode 100644 index 0000000..72c2c79 --- /dev/null +++ b/api/requests/BaseAgreement.go @@ -0,0 +1,26 @@ +package requests + +type BaseAgreementRequest struct { + GetBaseAgreementPage // 获取协议列表-分页 + PutBaseAgreement // 修改协议 + AddBaseAgreement // 新增协议 +} + +// GetBaseAgreementPage 获取协议列表-分页 +type GetBaseAgreementPage struct { + Page int `json:"page" form:"page" label:"页码"` + PageSize int `json:"page_size" form:"page_size" label:"每页个数"` +} + +// PutBaseAgreement 修改协议 +type PutBaseAgreement struct { + AgreementTitle string `json:"agreement_title" form:"agreement_title" label:"协议标题"` + AgreementContent string `json:"agreement_content" form:"agreement_content" label:"协议内容"` +} + +// AddBaseAgreement 新增协议 +type AddBaseAgreement struct { + AgreementTitle string `json:"agreement_title" form:"agreement_title" label:"协议标题"` + AgreementType int `json:"agreement_type" form:"agreement_type" label:"协议类型" validate:"required,oneof=1 2"` // (1:大赛介绍 2:投票规则) + AgreementContent string `json:"agreement_content" form:"agreement_content" label:"协议内容"` +} diff --git a/api/requests/BaseHospital.go b/api/requests/BaseHospital.go new file mode 100644 index 0000000..9c6bf4c --- /dev/null +++ b/api/requests/BaseHospital.go @@ -0,0 +1,18 @@ +package requests + +type BaseHospitalRequest struct { + GetBaseHospitalList // 获取医院列表 +} + +// GetBaseHospitalList 获取医院列表 +type GetBaseHospitalList struct { + HospitalName string `json:"hospital_name" form:"hospital_name" label:"医院名称"` + HospitalLevelName string `json:"hospital_level_name" form:"hospital_level_name" label:"医院等级名称"` + HospitalStatus int `json:"hospital_status" form:"hospital_status" label:"状态"` // 状态(0:禁用 1:正常 2:删除) + ProvinceId int `json:"province_id" form:"province_id" label:"省份id"` + Province string `json:"province" form:"province" label:"省份"` + CityId int `json:"city_id" form:"city_id" label:"城市id"` + City string `json:"city" form:"city" label:"城市"` + CountyId int `json:"county_id" form:"county_id" label:"区县id"` + County string `json:"county" form:"county" label:"区县"` +} diff --git a/api/requests/Public.go b/api/requests/Public.go index b6d50f6..f8a7c09 100644 --- a/api/requests/Public.go +++ b/api/requests/Public.go @@ -1,7 +1,8 @@ package requests type PublicRequest struct { - Login // 登陆 + Login // 登陆 + GetIndexData // 首页动态统计数据 } // Login 登陆 @@ -11,3 +12,10 @@ type Login struct { Captcha string `json:"captcha" form:"captcha" validate:"required" label:"验证码"` // 验证码 CaptchaId string `json:"captchaId" form:"captchaId" validate:"required"` // 验证码ID } + +// GetIndexData 首页动态统计数据 +type GetIndexData struct { + Type int `json:"type" form:"type" validate:"required,oneof=1 2 3" label:"分类"` // 分类(1:新增用户数 2:图文投票数 3:视频投票数) + StartTime string `json:"start_time" form:"start_time" validate:"required" label:"开始时间"` + EndTime string `json:"end_time" form:"end_time" validate:"required" label:"结束时间"` +} diff --git a/api/requests/User.go b/api/requests/User.go new file mode 100644 index 0000000..394ccf6 --- /dev/null +++ b/api/requests/User.go @@ -0,0 +1,21 @@ +package requests + +type UserRequest struct { + GetUserPage // 获取用户列表-分页 + PutUserStatus // 操作用户状态 +} + +// GetUserPage 获取用户列表-分页 +type GetUserPage struct { + Page int `json:"page" form:"page" label:"页码"` + PageSize int `json:"page_size" form:"page_size" label:"每页个数"` + UserId string `json:"user_id" form:"user_id" label:"用户id"` + UserStatus int `json:"user_status" form:"user_status" label:"状态"` + AppIden string `json:"app_iden" form:"app_iden" label:"app唯一标识"` + OpenId string `json:"open_id" form:"open_id" label:"用户微信标识"` +} + +// PutUserStatus 操作用户状态 +type PutUserStatus struct { + UserStatus int `json:"user_status" form:"user_status" label:"删除状态" validate:"required,oneof=1 2"` // 状态(1:正常 2:禁用) +} diff --git a/api/requests/UserVoteDay.go b/api/requests/UserVoteDay.go new file mode 100644 index 0000000..e98eb9d --- /dev/null +++ b/api/requests/UserVoteDay.go @@ -0,0 +1,36 @@ +package requests + +type UserVoteDayRequest struct { + GetArticleUserVoteDayPage // 用户投票记录列表-图文-分页 + GetVideoUserVoteDayPage // 用户投票记录列表-视频-分页 + GetArticleVoteDayPage // 投票记录列表-图文-分页 + GetVideoVoteDayPage // 投票记录列表-视频-分页 +} + +// GetArticleUserVoteDayPage 用户投票记录列表-图文-分页 +type GetArticleUserVoteDayPage struct { + Page int `json:"page" form:"page" label:"页码"` + PageSize int `json:"page_size" form:"page_size" label:"每页个数"` + UserId string `json:"user_id" form:"user_id" label:"用户id" validate:"required"` +} + +// GetVideoUserVoteDayPage 用户投票记录列表-视频-分页 +type GetVideoUserVoteDayPage struct { + Page int `json:"page" form:"page" label:"页码"` + PageSize int `json:"page_size" form:"page_size" label:"每页个数"` + UserId string `json:"user_id" form:"user_id" label:"用户id" validate:"required"` +} + +// GetArticleVoteDayPage 投票记录列表-图文-分页 +type GetArticleVoteDayPage struct { + Page int `json:"page" form:"page" label:"页码"` + PageSize int `json:"page_size" form:"page_size" label:"每页个数"` + ArticleId string `json:"article_id" form:"article_id" label:"文章id" validate:"required"` +} + +// GetVideoVoteDayPage 投票记录列表-视频-分页 +type GetVideoVoteDayPage struct { + Page int `json:"page" form:"page" label:"页码"` + PageSize int `json:"page_size" form:"page_size" label:"每页个数"` + VideoId string `json:"video_id" form:"video_id" label:"视频id" validate:"required"` +} diff --git a/api/requests/Video.go b/api/requests/Video.go index 95470a0..51f476f 100644 --- a/api/requests/Video.go +++ b/api/requests/Video.go @@ -2,11 +2,54 @@ package requests type VideoRequest struct { GetVideoPage // 获取视频列表-分页 + PutVideo // 修改视频详情 + AddVideo // 新增视频详情 } // GetVideoPage 获取视频列表-分页 type GetVideoPage struct { - Page int `json:"page" form:"page" label:"页码"` - PageSize int `json:"page_size" form:"page_size" label:"每页个数"` - Keyword string `json:"keyword" form:"keyword" label:"搜索关键字"` + Page int `json:"page" form:"page" label:"页码"` + PageSize int `json:"page_size" form:"page_size" label:"每页个数"` + VideoTitle string `json:"video_title" form:"Video_title" label:"视频标题"` + VideoStatus *int `json:"video_status" form:"Video_status" label:"视频状态"` // (1:正常 2:禁用) + VideoNo string `json:"video_no" form:"video_no" label:"视频编号"` // (保利) + VideoContent string `json:"video_content" form:"Video_content" label:"视频内容"` + Order *GetVideoPageOrder `json:"order" form:"order" label:"排序"` +} + +// GetVideoPageOrder 获取视频列表-分页-排序条件 +type GetVideoPageOrder struct { + VoteNum string `json:"vote_num" form:"vote_num" label:"排序"` // 总票数 +} + +// PutVideo 修改视频详情 +type PutVideo struct { + VideoTitle string `json:"video_title" form:"video_title" label:"视频标题" validate:"required"` + VideoStatus int `json:"video_status" form:"video_status" label:"视频状态" validate:"required,oneof=1 2"` // (1:正常 2:禁用) + VoteNum uint `json:"vote_num" form:"vote_num" label:"总票数" validate:"required"` + VideoNo string `json:"video_no" form:"video_no" label:"视频编号" validate:"required"` // (保利) + VideoContent string `json:"video_content" form:"video_content" label:"视频内容" validate:"required"` + VideoAuthor []*PutVideoAuthor `json:"video_author" form:"video_author" label:"作者" validate:"required"` +} + +// PutVideoAuthor 修改视频详情-作者 +type PutVideoAuthor struct { + AuthorName string `json:"author_name" form:"author_name" label:"作者姓名" validate:"required"` + HospitalId string `json:"hospital_id" form:"hospital_id" label:"作者所属医院id" validate:"required"` +} + +// AddVideo 新增视频详情 +type AddVideo struct { + VideoTitle string `json:"video_title" form:"video_title" label:"视频标题" validate:"required"` + VideoStatus int `json:"video_status" form:"video_status" label:"视频状态" validate:"required,oneof=1 2"` // (1:正常 2:禁用) + VoteNum uint `json:"vote_num" form:"vote_num" label:"总票数" validate:"required"` + VideoNo string `json:"video_no" form:"video_no" label:"视频编号" validate:"required"` // (保利) + VideoContent string `json:"video_content" form:"video_content" label:"视频内容" validate:"required"` + VideoAuthor []*PutVideoAuthor `json:"video_author" form:"video_author" label:"作者" validate:"required"` +} + +// AddVideoAuthor 新增视频详情-作者 +type AddVideoAuthor struct { + AuthorName string `json:"author_name" form:"author_name" label:"作者姓名" validate:"required"` + HospitalId string `json:"hospital_id" form:"hospital_id" label:"作者所属医院id" validate:"required"` } diff --git a/api/router/router.go b/api/router/router.go index b906e45..25b3ef2 100644 --- a/api/router/router.go +++ b/api/router/router.go @@ -83,7 +83,17 @@ func publicRouter(r *gin.Engine, api controller.Api) { // adminRouter 公共路由-验证权限 func adminRouter(r *gin.Engine, api controller.Api) { + adminGroup := r.Group("/admin") + // 首页 + indexGroup := adminGroup.Group("/index") + { + // 首页 + indexGroup.GET("", api.Public.GetIndex) + + // 首页动态统计数据 + indexGroup.GET("/data", api.Public.GetIndexData) + } } // basicRouter 基础数据-验证权限 @@ -93,5 +103,104 @@ func basicRouter(r *gin.Engine, api controller.Api) { // privateRouter 私有路由-验证权限 func privateRouter(r *gin.Engine, api controller.Api) { + adminGroup := r.Group("/admin") + // 图文 + articleGroup := adminGroup.Group("/article") + { + // 获取图文列表-分页 + articleGroup.POST("/page", api.Article.GetArticlePage) + + // 获取图文详情 + articleGroup.GET("/:article_id", api.Article.GetArticle) + + // 修改图文详情 + articleGroup.PUT("/:article_id", api.Article.PutArticle) + + // 新增图文详情 + articleGroup.POST("", api.Article.AddArticle) + + // 投票记录列表-图文-分页 + articleGroup.GET("/vote/page", api.UserVoteDay.GetArticleVotePage) + } + + // 视频 + videoGroup := adminGroup.Group("/video") + { + // 获取视频列表-分页 + videoGroup.POST("/page", api.Video.GetVideoPage) + + // 获取视频详情 + videoGroup.GET("/:video_id", api.Video.GetVideo) + + // 修改视频详情 + videoGroup.PUT("/:video_id", api.Video.PutVideo) + + // 新增视频详情 + videoGroup.POST("", api.Video.AddVideo) + + // 投票记录列表-视频-分页 + videoGroup.GET("/vote/page", api.UserVoteDay.GetVideoVotePage) + } + + // 基础数据 + basicGroup := adminGroup.Group("/basic") + { + // 协议 + agreementGroup := basicGroup.Group("/agreement") + { + // 获取协议列表-分页 + agreementGroup.POST("/page", api.BaseAgreement.GetBaseAgreementPage) + + // 获取协议详情 + agreementGroup.GET("/:agreement_id", api.BaseAgreement.GetBaseAgreement) + + // 修改协议 + agreementGroup.PUT("/:agreement_id", api.BaseAgreement.PutBaseAgreement) + + // 新增协议 + agreementGroup.POST("", api.BaseAgreement.AddBaseAgreement) + } + + // 医院管理 + hospitalGroup := basicGroup.Group("/hospital") + { + // 获取医院列表-限制条数 + hospitalGroup.GET("/page", api.BaseHospital.GetHospitalList) + } + } + + // 用户 + userGroup := adminGroup.Group("/user") + { + // 获取用户列表-分页 + userGroup.GET("/page", api.User.GetUserPage) + + // 获取用户详情 + userGroup.GET("/:user_id", api.User.GetUser) + + // 操作用户状态 + userGroup.PUT("/status/:user_id", api.User.PutUserStatus) + + // 用户投票记录 + voteGroup := userGroup.Group("/vote") + { + // 用户投票记录列表-图文-分页 + voteGroup.GET("/article/page", api.UserVoteDay.GetUserArticleVotePage) + + // 用户投票记录列表-视频-分页 + voteGroup.GET("/video/page", api.UserVoteDay.GetUserVideoVotePage) + } + } + + // 配置 + systemGroup := adminGroup.Group("/system") + { + // 投票时间 + timeGroup := systemGroup.Group("/time") + { + // 获取投票时间详情 + timeGroup.GET("/:system_time_id", api.System.GetSystemTime) + } + } } diff --git a/log/vote-admin-api.log b/log/vote-admin-api.log new file mode 100755 index 0000000..e584e16 --- /dev/null +++ b/log/vote-admin-api.log @@ -0,0 +1,61 @@ +time="2024-09-02 13:02:43" level=info msg=access http_status=200 ip=127.0.0.1 method=POST params="map[]" total_time=44.846083ms uri=/admin/article/page +time="2024-09-02 13:02:47" level=info msg=access http_status=200 ip=127.0.0.1 method=POST params="map[access:admin captcha:123 captchaId:123 password:123456]" total_time=80.349708ms uri=/admin/login +time="2024-09-02 13:02:56" level=info msg=access http_status=200 ip=127.0.0.1 method=POST params="map[]" total_time=114.16975ms uri=/admin/article/page +time="2024-09-02 13:03:21" level=info msg=access http_status=200 ip=127.0.0.1 method=POST params="map[page:1 page_size:1]" total_time=241.066041ms uri=/admin/article/page +time="2024-09-02 13:04:03" level=info msg=access http_status=200 ip=127.0.0.1 method=POST params="map[page:1 page_size:1]" total_time=249.173917ms uri=/admin/article/page +time="2024-09-02 13:04:49" level=info msg=access http_status=200 ip=127.0.0.1 method=POST params="map[page:1 page_size:1]" total_time=305.496791ms uri=/admin/article/page +time="2024-09-02 13:08:47" level=info msg=access http_status=200 ip=127.0.0.1 method=POST params="map[page:1 page_size:1]" total_time=247.795708ms uri=/admin/article/page +time="2024-09-02 13:09:12" level=info msg=access http_status=200 ip=127.0.0.1 method=GET params="map[]" total_time=345.363875ms uri=/admin/article/1 +time="2024-09-02 13:10:01" level=info msg=access http_status=200 ip=127.0.0.1 method=GET params="map[]" total_time=374.398667ms uri=/admin/article/1 +time="2024-09-02 13:19:04" level=info msg=access http_status=200 ip=127.0.0.1 method=GET params="map[]" total_time=437.131ms uri=/admin/article/1 +time="2024-09-03 08:58:04" level=info msg=access http_status=200 ip=127.0.0.1 method=PUT params="map[article_author:[map[author_name:作者1]] article_content:测试文章内容11 article_status:1 article_title:测试文章11]" total_time=448.089ms uri=/admin/article/1 +time="2024-09-03 08:58:33" level=info msg=access http_status=200 ip=127.0.0.1 method=PUT params="map[article_author:[map[author_name:作者1]] article_content:测试文章内容11 article_status:1 article_title:测试文章11]" total_time=469.887875ms uri=/admin/article/1 +time="2024-09-03 09:00:46" level=info msg=access http_status=200 ip=127.0.0.1 method=PUT params="map[article_author:[map[author_name:作者1]] article_content:测试文章内容11 article_status:1 article_title:测试文章11]" total_time=424.844875ms uri=/admin/article/1 +time="2024-09-03 09:01:24" level=info msg=access http_status=200 ip=127.0.0.1 method=PUT params="map[article_author:[map[author_name:作者1 hospital_id:515519285915684864]] article_content:测试文章内容11 article_status:1 article_title:测试文章11]" total_time=768.645459ms uri=/admin/article/1 +time="2024-09-03 09:10:38" level=info msg=access http_status=200 ip=127.0.0.1 method=POST params="map[article_author:[map[author_name:作者3 hospital_id:515519285915684864]] article_content:测试文章内容3 article_status:1 article_title:测试文章3]" total_time=253.08325ms uri=/admin/article +time="2024-09-03 09:12:31" level=info msg=access http_status=200 ip=127.0.0.1 method=POST params="map[article_author:[map[author_name:作者3 hospital_id:515519285915684864]] article_content:测试文章内容3 article_status:1 article_title:测试文章3]" total_time=682.433459ms uri=/admin/article +time="2024-09-03 09:12:37" level=info msg=access http_status=200 ip=127.0.0.1 method=GET params="map[]" total_time=519.242583ms uri=/admin/article/1 +time="2024-09-03 09:12:44" level=info msg=access http_status=200 ip=127.0.0.1 method=GET params="map[]" total_time=222.803041ms uri=/admin/article/3 +time="2024-09-03 09:40:31" level=info msg=access http_status=200 ip=127.0.0.1 method=POST params="map[page:1 page_size:1]" total_time=277.253125ms uri=/admin/video/page +time="2024-09-03 09:41:26" level=info msg=access http_status=200 ip=127.0.0.1 method=POST params="map[page:1 page_size:1]" total_time=242.252584ms uri=/admin/video/page +time="2024-09-03 09:41:45" level=info msg=access http_status=200 ip=127.0.0.1 method=GET params="map[]" total_time=449.189791ms uri=/admin/video/1 +time="2024-09-03 09:42:44" level=info msg=access http_status=200 ip=127.0.0.1 method=PUT params="map[video_author:[map[author_name:作者1 hospital_id:515519285915684864]] video_content:测试视频内容11 video_no:cfb7a69a75fabb5f52347d14c798738d_c1 video_status:1 video_title:测试视频11]" total_time=792.113458ms uri=/admin/video/1 +time="2024-09-03 09:43:18" level=info msg=access http_status=200 ip=127.0.0.1 method=POST params="map[video_author:[map[author_name:作者1 hospital_id:515519285915684864]] video_content:测试视频内容1 video_no:cfb7a69a75fabb5f52347d14c798738d_c video_status:1 video_title:测试视频1]" total_time=477.879125ms uri=/admin/video +time="2024-09-03 11:46:24" level=info msg=access http_status=404 ip=127.0.0.1 method=GET params="map[]" total_time=114.253834ms uri=/admin/agreement/page +time="2024-09-03 11:46:46" level=info msg=access http_status=404 ip=127.0.0.1 method=GET params="map[]" total_time=130.065625ms uri=/admin/basic/agreement/page +time="2024-09-03 11:46:59" level=info msg=access http_status=200 ip=127.0.0.1 method=POST params="map[]" total_time=115.495333ms uri=/admin/basic/agreement/page +time="2024-09-03 11:47:16" level=info msg=access http_status=200 ip=127.0.0.1 method=POST params="map[page:1 page_size:1]" total_time=273.4095ms uri=/admin/basic/agreement/page +time="2024-09-03 11:48:20" level=info msg=access http_status=200 ip=127.0.0.1 method=POST params="map[page:1 page_size:1]" total_time=258.470708ms uri=/admin/basic/agreement/page +time="2024-09-03 11:48:58" level=info msg=access http_status=200 ip=127.0.0.1 method=POST params="map[page:1 page_size:1]" total_time=278.053333ms uri=/admin/basic/agreement/page +time="2024-09-03 13:28:09" level=info msg=access http_status=200 ip=127.0.0.1 method=GET params="map[]" total_time=42.951458ms uri=/admin/agreement/1 +time="2024-09-03 13:28:16" level=info msg=access http_status=200 ip=127.0.0.1 method=POST params="map[access:admin captcha:123 captchaId:123 password:123456]" total_time=83.88125ms uri=/admin/login +time="2024-09-03 13:28:30" level=info msg=access http_status=404 ip=127.0.0.1 method=GET params="map[]" total_time=122.985167ms uri=/admin/agreement/1 +time="2024-09-03 13:28:39" level=info msg=access http_status=200 ip=127.0.0.1 method=GET params="map[]" total_time=205.725333ms uri=/admin/basic/agreement/1 +time="2024-09-03 13:29:00" level=info msg=access http_status=404 ip=127.0.0.1 method=PUT params="map[agreement_content:内容1 agreement_title:标题1]" total_time=126.555375ms uri=/admin/agreement/1 +time="2024-09-03 13:29:08" level=info msg=access http_status=200 ip=127.0.0.1 method=PUT params="map[agreement_content:内容1 agreement_title:标题1]" total_time=376.005542ms uri=/admin/basic/agreement/1 +time="2024-09-03 13:29:35" level=info msg=access http_status=200 ip=127.0.0.1 method=POST params="map[agreement_content:内容2 agreement_title:标题2 agreement_type:1]" total_time=307.189541ms uri=/admin/basic/agreement +time="2024-09-03 14:37:02" level=info msg=access http_status=200 ip=127.0.0.1 method=GET params="map[]" total_time=241.432292ms uri=/admin/user/page +time="2024-09-03 14:37:56" level=info msg=access http_status=200 ip=127.0.0.1 method=GET params="map[]" total_time=214.370625ms uri=/admin/user/1 +time="2024-09-03 14:39:26" level=info msg=access http_status=200 ip=127.0.0.1 method=PUT params="map[user_status:1]" total_time=205.848ms uri="/admin/user/status/1?user_status=1" +time="2024-09-03 14:40:32" level=info msg=access http_status=404 ip=127.0.0.1 method=GET params="map[]" total_time=122.696541ms uri=/admin/user/vote/article/page +time="2024-09-03 14:40:45" level=info msg=access http_status=404 ip=127.0.0.1 method=GET params="map[]" total_time=122.2905ms uri=/admin/user/vote/article/page +time="2024-09-03 14:41:10" level=info msg=access http_status=404 ip=127.0.0.1 method=GET params="map[]" total_time=122.97575ms uri=/admin/user/vote/article/page +time="2024-09-03 14:41:33" level=info msg=access http_status=200 ip=127.0.0.1 method=GET params="map[]" total_time=131.224041ms uri=/admin/user/vote/article/page +time="2024-09-03 14:41:40" level=info msg=access http_status=200 ip=127.0.0.1 method=GET params="map[user_id:1]" total_time=391.64225ms uri="/admin/user/vote/article/page?user_id=1" +time="2024-09-03 14:44:20" level=info msg=access http_status=200 ip=127.0.0.1 method=GET params="map[user_id:1]" total_time=377.584ms uri="/admin/user/vote/article/page?user_id=1" +time="2024-09-03 14:44:57" level=info msg=access http_status=200 ip=127.0.0.1 method=GET params="map[user_id:1]" total_time=375.755625ms uri="/admin/user/vote/video/page?user_id=1" +time="2024-09-03 14:52:23" level=info msg=access http_status=200 ip=127.0.0.1 method=GET params="map[]" total_time=219.679292ms uri=/admin/system/time/1 +time="2024-09-03 15:15:53" level=info msg=access http_status=404 ip=127.0.0.1 method=POST params="map[page:1 page_size:1]" total_time=114.426667ms uri=/admin/basic/hospital/page +time="2024-09-03 15:16:04" level=info msg=access http_status=404 ip=127.0.0.1 method=GET params="map[]" total_time=114.772208ms uri=/admin/basic/hospital/page +time="2024-09-03 15:16:25" level=info msg=access http_status=200 ip=127.0.0.1 method=GET params="map[]" total_time=213.651334ms uri=/admin/basic/hospital/page +time="2024-09-03 15:41:41" level=info msg=access http_status=200 ip=127.0.0.1 method=GET params="map[]" total_time=152.090917ms uri=/admin/article/vote/page +time="2024-09-03 15:42:08" level=info msg=access http_status=200 ip=127.0.0.1 method=GET params="map[]" total_time=121.774083ms uri=/admin/article/vote/page +time="2024-09-03 15:42:25" level=info msg=access http_status=500 ip=127.0.0.1 method=GET params="map[article_id:1]" total_time=381.150417ms uri="/admin/article/vote/page?article_id=1" +time="2024-09-03 15:43:54" level=info msg=access http_status=200 ip=127.0.0.1 method=GET params="map[article_id:1]" total_time=368.069ms uri="/admin/article/vote/page?article_id=1" +time="2024-09-03 15:44:28" level=info msg=access http_status=200 ip=127.0.0.1 method=GET params="map[article_id:1]" total_time=116.6395ms uri="/admin/video/vote/page?article_id=1" +time="2024-09-03 15:44:37" level=info msg=access http_status=200 ip=127.0.0.1 method=GET params="map[video_id:1]" total_time=403.1155ms uri="/admin/video/vote/page?video_id=1" +time="2024-09-03 16:03:48" level=info msg=access http_status=200 ip=127.0.0.1 method=GET params="map[]" total_time=206.054583ms uri=/admin/index +time="2024-09-03 16:04:24" level=info msg=access http_status=200 ip=127.0.0.1 method=GET params="map[end_time:2024-08-01 start_time:2024-07-01 type:1]" total_time=192.435875ms uri="/admin/index/data?type=1&start_time=2024-07-01&end_time=2024-08-01" +time="2024-09-03 16:04:35" level=info msg=access http_status=200 ip=127.0.0.1 method=GET params="map[end_time:2024-09-01 start_time:2024-07-01 type:1]" total_time=216.628333ms uri="/admin/index/data?type=1&start_time=2024-07-01&end_time=2024-09-01" +time="2024-09-03 16:04:41" level=info msg=access http_status=200 ip=127.0.0.1 method=GET params="map[end_time:2024-09-09 start_time:2024-07-01 type:1]" total_time=214.048625ms uri="/admin/index/data?type=1&start_time=2024-07-01&end_time=2024-09-09" +time="2024-09-03 16:04:47" level=info msg=access http_status=200 ip=127.0.0.1 method=GET params="map[end_time:2024-09-09 start_time:2024-07-01 type:2]" total_time=191.817375ms uri="/admin/index/data?type=2&start_time=2024-07-01&end_time=2024-09-09"