diff --git a/app/controllers/lostAndFoundController/create.go b/app/controllers/lostAndFoundController/create.go new file mode 100644 index 0000000..f52d717 --- /dev/null +++ b/app/controllers/lostAndFoundController/create.go @@ -0,0 +1,63 @@ +package lostAndFoundController + +import ( + "4u-go/app/apiException" + "4u-go/app/models" + "4u-go/app/services/lostAndFoundService" + "4u-go/app/utils" + "github.com/gin-gonic/gin" +) + +type createLostAndFoundData struct { + Type bool `json:"type"` // 1-失物 0-寻物 + Name string `json:"name" binding:"required"` // 物品名称 + Introduction string `json:"introduction" binding:"required"` // 物品介绍 + Campus uint8 `json:"campus"` // 校区 0-其他 1-朝晖 2-屏峰 3-莫干山 + Kind uint8 `json:"kind"` // 物品种类 1其他2证件3箱包4首饰5现金6电子产品7钥匙 + Place string `json:"place" binding:"required"` // 丢失或拾得地点 + Time string `json:"time" binding:"required"` // 丢失或拾得时间 + Imgs []string `json:"imgs"` // 物品图片,多个图片以逗号分隔 + Contact string `json:"contact" binding:"required"` // 联系方式 + ContactWay uint8 `json:"contact_way" binding:"required"` // 联系方式选项 1-手机号 2-qq 3-微信 4-邮箱 +} + +// CreateLostAndFound 创建一条失物招领 +func CreateLostAndFound(c *gin.Context) { + var data createLostAndFoundData + err := c.ShouldBindJSON(&data) + if err != nil { + apiException.AbortWithException(c, apiException.ParamError, err) + return + } + + // 判断imgs是否大于9 + if len(data.Imgs) > 9 { + apiException.AbortWithException(c, apiException.ParamError, nil) + return + } + + // 将[]string转为string + imgs := utils.StringsToString(data.Imgs) + + err = lostAndFoundService.SaveLostAndFound(models.LostAndFoundRecord{ + Type: data.Type, + Name: data.Name, + Introduction: data.Introduction, + Campus: data.Campus, + Kind: data.Kind, + Place: data.Place, + Time: data.Time, + Imgs: imgs, + Publisher: utils.GetUser(c).StudentID, + Contact: data.Contact, + ContactWay: data.ContactWay, + IsProcessed: 2, + IsApproved: 2, + }) + if err != nil { + apiException.AbortWithException(c, apiException.ServerError, err) + return + } + + utils.JsonSuccessResponse(c, nil) +} diff --git a/app/controllers/lostAndFoundController/delete.go b/app/controllers/lostAndFoundController/delete.go new file mode 100644 index 0000000..50117ce --- /dev/null +++ b/app/controllers/lostAndFoundController/delete.go @@ -0,0 +1,51 @@ +package lostAndFoundController + +import ( + "errors" + + "4u-go/app/apiException" + "4u-go/app/models" + "4u-go/app/services/lostAndFoundService" + "4u-go/app/utils" + "github.com/gin-gonic/gin" + "gorm.io/gorm" +) + +type deleteLostAndFoundData struct { + ID uint `json:"id" binding:"required"` +} + +// DeleteLostAndFound 撤回一条失物招领 +func DeleteLostAndFound(c *gin.Context) { + var data deleteLostAndFoundData + err := c.ShouldBindJSON(&data) + if err != nil { + apiException.AbortWithException(c, apiException.ParamError, err) + return + } + + // 判断失物招领是否存在 + record, err := lostAndFoundService.GetLostAndFoundById(data.ID) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + apiException.AbortWithException(c, apiException.ResourceNotFound, err) + } else { + apiException.AbortWithException(c, apiException.ServerError, err) + } + return + } + + user := utils.GetUser(c) + if user.Type != models.SuperAdmin && user.Type != models.ForU && user.StudentID != record.Publisher { + apiException.AbortWithException(c, apiException.NotPermission, nil) + return + } + + err = lostAndFoundService.DeleteLostAndFoundById(data.ID) + if err != nil { + apiException.AbortWithException(c, apiException.ServerError, err) + return + } + + utils.JsonSuccessResponse(c, nil) +} diff --git a/app/controllers/lostAndFoundController/get.go b/app/controllers/lostAndFoundController/get.go new file mode 100644 index 0000000..f7440c9 --- /dev/null +++ b/app/controllers/lostAndFoundController/get.go @@ -0,0 +1,168 @@ +package lostAndFoundController + +import ( + "errors" + + "4u-go/app/apiException" + "4u-go/app/services/lostAndFoundService" + "4u-go/app/utils" + "github.com/gin-gonic/gin" + "gorm.io/gorm" +) + +type getLostAndFoundListData struct { + Type bool `json:"type"` // 1-失物 0-寻物 + Campus uint8 `json:"campus"` // 校区 0-其他 1-朝晖 2-屏峰 3-莫干山 + Kind uint8 `json:"kind"` // 物品种类 0-全部 1-其他 2-饭卡 3-电子 4-文体 5-衣包 6-证件 +} +type getLostAndFoundListResponse struct { + LostAndFoundList []lostAndFoundElement `json:"list"` +} +type lostAndFoundElement struct { + ID uint `json:"id"` + Imgs []string `json:"imgs"` + Name string `json:"name"` + Place string `json:"place"` + Time string `json:"time"` + Introduction string `json:"introduction"` + Kind uint8 `json:"kind"` +} + +// GetLostAndFoundList 获取失物招领列表 +func GetLostAndFoundList(c *gin.Context) { + var data getLostAndFoundListData + err := c.ShouldBindJSON(&data) + if err != nil { + apiException.AbortWithException(c, apiException.ParamError, err) + return + } + + list, err := lostAndFoundService.GetLostAndFoundList(data.Type, data.Campus, data.Kind) + if err != nil { + apiException.AbortWithException(c, apiException.ServerError, err) + return + } + + lostAndFoundList := make([]lostAndFoundElement, 0) + for _, record := range list { + // 将string转为[]string + imgs := utils.StringToStrings(record.Imgs) + lostAndFoundList = append(lostAndFoundList, lostAndFoundElement{ + ID: record.ID, + Imgs: imgs, + Name: record.Name, + Place: record.Place, + Time: record.Time, + Introduction: record.Introduction, + }) + } + + utils.JsonSuccessResponse(c, getLostAndFoundListResponse{ + LostAndFoundList: lostAndFoundList, + }) +} + +type getLostAndFoundContentData struct { + ID uint `json:"id" binding:"required"` +} + +// GetLostAndFoundContact 获取失物招领联系方式 +func GetLostAndFoundContact(c *gin.Context) { + var data getLostAndFoundContentData + err := c.ShouldBindJSON(&data) + if err != nil { + apiException.AbortWithException(c, apiException.ParamError, err) + return + } + + contact, err := lostAndFoundService.GetLostAndFoundContact(data.ID, utils.GetUser(c).StudentID) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + apiException.AbortWithException(c, apiException.ResourceNotFound, err) + } else { + apiException.AbortWithException(c, apiException.ServerError, err) + } + return + } + + utils.JsonSuccessResponse(c, contact) +} + +type latestLostAndFoundResponse struct { + Type bool `json:"type"` + Imgs string `json:"imgs"` + Name string `json:"name"` + Place string `json:"place"` + Introduction string `json:"introduction"` +} + +// GetLatestLostAndFound 获取最新失物招领 +func GetLatestLostAndFound(c *gin.Context) { + record, err := lostAndFoundService.GetLatestLostAndFound() + if err != nil { + apiException.AbortWithException(c, apiException.ServerError, err) + return + } + + utils.JsonSuccessResponse(c, latestLostAndFoundResponse{ + Type: record.Type, + Imgs: record.Imgs, + Name: record.Name, + Place: record.Place, + Introduction: record.Introduction, + }) +} + +type getLostAndFoundStatusData struct { + Status uint8 `json:"status"` // 状态 0-已撤回 1-已审核 2-审核中 +} +type getLostAndFoundStatusResponse struct { + List []lostAndFoundStatusElement `json:"list"` +} +type lostAndFoundStatusElement struct { + ID uint `json:"id"` + Type bool `json:"type"` + Imgs []string `json:"imgs"` + Name string `json:"name"` + Kind uint8 `json:"kind"` + Place string `json:"place"` + Time string `json:"time"` + Introduction string `json:"introduction"` + IsApproved uint8 `json:"is_approved"` +} + +// GetUserLostAndFoundStatus 查看失物招领信息的状态 +func GetUserLostAndFoundStatus(c *gin.Context) { + var data getLostAndFoundStatusData + err := c.ShouldBindJSON(&data) + if err != nil { + apiException.AbortWithException(c, apiException.ParamError, err) + return + } + + list, err := lostAndFoundService.GetUserLostAndFoundStatus(utils.GetUser(c).StudentID, data.Status) + if err != nil { + apiException.AbortWithException(c, apiException.ServerError, err) + return + } + + lostAndFoundList := make([]lostAndFoundStatusElement, 0) + for _, record := range list { + // 将string转为[]string + imgs := utils.StringToStrings(record.Imgs) + lostAndFoundList = append(lostAndFoundList, lostAndFoundStatusElement{ + ID: record.ID, + Type: record.Type, + Imgs: imgs, + Name: record.Name, + Kind: record.Kind, + Place: record.Place, + Time: record.Time, + Introduction: record.Introduction, + IsApproved: record.IsApproved, + }) + } + utils.JsonSuccessResponse(c, getLostAndFoundStatusResponse{ + List: lostAndFoundList, + }) +} diff --git a/app/controllers/lostAndFoundController/update.go b/app/controllers/lostAndFoundController/update.go new file mode 100644 index 0000000..eaba049 --- /dev/null +++ b/app/controllers/lostAndFoundController/update.go @@ -0,0 +1,157 @@ +package lostAndFoundController + +import ( + "errors" + + "4u-go/app/apiException" + "4u-go/app/models" + "4u-go/app/services/lostAndFoundService" + "4u-go/app/utils" + "github.com/gin-gonic/gin" + "gorm.io/gorm" +) + +type reviewLostAndFoundData struct { + ID uint `json:"id" binding:"required"` + IsApproved bool `json:"is_approved"` +} + +// ReviewLostAndFound 审核失物招领 +func ReviewLostAndFound(c *gin.Context) { + var data reviewLostAndFoundData + err := c.ShouldBindJSON(&data) + if err != nil { + apiException.AbortWithException(c, apiException.ParamError, err) + return + } + + // 判断失物招领是否存在 + _, err = lostAndFoundService.GetLostAndFoundById(data.ID) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + apiException.AbortWithException(c, apiException.ResourceNotFound, err) + } else { + apiException.AbortWithException(c, apiException.ServerError, err) + } + return + } + + if data.IsApproved { + err = lostAndFoundService.ApproveLostAndFound(data.ID) + } else { + err = lostAndFoundService.RejectLostAndFound(data.ID) + } + + if err != nil { + apiException.AbortWithException(c, apiException.ServerError, err) + return + } + + utils.JsonSuccessResponse(c, nil) +} + +type updateLostAndFoundData struct { + ID uint `json:"id" binding:"required"` + Type bool `json:"type" binding:"required"` // 1-失物 0-寻物 + Name string `json:"name" binding:"required"` // 物品名称 + Introduction string `json:"introduction" binding:"required"` // 物品介绍 + Campus uint8 `json:"campus" binding:"required"` // 校区 1-朝晖 2-屏峰 3-莫干山 + Kind uint8 `json:"kind" binding:"required"` // 物品种类 1其他2证件3箱包4首饰5现金6电子产品7钥匙 + Place string `json:"place" binding:"required"` // 丢失或拾得地点 + Time string `json:"time" binding:"required"` // 丢失或拾得时间 + Imgs string `json:"imgs"` // 物品图片,多个图片以逗号分隔 + PickupPlace string `json:"pickup_place" binding:"required"` // 失物领取地点 + Contact string `json:"contact" binding:"required"` // 联系方式 +} + +// UpdateLostAndFound 修改失物招领 +func UpdateLostAndFound(c *gin.Context) { + var data updateLostAndFoundData + err := c.ShouldBindJSON(&data) + if err != nil { + apiException.AbortWithException(c, apiException.ParamError, err) + return + } + + // 判断失物招领是否存在 + record, err := lostAndFoundService.GetLostAndFoundById(data.ID) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + apiException.AbortWithException(c, apiException.ResourceNotFound, err) + } else { + apiException.AbortWithException(c, apiException.ServerError, err) + } + return + } + + user := utils.GetUser(c) + if user.Type != models.SuperAdmin && user.Type != models.ForU { + apiException.AbortWithException(c, apiException.NotPermission, nil) + return + } + + { // 更新失物招领信息 + record.Type = data.Type + record.Name = data.Name + record.Introduction = data.Introduction + record.Campus = data.Campus + record.Kind = data.Kind + record.Place = data.Place + record.Time = data.Time + record.Imgs = data.Imgs + record.Contact = data.Contact + record.IsApproved = 2 + record.IsProcessed = 2 + } + + err = lostAndFoundService.SaveLostAndFound(record) + if err != nil { + apiException.AbortWithException(c, apiException.ServerError, err) + return + } + + utils.JsonSuccessResponse(c, nil) +} + +type updateLostAndFoundStatusData struct { + ID uint `json:"id" binding:"required"` +} + +// UpdateLostAndFoundStatus 用户设置失物招领为已完成 +func UpdateLostAndFoundStatus(c *gin.Context) { + var data updateLostAndFoundStatusData + err := c.ShouldBindJSON(&data) + if err != nil { + apiException.AbortWithException(c, apiException.ParamError, err) + return + } + + // 判断失物招领是否存在 + record, err := lostAndFoundService.GetLostAndFoundById(data.ID) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + apiException.AbortWithException(c, apiException.ResourceNotFound, err) + } else { + apiException.AbortWithException(c, apiException.ServerError, err) + } + return + } + + user := utils.GetUser(c) + if user.StudentID != record.Publisher { + apiException.AbortWithException(c, apiException.NotPermission, nil) + return + } + + { // 更新失物招领信息 + record.IsProcessed = 1 + } + + err = lostAndFoundService.SaveLostAndFound(record) + if err != nil { + apiException.AbortWithException(c, apiException.ServerError, err) + return + } + + utils.JsonSuccessResponse(c, nil) +} diff --git a/app/models/contactViewRecord.go b/app/models/contactViewRecord.go new file mode 100644 index 0000000..5d1b7e8 --- /dev/null +++ b/app/models/contactViewRecord.go @@ -0,0 +1,11 @@ +package models + +import "time" + +// ContactViewRecord 联系方式查看记录的结构体 +type ContactViewRecord struct { + ID uint `json:"id"` + RecordID uint `json:"record_id"` // 失物招领记录编号 + StudentID string `json:"-"` // 查看者学号 + CreatedAt time.Time `json:"created_at" gorm:"type:timestamp;"` // 记录创建时间 +} diff --git a/app/models/lostAndFoundRecord.go b/app/models/lostAndFoundRecord.go index 3a6f952..5ff01e8 100644 --- a/app/models/lostAndFoundRecord.go +++ b/app/models/lostAndFoundRecord.go @@ -4,18 +4,19 @@ import "time" // LostAndFoundRecord 失物招领记录的结构体 type LostAndFoundRecord struct { - ID uint `json:"id"` - Type bool `json:"type"` // 1-失物 0-寻物 - ItemName string `json:"item_name"` // 物品名称 - Introduction string `json:"introduction"` // 物品介绍 - Campus uint8 `json:"campus"` // 校区 1-朝晖 2-屏峰 3-莫干山 - Kind string `json:"kind"` // 物品种类 0其他1证件2箱包3首饰4现金5电子产品6钥匙 - LostOrFoundPlace string `json:"lost_or_found_place"` // 丢失或拾得地点 - LostOrFoundTime string `json:"lost_or_found_time"` // 丢失或拾得时间 - Imgs string `json:"imgs"` // 物品图片,多个图片以逗号分隔 - Publisher string `json:"publisher"` // 发布者 - PickupPlace string `json:"pickup_place"` // 失物领取地点 - Contact string `json:"contact"` // 寻物联系方式 - PublishTime time.Time `json:"publish_time" gorm:"type:timestamp;"` // 发布时间 - IsProcessed bool `json:"-"` // 是否已处理 + ID uint `json:"id"` + Type bool `json:"type"` // 报失/捡拾 1-报失 0-捡拾 + Name string `json:"name"` // 物品名称 + Introduction string `json:"introduction"` // 物品介绍 + Campus uint8 `json:"campus"` // 校区 0-其他 1-朝晖 2-屏峰 3-莫干山 + Kind uint8 `json:"kind"` // 物品种类 0-全部 1-其他 2-饭卡 3-电子 4-文体 5-衣包 6-证件 + Place string `json:"place"` // 丢失或拾得地点 + Time string `json:"time"` // 丢失或拾得时间 + Imgs string `json:"imgs"` // 物品图片,多个图片以逗号分隔 + Contact string `json:"contact"` // 联系方式 + ContactWay uint8 `json:"contact_way"` // 联系方式选项 1-手机号 2-qq 3-微信 4-邮箱 + CreatedAt time.Time `json:"created_at" gorm:"type:timestamp;"` // 发布时间 + IsProcessed uint8 `json:"is_processed"` // 是否完成 0-已取消 1-已完成 2-进行中 + Publisher string `json:"-"` // 发布者 + IsApproved uint8 `json:"-"` // 是否审核通过 0-未通过 1-已通过 2-待审核 } diff --git a/app/services/lostAndFoundService/delete.go b/app/services/lostAndFoundService/delete.go new file mode 100644 index 0000000..82c1be5 --- /dev/null +++ b/app/services/lostAndFoundService/delete.go @@ -0,0 +1,12 @@ +package lostAndFoundService + +import ( + "4u-go/app/models" + "4u-go/config/database" +) + +// DeleteLostAndFoundById 通过 ID 撤回一条失物招领 +func DeleteLostAndFoundById(recordId uint) error { + result := database.DB.Model(&models.LostAndFoundRecord{}).Where("id = ?", recordId).Update("is_processed", 0) + return result.Error +} diff --git a/app/services/lostAndFoundService/get.go b/app/services/lostAndFoundService/get.go new file mode 100644 index 0000000..b6a60cb --- /dev/null +++ b/app/services/lostAndFoundService/get.go @@ -0,0 +1,76 @@ +package lostAndFoundService + +import ( + "4u-go/app/models" + "4u-go/config/database" +) + +// GetLostAndFoundById 获取指定ID的失物招领 +func GetLostAndFoundById(id uint) (record models.LostAndFoundRecord, err error) { + result := database.DB.Where("id = ?", id).First(&record) + err = result.Error + return record, err +} + +// GetLostAndFoundList 获取失物招领列表 +func GetLostAndFoundList(form bool, campus, kind uint8) (records []models.LostAndFoundRecord, err error) { + if kind == 0 { + result := database.DB. + Where("type =? AND campus =? AND is_processed = 2 AND is_approved = 1", form, campus). + Order("created_at desc"). + Find(&records) + err = result.Error + return records, err + } + result := database.DB. + Where("type = ? AND campus = ? AND kind = ? AND is_processed = 2 AND is_approved = 1", form, campus, kind). + Order("created_at desc"). + Find(&records) + err = result.Error + return records, err +} + +// GetLostAndFoundContact 获取失物招领联系方式 +func GetLostAndFoundContact(id uint, studentID string) (contact string, err error) { + result, err := GetLostAndFoundById(id) + if err != nil { + return "", err + } + var record models.ContactViewRecord + record.RecordID = id + record.StudentID = studentID + res := database.DB.Save(&record) + if res.Error != nil { + return "", res.Error + } + return result.Contact, nil +} + +// GetLatestLostAndFound 获取最新失物招领 +func GetLatestLostAndFound() (record models.LostAndFoundRecord, err error) { + result := database.DB.Where("is_processed = 2 AND is_approved = 1").Order("created_at desc").First(&record) + err = result.Error + return record, err +} + +// GetUserLostAndFoundStatus 查看失物招领信息的状态 +func GetUserLostAndFoundStatus(publisher string, status uint8) (records []models.LostAndFoundRecord, err error) { + if status == 0 { + result := database.DB.Where("publisher = ? AND is_processed = ?", publisher, 0). + Order("created_at desc"). + Find(&records) + err = result.Error + return records, err + } else if status == 1 { + result := database.DB.Where("publisher = ? AND (is_approved = 0 OR is_approved = 1)", publisher). + Order("created_at desc"). + Find(&records) + err = result.Error + return records, err + } + result := database.DB.Where("publisher = ? AND is_approved = ?", publisher, 2). + Order("created_at desc"). + Find(&records) + err = result.Error + return records, err +} diff --git a/app/services/lostAndFoundService/save.go b/app/services/lostAndFoundService/save.go new file mode 100644 index 0000000..28f6caa --- /dev/null +++ b/app/services/lostAndFoundService/save.go @@ -0,0 +1,12 @@ +package lostAndFoundService + +import ( + "4u-go/app/models" + "4u-go/config/database" +) + +// SaveLostAndFound 向数据库中保存一条失物招领 +func SaveLostAndFound(record models.LostAndFoundRecord) error { + result := database.DB.Save(&record) + return result.Error +} diff --git a/app/services/lostAndFoundService/update.go b/app/services/lostAndFoundService/update.go new file mode 100644 index 0000000..0505e9e --- /dev/null +++ b/app/services/lostAndFoundService/update.go @@ -0,0 +1,20 @@ +package lostAndFoundService + +import ( + "4u-go/app/models" + "4u-go/config/database" +) + +// ApproveLostAndFound 审核通过失物招领 +func ApproveLostAndFound(recordId uint) error { + result := database.DB.Model(&models.LostAndFoundRecord{}).Where("id = ?", recordId). + Updates(map[string]any{"is_approved": 1, "is_processed": 2}) + return result.Error +} + +// RejectLostAndFound 审核拒绝失物招领 +func RejectLostAndFound(recordId uint) error { + result := database.DB.Model(&models.LostAndFoundRecord{}).Where("id = ?", recordId). + Updates(map[string]any{"is_approved": 0, "is_processed": 1}) + return result.Error +} diff --git a/app/utils/converter.go b/app/utils/converter.go new file mode 100644 index 0000000..9b4d1a8 --- /dev/null +++ b/app/utils/converter.go @@ -0,0 +1,13 @@ +package utils + +import "strings" + +// StringsToString 将字符串数组转换为字符串,以逗号分隔 +func StringsToString(strSlice []string) string { + return strings.Join(strSlice, ",") +} + +// StringToStrings 将字符串转换为字符串数组 +func StringToStrings(str string) []string { + return strings.Split(str, ",") +} diff --git a/config/database/migrations.go b/config/database/migrations.go index fc02db2..e221050 100755 --- a/config/database/migrations.go +++ b/config/database/migrations.go @@ -13,6 +13,7 @@ func autoMigrate(db *gorm.DB) error { &models.LostAndFoundRecord{}, &models.Website{}, &models.College{}, + &models.ContactViewRecord{}, &models.Qrcode{}, &models.Counter{}, ) diff --git a/config/router/router.go b/config/router/router.go index fac8b3c..de31730 100644 --- a/config/router/router.go +++ b/config/router/router.go @@ -5,6 +5,7 @@ import ( "4u-go/app/controllers/adminController" "4u-go/app/controllers/announcementController" "4u-go/app/controllers/collegeController" + "4u-go/app/controllers/lostAndFoundController" "4u-go/app/controllers/objectController" "4u-go/app/controllers/qrcodeController" "4u-go/app/controllers/userController" @@ -38,6 +39,12 @@ func Init(r *gin.Engine) { { admin.POST("/create/key", adminController.CreateAdminByKey) + adminLostAndFound := admin.Group("/lost-and-found", midwares.CheckAdmin) + { + adminLostAndFound.PUT("", lostAndFoundController.ReviewLostAndFound) + adminLostAndFound.PUT("/update", lostAndFoundController.UpdateLostAndFound) + } + adminActivity := admin.Group("/activity", midwares.CheckAdmin) { adminActivity.POST("", activityController.CreateActivity) @@ -99,6 +106,17 @@ func Init(r *gin.Engine) { website.GET("/list", websiteController.GetWebsiteList) } + lostAndFound := api.Group("/lost-and-found") + { + lostAndFound.POST("", midwares.CheckLogin, lostAndFoundController.CreateLostAndFound) + lostAndFound.DELETE("", midwares.CheckLogin, lostAndFoundController.DeleteLostAndFound) + lostAndFound.GET("/list", lostAndFoundController.GetLostAndFoundList) + lostAndFound.GET("", midwares.CheckLogin, lostAndFoundController.GetLostAndFoundContact) + lostAndFound.GET("/latest", lostAndFoundController.GetLatestLostAndFound) + lostAndFound.GET("/user", midwares.CheckLogin, lostAndFoundController.GetUserLostAndFoundStatus) + lostAndFound.PUT("/user", midwares.CheckLogin, lostAndFoundController.UpdateLostAndFoundStatus) + } + track := api.Group("/track") { track.GET("/qrcode/scan_count", qrcodeController.ScanCount)