package web import ( "encoding/json" "fmt" "time" "dyproxy/.gen/model" "dyproxy/.gen/table" . "github.com/go-jet/jet/v2/sqlite" "github.com/gofiber/fiber/v3" "github.com/sirupsen/logrus" ) func (s *WebServer) routeGetExpertConfig(c fiber.Ctx) error { uid := c.Params("uid", "") var user model.Expert err := table.Expert.SELECT(table.Expert.AllColumns).WHERE(table.Expert.UID.EQ(String(uid))).QueryContext(c.UserContext(), s.db, &user) if err != nil { return err } if user.Config == "" { user.Config = "{}" } var config ExpertConfig if err := json.Unmarshal([]byte(user.Config), &config); err != nil { return err } c.Response().Header.Set("x-config-at", fmt.Sprintf("%d", user.ConfigAt)) return c.JSON(config) } func (s *WebServer) routeGetExpert(c fiber.Ctx) error { uid := c.Params("uid", "") var user model.Expert err := table.Expert.SELECT(table.Expert.AllColumns).WHERE(table.Expert.UID.EQ(String(uid))).QueryContext(c.UserContext(), s.db, &user) if err != nil { return err } return c.JSON(user) } func (s *WebServer) routeGetExperts(c fiber.Ctx) error { stmt := table.Expert.SELECT(table.Expert.AllColumns).ORDER_BY(table.Expert.ID) var rows []model.Expert if err := stmt.Query(s.db, &rows); err != nil { return err } sql := `SELECT expert_uid, COUNT(*) AS total, SUM(case when followed = 1 then 1 else 0 end) AS followed FROM follower GROUP BY expert_uid;` r, err := s.db.QueryContext(c.UserContext(), sql) if err != nil { return err } type statistics struct { UserUID string Total int32 Followed int32 } var statisticsItems []statistics for r.Next() { item := statistics{} if err := r.Scan(&item.UserUID, &item.Total, &item.Followed); err != nil { return err } statisticsItems = append(statisticsItems, item) } type resp struct { Focus int32 Total int32 Conf ExpertConfig model.Expert `json:",inline"` } var users []resp for _, row := range rows { stat := statistics{} // get item from statisticsItems where row.UID == item.UserUID for _, item := range statisticsItems { if row.UID == item.UserUID { stat = item break } } var conf ExpertConfig if row.Config == "" { row.Config = "{}" } if err := json.Unmarshal([]byte(row.Config), &conf); err != nil { logrus.Error(err) continue } row.Config = "" users = append(users, resp{ Focus: stat.Followed, Total: stat.Total, Conf: conf, Expert: row, }) } return c.JSON(users) } func (s *WebServer) routePostExperts(c fiber.Ctx) error { expert := &model.Expert{} if err := c.Bind().JSON(expert); err != nil { return err } tbl := table.Expert _, err := tbl. INSERT(tbl.AllColumns.Except(tbl.ID)). MODEL(expert). ON_CONFLICT(tbl.UID). DO_NOTHING(). ExecContext(c.UserContext(), s.db) return err } func (s *WebServer) routePatchExpertConfig(c fiber.Ctx) error { var data struct { Since int32 `json:"since"` ExpertConfig `json:",inline"` } if err := c.Bind().JSON(&data); err != nil { return err } uid := c.Params("uid") tbl := table.Expert // get expert by uid var expert model.Expert if err := tbl.SELECT(tbl.AllColumns).WHERE(tbl.UID.EQ(String(uid))).QueryContext(c.UserContext(), s.db, &expert); err != nil { return err } if expert.Config == "" { expert.Config = "{}" } newExpertConfig, err := json.Marshal(data.ExpertConfig) if err != nil { return err } _, err = tbl. UPDATE(). SET( tbl.Config.SET(String(string(newExpertConfig))), tbl.ConfigAt.SET(Int(time.Now().Unix())), ). WHERE(tbl.UID.EQ(String(uid))). ExecContext(c.UserContext(), s.db) return err } const ( StateNormal = "" StateStop = "stop" ) func (s *WebServer) routePatchExpertState(c fiber.Ctx) error { var state struct { State string `json:"state"` } if err := c.Bind().JSON(&state); err != nil { return err } uid := c.Params("uid") tbl := table.Expert _, err := tbl. UPDATE(). SET(tbl.State.SET(String(state.State))). WHERE(tbl.UID.EQ(String(uid))). ExecContext(c.UserContext(), s.db) return err }