chore(服务端): 初始化工程仓库

This commit is contained in:
leon_mac
2026-10-18 15:11:44 +08:00
commit 13c8bcbf3c
23 changed files with 2543 additions and 0 deletions
+177
View File
@@ -0,0 +1,177 @@
package server
import (
"encoding/json"
"errors"
"github.com/gin-gonic/gin"
"github.com/google/uuid"
"net/url"
"perler-beads-server/internal/domain"
)
func (s *Server) visitCreate(c *gin.Context) {
if !need(c, "") {
return
}
var in struct {
StoreID string `json:"storeId"`
TableCode string `json:"tableCode"`
}
if !bind(c, &in) {
return
}
var tables []domain.Table
if s.get(c, "tables", in.StoreID, &tables) != nil {
fail(c, errors.New("门店不存在"))
return
}
enabled := false
for _, t := range tables {
if t.Code == in.TableCode && t.Enabled {
enabled = true
}
}
if !enabled {
fail(c, errors.New("桌码未启用"))
return
}
v := domain.Visit{ID: uuid.NewString(), StoreID: in.StoreID, TableCode: in.TableCode, Status: "active"}
b, _ := json.Marshal(v)
if _, e := s.DB.Exec(c, `INSERT INTO visits(user_id,body) VALUES($1,$2) ON CONFLICT(user_id) DO UPDATE SET body=EXCLUDED.body`, user(c).ID, b); e != nil {
fail(c, e)
return
}
ok(c, v)
}
func (s *Server) visit(c *gin.Context) (domain.Visit, error) {
var b []byte
var v domain.Visit
e := s.DB.QueryRow(c, `SELECT body FROM visits WHERE user_id=$1`, user(c).ID).Scan(&b)
if e == nil {
e = json.Unmarshal(b, &v)
}
return v, e
}
func (s *Server) visitGet(c *gin.Context) {
if !need(c, "") {
return
}
v, e := s.visit(c)
if e != nil || v.Status != "active" {
ok(c, nil)
return
}
ok(c, v)
}
func (s *Server) visitClose(c *gin.Context) {
if !need(c, "") {
return
}
if _, e := s.DB.Exec(c, `DELETE FROM visits WHERE user_id=$1`, user(c).ID); e != nil {
fail(c, e)
return
}
ok(c, nil)
}
func (s *Server) tableList(c *gin.Context) {
if !need(c, "staff") {
return
}
if storeID(c) != user(c).StoreID {
reply(c, 401, "门店无权限", nil)
return
}
var v []domain.Table
if e := s.get(c, "tables", storeID(c), &v); e != nil {
fail(c, e)
return
}
ok(c, v)
}
func (s *Server) palettePut(c *gin.Context) {
if !need(c, "admin") {
return
}
var in struct {
StoreID string `json:"storeId"`
Colors []domain.Color `json:"colors"`
}
if !bind(c, &in) {
return
}
if in.StoreID != user(c).StoreID {
reply(c, 401, "门店无权限", nil)
return
}
if e := domain.ValidateColors(in.Colors); e != nil {
fail(c, e)
return
}
if e := s.put(c, "palette", in.StoreID, in.StoreID, "", in.Colors); e != nil {
fail(c, e)
return
}
ok(c, in.Colors)
}
func (s *Server) tablePut(c *gin.Context) {
if !need(c, "admin") {
return
}
var in struct {
StoreID string `json:"storeId"`
Tables []domain.Table `json:"tables"`
}
if !bind(c, &in) {
return
}
if in.StoreID != user(c).StoreID {
reply(c, 401, "门店无权限", nil)
return
}
seen := map[string]bool{}
if len(in.Tables) > 200 {
fail(c, errors.New("桌位超过限制"))
return
}
for _, t := range in.Tables {
if t.Code == "" || len(t.Code) > 64 || seen[t.Code] || t.Label == "" {
fail(c, errors.New("桌码或名称无效/重复"))
return
}
seen[t.Code] = true
}
if e := s.put(c, "tables", in.StoreID, in.StoreID, "", in.Tables); e != nil {
fail(c, e)
return
}
ok(c, in.Tables)
}
func endpointValid(v string) bool {
if v == "" {
return true
}
u, e := url.Parse(v)
return e == nil && u.Scheme == "https" && u.Host != "" && u.User == nil && u.RawQuery == "" && u.Fragment == ""
}
func (s *Server) storePut(c *gin.Context) {
if !need(c, "admin") {
return
}
var v domain.Store
if !bind(c, &v) {
return
}
if v.ID != user(c).StoreID {
reply(c, 401, "门店无权限", nil)
return
}
if v.Name == "" || !endpointValid(v.LocalBaseURL) || !endpointValid(v.PublicBaseURL) {
fail(c, errors.New("门店名称或 HTTPS 端点无效"))
return
}
if e := s.put(c, "store", v.ID, v.ID, "", v); e != nil {
fail(c, e)
return
}
ok(c, v)
}