feat: rebuild pet app and backend around core care flows

This commit is contained in:
2026-10-01 13:11:30 +08:00
parent 51ead8f411
commit bfcf8788a4
321 changed files with 4918 additions and 25199 deletions
+99
View File
@@ -0,0 +1,99 @@
package httpapi
import (
"github.com/gin-gonic/gin"
"github.com/sundynix/pets-be/internal/model"
"net/http"
)
func (a *API) adminStats(c *gin.Context) {
counts := gin.H{}
for _, pair := range []struct {
name string
value any
}{{"users", &model.User{}}, {"pets", &model.Pet{}}, {"walks", &model.Walk{}}, {"meetups", &model.Meetup{}}} {
var n int64
a.db.Model(pair.value).Count(&n)
counts[pair.name] = n
}
ok(c, counts)
}
func (a *API) adminUsers(c *gin.Context) {
var rows []model.User
if a.db.Order("created_at DESC").Limit(200).Find(&rows).Error != nil {
fail(c, 500, "读取用户失败")
return
}
items := make([]gin.H, 0, len(rows))
for _, u := range rows {
v := a.userView(u)
v["disabled"] = u.Disabled
items = append(items, v)
}
ok(c, items)
}
func (a *API) adminPets(c *gin.Context) {
var rows []model.Pet
if a.db.Order("created_at DESC").Limit(200).Find(&rows).Error != nil {
fail(c, 500, "读取宠物失败")
return
}
items := make([]gin.H, 0, len(rows))
for _, p := range rows {
v := a.petView(p)
v["user_id"] = p.UserID
v["archived"] = p.Archived
items = append(items, v)
}
ok(c, items)
}
func (a *API) adminWalks(c *gin.Context) {
var rows []model.Walk
if a.db.Order("started_at DESC").Limit(200).Find(&rows).Error != nil {
fail(c, 500, "读取遛狗失败")
return
}
ok(c, rows)
}
func (a *API) adminMeetups(c *gin.Context) {
var rows []model.Meetup
if a.db.Order("created_at DESC").Limit(200).Find(&rows).Error != nil {
fail(c, 500, "读取约遛失败")
return
}
items := make([]gin.H, 0, len(rows))
for _, m := range rows {
items = append(items, a.meetupView(m))
}
ok(c, items)
}
func (a *API) adminSetUserDisabled(c *gin.Context) {
var in struct {
Disabled bool `json:"disabled"`
}
if !validID(c.Param("id")) || c.ShouldBindJSON(&in) != nil {
fail(c, 400, "参数无效")
return
}
r := a.db.Model(&model.User{}).Where("id = ?", c.Param("id")).Update("disabled", in.Disabled)
if r.Error != nil || r.RowsAffected == 0 {
fail(c, 404, "用户不存在")
return
}
ok(c, gin.H{"disabled": in.Disabled})
}
func (a *API) adminSetMeetupStatus(c *gin.Context) {
var in struct {
Status string `json:"status"`
}
if !validID(c.Param("id")) || c.ShouldBindJSON(&in) != nil || (in.Status != "open" && in.Status != "cancelled") {
fail(c, http.StatusBadRequest, "状态无效")
return
}
r := a.db.Model(&model.Meetup{}).Where("id = ?", c.Param("id")).Update("status", in.Status)
if r.Error != nil || r.RowsAffected == 0 {
fail(c, 404, "约遛不存在")
return
}
ok(c, gin.H{"status": in.Status})
}