package handler import ( "net/http" "strings" "time" "bj_power_workstation/internal/auth" "bj_power_workstation/internal/svc" "golang.org/x/crypto/bcrypt" ) func healthHandler(ctx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { if err := ctx.Store.Ping(); err == nil { ok(w, map[string]any{ "status": "UP", "time": time.Now().Format("2006-01-02 15:04:05"), "service": "bj_power_workstation", }) return } fail(w, http.StatusServiceUnavailable, "本地数据库不可用") } } // loginHandler 本地 SQLite + bcrypt 校验登录,返回 {token, expireAt, user}。 func loginHandler(ctx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { var req struct { Username string `json:"username"` Password string `json:"password"` } if err := parseJSON(r, &req); err != nil { fail(w, http.StatusBadRequest, "参数错误") return } if strings.TrimSpace(req.Username) == "" || req.Password == "" { fail(w, http.StatusBadRequest, "用户名和密码必填") return } u, err := ctx.Store.GetUserByUsername(strings.TrimSpace(req.Username)) if err != nil { fail(w, http.StatusUnauthorized, "用户名或密码错误") return } if bcrypt.CompareHashAndPassword([]byte(u.PasswordHash), []byte(req.Password)) != nil { fail(w, http.StatusUnauthorized, "用户名或密码错误") return } token, expireAt, err := auth.SignToken( ctx.Config.Auth.AccessSecret, ctx.Config.Auth.AccessExpire, auth.TokenInfo{UserID: u.ID, Username: u.Username, RealName: u.RealName, Role: u.Role}, ) if err != nil { fail(w, http.StatusInternalServerError, "签发 token 失败") return } ok(w, map[string]any{ "token": token, "expireAt": expireAt, "user": map[string]any{ "id": u.ID, "username": u.Username, "realName": u.RealName, "role": u.Role, }, }) } }