比較提交

..

10 次程式碼提交

共有 8 個檔案被更改,包括 97 行新增13 行删除

1
.gitignore vendored
查看文件

@ -1,2 +1,3 @@
.idea .idea
integrity-checkin integrity-checkin
files

查看文件

@ -23,7 +23,18 @@ func (c CheckinDAO) FindUserActivityByDay(userID int, activityID int, day string
} }
return &userActivity return &userActivity
} }
func (c CheckinDAO) CreateCheckin(userID int, activityID int, image string) (*po.UserActivity, error) { func (c CheckinDAO) FindUserActivityInHistorySince(userID int, activityID int) *po.UserActivity {
var userActivity po.UserActivity
err := c.Tx.Take(&userActivity, "user_id=? and activity_id=?", userID, activityID).Error
if err == gorm.ErrRecordNotFound {
return nil
}
if err != nil {
panic(err)
}
return &userActivity
}
func (c CheckinDAO) CreateCheckin(userID int, activityID int, files string) (*po.UserActivity, error) {
if activity := c.FindActivityByID(activityID); activity == nil { if activity := c.FindActivityByID(activityID); activity == nil {
return nil, errors.New("activityID不存在") return nil, errors.New("activityID不存在")
} }
@ -31,7 +42,7 @@ func (c CheckinDAO) CreateCheckin(userID int, activityID int, image string) (*po
UserID: userID, UserID: userID,
UserActivityForm: po.UserActivityForm{ UserActivityForm: po.UserActivityForm{
ActivityID: activityID, ActivityID: activityID,
Image: image, Files: files,
}, },
Status: 1, Status: 1,
Day: time.Now().Format("20060102"), Day: time.Now().Format("20060102"),
@ -74,10 +85,11 @@ func (c CheckinDAO) SaveUserActivity(userActivity *po.UserActivity) {
func (c CheckinDAO) FindAllActivities(isTeacher bool) []po.Activity { func (c CheckinDAO) FindAllActivities(isTeacher bool) []po.Activity {
var arr []po.Activity var arr []po.Activity
var err error var err error
// 按照主键排序
if isTeacher { if isTeacher {
err = c.Tx.Find(&arr, "teacher_available=?", true).Error err = c.Tx.Find(&arr, "visible=?", true).Order("id").Error
} else { } else {
err = c.Tx.Find(&arr).Error err = c.Tx.Find(&arr, "visible=?", true).Order("id").Error
} }
if err != nil { if err != nil {
panic(err) panic(err)
@ -86,7 +98,7 @@ func (c CheckinDAO) FindAllActivities(isTeacher bool) []po.Activity {
} }
func getUserActivityExtendedSQL(where string) string { func getUserActivityExtendedSQL(where string) string {
return "select ua.*,a.category activity_category," + return "select ua.*,a.category activity_category," +
"a.name activity_name from user_activity ua left join activities a on a.id=ua.activity_id " + "a.name activity_name,u.real_name,u.username from user_activity ua left join activities a on a.id=ua.activity_id " +
"left join users u on u.id=ua.user_id " + where + "left join users u on u.id=ua.user_id " + where +
" order by created_at desc" " order by created_at desc"
} }

查看文件

@ -14,4 +14,6 @@ type UserActivityExtended struct {
po.UserActivity po.UserActivity
ActivityCategory string `json:"activity_category"` ActivityCategory string `json:"activity_category"`
ActivityName string `json:"activity_name"` ActivityName string `json:"activity_name"`
Username string `json:"username"`
RealName string `json:"real_name"`
} }

查看文件

@ -1,8 +1,6 @@
package po package po
import ( import (
"errors"
"strings"
"time" "time"
) )
@ -12,6 +10,8 @@ type Activity struct {
Name string `json:"name"` Name string `json:"name"`
Image string `json:"image"` Image string `json:"image"`
Credit int `json:"credit"` Credit int `json:"credit"`
Visible int `json:"visible"`
Limit int `json:"limit"`
TeacherAvailable int `json:"teacher_available"` TeacherAvailable int `json:"teacher_available"`
} }
@ -36,12 +36,14 @@ func (u UserActivity) TableName() string {
type UserActivityForm struct { type UserActivityForm struct {
ActivityID int `json:"activity_id" form:"activity_id" binding:"required"` ActivityID int `json:"activity_id" form:"activity_id" binding:"required"`
Image string `json:"image" form:"image" binding:"required,url"` Files string `json:"files" form:"files" binding:"required"`
} }
func (u UserActivityForm) Validate() error { func (u UserActivityForm) Validate() error {
if !strings.HasPrefix(u.Image, "https://") { //for _, filename := range strings.Split(u.Files, ",") {
return errors.New("不是图床链接") // if err := util.ValidateFilename(filename); err != nil {
} // return err
// }
//}
return nil return nil
} }

19
pkg/util/util.go Normal file
查看文件

@ -0,0 +1,19 @@
package util
import (
"errors"
"path/filepath"
"strings"
)
func ValidateFilename(filename string) error {
switch filepath.Ext(strings.ToLower(filename)) {
case ".pdf", ".doc", ".jpg", ".gif", ".png", ".jpeg",
".docx", ".xls", ".xlsx", ".zip", ".rar", ".7z", ".txt",
// 支持 iOS 的 HEIC 格式
".heic", ".heif", "png":
return nil
default:
return errors.New("扩展名不支持")
}
}

查看文件

@ -9,6 +9,7 @@ import (
func Setup(engine *gin.Engine) { func Setup(engine *gin.Engine) {
engine.Use(middleware.Cors()) engine.Use(middleware.Cors())
engine.Static("/files", "files")
user := engine.Group("/user") user := engine.Group("/user")
{ {
hub := service.ExUserService hub := service.ExUserService
@ -25,6 +26,7 @@ func Setup(engine *gin.Engine) {
checkin.GET("/list_activities", app.HandlerFunc(hub.ListActivities)) checkin.GET("/list_activities", app.HandlerFunc(hub.ListActivities))
checkin.POST("/submit", app.HandlerFunc(hub.Submit)) checkin.POST("/submit", app.HandlerFunc(hub.Submit))
checkin.GET("/get_my_activities_today", app.HandlerFunc(hub.GetMyActivitiesToday)) checkin.GET("/get_my_activities_today", app.HandlerFunc(hub.GetMyActivitiesToday))
checkin.POST("/upload_file", middleware.JWT(1), app.HandlerFunc(hub.UploadFile))
checkin.POST("/set_status", middleware.JWT(2), app.HandlerFunc(hub.SetStatus)) checkin.POST("/set_status", middleware.JWT(2), app.HandlerFunc(hub.SetStatus))
checkin.GET("/get_user_activity", middleware.JWT(2), app.HandlerFunc(hub.GetUserActivity)) checkin.GET("/get_user_activity", middleware.JWT(2), app.HandlerFunc(hub.GetUserActivity))
checkin.GET("/list_user_activities", middleware.JWT(2), app.HandlerFunc(hub.ListUserActivities)) checkin.GET("/list_user_activities", middleware.JWT(2), app.HandlerFunc(hub.ListUserActivities))

查看文件

@ -35,7 +35,7 @@ func UserActivity() {
io.WriteString(f, "姓名,学号,日期,活动,图片\n") io.WriteString(f, "姓名,学号,日期,活动,图片\n")
for _, userActivity := range userActivities { for _, userActivity := range userActivities {
io.WriteString(f, userActivity.RealName+","+userActivity.Username+","+ io.WriteString(f, userActivity.RealName+","+userActivity.Username+","+
userActivity.Day+","+userActivity.ActivityName+","+userActivity.Image+"\n") userActivity.Day+","+userActivity.ActivityName+","+userActivity.Files+"\n")
} }
} }
func Student() { func Student() {

查看文件

@ -1,8 +1,13 @@
package service package service
import ( import (
"fmt"
"github.com/google/uuid"
"integrity-checkin/data/po" "integrity-checkin/data/po"
"integrity-checkin/pkg/app" "integrity-checkin/pkg/app"
"io"
"os"
"path/filepath"
"strconv" "strconv"
"time" "time"
) )
@ -20,10 +25,20 @@ func (c CheckinService) Submit(aw *app.Wrapper) app.Result {
return aw.Error(err.Error()) return aw.Error(err.Error())
} }
today := time.Now().Format("20060102") today := time.Now().Format("20060102")
// 检查是否为限制打卡总次数的活动
activity := checkinDAO.FindActivityByID(req.ActivityID)
if activity == nil {
return aw.Error("活动不存在")
} else if activity.Limit > 0 {
if checkinDAO.FindUserActivityInHistorySince(uc.UserID, req.ActivityID) != nil {
return aw.Error("该打卡活动已经达到限制次数")
}
}
// 检查当天是否已经打卡过
if checkinDAO.FindUserActivityByDay(uc.UserID, req.ActivityID, today) != nil { if checkinDAO.FindUserActivityByDay(uc.UserID, req.ActivityID, today) != nil {
return aw.Error("您今天已参加过该项目,请明天再来") return aw.Error("您今天已参加过该项目,请明天再来")
} }
userActivity, err := checkinDAO.CreateCheckin(uc.UserID, req.ActivityID, req.Image) userActivity, err := checkinDAO.CreateCheckin(uc.UserID, req.ActivityID, req.Files)
if err != nil { if err != nil {
return aw.Error(err.Error()) return aw.Error(err.Error())
} }
@ -92,3 +107,34 @@ func (c CheckinService) GetUserActivity(aw *app.Wrapper) app.Result {
func (c CheckinService) GetMyActivitiesToday(aw *app.Wrapper) app.Result { func (c CheckinService) GetMyActivitiesToday(aw *app.Wrapper) app.Result {
return aw.Success(checkinDAO.FindUserActivitiesToday(aw.ExtractUserClaims().UserID, time.Now().Format("20060102"))) return aw.Success(checkinDAO.FindUserActivitiesToday(aw.ExtractUserClaims().UserID, time.Now().Format("20060102")))
} }
func (c CheckinService) UploadFile(aw *app.Wrapper) app.Result {
formFile, err := aw.Ctx.FormFile("file")
if err != nil {
return aw.Error(err.Error())
}
file, err := formFile.Open()
if err != nil {
return aw.Error(err.Error())
}
fmt.Println(formFile.Filename)
//if err = util.ValidateFilename(formFile.Filename); err != nil {
// return aw.Error(err.Error())
//}
if _, err = os.Stat("files"); err != nil {
err = os.Mkdir("files", 0666)
if err != nil {
return aw.Error(err.Error())
}
}
filename := uuid.New().String() + filepath.Ext(formFile.Filename)
out, err := os.OpenFile("files/"+filename, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
if err != nil {
return aw.Error(err.Error())
}
defer out.Close()
_, err = io.Copy(out, file)
if err != nil {
return aw.Error(err.Error())
}
return aw.Success(filename)
}