比較提交
10 次程式碼提交
integrity-
...
master
作者 | SHA1 | 日期 | |
---|---|---|---|
6879d8c27e | |||
2d14222073 | |||
29ea61034a | |||
686ac375f2 | |||
e1e1049b45 | |||
d327fa2021 | |||
0dc3aed4fe | |||
4048ee982b | |||
10855d554c | |||
8f51e7a8dc |
1
.gitignore
vendored
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
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)
|
||||||
|
}
|
||||||
|
載入中…
x
新增問題並參考
Block a user