first
This commit is contained in:
commit
cca66faed5
20
.gitignore
vendored
Normal file
20
.gitignore
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# idea
|
||||||
|
.idea
|
||||||
|
.idea/
|
||||||
|
*.iml
|
||||||
|
.DS_Store
|
||||||
|
**/.DS_Store
|
||||||
|
|
||||||
|
#deploy data
|
||||||
|
|
||||||
|
data/*
|
||||||
|
!data/.gitkeep
|
||||||
|
|
||||||
|
# gitlab ci
|
||||||
|
.cache
|
||||||
|
|
||||||
|
#vscode
|
||||||
|
.vscode
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
|
6
app/user/cmd/api/.air.toml
Normal file
6
app/user/cmd/api/.air.toml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
root = "."
|
||||||
|
[build]
|
||||||
|
cmd = "go build -o ./tmp/main ./app/user/cmd/api/user.go" # 指定 user-api 的入口文件
|
||||||
|
bin = "./tmp/main"
|
||||||
|
include_ext = ["go", "tmpl", "html"]
|
||||||
|
exclude_dir = ["tmp", "deploy", "data"]
|
31
app/user/cmd/api/Dockerfile
Normal file
31
app/user/cmd/api/Dockerfile
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
FROM golang:1.22.4-alpine AS builder
|
||||||
|
|
||||||
|
LABEL stage=gobuilder
|
||||||
|
|
||||||
|
ENV CGO_ENABLED 0
|
||||||
|
ENV GOPROXY https://goproxy.cn,direct
|
||||||
|
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
|
||||||
|
|
||||||
|
RUN apk update --no-cache && apk add --no-cache tzdata
|
||||||
|
|
||||||
|
WORKDIR /build
|
||||||
|
|
||||||
|
ADD go.mod .
|
||||||
|
ADD go.sum .
|
||||||
|
RUN go mod download
|
||||||
|
COPY . .
|
||||||
|
COPY app/user/cmd/api/etc /app/etc
|
||||||
|
RUN go build -ldflags="-s -w" -o /app/user app/user/cmd/api/.\user.go
|
||||||
|
|
||||||
|
|
||||||
|
FROM scratch
|
||||||
|
|
||||||
|
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
|
||||||
|
COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /usr/share/zoneinfo/Asia/Shanghai
|
||||||
|
ENV TZ Asia/Shanghai
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=builder /app/user /app/user
|
||||||
|
COPY --from=builder /app/etc /app/etc
|
||||||
|
|
||||||
|
CMD ["./user", "-f", "etc/user.yaml"]
|
16
app/user/cmd/api/desc/auth/auth.api
Normal file
16
app/user/cmd/api/desc/auth/auth.api
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
syntax = "v1"
|
||||||
|
|
||||||
|
info (
|
||||||
|
title: "认证服务"
|
||||||
|
desc: "认证服务"
|
||||||
|
author: "Liangzai"
|
||||||
|
email: "2440983361@qq.com"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
sendSmsReq {
|
||||||
|
Mobile string `json:"mobile" validate:"required,mobile"`
|
||||||
|
actionType string `json:"actionType" validate:"required"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
58
app/user/cmd/api/desc/user.api
Normal file
58
app/user/cmd/api/desc/user.api
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
syntax = "v1"
|
||||||
|
|
||||||
|
info (
|
||||||
|
title: "用户中心服务"
|
||||||
|
desc: "用户中心服务"
|
||||||
|
author: "Liangzai"
|
||||||
|
email: "2440983361@qq.com"
|
||||||
|
version: "v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
import (
|
||||||
|
"user/user.api"
|
||||||
|
"auth/auth.api"
|
||||||
|
)
|
||||||
|
|
||||||
|
//============================> user v1 <============================
|
||||||
|
//no need login
|
||||||
|
@server (
|
||||||
|
prefix: user/v1
|
||||||
|
group: user
|
||||||
|
)
|
||||||
|
service user {
|
||||||
|
@doc "register"
|
||||||
|
@handler register
|
||||||
|
post /user/register (RegisterReq) returns (RegisterResp)
|
||||||
|
|
||||||
|
@doc "login"
|
||||||
|
@handler login
|
||||||
|
post /user/login (LoginReq) returns (LoginResp)
|
||||||
|
}
|
||||||
|
|
||||||
|
//need login
|
||||||
|
@server (
|
||||||
|
prefix: user/v1
|
||||||
|
group: user
|
||||||
|
jwt: JwtAuth
|
||||||
|
)
|
||||||
|
service user {
|
||||||
|
@doc "get user info"
|
||||||
|
@handler detail
|
||||||
|
post /user/detail (UserInfoReq) returns (UserInfoResp)
|
||||||
|
|
||||||
|
@doc "wechat mini auth"
|
||||||
|
@handler wxMiniAuth
|
||||||
|
post /user/wxMiniAuth (WXMiniAuthReq) returns (WXMiniAuthResp)
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================> auth v1 <============================
|
||||||
|
@server (
|
||||||
|
prefix: auth/v1
|
||||||
|
group: auth
|
||||||
|
)
|
||||||
|
service user {
|
||||||
|
@doc "get mobile verify code"
|
||||||
|
@handler sendSms
|
||||||
|
post /auth/sendSms (sendSmsReq)
|
||||||
|
}
|
||||||
|
|
58
app/user/cmd/api/desc/user/user.api
Normal file
58
app/user/cmd/api/desc/user/user.api
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
syntax = "v1"
|
||||||
|
|
||||||
|
info (
|
||||||
|
title: "用户实例"
|
||||||
|
desc: "用户实例"
|
||||||
|
author: "Liangzai"
|
||||||
|
email: "2440983361@qq.com"
|
||||||
|
)
|
||||||
|
|
||||||
|
type User {
|
||||||
|
Id int64 `json:"id"`
|
||||||
|
Mobile string `json:"mobile"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type (
|
||||||
|
RegisterReq {
|
||||||
|
Mobile string `json:"mobile" validate:"required,mobile"`
|
||||||
|
Password string `json:"password" validate:"required"`
|
||||||
|
}
|
||||||
|
RegisterResp {
|
||||||
|
AccessToken string `json:"accessToken"`
|
||||||
|
AccessExpire int64 `json:"accessExpire"`
|
||||||
|
RefreshAfter int64 `json:"refreshAfter"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
LoginReq {
|
||||||
|
Mobile string `json:"mobile"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
}
|
||||||
|
LoginResp {
|
||||||
|
AccessToken string `json:"accessToken"`
|
||||||
|
AccessExpire int64 `json:"accessExpire"`
|
||||||
|
RefreshAfter int64 `json:"refreshAfter"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
WXMiniAuthReq {
|
||||||
|
Code string `json:"code"`
|
||||||
|
IV string `json:"iv"`
|
||||||
|
EncryptedData string `json:"encryptedData"`
|
||||||
|
}
|
||||||
|
WXMiniAuthResp {
|
||||||
|
AccessToken string `json:"accessToken"`
|
||||||
|
AccessExpire int64 `json:"accessExpire"`
|
||||||
|
RefreshAfter int64 `json:"refreshAfter"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
UserInfoReq {}
|
||||||
|
UserInfoResp {
|
||||||
|
UserInfo User `json:"userInfo"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
19
app/user/cmd/api/etc/user.yaml
Normal file
19
app/user/cmd/api/etc/user.yaml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Name: user
|
||||||
|
Host: 0.0.0.0
|
||||||
|
Port: 8888
|
||||||
|
DataSource: "qnc:V3j@K9!qL5#wX4$p@tcp(127.0.0.1:20001)/qnc?charset=utf8mb4&parseTime=True&loc=Local"
|
||||||
|
CacheRedis:
|
||||||
|
- Host: "127.0.0.1:20002"
|
||||||
|
Pass: "A!02Myl>H}ZQfpxC" # Redis 密码,如果未设置则留空
|
||||||
|
Type: "node" # 单节点模式
|
||||||
|
JwtAuth:
|
||||||
|
AccessSecret: "WUvoIwL-FK0qnlxhvxR9tV6SjfOpeJMpKmY2QvT99lA"
|
||||||
|
AccessExpire: 86400 # JWT过期时间
|
||||||
|
RefreshAfter: 43200 # 更新时间
|
||||||
|
VerifyCode:
|
||||||
|
AccessKeyID: "LTAI5tKGB3TVJbMHSoZN3yr9"
|
||||||
|
AccessKeySecret: "OCQ30GWp4yENMjmfOAaagksE18bp65"
|
||||||
|
EndpointURL: "dysmsapi.aliyuncs.com"
|
||||||
|
SignName: "天远数据"
|
||||||
|
TemplateCode: "SMS_474525324"
|
||||||
|
ValidTime: 300
|
29
app/user/cmd/api/internal/config/config.go
Normal file
29
app/user/cmd/api/internal/config/config.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||||
|
"github.com/zeromicro/go-zero/rest"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
rest.RestConf
|
||||||
|
DataSource string
|
||||||
|
CacheRedis cache.CacheConf
|
||||||
|
JwtAuth JwtAuth // JWT 鉴权相关配置
|
||||||
|
VerifyCode VerifyCode
|
||||||
|
}
|
||||||
|
|
||||||
|
// JwtAuth 用于 JWT 鉴权配置
|
||||||
|
type JwtAuth struct {
|
||||||
|
AccessSecret string // JWT 密钥,用于签发 Token
|
||||||
|
AccessExpire int64 // Token 过期时间,单位为秒
|
||||||
|
RefreshAfter int64
|
||||||
|
}
|
||||||
|
type VerifyCode struct {
|
||||||
|
AccessKeyID string
|
||||||
|
AccessKeySecret string
|
||||||
|
EndpointURL string
|
||||||
|
SignName string
|
||||||
|
TemplateCode string
|
||||||
|
ValidTime int
|
||||||
|
}
|
29
app/user/cmd/api/internal/handler/auth/sendsmshandler.go
Normal file
29
app/user/cmd/api/internal/handler/auth/sendsmshandler.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
|
"qnc-server/app/user/cmd/api/internal/logic/auth"
|
||||||
|
"qnc-server/app/user/cmd/api/internal/svc"
|
||||||
|
"qnc-server/app/user/cmd/api/internal/types"
|
||||||
|
"qnc-server/common/result"
|
||||||
|
"qnc-server/pkg/lzkit/validator"
|
||||||
|
)
|
||||||
|
|
||||||
|
func SendSmsHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var req types.SendSmsReq
|
||||||
|
if err := httpx.Parse(r, &req); err != nil {
|
||||||
|
result.ParamErrorResult(r, w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := validator.Validate(req); err != nil {
|
||||||
|
result.ParamValidateErrorResult(r, w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
l := auth.NewSendSmsLogic(r.Context(), svcCtx)
|
||||||
|
err := l.SendSms(&req)
|
||||||
|
result.HttpResult(r, w, nil, err)
|
||||||
|
}
|
||||||
|
}
|
63
app/user/cmd/api/internal/handler/routes.go
Normal file
63
app/user/cmd/api/internal/handler/routes.go
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// Code generated by goctl. DO NOT EDIT.
|
||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
auth "qnc-server/app/user/cmd/api/internal/handler/auth"
|
||||||
|
user "qnc-server/app/user/cmd/api/internal/handler/user"
|
||||||
|
"qnc-server/app/user/cmd/api/internal/svc"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/rest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||||
|
server.AddRoutes(
|
||||||
|
[]rest.Route{
|
||||||
|
{
|
||||||
|
// get mobile verify code
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Path: "/auth/sendSms",
|
||||||
|
Handler: auth.SendSmsHandler(serverCtx),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rest.WithPrefix("/auth/v1"),
|
||||||
|
)
|
||||||
|
|
||||||
|
server.AddRoutes(
|
||||||
|
[]rest.Route{
|
||||||
|
{
|
||||||
|
// login
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Path: "/user/login",
|
||||||
|
Handler: user.LoginHandler(serverCtx),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// register
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Path: "/user/register",
|
||||||
|
Handler: user.RegisterHandler(serverCtx),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rest.WithPrefix("/user/v1"),
|
||||||
|
)
|
||||||
|
|
||||||
|
server.AddRoutes(
|
||||||
|
[]rest.Route{
|
||||||
|
{
|
||||||
|
// get user info
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Path: "/user/detail",
|
||||||
|
Handler: user.DetailHandler(serverCtx),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// wechat mini auth
|
||||||
|
Method: http.MethodPost,
|
||||||
|
Path: "/user/wxMiniAuth",
|
||||||
|
Handler: user.WxMiniAuthHandler(serverCtx),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rest.WithJwt(serverCtx.Config.JwtAuth.AccessSecret),
|
||||||
|
rest.WithPrefix("/user/v1"),
|
||||||
|
)
|
||||||
|
}
|
29
app/user/cmd/api/internal/handler/user/detailhandler.go
Normal file
29
app/user/cmd/api/internal/handler/user/detailhandler.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
|
"qnc-server/app/user/cmd/api/internal/logic/user"
|
||||||
|
"qnc-server/app/user/cmd/api/internal/svc"
|
||||||
|
"qnc-server/app/user/cmd/api/internal/types"
|
||||||
|
"qnc-server/common/result"
|
||||||
|
"qnc-server/pkg/lzkit/validator"
|
||||||
|
)
|
||||||
|
|
||||||
|
func DetailHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var req types.UserInfoReq
|
||||||
|
if err := httpx.Parse(r, &req); err != nil {
|
||||||
|
result.ParamErrorResult(r, w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := validator.Validate(req); err != nil {
|
||||||
|
result.ParamValidateErrorResult(r, w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
l := user.NewDetailLogic(r.Context(), svcCtx)
|
||||||
|
resp, err := l.Detail(&req)
|
||||||
|
result.HttpResult(r, w, resp, err)
|
||||||
|
}
|
||||||
|
}
|
29
app/user/cmd/api/internal/handler/user/loginhandler.go
Normal file
29
app/user/cmd/api/internal/handler/user/loginhandler.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
|
"qnc-server/app/user/cmd/api/internal/logic/user"
|
||||||
|
"qnc-server/app/user/cmd/api/internal/svc"
|
||||||
|
"qnc-server/app/user/cmd/api/internal/types"
|
||||||
|
"qnc-server/common/result"
|
||||||
|
"qnc-server/pkg/lzkit/validator"
|
||||||
|
)
|
||||||
|
|
||||||
|
func LoginHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var req types.LoginReq
|
||||||
|
if err := httpx.Parse(r, &req); err != nil {
|
||||||
|
result.ParamErrorResult(r, w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := validator.Validate(req); err != nil {
|
||||||
|
result.ParamValidateErrorResult(r, w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
l := user.NewLoginLogic(r.Context(), svcCtx)
|
||||||
|
resp, err := l.Login(&req)
|
||||||
|
result.HttpResult(r, w, resp, err)
|
||||||
|
}
|
||||||
|
}
|
29
app/user/cmd/api/internal/handler/user/registerhandler.go
Normal file
29
app/user/cmd/api/internal/handler/user/registerhandler.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
|
"qnc-server/app/user/cmd/api/internal/logic/user"
|
||||||
|
"qnc-server/app/user/cmd/api/internal/svc"
|
||||||
|
"qnc-server/app/user/cmd/api/internal/types"
|
||||||
|
"qnc-server/common/result"
|
||||||
|
"qnc-server/pkg/lzkit/validator"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RegisterHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var req types.RegisterReq
|
||||||
|
if err := httpx.Parse(r, &req); err != nil {
|
||||||
|
result.ParamErrorResult(r, w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := validator.Validate(req); err != nil {
|
||||||
|
result.ParamValidateErrorResult(r, w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
l := user.NewRegisterLogic(r.Context(), svcCtx)
|
||||||
|
resp, err := l.Register(&req)
|
||||||
|
result.HttpResult(r, w, resp, err)
|
||||||
|
}
|
||||||
|
}
|
29
app/user/cmd/api/internal/handler/user/wxminiauthhandler.go
Normal file
29
app/user/cmd/api/internal/handler/user/wxminiauthhandler.go
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
|
"qnc-server/app/user/cmd/api/internal/logic/user"
|
||||||
|
"qnc-server/app/user/cmd/api/internal/svc"
|
||||||
|
"qnc-server/app/user/cmd/api/internal/types"
|
||||||
|
"qnc-server/common/result"
|
||||||
|
"qnc-server/pkg/lzkit/validator"
|
||||||
|
)
|
||||||
|
|
||||||
|
func WxMiniAuthHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var req types.WXMiniAuthReq
|
||||||
|
if err := httpx.Parse(r, &req); err != nil {
|
||||||
|
result.ParamErrorResult(r, w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := validator.Validate(req); err != nil {
|
||||||
|
result.ParamValidateErrorResult(r, w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
l := user.NewWxMiniAuthLogic(r.Context(), svcCtx)
|
||||||
|
resp, err := l.WxMiniAuth(&req)
|
||||||
|
result.HttpResult(r, w, resp, err)
|
||||||
|
}
|
||||||
|
}
|
98
app/user/cmd/api/internal/logic/auth/sendsmslogic.go
Normal file
98
app/user/cmd/api/internal/logic/auth/sendsmslogic.go
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
package auth
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"math/rand"
|
||||||
|
"qnc-server/common/xerr"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"qnc-server/app/user/cmd/api/internal/svc"
|
||||||
|
"qnc-server/app/user/cmd/api/internal/types"
|
||||||
|
|
||||||
|
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
|
||||||
|
dysmsapi "github.com/alibabacloud-go/dysmsapi-20170525/v3/client"
|
||||||
|
"github.com/alibabacloud-go/tea-utils/v2/service"
|
||||||
|
"github.com/alibabacloud-go/tea/tea"
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SendSmsLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSendSmsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SendSmsLogic {
|
||||||
|
return &SendSmsLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *SendSmsLogic) SendSms(req *types.SendSmsReq) error {
|
||||||
|
// 检查手机号是否在一分钟内已发送过验证码
|
||||||
|
redisKey := fmt.Sprintf("%s:%s", req.ActionType, req.Mobile)
|
||||||
|
exists, err := l.svcCtx.Redis.Exists(redisKey)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if exists {
|
||||||
|
// 如果 Redis 中已经存在标记,说明在 1 分钟内请求过,返回错误
|
||||||
|
return errors.Wrapf(xerr.NewErrMsg("一分钟内不能重复发送验证码"), "手机号1分钟内重复请求发送二维码, 手机号: %s", req.Mobile)
|
||||||
|
}
|
||||||
|
|
||||||
|
code := fmt.Sprintf("%06d", rand.New(rand.NewSource(time.Now().UnixNano())).Intn(1000000))
|
||||||
|
|
||||||
|
// 发送短信
|
||||||
|
smsResp, err := l.sendSmsRequest(req.Mobile, code)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "短信发送失败, 调用阿里客户端失败: %+v", err)
|
||||||
|
}
|
||||||
|
if *smsResp.Body.Code != "OK" {
|
||||||
|
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "短信发送失败, 阿里客户端响应失败: %s", *smsResp.Body.Message)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 将验证码保存到 Redis,设置过期时间
|
||||||
|
err = l.svcCtx.Redis.Setex(req.Mobile, code, l.svcCtx.Config.VerifyCode.ValidTime) // 验证码有效期5分钟
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "缓存失败, 验证码设置过期时间失败: %+v", err)
|
||||||
|
}
|
||||||
|
// 在 Redis 中设置 1 分钟的标记,限制重复请求
|
||||||
|
err = l.svcCtx.Redis.Setex(redisKey, code, 60) // 标记 1 分钟内不能重复请求
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "缓存失败, 验证码设置限制重复请求失败: %+v", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateClient 创建阿里云短信客户端
|
||||||
|
func (l *SendSmsLogic) CreateClient() (*dysmsapi.Client, error) {
|
||||||
|
config := &openapi.Config{
|
||||||
|
AccessKeyId: &l.svcCtx.Config.VerifyCode.AccessKeyID,
|
||||||
|
AccessKeySecret: &l.svcCtx.Config.VerifyCode.AccessKeySecret,
|
||||||
|
}
|
||||||
|
config.Endpoint = tea.String(l.svcCtx.Config.VerifyCode.EndpointURL)
|
||||||
|
return dysmsapi.NewClient(config)
|
||||||
|
}
|
||||||
|
|
||||||
|
// sendSmsRequest 发送短信请求
|
||||||
|
func (l *SendSmsLogic) sendSmsRequest(mobile, code string) (*dysmsapi.SendSmsResponse, error) {
|
||||||
|
// 初始化阿里云短信客户端
|
||||||
|
cli, err := l.CreateClient()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
request := &dysmsapi.SendSmsRequest{
|
||||||
|
SignName: tea.String(l.svcCtx.Config.VerifyCode.SignName),
|
||||||
|
TemplateCode: tea.String(l.svcCtx.Config.VerifyCode.TemplateCode),
|
||||||
|
PhoneNumbers: tea.String(mobile),
|
||||||
|
TemplateParam: tea.String(fmt.Sprintf("{\"code\":\"%s\"}", code)),
|
||||||
|
}
|
||||||
|
runtime := &service.RuntimeOptions{}
|
||||||
|
return cli.SendSmsWithOptions(request, runtime)
|
||||||
|
}
|
30
app/user/cmd/api/internal/logic/user/detaillogic.go
Normal file
30
app/user/cmd/api/internal/logic/user/detaillogic.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"qnc-server/app/user/cmd/api/internal/svc"
|
||||||
|
"qnc-server/app/user/cmd/api/internal/types"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DetailLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDetailLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DetailLogic {
|
||||||
|
return &DetailLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *DetailLogic) Detail(req *types.UserInfoReq) (resp *types.UserInfoResp, err error) {
|
||||||
|
// todo: add your logic here and delete this line
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
30
app/user/cmd/api/internal/logic/user/loginlogic.go
Normal file
30
app/user/cmd/api/internal/logic/user/loginlogic.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"qnc-server/app/user/cmd/api/internal/svc"
|
||||||
|
"qnc-server/app/user/cmd/api/internal/types"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type LoginLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LoginLogic {
|
||||||
|
return &LoginLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *LoginLogic) Login(req *types.LoginReq) (resp *types.LoginResp, err error) {
|
||||||
|
// todo: add your logic here and delete this line
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
83
app/user/cmd/api/internal/logic/user/registerlogic.go
Normal file
83
app/user/cmd/api/internal/logic/user/registerlogic.go
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
"qnc-server/app/user/cmd/api/internal/svc"
|
||||||
|
"qnc-server/app/user/cmd/api/internal/types"
|
||||||
|
"qnc-server/app/user/model"
|
||||||
|
jwtx "qnc-server/common/jwt"
|
||||||
|
"qnc-server/common/tool"
|
||||||
|
"qnc-server/common/xerr"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ErrUserAlreadyRegisterError = xerr.NewErrMsg("该手机号码已注册")
|
||||||
|
|
||||||
|
type RegisterLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRegisterLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RegisterLogic {
|
||||||
|
return &RegisterLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *RegisterLogic) Register(req *types.RegisterReq) (resp *types.RegisterResp, err error) {
|
||||||
|
hasUser, findUserErr := l.svcCtx.UserModel.FindOneByMobile(l.ctx, req.Mobile)
|
||||||
|
if findUserErr != nil && findUserErr != model.ErrNotFound {
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "mobile:%s,err:%v", req.Mobile, err)
|
||||||
|
}
|
||||||
|
if hasUser != nil {
|
||||||
|
return nil, errors.Wrapf(ErrUserAlreadyRegisterError, "Register user exists mobile:%s,err:%v", req.Mobile, err)
|
||||||
|
}
|
||||||
|
var userId int64
|
||||||
|
if transErr := l.svcCtx.UserModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
|
||||||
|
user := new(model.User)
|
||||||
|
user.Mobile = req.Mobile
|
||||||
|
if len(user.Nickname) == 0 {
|
||||||
|
user.Nickname = tool.Krand(8, tool.KC_RAND_KIND_ALL)
|
||||||
|
}
|
||||||
|
if len(req.Password) > 0 {
|
||||||
|
user.Password = tool.Md5ByString(req.Password)
|
||||||
|
}
|
||||||
|
insertResult, userInsertErr := l.svcCtx.UserModel.Insert(ctx, session, user)
|
||||||
|
if userInsertErr != nil {
|
||||||
|
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "Register db user Insert err:%v,user:%+v", userInsertErr, user)
|
||||||
|
}
|
||||||
|
lastId, lastInsertIdErr := insertResult.LastInsertId()
|
||||||
|
if lastInsertIdErr != nil {
|
||||||
|
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "Register db user insertResult.LastInsertId err:%v,user:%+v", lastInsertIdErr, user)
|
||||||
|
}
|
||||||
|
userId = lastId
|
||||||
|
|
||||||
|
userAuth := new(model.UserAuth)
|
||||||
|
userAuth.UserId = lastId
|
||||||
|
userAuth.AuthKey = req.Mobile
|
||||||
|
userAuth.AuthType = model.UserAuthTypeAppMobile
|
||||||
|
if _, userAuthInsertErr := l.svcCtx.UserAuthModel.Insert(ctx, session, userAuth); err != nil {
|
||||||
|
return errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "Register db user_auth Insert err:%v,userAuth:%v", err, userAuthInsertErr)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}); transErr != nil {
|
||||||
|
return nil, transErr
|
||||||
|
}
|
||||||
|
|
||||||
|
token, generaErr := jwtx.GenerateJwtToken(userId, l.svcCtx.Config.JwtAuth.AccessSecret, l.svcCtx.Config.JwtAuth.AccessExpire)
|
||||||
|
if generaErr != nil {
|
||||||
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "GenerateToken error userId : %d", userId)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &types.RegisterResp{
|
||||||
|
AccessToken: token,
|
||||||
|
AccessExpire: l.svcCtx.Config.JwtAuth.AccessExpire,
|
||||||
|
RefreshAfter: l.svcCtx.Config.JwtAuth.RefreshAfter,
|
||||||
|
}, nil
|
||||||
|
}
|
30
app/user/cmd/api/internal/logic/user/wxminiauthlogic.go
Normal file
30
app/user/cmd/api/internal/logic/user/wxminiauthlogic.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package user
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"qnc-server/app/user/cmd/api/internal/svc"
|
||||||
|
"qnc-server/app/user/cmd/api/internal/types"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type WxMiniAuthLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewWxMiniAuthLogic(ctx context.Context, svcCtx *svc.ServiceContext) *WxMiniAuthLogic {
|
||||||
|
return &WxMiniAuthLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *WxMiniAuthLogic) WxMiniAuth(req *types.WXMiniAuthReq) (resp *types.WXMiniAuthResp, err error) {
|
||||||
|
// todo: add your logic here and delete this line
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
30
app/user/cmd/api/internal/svc/servicecontext.go
Normal file
30
app/user/cmd/api/internal/svc/servicecontext.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package svc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/redis"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
"qnc-server/app/user/cmd/api/internal/config"
|
||||||
|
"qnc-server/app/user/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ServiceContext struct {
|
||||||
|
Config config.Config
|
||||||
|
Redis *redis.Redis
|
||||||
|
UserModel model.UserModel
|
||||||
|
UserAuthModel model.UserAuthModel
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||||||
|
db := sqlx.NewMysql(c.DataSource) // 创建数据库连接
|
||||||
|
redisConf := redis.RedisConf{
|
||||||
|
Host: c.CacheRedis[0].Host,
|
||||||
|
Pass: c.CacheRedis[0].Pass,
|
||||||
|
Type: c.CacheRedis[0].Type, // Redis 节点类型,如 "node"
|
||||||
|
}
|
||||||
|
return &ServiceContext{
|
||||||
|
Config: c,
|
||||||
|
Redis: redis.MustNewRedis(redisConf),
|
||||||
|
UserModel: model.NewUserModel(db, c.CacheRedis),
|
||||||
|
UserAuthModel: model.NewUserAuthModel(db, c.CacheRedis),
|
||||||
|
}
|
||||||
|
}
|
53
app/user/cmd/api/internal/types/types.go
Normal file
53
app/user/cmd/api/internal/types/types.go
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// Code generated by goctl. DO NOT EDIT.
|
||||||
|
package types
|
||||||
|
|
||||||
|
type LoginReq struct {
|
||||||
|
Mobile string `json:"mobile"`
|
||||||
|
Password string `json:"password"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type LoginResp struct {
|
||||||
|
AccessToken string `json:"accessToken"`
|
||||||
|
AccessExpire int64 `json:"accessExpire"`
|
||||||
|
RefreshAfter int64 `json:"refreshAfter"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RegisterReq struct {
|
||||||
|
Mobile string `json:"mobile" validate:"required,mobile"`
|
||||||
|
Password string `json:"password" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RegisterResp struct {
|
||||||
|
AccessToken string `json:"accessToken"`
|
||||||
|
AccessExpire int64 `json:"accessExpire"`
|
||||||
|
RefreshAfter int64 `json:"refreshAfter"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type User struct {
|
||||||
|
Id int64 `json:"id"`
|
||||||
|
Mobile string `json:"mobile"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserInfoReq struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserInfoResp struct {
|
||||||
|
UserInfo User `json:"userInfo"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type WXMiniAuthReq struct {
|
||||||
|
Code string `json:"code"`
|
||||||
|
IV string `json:"iv"`
|
||||||
|
EncryptedData string `json:"encryptedData"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type WXMiniAuthResp struct {
|
||||||
|
AccessToken string `json:"accessToken"`
|
||||||
|
AccessExpire int64 `json:"accessExpire"`
|
||||||
|
RefreshAfter int64 `json:"refreshAfter"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SendSmsReq struct {
|
||||||
|
Mobile string `json:"mobile" validate:"required,mobile"`
|
||||||
|
ActionType string `json:"actionType" validate:"required"`
|
||||||
|
}
|
31
app/user/cmd/api/user.go
Normal file
31
app/user/cmd/api/user.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"qnc-server/app/user/cmd/api/internal/config"
|
||||||
|
"qnc-server/app/user/cmd/api/internal/handler"
|
||||||
|
"qnc-server/app/user/cmd/api/internal/svc"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/conf"
|
||||||
|
"github.com/zeromicro/go-zero/rest"
|
||||||
|
)
|
||||||
|
|
||||||
|
var configFile = flag.String("f", "etc/user.yaml", "the config file")
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
var c config.Config
|
||||||
|
conf.MustLoad(*configFile, &c)
|
||||||
|
|
||||||
|
ctx := svc.NewServiceContext(c)
|
||||||
|
server := rest.MustNewServer(c.RestConf)
|
||||||
|
|
||||||
|
defer server.Stop()
|
||||||
|
|
||||||
|
handler.RegisterHandlers(server, ctx)
|
||||||
|
|
||||||
|
fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
|
||||||
|
server.Start()
|
||||||
|
}
|
27
app/user/model/userauthmodel.go
Normal file
27
app/user/model/userauthmodel.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ UserAuthModel = (*customUserAuthModel)(nil)
|
||||||
|
|
||||||
|
type (
|
||||||
|
// UserAuthModel is an interface to be customized, add more methods here,
|
||||||
|
// and implement the added methods in customUserAuthModel.
|
||||||
|
UserAuthModel interface {
|
||||||
|
userAuthModel
|
||||||
|
}
|
||||||
|
|
||||||
|
customUserAuthModel struct {
|
||||||
|
*defaultUserAuthModel
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewUserAuthModel returns a model for the database table.
|
||||||
|
func NewUserAuthModel(conn sqlx.SqlConn, c cache.CacheConf) UserAuthModel {
|
||||||
|
return &customUserAuthModel{
|
||||||
|
defaultUserAuthModel: newUserAuthModel(conn, c),
|
||||||
|
}
|
||||||
|
}
|
435
app/user/model/userauthmodel_gen.go
Normal file
435
app/user/model/userauthmodel_gen.go
Normal file
@ -0,0 +1,435 @@
|
|||||||
|
// Code generated by goctl. DO NOT EDIT!
|
||||||
|
|
||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/Masterminds/squirrel"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/builder"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlc"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
"github.com/zeromicro/go-zero/core/stringx"
|
||||||
|
"qnc-server/common/globalkey"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
userAuthFieldNames = builder.RawFieldNames(&UserAuth{})
|
||||||
|
userAuthRows = strings.Join(userAuthFieldNames, ",")
|
||||||
|
userAuthRowsExpectAutoSet = strings.Join(stringx.Remove(userAuthFieldNames, "`id`", "`create_time`", "`update_time`"), ",")
|
||||||
|
userAuthRowsWithPlaceHolder = strings.Join(stringx.Remove(userAuthFieldNames, "`id`", "`create_time`", "`update_time`"), "=?,") + "=?"
|
||||||
|
|
||||||
|
cacheUserAuthIdPrefix = "cache:userAuth:id:"
|
||||||
|
cacheUserAuthAuthTypeAuthKeyPrefix = "cache:userAuth:authType:authKey:"
|
||||||
|
cacheUserAuthUserIdAuthTypePrefix = "cache:userAuth:userId:authType:"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
userAuthModel interface {
|
||||||
|
Insert(ctx context.Context, session sqlx.Session, data *UserAuth) (sql.Result, error)
|
||||||
|
FindOne(ctx context.Context, id int64) (*UserAuth, error)
|
||||||
|
FindOneByAuthTypeAuthKey(ctx context.Context, authType string, authKey string) (*UserAuth, error)
|
||||||
|
FindOneByUserIdAuthType(ctx context.Context, userId int64, authType string) (*UserAuth, error)
|
||||||
|
Update(ctx context.Context, session sqlx.Session, data *UserAuth) (sql.Result, error)
|
||||||
|
UpdateWithVersion(ctx context.Context, session sqlx.Session, data *UserAuth) error
|
||||||
|
Trans(ctx context.Context, fn func(context context.Context, session sqlx.Session) error) error
|
||||||
|
SelectBuilder() squirrel.SelectBuilder
|
||||||
|
DeleteSoft(ctx context.Context, session sqlx.Session, data *UserAuth) error
|
||||||
|
FindSum(ctx context.Context, sumBuilder squirrel.SelectBuilder, field string) (float64, error)
|
||||||
|
FindCount(ctx context.Context, countBuilder squirrel.SelectBuilder, field string) (int64, error)
|
||||||
|
FindAll(ctx context.Context, rowBuilder squirrel.SelectBuilder, orderBy string) ([]*UserAuth, error)
|
||||||
|
FindPageListByPage(ctx context.Context, rowBuilder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*UserAuth, error)
|
||||||
|
FindPageListByPageWithTotal(ctx context.Context, rowBuilder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*UserAuth, int64, error)
|
||||||
|
FindPageListByIdDESC(ctx context.Context, rowBuilder squirrel.SelectBuilder, preMinId, pageSize int64) ([]*UserAuth, error)
|
||||||
|
FindPageListByIdASC(ctx context.Context, rowBuilder squirrel.SelectBuilder, preMaxId, pageSize int64) ([]*UserAuth, error)
|
||||||
|
Delete(ctx context.Context, session sqlx.Session, id int64) error
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultUserAuthModel struct {
|
||||||
|
sqlc.CachedConn
|
||||||
|
table string
|
||||||
|
}
|
||||||
|
|
||||||
|
UserAuth struct {
|
||||||
|
Id int64 `db:"id"`
|
||||||
|
CreateTime time.Time `db:"create_time"`
|
||||||
|
UpdateTime time.Time `db:"update_time"`
|
||||||
|
DeleteTime time.Time `db:"delete_time"`
|
||||||
|
DelState int64 `db:"del_state"`
|
||||||
|
Version int64 `db:"version"` // 版本号
|
||||||
|
UserId int64 `db:"user_id"`
|
||||||
|
AuthKey string `db:"auth_key"` // 平台唯一id
|
||||||
|
AuthType string `db:"auth_type"` // 平台类型
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func newUserAuthModel(conn sqlx.SqlConn, c cache.CacheConf) *defaultUserAuthModel {
|
||||||
|
return &defaultUserAuthModel{
|
||||||
|
CachedConn: sqlc.NewConn(conn, c),
|
||||||
|
table: "`user_auth`",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserAuthModel) Insert(ctx context.Context, session sqlx.Session, data *UserAuth) (sql.Result, error) {
|
||||||
|
data.DeleteTime = time.Unix(0, 0)
|
||||||
|
data.DelState = globalkey.DelStateNo
|
||||||
|
userAuthAuthTypeAuthKeyKey := fmt.Sprintf("%s%v:%v", cacheUserAuthAuthTypeAuthKeyPrefix, data.AuthType, data.AuthKey)
|
||||||
|
userAuthIdKey := fmt.Sprintf("%s%v", cacheUserAuthIdPrefix, data.Id)
|
||||||
|
userAuthUserIdAuthTypeKey := fmt.Sprintf("%s%v:%v", cacheUserAuthUserIdAuthTypePrefix, data.UserId, data.AuthType)
|
||||||
|
return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||||
|
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?)", m.table, userAuthRowsExpectAutoSet)
|
||||||
|
if session != nil {
|
||||||
|
return session.ExecCtx(ctx, query, data.DeleteTime, data.DelState, data.Version, data.UserId, data.AuthKey, data.AuthType)
|
||||||
|
}
|
||||||
|
return conn.ExecCtx(ctx, query, data.DeleteTime, data.DelState, data.Version, data.UserId, data.AuthKey, data.AuthType)
|
||||||
|
}, userAuthAuthTypeAuthKeyKey, userAuthIdKey, userAuthUserIdAuthTypeKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserAuthModel) FindOne(ctx context.Context, id int64) (*UserAuth, error) {
|
||||||
|
userAuthIdKey := fmt.Sprintf("%s%v", cacheUserAuthIdPrefix, id)
|
||||||
|
var resp UserAuth
|
||||||
|
err := m.QueryRowCtx(ctx, &resp, userAuthIdKey, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) error {
|
||||||
|
query := fmt.Sprintf("select %s from %s where `id` = ? and del_state = ? limit 1", userAuthRows, m.table)
|
||||||
|
return conn.QueryRowCtx(ctx, v, query, id, globalkey.DelStateNo)
|
||||||
|
})
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return &resp, nil
|
||||||
|
case sqlc.ErrNotFound:
|
||||||
|
return nil, ErrNotFound
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserAuthModel) FindOneByAuthTypeAuthKey(ctx context.Context, authType string, authKey string) (*UserAuth, error) {
|
||||||
|
userAuthAuthTypeAuthKeyKey := fmt.Sprintf("%s%v:%v", cacheUserAuthAuthTypeAuthKeyPrefix, authType, authKey)
|
||||||
|
var resp UserAuth
|
||||||
|
err := m.QueryRowIndexCtx(ctx, &resp, userAuthAuthTypeAuthKeyKey, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) (i interface{}, e error) {
|
||||||
|
query := fmt.Sprintf("select %s from %s where `auth_type` = ? and `auth_key` = ? and del_state = ? limit 1", userAuthRows, m.table)
|
||||||
|
if err := conn.QueryRowCtx(ctx, &resp, query, authType, authKey, globalkey.DelStateNo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return resp.Id, nil
|
||||||
|
}, m.queryPrimary)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return &resp, nil
|
||||||
|
case sqlc.ErrNotFound:
|
||||||
|
return nil, ErrNotFound
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserAuthModel) FindOneByUserIdAuthType(ctx context.Context, userId int64, authType string) (*UserAuth, error) {
|
||||||
|
userAuthUserIdAuthTypeKey := fmt.Sprintf("%s%v:%v", cacheUserAuthUserIdAuthTypePrefix, userId, authType)
|
||||||
|
var resp UserAuth
|
||||||
|
err := m.QueryRowIndexCtx(ctx, &resp, userAuthUserIdAuthTypeKey, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) (i interface{}, e error) {
|
||||||
|
query := fmt.Sprintf("select %s from %s where `user_id` = ? and `auth_type` = ? and del_state = ? limit 1", userAuthRows, m.table)
|
||||||
|
if err := conn.QueryRowCtx(ctx, &resp, query, userId, authType, globalkey.DelStateNo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return resp.Id, nil
|
||||||
|
}, m.queryPrimary)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return &resp, nil
|
||||||
|
case sqlc.ErrNotFound:
|
||||||
|
return nil, ErrNotFound
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserAuthModel) Update(ctx context.Context, session sqlx.Session, newData *UserAuth) (sql.Result, error) {
|
||||||
|
data, err := m.FindOne(ctx, newData.Id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
userAuthAuthTypeAuthKeyKey := fmt.Sprintf("%s%v:%v", cacheUserAuthAuthTypeAuthKeyPrefix, data.AuthType, data.AuthKey)
|
||||||
|
userAuthIdKey := fmt.Sprintf("%s%v", cacheUserAuthIdPrefix, data.Id)
|
||||||
|
userAuthUserIdAuthTypeKey := fmt.Sprintf("%s%v:%v", cacheUserAuthUserIdAuthTypePrefix, data.UserId, data.AuthType)
|
||||||
|
return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||||
|
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, userAuthRowsWithPlaceHolder)
|
||||||
|
if session != nil {
|
||||||
|
return session.ExecCtx(ctx, query, newData.DeleteTime, newData.DelState, newData.Version, newData.UserId, newData.AuthKey, newData.AuthType, newData.Id)
|
||||||
|
}
|
||||||
|
return conn.ExecCtx(ctx, query, newData.DeleteTime, newData.DelState, newData.Version, newData.UserId, newData.AuthKey, newData.AuthType, newData.Id)
|
||||||
|
}, userAuthAuthTypeAuthKeyKey, userAuthIdKey, userAuthUserIdAuthTypeKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserAuthModel) UpdateWithVersion(ctx context.Context, session sqlx.Session, newData *UserAuth) error {
|
||||||
|
|
||||||
|
oldVersion := newData.Version
|
||||||
|
newData.Version += 1
|
||||||
|
|
||||||
|
var sqlResult sql.Result
|
||||||
|
var err error
|
||||||
|
|
||||||
|
data, err := m.FindOne(ctx, newData.Id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
userAuthAuthTypeAuthKeyKey := fmt.Sprintf("%s%v:%v", cacheUserAuthAuthTypeAuthKeyPrefix, data.AuthType, data.AuthKey)
|
||||||
|
userAuthIdKey := fmt.Sprintf("%s%v", cacheUserAuthIdPrefix, data.Id)
|
||||||
|
userAuthUserIdAuthTypeKey := fmt.Sprintf("%s%v:%v", cacheUserAuthUserIdAuthTypePrefix, data.UserId, data.AuthType)
|
||||||
|
sqlResult, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||||
|
query := fmt.Sprintf("update %s set %s where `id` = ? and version = ? ", m.table, userAuthRowsWithPlaceHolder)
|
||||||
|
if session != nil {
|
||||||
|
return session.ExecCtx(ctx, query, newData.DeleteTime, newData.DelState, newData.Version, newData.UserId, newData.AuthKey, newData.AuthType, newData.Id, oldVersion)
|
||||||
|
}
|
||||||
|
return conn.ExecCtx(ctx, query, newData.DeleteTime, newData.DelState, newData.Version, newData.UserId, newData.AuthKey, newData.AuthType, newData.Id, oldVersion)
|
||||||
|
}, userAuthAuthTypeAuthKeyKey, userAuthIdKey, userAuthUserIdAuthTypeKey)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
updateCount, err := sqlResult.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if updateCount == 0 {
|
||||||
|
return ErrNoRowsUpdate
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserAuthModel) DeleteSoft(ctx context.Context, session sqlx.Session, data *UserAuth) error {
|
||||||
|
data.DelState = globalkey.DelStateYes
|
||||||
|
data.DeleteTime = time.Now()
|
||||||
|
if err := m.UpdateWithVersion(ctx, session, data); err != nil {
|
||||||
|
return errors.Wrapf(errors.New("delete soft failed "), "UserAuthModel delete err : %+v", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserAuthModel) FindSum(ctx context.Context, builder squirrel.SelectBuilder, field string) (float64, error) {
|
||||||
|
|
||||||
|
if len(field) == 0 {
|
||||||
|
return 0, errors.Wrapf(errors.New("FindSum Least One Field"), "FindSum Least One Field")
|
||||||
|
}
|
||||||
|
|
||||||
|
builder = builder.Columns("IFNULL(SUM(" + field + "),0)")
|
||||||
|
|
||||||
|
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).ToSql()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp float64
|
||||||
|
err = m.QueryRowNoCacheCtx(ctx, &resp, query, values...)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return resp, nil
|
||||||
|
default:
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserAuthModel) FindCount(ctx context.Context, builder squirrel.SelectBuilder, field string) (int64, error) {
|
||||||
|
|
||||||
|
if len(field) == 0 {
|
||||||
|
return 0, errors.Wrapf(errors.New("FindCount Least One Field"), "FindCount Least One Field")
|
||||||
|
}
|
||||||
|
|
||||||
|
builder = builder.Columns("COUNT(" + field + ")")
|
||||||
|
|
||||||
|
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).ToSql()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp int64
|
||||||
|
err = m.QueryRowNoCacheCtx(ctx, &resp, query, values...)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return resp, nil
|
||||||
|
default:
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserAuthModel) FindAll(ctx context.Context, builder squirrel.SelectBuilder, orderBy string) ([]*UserAuth, error) {
|
||||||
|
|
||||||
|
builder = builder.Columns(userAuthRows)
|
||||||
|
|
||||||
|
if orderBy == "" {
|
||||||
|
builder = builder.OrderBy("id DESC")
|
||||||
|
} else {
|
||||||
|
builder = builder.OrderBy(orderBy)
|
||||||
|
}
|
||||||
|
|
||||||
|
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).ToSql()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp []*UserAuth
|
||||||
|
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return resp, nil
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserAuthModel) FindPageListByPage(ctx context.Context, builder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*UserAuth, error) {
|
||||||
|
|
||||||
|
builder = builder.Columns(userAuthRows)
|
||||||
|
|
||||||
|
if orderBy == "" {
|
||||||
|
builder = builder.OrderBy("id DESC")
|
||||||
|
} else {
|
||||||
|
builder = builder.OrderBy(orderBy)
|
||||||
|
}
|
||||||
|
|
||||||
|
if page < 1 {
|
||||||
|
page = 1
|
||||||
|
}
|
||||||
|
offset := (page - 1) * pageSize
|
||||||
|
|
||||||
|
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).Offset(uint64(offset)).Limit(uint64(pageSize)).ToSql()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp []*UserAuth
|
||||||
|
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return resp, nil
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserAuthModel) FindPageListByPageWithTotal(ctx context.Context, builder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*UserAuth, int64, error) {
|
||||||
|
|
||||||
|
total, err := m.FindCount(ctx, builder, "id")
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
builder = builder.Columns(userAuthRows)
|
||||||
|
|
||||||
|
if orderBy == "" {
|
||||||
|
builder = builder.OrderBy("id DESC")
|
||||||
|
} else {
|
||||||
|
builder = builder.OrderBy(orderBy)
|
||||||
|
}
|
||||||
|
|
||||||
|
if page < 1 {
|
||||||
|
page = 1
|
||||||
|
}
|
||||||
|
offset := (page - 1) * pageSize
|
||||||
|
|
||||||
|
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).Offset(uint64(offset)).Limit(uint64(pageSize)).ToSql()
|
||||||
|
if err != nil {
|
||||||
|
return nil, total, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp []*UserAuth
|
||||||
|
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return resp, total, nil
|
||||||
|
default:
|
||||||
|
return nil, total, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserAuthModel) FindPageListByIdDESC(ctx context.Context, builder squirrel.SelectBuilder, preMinId, pageSize int64) ([]*UserAuth, error) {
|
||||||
|
|
||||||
|
builder = builder.Columns(userAuthRows)
|
||||||
|
|
||||||
|
if preMinId > 0 {
|
||||||
|
builder = builder.Where(" id < ? ", preMinId)
|
||||||
|
}
|
||||||
|
|
||||||
|
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).OrderBy("id DESC").Limit(uint64(pageSize)).ToSql()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp []*UserAuth
|
||||||
|
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return resp, nil
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserAuthModel) FindPageListByIdASC(ctx context.Context, builder squirrel.SelectBuilder, preMaxId, pageSize int64) ([]*UserAuth, error) {
|
||||||
|
|
||||||
|
builder = builder.Columns(userAuthRows)
|
||||||
|
|
||||||
|
if preMaxId > 0 {
|
||||||
|
builder = builder.Where(" id > ? ", preMaxId)
|
||||||
|
}
|
||||||
|
|
||||||
|
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).OrderBy("id ASC").Limit(uint64(pageSize)).ToSql()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp []*UserAuth
|
||||||
|
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return resp, nil
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserAuthModel) Trans(ctx context.Context, fn func(ctx context.Context, session sqlx.Session) error) error {
|
||||||
|
|
||||||
|
return m.TransactCtx(ctx, func(ctx context.Context, session sqlx.Session) error {
|
||||||
|
return fn(ctx, session)
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserAuthModel) SelectBuilder() squirrel.SelectBuilder {
|
||||||
|
return squirrel.Select().From(m.table)
|
||||||
|
}
|
||||||
|
func (m *defaultUserAuthModel) Delete(ctx context.Context, session sqlx.Session, id int64) error {
|
||||||
|
data, err := m.FindOne(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
userAuthAuthTypeAuthKeyKey := fmt.Sprintf("%s%v:%v", cacheUserAuthAuthTypeAuthKeyPrefix, data.AuthType, data.AuthKey)
|
||||||
|
userAuthIdKey := fmt.Sprintf("%s%v", cacheUserAuthIdPrefix, id)
|
||||||
|
userAuthUserIdAuthTypeKey := fmt.Sprintf("%s%v:%v", cacheUserAuthUserIdAuthTypePrefix, data.UserId, data.AuthType)
|
||||||
|
_, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||||
|
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
|
||||||
|
if session != nil {
|
||||||
|
return session.ExecCtx(ctx, query, id)
|
||||||
|
}
|
||||||
|
return conn.ExecCtx(ctx, query, id)
|
||||||
|
}, userAuthAuthTypeAuthKeyKey, userAuthIdKey, userAuthUserIdAuthTypeKey)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
func (m *defaultUserAuthModel) formatPrimary(primary interface{}) string {
|
||||||
|
return fmt.Sprintf("%s%v", cacheUserAuthIdPrefix, primary)
|
||||||
|
}
|
||||||
|
func (m *defaultUserAuthModel) queryPrimary(ctx context.Context, conn sqlx.SqlConn, v, primary interface{}) error {
|
||||||
|
query := fmt.Sprintf("select %s from %s where `id` = ? and del_state = ? limit 1", userAuthRows, m.table)
|
||||||
|
return conn.QueryRowCtx(ctx, v, query, primary, globalkey.DelStateNo)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserAuthModel) tableName() string {
|
||||||
|
return m.table
|
||||||
|
}
|
27
app/user/model/usermodel.go
Normal file
27
app/user/model/usermodel.go
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ UserModel = (*customUserModel)(nil)
|
||||||
|
|
||||||
|
type (
|
||||||
|
// UserModel is an interface to be customized, add more methods here,
|
||||||
|
// and implement the added methods in customUserModel.
|
||||||
|
UserModel interface {
|
||||||
|
userModel
|
||||||
|
}
|
||||||
|
|
||||||
|
customUserModel struct {
|
||||||
|
*defaultUserModel
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewUserModel returns a model for the database table.
|
||||||
|
func NewUserModel(conn sqlx.SqlConn, c cache.CacheConf) UserModel {
|
||||||
|
return &customUserModel{
|
||||||
|
defaultUserModel: newUserModel(conn, c),
|
||||||
|
}
|
||||||
|
}
|
410
app/user/model/usermodel_gen.go
Normal file
410
app/user/model/usermodel_gen.go
Normal file
@ -0,0 +1,410 @@
|
|||||||
|
// Code generated by goctl. DO NOT EDIT!
|
||||||
|
|
||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/Masterminds/squirrel"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/builder"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlc"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
"github.com/zeromicro/go-zero/core/stringx"
|
||||||
|
"qnc-server/common/globalkey"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
userFieldNames = builder.RawFieldNames(&User{})
|
||||||
|
userRows = strings.Join(userFieldNames, ",")
|
||||||
|
userRowsExpectAutoSet = strings.Join(stringx.Remove(userFieldNames, "`id`", "`create_time`", "`update_time`"), ",")
|
||||||
|
userRowsWithPlaceHolder = strings.Join(stringx.Remove(userFieldNames, "`id`", "`create_time`", "`update_time`"), "=?,") + "=?"
|
||||||
|
|
||||||
|
cacheUserIdPrefix = "cache:user:id:"
|
||||||
|
cacheUserMobilePrefix = "cache:user:mobile:"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
userModel interface {
|
||||||
|
Insert(ctx context.Context, session sqlx.Session, data *User) (sql.Result, error)
|
||||||
|
FindOne(ctx context.Context, id int64) (*User, error)
|
||||||
|
FindOneByMobile(ctx context.Context, mobile string) (*User, error)
|
||||||
|
Update(ctx context.Context, session sqlx.Session, data *User) (sql.Result, error)
|
||||||
|
UpdateWithVersion(ctx context.Context, session sqlx.Session, data *User) error
|
||||||
|
Trans(ctx context.Context, fn func(context context.Context, session sqlx.Session) error) error
|
||||||
|
SelectBuilder() squirrel.SelectBuilder
|
||||||
|
DeleteSoft(ctx context.Context, session sqlx.Session, data *User) error
|
||||||
|
FindSum(ctx context.Context, sumBuilder squirrel.SelectBuilder, field string) (float64, error)
|
||||||
|
FindCount(ctx context.Context, countBuilder squirrel.SelectBuilder, field string) (int64, error)
|
||||||
|
FindAll(ctx context.Context, rowBuilder squirrel.SelectBuilder, orderBy string) ([]*User, error)
|
||||||
|
FindPageListByPage(ctx context.Context, rowBuilder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*User, error)
|
||||||
|
FindPageListByPageWithTotal(ctx context.Context, rowBuilder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*User, int64, error)
|
||||||
|
FindPageListByIdDESC(ctx context.Context, rowBuilder squirrel.SelectBuilder, preMinId, pageSize int64) ([]*User, error)
|
||||||
|
FindPageListByIdASC(ctx context.Context, rowBuilder squirrel.SelectBuilder, preMaxId, pageSize int64) ([]*User, error)
|
||||||
|
Delete(ctx context.Context, session sqlx.Session, id int64) error
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultUserModel struct {
|
||||||
|
sqlc.CachedConn
|
||||||
|
table string
|
||||||
|
}
|
||||||
|
|
||||||
|
User struct {
|
||||||
|
Id int64 `db:"id"`
|
||||||
|
CreateTime time.Time `db:"create_time"`
|
||||||
|
UpdateTime time.Time `db:"update_time"`
|
||||||
|
DeleteTime time.Time `db:"delete_time"`
|
||||||
|
DelState int64 `db:"del_state"`
|
||||||
|
Version int64 `db:"version"` // 版本号
|
||||||
|
Mobile string `db:"mobile"`
|
||||||
|
Password string `db:"password"`
|
||||||
|
Nickname string `db:"nickname"`
|
||||||
|
Info string `db:"info"`
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func newUserModel(conn sqlx.SqlConn, c cache.CacheConf) *defaultUserModel {
|
||||||
|
return &defaultUserModel{
|
||||||
|
CachedConn: sqlc.NewConn(conn, c),
|
||||||
|
table: "`user`",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserModel) Insert(ctx context.Context, session sqlx.Session, data *User) (sql.Result, error) {
|
||||||
|
data.DeleteTime = time.Unix(0, 0)
|
||||||
|
data.DelState = globalkey.DelStateNo
|
||||||
|
userIdKey := fmt.Sprintf("%s%v", cacheUserIdPrefix, data.Id)
|
||||||
|
userMobileKey := fmt.Sprintf("%s%v", cacheUserMobilePrefix, data.Mobile)
|
||||||
|
return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||||
|
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?)", m.table, userRowsExpectAutoSet)
|
||||||
|
if session != nil {
|
||||||
|
return session.ExecCtx(ctx, query, data.DeleteTime, data.DelState, data.Version, data.Mobile, data.Password, data.Nickname, data.Info)
|
||||||
|
}
|
||||||
|
return conn.ExecCtx(ctx, query, data.DeleteTime, data.DelState, data.Version, data.Mobile, data.Password, data.Nickname, data.Info)
|
||||||
|
}, userIdKey, userMobileKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserModel) FindOne(ctx context.Context, id int64) (*User, error) {
|
||||||
|
userIdKey := fmt.Sprintf("%s%v", cacheUserIdPrefix, id)
|
||||||
|
var resp User
|
||||||
|
err := m.QueryRowCtx(ctx, &resp, userIdKey, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) error {
|
||||||
|
query := fmt.Sprintf("select %s from %s where `id` = ? and del_state = ? limit 1", userRows, m.table)
|
||||||
|
return conn.QueryRowCtx(ctx, v, query, id, globalkey.DelStateNo)
|
||||||
|
})
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return &resp, nil
|
||||||
|
case sqlc.ErrNotFound:
|
||||||
|
return nil, ErrNotFound
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserModel) FindOneByMobile(ctx context.Context, mobile string) (*User, error) {
|
||||||
|
userMobileKey := fmt.Sprintf("%s%v", cacheUserMobilePrefix, mobile)
|
||||||
|
var resp User
|
||||||
|
err := m.QueryRowIndexCtx(ctx, &resp, userMobileKey, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) (i interface{}, e error) {
|
||||||
|
query := fmt.Sprintf("select %s from %s where `mobile` = ? and del_state = ? limit 1", userRows, m.table)
|
||||||
|
if err := conn.QueryRowCtx(ctx, &resp, query, mobile, globalkey.DelStateNo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return resp.Id, nil
|
||||||
|
}, m.queryPrimary)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return &resp, nil
|
||||||
|
case sqlc.ErrNotFound:
|
||||||
|
return nil, ErrNotFound
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserModel) Update(ctx context.Context, session sqlx.Session, newData *User) (sql.Result, error) {
|
||||||
|
data, err := m.FindOne(ctx, newData.Id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
userIdKey := fmt.Sprintf("%s%v", cacheUserIdPrefix, data.Id)
|
||||||
|
userMobileKey := fmt.Sprintf("%s%v", cacheUserMobilePrefix, data.Mobile)
|
||||||
|
return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||||
|
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, userRowsWithPlaceHolder)
|
||||||
|
if session != nil {
|
||||||
|
return session.ExecCtx(ctx, query, newData.DeleteTime, newData.DelState, newData.Version, newData.Mobile, newData.Password, newData.Nickname, newData.Info, newData.Id)
|
||||||
|
}
|
||||||
|
return conn.ExecCtx(ctx, query, newData.DeleteTime, newData.DelState, newData.Version, newData.Mobile, newData.Password, newData.Nickname, newData.Info, newData.Id)
|
||||||
|
}, userIdKey, userMobileKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserModel) UpdateWithVersion(ctx context.Context, session sqlx.Session, newData *User) error {
|
||||||
|
|
||||||
|
oldVersion := newData.Version
|
||||||
|
newData.Version += 1
|
||||||
|
|
||||||
|
var sqlResult sql.Result
|
||||||
|
var err error
|
||||||
|
|
||||||
|
data, err := m.FindOne(ctx, newData.Id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
userIdKey := fmt.Sprintf("%s%v", cacheUserIdPrefix, data.Id)
|
||||||
|
userMobileKey := fmt.Sprintf("%s%v", cacheUserMobilePrefix, data.Mobile)
|
||||||
|
sqlResult, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||||
|
query := fmt.Sprintf("update %s set %s where `id` = ? and version = ? ", m.table, userRowsWithPlaceHolder)
|
||||||
|
if session != nil {
|
||||||
|
return session.ExecCtx(ctx, query, newData.DeleteTime, newData.DelState, newData.Version, newData.Mobile, newData.Password, newData.Nickname, newData.Info, newData.Id, oldVersion)
|
||||||
|
}
|
||||||
|
return conn.ExecCtx(ctx, query, newData.DeleteTime, newData.DelState, newData.Version, newData.Mobile, newData.Password, newData.Nickname, newData.Info, newData.Id, oldVersion)
|
||||||
|
}, userIdKey, userMobileKey)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
updateCount, err := sqlResult.RowsAffected()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if updateCount == 0 {
|
||||||
|
return ErrNoRowsUpdate
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserModel) DeleteSoft(ctx context.Context, session sqlx.Session, data *User) error {
|
||||||
|
data.DelState = globalkey.DelStateYes
|
||||||
|
data.DeleteTime = time.Now()
|
||||||
|
if err := m.UpdateWithVersion(ctx, session, data); err != nil {
|
||||||
|
return errors.Wrapf(errors.New("delete soft failed "), "UserModel delete err : %+v", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserModel) FindSum(ctx context.Context, builder squirrel.SelectBuilder, field string) (float64, error) {
|
||||||
|
|
||||||
|
if len(field) == 0 {
|
||||||
|
return 0, errors.Wrapf(errors.New("FindSum Least One Field"), "FindSum Least One Field")
|
||||||
|
}
|
||||||
|
|
||||||
|
builder = builder.Columns("IFNULL(SUM(" + field + "),0)")
|
||||||
|
|
||||||
|
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).ToSql()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp float64
|
||||||
|
err = m.QueryRowNoCacheCtx(ctx, &resp, query, values...)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return resp, nil
|
||||||
|
default:
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserModel) FindCount(ctx context.Context, builder squirrel.SelectBuilder, field string) (int64, error) {
|
||||||
|
|
||||||
|
if len(field) == 0 {
|
||||||
|
return 0, errors.Wrapf(errors.New("FindCount Least One Field"), "FindCount Least One Field")
|
||||||
|
}
|
||||||
|
|
||||||
|
builder = builder.Columns("COUNT(" + field + ")")
|
||||||
|
|
||||||
|
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).ToSql()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp int64
|
||||||
|
err = m.QueryRowNoCacheCtx(ctx, &resp, query, values...)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return resp, nil
|
||||||
|
default:
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserModel) FindAll(ctx context.Context, builder squirrel.SelectBuilder, orderBy string) ([]*User, error) {
|
||||||
|
|
||||||
|
builder = builder.Columns(userRows)
|
||||||
|
|
||||||
|
if orderBy == "" {
|
||||||
|
builder = builder.OrderBy("id DESC")
|
||||||
|
} else {
|
||||||
|
builder = builder.OrderBy(orderBy)
|
||||||
|
}
|
||||||
|
|
||||||
|
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).ToSql()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp []*User
|
||||||
|
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return resp, nil
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserModel) FindPageListByPage(ctx context.Context, builder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*User, error) {
|
||||||
|
|
||||||
|
builder = builder.Columns(userRows)
|
||||||
|
|
||||||
|
if orderBy == "" {
|
||||||
|
builder = builder.OrderBy("id DESC")
|
||||||
|
} else {
|
||||||
|
builder = builder.OrderBy(orderBy)
|
||||||
|
}
|
||||||
|
|
||||||
|
if page < 1 {
|
||||||
|
page = 1
|
||||||
|
}
|
||||||
|
offset := (page - 1) * pageSize
|
||||||
|
|
||||||
|
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).Offset(uint64(offset)).Limit(uint64(pageSize)).ToSql()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp []*User
|
||||||
|
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return resp, nil
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserModel) FindPageListByPageWithTotal(ctx context.Context, builder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*User, int64, error) {
|
||||||
|
|
||||||
|
total, err := m.FindCount(ctx, builder, "id")
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
builder = builder.Columns(userRows)
|
||||||
|
|
||||||
|
if orderBy == "" {
|
||||||
|
builder = builder.OrderBy("id DESC")
|
||||||
|
} else {
|
||||||
|
builder = builder.OrderBy(orderBy)
|
||||||
|
}
|
||||||
|
|
||||||
|
if page < 1 {
|
||||||
|
page = 1
|
||||||
|
}
|
||||||
|
offset := (page - 1) * pageSize
|
||||||
|
|
||||||
|
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).Offset(uint64(offset)).Limit(uint64(pageSize)).ToSql()
|
||||||
|
if err != nil {
|
||||||
|
return nil, total, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp []*User
|
||||||
|
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return resp, total, nil
|
||||||
|
default:
|
||||||
|
return nil, total, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserModel) FindPageListByIdDESC(ctx context.Context, builder squirrel.SelectBuilder, preMinId, pageSize int64) ([]*User, error) {
|
||||||
|
|
||||||
|
builder = builder.Columns(userRows)
|
||||||
|
|
||||||
|
if preMinId > 0 {
|
||||||
|
builder = builder.Where(" id < ? ", preMinId)
|
||||||
|
}
|
||||||
|
|
||||||
|
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).OrderBy("id DESC").Limit(uint64(pageSize)).ToSql()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp []*User
|
||||||
|
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return resp, nil
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserModel) FindPageListByIdASC(ctx context.Context, builder squirrel.SelectBuilder, preMaxId, pageSize int64) ([]*User, error) {
|
||||||
|
|
||||||
|
builder = builder.Columns(userRows)
|
||||||
|
|
||||||
|
if preMaxId > 0 {
|
||||||
|
builder = builder.Where(" id > ? ", preMaxId)
|
||||||
|
}
|
||||||
|
|
||||||
|
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).OrderBy("id ASC").Limit(uint64(pageSize)).ToSql()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp []*User
|
||||||
|
err = m.QueryRowsNoCacheCtx(ctx, &resp, query, values...)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return resp, nil
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserModel) Trans(ctx context.Context, fn func(ctx context.Context, session sqlx.Session) error) error {
|
||||||
|
|
||||||
|
return m.TransactCtx(ctx, func(ctx context.Context, session sqlx.Session) error {
|
||||||
|
return fn(ctx, session)
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserModel) SelectBuilder() squirrel.SelectBuilder {
|
||||||
|
return squirrel.Select().From(m.table)
|
||||||
|
}
|
||||||
|
func (m *defaultUserModel) Delete(ctx context.Context, session sqlx.Session, id int64) error {
|
||||||
|
data, err := m.FindOne(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
userIdKey := fmt.Sprintf("%s%v", cacheUserIdPrefix, id)
|
||||||
|
userMobileKey := fmt.Sprintf("%s%v", cacheUserMobilePrefix, data.Mobile)
|
||||||
|
_, err = m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||||
|
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
|
||||||
|
if session != nil {
|
||||||
|
return session.ExecCtx(ctx, query, id)
|
||||||
|
}
|
||||||
|
return conn.ExecCtx(ctx, query, id)
|
||||||
|
}, userIdKey, userMobileKey)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
func (m *defaultUserModel) formatPrimary(primary interface{}) string {
|
||||||
|
return fmt.Sprintf("%s%v", cacheUserIdPrefix, primary)
|
||||||
|
}
|
||||||
|
func (m *defaultUserModel) queryPrimary(ctx context.Context, conn sqlx.SqlConn, v, primary interface{}) error {
|
||||||
|
query := fmt.Sprintf("select %s from %s where `id` = ? and del_state = ? limit 1", userRows, m.table)
|
||||||
|
return conn.QueryRowCtx(ctx, v, query, primary, globalkey.DelStateNo)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultUserModel) tableName() string {
|
||||||
|
return m.table
|
||||||
|
}
|
15
app/user/model/vars.go
Normal file
15
app/user/model/vars.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ErrNotFound = sqlx.ErrNotFound
|
||||||
|
var ErrNoRowsUpdate = errors.New("update db no rows change")
|
||||||
|
|
||||||
|
var UserAuthTypeAppMobile string = "app_mobile" //平台内部
|
||||||
|
var UserAuthTypeAppWechat string = "app_wechat" //微信小程序
|
||||||
|
var UserAuthTypeH5Mobile string = "h5_mobile"
|
||||||
|
var UserAuthTypeWxMini string = "wx_mini"
|
||||||
|
var UserAuthTypeWxOfficialAccount string = "wx_official_account"
|
22
common/ctxdata/ctxData.go
Normal file
22
common/ctxdata/ctxData.go
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
package ctxdata
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CtxKeyJwtUserId get uid from ctx
|
||||||
|
var CtxKeyJwtUserId = "jwtUserId"
|
||||||
|
|
||||||
|
func GetUidFromCtx(ctx context.Context) int64 {
|
||||||
|
var uid int64
|
||||||
|
if jsonUid, ok := ctx.Value(CtxKeyJwtUserId).(json.Number); ok {
|
||||||
|
if int64Uid, err := jsonUid.Int64(); err == nil {
|
||||||
|
uid = int64Uid
|
||||||
|
} else {
|
||||||
|
logx.WithContext(ctx).Errorf("GetUidFromCtx err : %+v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return uid
|
||||||
|
}
|
14
common/globalkey/constantKey.go
Normal file
14
common/globalkey/constantKey.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package globalkey
|
||||||
|
|
||||||
|
/**
|
||||||
|
global constant key
|
||||||
|
*/
|
||||||
|
|
||||||
|
//软删除
|
||||||
|
var DelStateNo int64 = 0 //未删除
|
||||||
|
var DelStateYes int64 = 1 //已删除
|
||||||
|
|
||||||
|
//时间格式化模版
|
||||||
|
var DateTimeFormatTplStandardDateTime = "Y-m-d H:i:s"
|
||||||
|
var DateTimeFormatTplStandardDate = "Y-m-d"
|
||||||
|
var DateTimeFormatTplStandardTime = "H:i:s"
|
9
common/globalkey/redisCacheKey.go
Normal file
9
common/globalkey/redisCacheKey.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package globalkey
|
||||||
|
|
||||||
|
/**
|
||||||
|
redis key except "model cache key" in here,
|
||||||
|
but "model cache key" in model
|
||||||
|
*/
|
||||||
|
|
||||||
|
// CacheUserTokenKey /** 用户登陆的token
|
||||||
|
const CacheUserTokenKey = "user_token:%d"
|
39
common/interceptor/rpcserver/loggerInterceptor.go
Normal file
39
common/interceptor/rpcserver/loggerInterceptor.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package rpcserver
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"qnc-server/common/xerr"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
"google.golang.org/grpc/codes"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Description rpc service logger interceptor
|
||||||
|
* @Author Mikael
|
||||||
|
* @Date 2021/1/9 13:35
|
||||||
|
* @Version 1.0
|
||||||
|
**/
|
||||||
|
|
||||||
|
func LoggerInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
|
||||||
|
|
||||||
|
resp, err = handler(ctx, req)
|
||||||
|
if err != nil {
|
||||||
|
causeErr := errors.Cause(err) // err类型
|
||||||
|
if e, ok := causeErr.(*xerr.CodeError); ok { //自定义错误类型
|
||||||
|
logx.WithContext(ctx).Errorf("【RPC-SRV-ERR】 %+v", err)
|
||||||
|
|
||||||
|
//转成grpc err
|
||||||
|
err = status.Error(codes.Code(e.GetErrCode()), e.GetErrMsg())
|
||||||
|
} else {
|
||||||
|
logx.WithContext(ctx).Errorf("【RPC-SRV-ERR】 %+v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, err
|
||||||
|
}
|
68
common/jwt/jwtx.go
Normal file
68
common/jwt/jwtx.go
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
package jwtx
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"github.com/golang-jwt/jwt/v4"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Token 生成逻辑的函数,接收 userId、过期时间和密钥,返回生成的 token
|
||||||
|
func GenerateJwtToken(userId int64, secret string, expireTime int64) (string, error) {
|
||||||
|
// 获取当前时间戳
|
||||||
|
now := time.Now().Unix()
|
||||||
|
// 定义 JWT Claims
|
||||||
|
claims := jwt.MapClaims{
|
||||||
|
"exp": now + expireTime, // token 过期时间
|
||||||
|
"iat": now, // 签发时间
|
||||||
|
"userId": userId, // 用户ID
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建新的 JWT token
|
||||||
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||||
|
|
||||||
|
// 使用密钥对 token 签名
|
||||||
|
signedToken, err := token.SignedString([]byte(secret))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return signedToken, nil
|
||||||
|
}
|
||||||
|
func ParseJwtToken(tokenStr string, secret string) (int64, error) {
|
||||||
|
token, err := jwt.Parse(tokenStr, func(token *jwt.Token) (interface{}, error) {
|
||||||
|
return []byte(secret), nil
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil || !token.Valid {
|
||||||
|
return 0, errors.New("invalid JWT")
|
||||||
|
}
|
||||||
|
|
||||||
|
claims, ok := token.Claims.(jwt.MapClaims)
|
||||||
|
if !ok || !token.Valid {
|
||||||
|
return 0, errors.New("invalid JWT claims")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从 claims 中提取 userId
|
||||||
|
userIdRaw, ok := claims["userId"]
|
||||||
|
if !ok {
|
||||||
|
return 0, errors.New("userId not found in JWT")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理不同类型的 userId,确保它被转换为 int64
|
||||||
|
switch userId := userIdRaw.(type) {
|
||||||
|
case float64:
|
||||||
|
return int64(userId), nil
|
||||||
|
case int64:
|
||||||
|
return userId, nil
|
||||||
|
case string:
|
||||||
|
// 如果 userId 是字符串,可以尝试将其转换为 int64
|
||||||
|
parsedId, err := strconv.ParseInt(userId, 10, 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0, errors.New("invalid userId in JWT")
|
||||||
|
}
|
||||||
|
return parsedId, nil
|
||||||
|
default:
|
||||||
|
return 0, errors.New("unsupported userId type in JWT")
|
||||||
|
}
|
||||||
|
}
|
8
common/kqueue/message.go
Normal file
8
common/kqueue/message.go
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
//KqMessage
|
||||||
|
package kqueue
|
||||||
|
|
||||||
|
//第三方支付回调更改支付状态通知
|
||||||
|
type ThirdPaymentUpdatePayStatusNotifyMessage struct {
|
||||||
|
PayStatus int64 `json:"payStatus"`
|
||||||
|
OrderSn string `json:"orderSn"`
|
||||||
|
}
|
31
common/middleware/commonJwtAuthMiddleware.go
Normal file
31
common/middleware/commonJwtAuthMiddleware.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
package middleware
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/zeromicro/go-zero/rest/handler"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
// CommonJwtAuthMiddleware : with jwt on the verification, no jwt on the verification
|
||||||
|
type CommonJwtAuthMiddleware struct {
|
||||||
|
secret string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewCommonJwtAuthMiddleware(secret string) *CommonJwtAuthMiddleware {
|
||||||
|
return &CommonJwtAuthMiddleware{
|
||||||
|
secret: secret,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *CommonJwtAuthMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if len(r.Header.Get("Authorization")) > 0 {
|
||||||
|
//has jwt Authorization
|
||||||
|
authHandler := handler.Authorize(m.secret)
|
||||||
|
authHandler(next).ServeHTTP(w, r)
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
//no jwt Authorization
|
||||||
|
next(w, r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
89
common/result/httpResult.go
Normal file
89
common/result/httpResult.go
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
package result
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"qnc-server/common/xerr"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
|
)
|
||||||
|
|
||||||
|
// http返回
|
||||||
|
func HttpResult(r *http.Request, w http.ResponseWriter, resp interface{}, err error) {
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
httpx.WriteJson(w, http.StatusOK, Success(resp))
|
||||||
|
} else {
|
||||||
|
//错误返回
|
||||||
|
errcode := xerr.SERVER_COMMON_ERROR
|
||||||
|
errmsg := "服务器开小差啦,稍后再来试一试"
|
||||||
|
|
||||||
|
causeErr := errors.Cause(err) // err类型
|
||||||
|
if e, ok := causeErr.(*xerr.CodeError); ok { //自定义错误类型
|
||||||
|
//自定义CodeError
|
||||||
|
errcode = e.GetErrCode()
|
||||||
|
errmsg = e.GetErrMsg()
|
||||||
|
} else {
|
||||||
|
if gstatus, ok := status.FromError(causeErr); ok { // grpc err错误
|
||||||
|
grpcCode := uint32(gstatus.Code())
|
||||||
|
if xerr.IsCodeErr(grpcCode) { //区分自定义错误跟系统底层、db等错误,底层、db错误不能返回给前端
|
||||||
|
errcode = grpcCode
|
||||||
|
errmsg = gstatus.Message()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logx.WithContext(r.Context()).Errorf("【API-ERR】 : %+v ", err)
|
||||||
|
|
||||||
|
httpx.WriteJson(w, http.StatusBadRequest, Error(errcode, errmsg))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 授权的http方法
|
||||||
|
func AuthHttpResult(r *http.Request, w http.ResponseWriter, resp interface{}, err error) {
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
//成功返回
|
||||||
|
r := Success(resp)
|
||||||
|
httpx.WriteJson(w, http.StatusOK, r)
|
||||||
|
} else {
|
||||||
|
//错误返回
|
||||||
|
errcode := xerr.SERVER_COMMON_ERROR
|
||||||
|
errmsg := "服务器开小差啦,稍后再来试一试"
|
||||||
|
|
||||||
|
causeErr := errors.Cause(err) // err类型
|
||||||
|
if e, ok := causeErr.(*xerr.CodeError); ok { //自定义错误类型
|
||||||
|
//自定义CodeError
|
||||||
|
errcode = e.GetErrCode()
|
||||||
|
errmsg = e.GetErrMsg()
|
||||||
|
} else {
|
||||||
|
if gstatus, ok := status.FromError(causeErr); ok { // grpc err错误
|
||||||
|
grpcCode := uint32(gstatus.Code())
|
||||||
|
if xerr.IsCodeErr(grpcCode) { //区分自定义错误跟系统底层、db等错误,底层、db错误不能返回给前端
|
||||||
|
errcode = grpcCode
|
||||||
|
errmsg = gstatus.Message()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logx.WithContext(r.Context()).Errorf("【GATEWAY-ERR】 : %+v ", err)
|
||||||
|
|
||||||
|
httpx.WriteJson(w, http.StatusUnauthorized, Error(errcode, errmsg))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// http 参数错误返回
|
||||||
|
func ParamErrorResult(r *http.Request, w http.ResponseWriter, err error) {
|
||||||
|
errMsg := fmt.Sprintf("%s,%s", xerr.MapErrMsg(xerr.REUQEST_PARAM_ERROR), err.Error())
|
||||||
|
httpx.WriteJson(w, http.StatusBadRequest, Error(xerr.REUQEST_PARAM_ERROR, errMsg))
|
||||||
|
}
|
||||||
|
|
||||||
|
// http 参数校验失败返回
|
||||||
|
func ParamValidateErrorResult(r *http.Request, w http.ResponseWriter, err error) {
|
||||||
|
//errMsg := fmt.Sprintf("%s,%s", xerr.MapErrMsg(xerr.REUQEST_PARAM_ERROR), err.Error())
|
||||||
|
httpx.WriteJson(w, http.StatusOK, Error(xerr.PARAM_VERIFICATION_ERROR, err.Error()))
|
||||||
|
}
|
44
common/result/jobResult.go
Normal file
44
common/result/jobResult.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package result
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"qnc-server/common/xerr"
|
||||||
|
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
"google.golang.org/grpc/status"
|
||||||
|
)
|
||||||
|
|
||||||
|
// job返回
|
||||||
|
func JobResult(ctx context.Context, resp interface{}, err error) {
|
||||||
|
if err == nil {
|
||||||
|
// 成功返回 ,只有dev环境下才会打印info,线上不显示
|
||||||
|
if resp != nil {
|
||||||
|
logx.Infof("resp: %+v", resp)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
errCode := xerr.SERVER_COMMON_ERROR
|
||||||
|
errMsg := "服务器开小差啦,稍后再来试一试"
|
||||||
|
|
||||||
|
// 错误返回
|
||||||
|
causeErr := errors.Cause(err) // err类型
|
||||||
|
if e, ok := causeErr.(*xerr.CodeError); ok { // 自定义错误类型
|
||||||
|
// 自定义CodeError
|
||||||
|
errCode = e.GetErrCode()
|
||||||
|
errMsg = e.GetErrMsg()
|
||||||
|
} else {
|
||||||
|
if gstatus, ok := status.FromError(causeErr); ok { // grpc err错误
|
||||||
|
grpcCode := uint32(gstatus.Code())
|
||||||
|
if xerr.IsCodeErr(grpcCode) { // 区分自定义错误跟系统底层、db等错误,底层、db错误不能返回给前端
|
||||||
|
errCode = grpcCode
|
||||||
|
errMsg = gstatus.Message()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logx.WithContext(ctx).Errorf("【JOB-ERR】 : %+v ,errCode:%d , errMsg:%s ", err, errCode, errMsg)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
21
common/result/responseBean.go
Normal file
21
common/result/responseBean.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package result
|
||||||
|
|
||||||
|
type ResponseSuccessBean struct {
|
||||||
|
Code uint32 `json:"code"`
|
||||||
|
Msg string `json:"msg"`
|
||||||
|
Data interface{} `json:"data"`
|
||||||
|
}
|
||||||
|
type NullJson struct{}
|
||||||
|
|
||||||
|
func Success(data interface{}) *ResponseSuccessBean {
|
||||||
|
return &ResponseSuccessBean{200, "OK", data}
|
||||||
|
}
|
||||||
|
|
||||||
|
type ResponseErrorBean struct {
|
||||||
|
Code uint32 `json:"code"`
|
||||||
|
Msg string `json:"msg"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func Error(errCode uint32, errMsg string) *ResponseErrorBean {
|
||||||
|
return &ResponseErrorBean{errCode, errMsg}
|
||||||
|
}
|
19
common/tool/coinconvert.go
Normal file
19
common/tool/coinconvert.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package tool
|
||||||
|
|
||||||
|
import "github.com/shopspring/decimal"
|
||||||
|
|
||||||
|
var oneHundredDecimal decimal.Decimal = decimal.NewFromInt(100)
|
||||||
|
|
||||||
|
//分转元
|
||||||
|
func Fen2Yuan(fen int64) float64 {
|
||||||
|
y, _ := decimal.NewFromInt(fen).Div(oneHundredDecimal).Truncate(2).Float64()
|
||||||
|
return y
|
||||||
|
}
|
||||||
|
|
||||||
|
//元转分
|
||||||
|
func Yuan2Fen(yuan float64) int64 {
|
||||||
|
|
||||||
|
f, _ := decimal.NewFromFloat(yuan).Mul(oneHundredDecimal).Truncate(0).Float64()
|
||||||
|
return int64(f)
|
||||||
|
|
||||||
|
}
|
23
common/tool/encryption.go
Normal file
23
common/tool/encryption.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package tool
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
)
|
||||||
|
|
||||||
|
/** 加密方式 **/
|
||||||
|
|
||||||
|
func Md5ByString(str string) string {
|
||||||
|
m := md5.New()
|
||||||
|
_, err := io.WriteString(m, str)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
arr := m.Sum(nil)
|
||||||
|
return fmt.Sprintf("%x", arr)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Md5ByBytes(b []byte) string {
|
||||||
|
return fmt.Sprintf("%x", md5.Sum(b))
|
||||||
|
}
|
28
common/tool/krand.go
Normal file
28
common/tool/krand.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package tool
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/rand"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
KC_RAND_KIND_NUM = 0 // 纯数字
|
||||||
|
KC_RAND_KIND_LOWER = 1 // 小写字母
|
||||||
|
KC_RAND_KIND_UPPER = 2 // 大写字母
|
||||||
|
KC_RAND_KIND_ALL = 3 // 数字、大小写字母
|
||||||
|
)
|
||||||
|
|
||||||
|
// 随机字符串
|
||||||
|
func Krand(size int, kind int) string {
|
||||||
|
ikind, kinds, result := kind, [][]int{[]int{10, 48}, []int{26, 97}, []int{26, 65}}, make([]byte, size)
|
||||||
|
is_all := kind > 2 || kind < 0
|
||||||
|
rand.Seed(time.Now().UnixNano())
|
||||||
|
for i := 0; i < size; i++ {
|
||||||
|
if is_all { // random ikind
|
||||||
|
ikind = rand.Intn(3)
|
||||||
|
}
|
||||||
|
scope, base := kinds[ikind][0], kinds[ikind][1]
|
||||||
|
result[i] = uint8(base + rand.Intn(scope))
|
||||||
|
}
|
||||||
|
return string(result)
|
||||||
|
}
|
8
common/tool/krand_test.go
Normal file
8
common/tool/krand_test.go
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
package tool
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestMd5ByString(t *testing.T) {
|
||||||
|
s := Md5ByString("AAA")
|
||||||
|
t.Log(s)
|
||||||
|
}
|
15
common/tool/placeholders.go
Normal file
15
common/tool/placeholders.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package tool
|
||||||
|
|
||||||
|
import "strings"
|
||||||
|
|
||||||
|
//替换
|
||||||
|
func InPlaceholders(n int) string {
|
||||||
|
var b strings.Builder
|
||||||
|
for i := 0; i < n-1; i++ {
|
||||||
|
b.WriteString("?,")
|
||||||
|
}
|
||||||
|
if n > 0 {
|
||||||
|
b.WriteString("?")
|
||||||
|
}
|
||||||
|
return b.String()
|
||||||
|
}
|
20
common/uniqueid/sn.go
Normal file
20
common/uniqueid/sn.go
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package uniqueid
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"qnc-server/common/tool"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 生成sn单号
|
||||||
|
type SnPrefix string
|
||||||
|
|
||||||
|
const (
|
||||||
|
SN_PREFIX_HOMESTAY_ORDER SnPrefix = "HSO" //民宿订单前缀 qnc-server_order/homestay_order
|
||||||
|
SN_PREFIX_THIRD_PAYMENT SnPrefix = "PMT" //第三方支付流水记录前缀 qnc-server_payment/third_payment
|
||||||
|
)
|
||||||
|
|
||||||
|
// 生成单号
|
||||||
|
func GenSn(snPrefix SnPrefix) string {
|
||||||
|
return fmt.Sprintf("%s%s%s", snPrefix, time.Now().Format("20060102150405"), tool.Krand(8, tool.KC_RAND_KIND_NUM))
|
||||||
|
}
|
7
common/uniqueid/sn_test.go
Normal file
7
common/uniqueid/sn_test.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package uniqueid
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestGenSn(t *testing.T) {
|
||||||
|
GenSn(SN_PREFIX_HOMESTAY_ORDER)
|
||||||
|
}
|
23
common/uniqueid/uniqueid.go
Normal file
23
common/uniqueid/uniqueid.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package uniqueid
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/sony/sonyflake"
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
var flake *sonyflake.Sonyflake
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
flake = sonyflake.NewSonyflake(sonyflake.Settings{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func GenId() int64 {
|
||||||
|
|
||||||
|
id, err := flake.NextID()
|
||||||
|
if err != nil {
|
||||||
|
logx.Severef("flake NextID failed with %s \n", err)
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return int64(id)
|
||||||
|
}
|
7
common/wxminisub/tpl.go
Normal file
7
common/wxminisub/tpl.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package wxminisub
|
||||||
|
|
||||||
|
//订单支付成功
|
||||||
|
const OrderPaySuccessTemplateID = "QIJPmfxaNqYzSjOlXGk1T6Xfw94JwbSPuOd3u_hi3WE"
|
||||||
|
|
||||||
|
//支付成功入驻通知
|
||||||
|
const OrderPaySuccessLiveKnowTemplateID = "kmm-maRr6v_9eMxEPpj-5clJ2YW_EFpd8-ngyYk63e4"
|
18
common/xerr/errCode.go
Normal file
18
common/xerr/errCode.go
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package xerr
|
||||||
|
|
||||||
|
// 成功返回
|
||||||
|
const OK uint32 = 200
|
||||||
|
|
||||||
|
/**(前3位代表业务,后三位代表具体功能)**/
|
||||||
|
|
||||||
|
// 全局错误码
|
||||||
|
const SERVER_COMMON_ERROR uint32 = 100001
|
||||||
|
const REUQEST_PARAM_ERROR uint32 = 100002
|
||||||
|
const TOKEN_EXPIRE_ERROR uint32 = 100003
|
||||||
|
const TOKEN_GENERATE_ERROR uint32 = 100004
|
||||||
|
const DB_ERROR uint32 = 100005
|
||||||
|
const DB_UPDATE_AFFECTED_ZERO_ERROR uint32 = 100006
|
||||||
|
const PARAM_VERIFICATION_ERROR uint32 = 100007
|
||||||
|
const CUSTOM_ERROR uint32 = 100008
|
||||||
|
|
||||||
|
//用户模块
|
30
common/xerr/errMsg.go
Normal file
30
common/xerr/errMsg.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package xerr
|
||||||
|
|
||||||
|
var message map[uint32]string
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
message = make(map[uint32]string)
|
||||||
|
message[OK] = "SUCCESS"
|
||||||
|
message[SERVER_COMMON_ERROR] = "服务器开小差啦,稍后再来试一试"
|
||||||
|
message[REUQEST_PARAM_ERROR] = "参数错误"
|
||||||
|
message[TOKEN_EXPIRE_ERROR] = "token失效,请重新登陆"
|
||||||
|
message[TOKEN_GENERATE_ERROR] = "生成token失败"
|
||||||
|
message[DB_ERROR] = "数据库繁忙,请稍后再试"
|
||||||
|
message[DB_UPDATE_AFFECTED_ZERO_ERROR] = "更新数据影响行数为0"
|
||||||
|
}
|
||||||
|
|
||||||
|
func MapErrMsg(errcode uint32) string {
|
||||||
|
if msg, ok := message[errcode]; ok {
|
||||||
|
return msg
|
||||||
|
} else {
|
||||||
|
return "服务器开小差啦,稍后再来试一试"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func IsCodeErr(errcode uint32) bool {
|
||||||
|
if _, ok := message[errcode]; ok {
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
39
common/xerr/errors.go
Normal file
39
common/xerr/errors.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package xerr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
常用通用固定错误
|
||||||
|
*/
|
||||||
|
|
||||||
|
type CodeError struct {
|
||||||
|
errCode uint32
|
||||||
|
errMsg string
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回给前端的错误码
|
||||||
|
func (e *CodeError) GetErrCode() uint32 {
|
||||||
|
return e.errCode
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回给前端显示端错误信息
|
||||||
|
func (e *CodeError) GetErrMsg() string {
|
||||||
|
return e.errMsg
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *CodeError) Error() string {
|
||||||
|
return fmt.Sprintf("ErrCode:%d,ErrMsg:%s", e.errCode, e.errMsg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewErrCodeMsg(errCode uint32, errMsg string) *CodeError {
|
||||||
|
return &CodeError{errCode: errCode, errMsg: errMsg}
|
||||||
|
}
|
||||||
|
func NewErrCode(errCode uint32) *CodeError {
|
||||||
|
return &CodeError{errCode: errCode, errMsg: MapErrMsg(errCode)}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewErrMsg(errMsg string) *CodeError {
|
||||||
|
return &CodeError{errCode: CUSTOM_ERROR, errMsg: errMsg}
|
||||||
|
}
|
0
data/.gitkeep
Normal file
0
data/.gitkeep
Normal file
42
deploy/sql/user.sql
Normal file
42
deploy/sql/user.sql
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
SET NAMES utf8mb4;
|
||||||
|
SET FOREIGN_KEY_CHECKS = 0;
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for user
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `user`;
|
||||||
|
CREATE TABLE `user` (
|
||||||
|
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||||
|
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
`delete_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`del_state` tinyint NOT NULL DEFAULT '0',
|
||||||
|
`version` bigint NOT NULL DEFAULT '0' COMMENT '版本号',
|
||||||
|
`mobile` char(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
|
||||||
|
`password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
|
||||||
|
`nickname` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
|
||||||
|
`info` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '',
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `idx_mobile` (`mobile`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户表';
|
||||||
|
|
||||||
|
-- ----------------------------
|
||||||
|
-- Table structure for user_auth
|
||||||
|
-- ----------------------------
|
||||||
|
DROP TABLE IF EXISTS `user_auth`;
|
||||||
|
CREATE TABLE `user_auth` (
|
||||||
|
`id` bigint NOT NULL AUTO_INCREMENT,
|
||||||
|
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
`delete_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`del_state` tinyint NOT NULL DEFAULT '0',
|
||||||
|
`version` bigint NOT NULL DEFAULT '0' COMMENT '版本号',
|
||||||
|
`user_id` bigint NOT NULL DEFAULT '0',
|
||||||
|
`auth_key` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '平台唯一id',
|
||||||
|
`auth_type` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL DEFAULT '' COMMENT '平台类型',
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
UNIQUE KEY `idx_type_key` (`auth_type`,`auth_key`) USING BTREE,
|
||||||
|
UNIQUE KEY `idx_userId_key` (`user_id`,`auth_type`)
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户授权表';
|
||||||
|
|
||||||
|
SET FOREIGN_KEY_CHECKS = 1;
|
9
deploy/template/api/config.tpl
Normal file
9
deploy/template/api/config.tpl
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import {{.authImport}}
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
rest.RestConf
|
||||||
|
{{.auth}}
|
||||||
|
{{.jwtTrans}}
|
||||||
|
}
|
17
deploy/template/api/context.tpl
Normal file
17
deploy/template/api/context.tpl
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package svc
|
||||||
|
|
||||||
|
import (
|
||||||
|
{{.configImport}}
|
||||||
|
)
|
||||||
|
|
||||||
|
type ServiceContext struct {
|
||||||
|
Config {{.config}}
|
||||||
|
{{.middleware}}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewServiceContext(c {{.config}}) *ServiceContext {
|
||||||
|
return &ServiceContext{
|
||||||
|
Config: c,
|
||||||
|
{{.middlewareAssignment}}
|
||||||
|
}
|
||||||
|
}
|
3
deploy/template/api/etc.tpl
Normal file
3
deploy/template/api/etc.tpl
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Name: {{.serviceName}}
|
||||||
|
Host: {{.host}}
|
||||||
|
Port: {{.port}}
|
27
deploy/template/api/handler.tpl
Normal file
27
deploy/template/api/handler.tpl
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package {{.PkgName}}
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"qnc-server/common/result"
|
||||||
|
"qnc-server/pkg/lzkit/validator"
|
||||||
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
|
{{.ImportPackages}}
|
||||||
|
)
|
||||||
|
|
||||||
|
func {{.HandlerName}}(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
{{if .HasRequest}}var req types.{{.RequestType}}
|
||||||
|
if err := httpx.Parse(r, &req); err != nil {
|
||||||
|
result.ParamErrorResult(r,w,err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if err := validator.Validate(req); err != nil {
|
||||||
|
result.ParamValidateErrorResult(r, w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
{{end}}l := {{.LogicName}}.New{{.LogicType}}(r.Context(), svcCtx)
|
||||||
|
{{if .HasResp}}resp, {{end}}err := l.{{.Call}}({{if .HasRequest}}&req{{end}})
|
||||||
|
result.HttpResult(r, w, {{if .HasResp}}resp{{else}}nil{{end}}, err)
|
||||||
|
}
|
||||||
|
}
|
25
deploy/template/api/logic.tpl
Normal file
25
deploy/template/api/logic.tpl
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package {{.pkgName}}
|
||||||
|
|
||||||
|
import (
|
||||||
|
{{.imports}}
|
||||||
|
)
|
||||||
|
|
||||||
|
type {{.logic}} struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
func New{{.logic}}(ctx context.Context, svcCtx *svc.ServiceContext) *{{.logic}} {
|
||||||
|
return &{{.logic}}{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *{{.logic}}) {{.function}}({{.request}}) {{.responseType}} {
|
||||||
|
// todo: add your logic here and delete this line
|
||||||
|
|
||||||
|
{{.returnString}}
|
||||||
|
}
|
27
deploy/template/api/main.tpl
Normal file
27
deploy/template/api/main.tpl
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
{{.importPackages}}
|
||||||
|
"qnc-server/common/middleware"
|
||||||
|
)
|
||||||
|
|
||||||
|
var configFile = flag.String("f", "etc/{{.serviceName}}.yaml", "the config file")
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
var c config.Config
|
||||||
|
conf.MustLoad(*configFile, &c)
|
||||||
|
|
||||||
|
ctx := svc.NewServiceContext(c)
|
||||||
|
server := rest.MustNewServer(c.RestConf)
|
||||||
|
defer server.Stop()
|
||||||
|
|
||||||
|
handler.RegisterHandlers(server, ctx)
|
||||||
|
|
||||||
|
fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
|
||||||
|
server.Start()
|
||||||
|
}
|
20
deploy/template/api/middleware.tpl
Normal file
20
deploy/template/api/middleware.tpl
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
|
||||||
|
package middleware
|
||||||
|
|
||||||
|
import "net/http"
|
||||||
|
|
||||||
|
type {{.name}} struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func New{{.name}}() *{{.name}} {
|
||||||
|
return &{{.name}}{}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *{{.name}})Handle(next http.HandlerFunc) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// TODO generate middleware implement function, delete after code implementation
|
||||||
|
|
||||||
|
// Passthrough to next handler if need
|
||||||
|
next(w, r)
|
||||||
|
}
|
||||||
|
}
|
4
deploy/template/api/route-addition.tpl
Normal file
4
deploy/template/api/route-addition.tpl
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
server.AddRoutes(
|
||||||
|
{{.routes}} {{.jwt}}{{.signature}} {{.prefix}} {{.timeout}} {{.maxBytes}}
|
||||||
|
)
|
13
deploy/template/api/routes.tpl
Normal file
13
deploy/template/api/routes.tpl
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// Code generated by goctl. DO NOT EDIT.
|
||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"{{if .hasTimeout}}
|
||||||
|
"time"{{end}}
|
||||||
|
|
||||||
|
{{.importPackages}}
|
||||||
|
)
|
||||||
|
|
||||||
|
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||||
|
{{.routesAdditions}}
|
||||||
|
}
|
24
deploy/template/api/template.tpl
Normal file
24
deploy/template/api/template.tpl
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
syntax = "v1"
|
||||||
|
|
||||||
|
info (
|
||||||
|
title: // TODO: add title
|
||||||
|
desc: // TODO: add description
|
||||||
|
author: "{{.gitUser}}"
|
||||||
|
email: "{{.gitEmail}}"
|
||||||
|
)
|
||||||
|
|
||||||
|
type request {
|
||||||
|
// TODO: add members here and delete this comment
|
||||||
|
}
|
||||||
|
|
||||||
|
type response {
|
||||||
|
// TODO: add members here and delete this comment
|
||||||
|
}
|
||||||
|
|
||||||
|
service {{.serviceName}} {
|
||||||
|
@handler GetUser // TODO: set handler name and delete this comment
|
||||||
|
get /users/id/:userId(request) returns(response)
|
||||||
|
|
||||||
|
@handler CreateUser // TODO: set handler name and delete this comment
|
||||||
|
post /users/create(request)
|
||||||
|
}
|
6
deploy/template/api/types.tpl
Normal file
6
deploy/template/api/types.tpl
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
// Code generated by goctl. DO NOT EDIT.
|
||||||
|
package types{{if .containsTime}}
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
){{end}}
|
||||||
|
{{.types}}
|
33
deploy/template/docker/docker.tpl
Normal file
33
deploy/template/docker/docker.tpl
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
FROM golang:{{.Version}}alpine AS builder
|
||||||
|
|
||||||
|
LABEL stage=gobuilder
|
||||||
|
|
||||||
|
ENV CGO_ENABLED 0
|
||||||
|
{{if .Chinese}}ENV GOPROXY https://goproxy.cn,direct
|
||||||
|
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
|
||||||
|
{{end}}{{if .HasTimezone}}
|
||||||
|
RUN apk update --no-cache && apk add --no-cache tzdata
|
||||||
|
{{end}}
|
||||||
|
WORKDIR /build
|
||||||
|
|
||||||
|
ADD go.mod .
|
||||||
|
ADD go.sum .
|
||||||
|
RUN go mod download
|
||||||
|
COPY . .
|
||||||
|
{{if .Argument}}COPY {{.GoRelPath}}/etc /app/etc
|
||||||
|
{{end}}RUN go build -ldflags="-s -w" -o /app/{{.ExeFile}} {{.GoMainFrom}}
|
||||||
|
|
||||||
|
|
||||||
|
FROM {{.BaseImage}}
|
||||||
|
|
||||||
|
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
|
||||||
|
{{if .HasTimezone}}COPY --from=builder /usr/share/zoneinfo/{{.Timezone}} /usr/share/zoneinfo/{{.Timezone}}
|
||||||
|
ENV TZ {{.Timezone}}
|
||||||
|
{{end}}
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=builder /app/{{.ExeFile}} /app/{{.ExeFile}}{{if .Argument}}
|
||||||
|
COPY --from=builder /app/etc /app/etc{{end}}
|
||||||
|
{{if .HasPort}}
|
||||||
|
EXPOSE {{.Port}}
|
||||||
|
{{end}}
|
||||||
|
CMD ["./{{.ExeFile}}"{{.Argument}}]
|
18
deploy/template/gateway/etc.tpl
Normal file
18
deploy/template/gateway/etc.tpl
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
Name: gateway-example # gateway name
|
||||||
|
Host: localhost # gateway host
|
||||||
|
Port: 8888 # gateway port
|
||||||
|
Upstreams: # upstreams
|
||||||
|
- Grpc: # grpc upstream
|
||||||
|
Target: 0.0.0.0:8080 # grpc target,the direct grpc server address,for only one node
|
||||||
|
# Endpoints: [0.0.0.0:8080,192.168.120.1:8080] # grpc endpoints, the grpc server address list, for multiple nodes
|
||||||
|
# Etcd: # etcd config, if you want to use etcd to discover the grpc server address
|
||||||
|
# Hosts: [127.0.0.1:2378,127.0.0.1:2379] # etcd hosts
|
||||||
|
# Key: greet.grpc # the discovery key
|
||||||
|
# protoset mode
|
||||||
|
ProtoSets:
|
||||||
|
- hello.pb
|
||||||
|
# Mappings can also be written in proto options
|
||||||
|
# Mappings: # routes mapping
|
||||||
|
# - Method: get
|
||||||
|
# Path: /ping
|
||||||
|
# RpcPath: hello.Hello/Ping
|
20
deploy/template/gateway/main.tpl
Normal file
20
deploy/template/gateway/main.tpl
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/conf"
|
||||||
|
"github.com/zeromicro/go-zero/gateway"
|
||||||
|
)
|
||||||
|
|
||||||
|
var configFile = flag.String("f", "etc/gateway.yaml", "config file")
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
var c gateway.GatewayConf
|
||||||
|
conf.MustLoad(*configFile, &c)
|
||||||
|
gw := gateway.MustNewServer(c)
|
||||||
|
defer gw.Stop()
|
||||||
|
gw.Start()
|
||||||
|
}
|
117
deploy/template/kube/deployment.tpl
Normal file
117
deploy/template/kube/deployment.tpl
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: {{.Name}}
|
||||||
|
namespace: {{.Namespace}}
|
||||||
|
labels:
|
||||||
|
app: {{.Name}}
|
||||||
|
spec:
|
||||||
|
replicas: {{.Replicas}}
|
||||||
|
revisionHistoryLimit: {{.Revisions}}
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: {{.Name}}
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: {{.Name}}
|
||||||
|
spec:{{if .ServiceAccount}}
|
||||||
|
serviceAccountName: {{.ServiceAccount}}{{end}}
|
||||||
|
containers:
|
||||||
|
- name: {{.Name}}
|
||||||
|
image: {{.Image}}
|
||||||
|
{{if .ImagePullPolicy}}imagePullPolicy: {{.ImagePullPolicy}}
|
||||||
|
{{end}}ports:
|
||||||
|
- containerPort: {{.Port}}
|
||||||
|
readinessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: {{.Port}}
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 10
|
||||||
|
livenessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: {{.Port}}
|
||||||
|
initialDelaySeconds: 15
|
||||||
|
periodSeconds: 20
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: {{.RequestCpu}}m
|
||||||
|
memory: {{.RequestMem}}Mi
|
||||||
|
limits:
|
||||||
|
cpu: {{.LimitCpu}}m
|
||||||
|
memory: {{.LimitMem}}Mi
|
||||||
|
volumeMounts:
|
||||||
|
- name: timezone
|
||||||
|
mountPath: /etc/localtime
|
||||||
|
{{if .Secret}}imagePullSecrets:
|
||||||
|
- name: {{.Secret}}
|
||||||
|
{{end}}volumes:
|
||||||
|
- name: timezone
|
||||||
|
hostPath:
|
||||||
|
path: /usr/share/zoneinfo/Asia/Shanghai
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: {{.Name}}-svc
|
||||||
|
namespace: {{.Namespace}}
|
||||||
|
spec:
|
||||||
|
ports:
|
||||||
|
{{if .UseNodePort}}- nodePort: {{.NodePort}}
|
||||||
|
port: {{.Port}}
|
||||||
|
protocol: TCP
|
||||||
|
targetPort: {{.TargetPort}}
|
||||||
|
type: NodePort{{else}}- port: {{.Port}}
|
||||||
|
targetPort: {{.TargetPort}}{{end}}
|
||||||
|
selector:
|
||||||
|
app: {{.Name}}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
apiVersion: autoscaling/v2beta2
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: {{.Name}}-hpa-c
|
||||||
|
namespace: {{.Namespace}}
|
||||||
|
labels:
|
||||||
|
app: {{.Name}}-hpa-c
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: {{.Name}}
|
||||||
|
minReplicas: {{.MinReplicas}}
|
||||||
|
maxReplicas: {{.MaxReplicas}}
|
||||||
|
metrics:
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: cpu
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: 80
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
apiVersion: autoscaling/v2beta2
|
||||||
|
kind: HorizontalPodAutoscaler
|
||||||
|
metadata:
|
||||||
|
name: {{.Name}}-hpa-m
|
||||||
|
namespace: {{.Namespace}}
|
||||||
|
labels:
|
||||||
|
app: {{.Name}}-hpa-m
|
||||||
|
spec:
|
||||||
|
scaleTargetRef:
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
name: {{.Name}}
|
||||||
|
minReplicas: {{.MinReplicas}}
|
||||||
|
maxReplicas: {{.MaxReplicas}}
|
||||||
|
metrics:
|
||||||
|
- type: Resource
|
||||||
|
resource:
|
||||||
|
name: memory
|
||||||
|
target:
|
||||||
|
type: Utilization
|
||||||
|
averageUtilization: 80
|
37
deploy/template/kube/job.tpl
Normal file
37
deploy/template/kube/job.tpl
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
apiVersion: batch/v1
|
||||||
|
kind: CronJob
|
||||||
|
metadata:
|
||||||
|
name: {{.Name}}
|
||||||
|
namespace: {{.Namespace}}
|
||||||
|
spec:
|
||||||
|
successfulJobsHistoryLimit: {{.SuccessfulJobsHistoryLimit}}
|
||||||
|
schedule: "{{.Schedule}}"
|
||||||
|
jobTemplate:
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:{{if .ServiceAccount}}
|
||||||
|
serviceAccountName: {{.ServiceAccount}}{{end}}
|
||||||
|
{{end}}containers:
|
||||||
|
- name: {{.Name}}
|
||||||
|
image: # todo image url
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: {{.RequestCpu}}m
|
||||||
|
memory: {{.RequestMem}}Mi
|
||||||
|
limits:
|
||||||
|
cpu: {{.LimitCpu}}m
|
||||||
|
memory: {{.LimitMem}}Mi
|
||||||
|
command:
|
||||||
|
- ./{{.ServiceName}}
|
||||||
|
- -f
|
||||||
|
- ./{{.Name}}.yaml
|
||||||
|
volumeMounts:
|
||||||
|
- name: timezone
|
||||||
|
mountPath: /etc/localtime
|
||||||
|
imagePullSecrets:
|
||||||
|
- name: # registry secret, if no, remove this
|
||||||
|
restartPolicy: OnFailure
|
||||||
|
volumes:
|
||||||
|
- name: timezone
|
||||||
|
hostPath:
|
||||||
|
path: /usr/share/zoneinfo/Asia/Shanghai
|
21
deploy/template/model/delete.tpl
Normal file
21
deploy/template/model/delete.tpl
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
func (m *default{{.upperStartCamelObject}}Model) Delete(ctx context.Context, session sqlx.Session, {{.lowerStartCamelPrimaryKey}} {{.dataType}}) error {
|
||||||
|
{{if .withCache}}{{if .containsIndexCache}}data, err:=m.FindOne(ctx, {{.lowerStartCamelPrimaryKey}})
|
||||||
|
if err!=nil{
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
{{end}} {{.keys}}
|
||||||
|
_, err {{if .containsIndexCache}}={{else}}:={{end}} m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||||
|
query := fmt.Sprintf("delete from %s where {{.originalPrimaryKey}} = {{if .postgreSql}}$1{{else}}?{{end}}", m.table)
|
||||||
|
if session!=nil{
|
||||||
|
return session.ExecCtx(ctx,query, {{.lowerStartCamelPrimaryKey}})
|
||||||
|
}
|
||||||
|
return conn.ExecCtx(ctx, query, {{.lowerStartCamelPrimaryKey}})
|
||||||
|
}, {{.keyValues}}){{else}}query := fmt.Sprintf("delete from %s where {{.originalPrimaryKey}} = {{if .postgreSql}}$1{{else}}?{{end}}", m.table)
|
||||||
|
if session!=nil{
|
||||||
|
_,err:= session.ExecCtx(ctx,query, {{.lowerStartCamelPrimaryKey}})
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_,err:=m.conn.ExecCtx(ctx, query, {{.lowerStartCamelPrimaryKey}}){{end}}
|
||||||
|
return err
|
||||||
|
}
|
9
deploy/template/model/err.tpl
Normal file
9
deploy/template/model/err.tpl
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
package {{.pkg}}
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ErrNotFound = sqlx.ErrNotFound
|
||||||
|
var ErrNoRowsUpdate = errors.New("update db no rows change")
|
1
deploy/template/model/field.tpl
Normal file
1
deploy/template/model/field.tpl
Normal file
@ -0,0 +1 @@
|
|||||||
|
{{.name}} {{.type}} {{.tag}} {{if .hasComment}}// {{.comment}}{{end}}
|
7
deploy/template/model/find-one-by-field-extra-method.tpl
Normal file
7
deploy/template/model/find-one-by-field-extra-method.tpl
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
func (m *default{{.upperStartCamelObject}}Model) formatPrimary(primary interface{}) string {
|
||||||
|
return fmt.Sprintf("%s%v", {{.primaryKeyLeft}}, primary)
|
||||||
|
}
|
||||||
|
func (m *default{{.upperStartCamelObject}}Model) queryPrimary(ctx context.Context, conn sqlx.SqlConn, v, primary interface{}) error {
|
||||||
|
query := fmt.Sprintf("select %s from %s where {{.originalPrimaryField}} = {{if .postgreSql}}$1{{else}}?{{end}} and del_state = ? limit 1", {{.lowerStartCamelObject}}Rows, m.table )
|
||||||
|
return conn.QueryRowCtx(ctx, v, query, primary,globalkey.DelStateNo)
|
||||||
|
}
|
32
deploy/template/model/find-one-by-field.tpl
Normal file
32
deploy/template/model/find-one-by-field.tpl
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
func (m *default{{.upperStartCamelObject}}Model) FindOneBy{{.upperField}}(ctx context.Context, {{.in}}) (*{{.upperStartCamelObject}}, error) {
|
||||||
|
{{if .withCache}}{{.cacheKey}}
|
||||||
|
var resp {{.upperStartCamelObject}}
|
||||||
|
err := m.QueryRowIndexCtx(ctx, &resp, {{.cacheKeyVariable}}, m.formatPrimary, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) (i interface{}, e error) {
|
||||||
|
query := fmt.Sprintf("select %s from %s where {{.originalField}} and del_state = ? limit 1", {{.lowerStartCamelObject}}Rows, m.table)
|
||||||
|
if err := conn.QueryRowCtx(ctx, &resp, query, {{.lowerStartCamelField}},globalkey.DelStateNo); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return resp.{{.upperStartCamelPrimaryKey}}, nil
|
||||||
|
}, m.queryPrimary)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return &resp, nil
|
||||||
|
case sqlc.ErrNotFound:
|
||||||
|
return nil, ErrNotFound
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}{{else}}var resp {{.upperStartCamelObject}}
|
||||||
|
query := fmt.Sprintf("select %s from %s where {{.originalField}} and del_state = ? limit 1", {{.lowerStartCamelObject}}Rows, m.table )
|
||||||
|
err := m.conn.QueryRowCtx(ctx, &resp, query, {{.lowerStartCamelField}},globalkey.DelStateNo)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return &resp, nil
|
||||||
|
case sqlc.ErrNotFound:
|
||||||
|
return nil, ErrNotFound
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}{{end}}
|
||||||
|
|
26
deploy/template/model/find-one.tpl
Normal file
26
deploy/template/model/find-one.tpl
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
func (m *default{{.upperStartCamelObject}}Model) FindOne(ctx context.Context, {{.lowerStartCamelPrimaryKey}} {{.dataType}}) (*{{.upperStartCamelObject}}, error) {
|
||||||
|
{{if .withCache}}{{.cacheKey}}
|
||||||
|
var resp {{.upperStartCamelObject}}
|
||||||
|
err := m.QueryRowCtx(ctx, &resp, {{.cacheKeyVariable}}, func(ctx context.Context, conn sqlx.SqlConn, v interface{}) error {
|
||||||
|
query := fmt.Sprintf("select %s from %s where {{.originalPrimaryKey}} = {{if .postgreSql}}$1{{else}}?{{end}} and del_state = ? limit 1", {{.lowerStartCamelObject}}Rows, m.table)
|
||||||
|
return conn.QueryRowCtx(ctx, v, query, {{.lowerStartCamelPrimaryKey}},globalkey.DelStateNo)
|
||||||
|
})
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return &resp, nil
|
||||||
|
case sqlc.ErrNotFound:
|
||||||
|
return nil, ErrNotFound
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}{{else}}query := fmt.Sprintf("select %s from %s where {{.originalPrimaryKey}} = {{if .postgreSql}}$1{{else}}?{{end}} and del_state = ? limit 1", {{.lowerStartCamelObject}}Rows, m.table)
|
||||||
|
var resp {{.upperStartCamelObject}}
|
||||||
|
err := m.conn.QueryRowCtx(ctx, &resp, query, {{.lowerStartCamelPrimaryKey}},globalkey.DelStateNo)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return &resp, nil
|
||||||
|
case sqlc.ErrNotFound:
|
||||||
|
return nil, ErrNotFound
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}{{end}}
|
||||||
|
}
|
16
deploy/template/model/import-no-cache.tpl
Normal file
16
deploy/template/model/import-no-cache.tpl
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
{{if .time}}"time"{{end}}
|
||||||
|
|
||||||
|
"qnc-server/common/globalkey"
|
||||||
|
"github.com/Masterminds/squirrel"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/builder"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlc"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
"github.com/zeromicro/go-zero/core/stringx"
|
||||||
|
)
|
17
deploy/template/model/import.tpl
Normal file
17
deploy/template/model/import.tpl
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
{{if .time}}"time"{{end}}
|
||||||
|
|
||||||
|
"qnc-server/common/globalkey"
|
||||||
|
"github.com/Masterminds/squirrel"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/builder"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlc"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
"github.com/zeromicro/go-zero/core/stringx"
|
||||||
|
)
|
18
deploy/template/model/insert.tpl
Normal file
18
deploy/template/model/insert.tpl
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
func (m *default{{.upperStartCamelObject}}Model) Insert(ctx context.Context,session sqlx.Session, data *{{.upperStartCamelObject}}) (sql.Result,error) {
|
||||||
|
data.DeleteTime = time.Unix(0,0)
|
||||||
|
data.DelState = globalkey.DelStateNo
|
||||||
|
{{if .withCache}}{{.keys}}
|
||||||
|
return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||||
|
query := fmt.Sprintf("insert into %s (%s) values ({{.expression}})", m.table, {{.lowerStartCamelObject}}RowsExpectAutoSet)
|
||||||
|
if session != nil{
|
||||||
|
return session.ExecCtx(ctx,query,{{.expressionValues}})
|
||||||
|
}
|
||||||
|
return conn.ExecCtx(ctx, query, {{.expressionValues}})
|
||||||
|
}, {{.keyValues}}){{else}}
|
||||||
|
query := fmt.Sprintf("insert into %s (%s) values ({{.expression}})", m.table, {{.lowerStartCamelObject}}RowsExpectAutoSet)
|
||||||
|
if session != nil{
|
||||||
|
return session.ExecCtx(ctx,query,{{.expressionValues}})
|
||||||
|
}
|
||||||
|
return m.conn.ExecCtx(ctx, query, {{.expressionValues}}){{end}}
|
||||||
|
}
|
1
deploy/template/model/interface-delete.tpl
Normal file
1
deploy/template/model/interface-delete.tpl
Normal file
@ -0,0 +1 @@
|
|||||||
|
Delete(ctx context.Context,session sqlx.Session, {{.lowerStartCamelPrimaryKey}} {{.dataType}}) error
|
1
deploy/template/model/interface-find-one-by-field.tpl
Normal file
1
deploy/template/model/interface-find-one-by-field.tpl
Normal file
@ -0,0 +1 @@
|
|||||||
|
FindOneBy{{.upperField}}(ctx context.Context, {{.in}}) (*{{.upperStartCamelObject}}, error)
|
1
deploy/template/model/interface-find-one.tpl
Normal file
1
deploy/template/model/interface-find-one.tpl
Normal file
@ -0,0 +1 @@
|
|||||||
|
FindOne(ctx context.Context, {{.lowerStartCamelPrimaryKey}} {{.dataType}}) (*{{.upperStartCamelObject}}, error)
|
1
deploy/template/model/interface-insert.tpl
Normal file
1
deploy/template/model/interface-insert.tpl
Normal file
@ -0,0 +1 @@
|
|||||||
|
Insert(ctx context.Context, session sqlx.Session,data *{{.upperStartCamelObject}}) (sql.Result,error)
|
12
deploy/template/model/interface-update.tpl
Normal file
12
deploy/template/model/interface-update.tpl
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
Update(ctx context.Context,session sqlx.Session, data *{{.upperStartCamelObject}}) (sql.Result, error)
|
||||||
|
UpdateWithVersion(ctx context.Context,session sqlx.Session,data *{{.upperStartCamelObject}}) error
|
||||||
|
Trans(ctx context.Context,fn func(context context.Context,session sqlx.Session) error) error
|
||||||
|
SelectBuilder() squirrel.SelectBuilder
|
||||||
|
DeleteSoft(ctx context.Context,session sqlx.Session, data *{{.upperStartCamelObject}}) error
|
||||||
|
FindSum(ctx context.Context,sumBuilder squirrel.SelectBuilder,field string) (float64,error)
|
||||||
|
FindCount(ctx context.Context,countBuilder squirrel.SelectBuilder,field string) (int64,error)
|
||||||
|
FindAll(ctx context.Context,rowBuilder squirrel.SelectBuilder,orderBy string) ([]*{{.upperStartCamelObject}},error)
|
||||||
|
FindPageListByPage(ctx context.Context,rowBuilder squirrel.SelectBuilder,page ,pageSize int64,orderBy string) ([]*{{.upperStartCamelObject}},error)
|
||||||
|
FindPageListByPageWithTotal(ctx context.Context, rowBuilder squirrel.SelectBuilder, page, pageSize int64, orderBy string) ([]*{{.upperStartCamelObject}}, int64, error)
|
||||||
|
FindPageListByIdDESC(ctx context.Context,rowBuilder squirrel.SelectBuilder ,preMinId ,pageSize int64) ([]*{{.upperStartCamelObject}},error)
|
||||||
|
FindPageListByIdASC(ctx context.Context,rowBuilder squirrel.SelectBuilder,preMaxId ,pageSize int64) ([]*{{.upperStartCamelObject}},error)
|
13
deploy/template/model/model-gen.tpl
Normal file
13
deploy/template/model/model-gen.tpl
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
// Code generated by goctl. DO NOT EDIT!
|
||||||
|
|
||||||
|
package {{.pkg}}
|
||||||
|
{{.imports}}
|
||||||
|
{{.vars}}
|
||||||
|
{{.types}}
|
||||||
|
{{.new}}
|
||||||
|
{{.insert}}
|
||||||
|
{{.find}}
|
||||||
|
{{.update}}
|
||||||
|
{{.delete}}
|
||||||
|
{{.extraMethod}}
|
||||||
|
{{.tableName}}
|
7
deploy/template/model/model-new.tpl
Normal file
7
deploy/template/model/model-new.tpl
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
|
||||||
|
func new{{.upperStartCamelObject}}Model(conn sqlx.SqlConn{{if .withCache}}, c cache.CacheConf{{end}}) *default{{.upperStartCamelObject}}Model {
|
||||||
|
return &default{{.upperStartCamelObject}}Model{
|
||||||
|
{{if .withCache}}CachedConn: sqlc.NewConn(conn, c){{else}}conn:conn{{end}},
|
||||||
|
table: {{.table}},
|
||||||
|
}
|
||||||
|
}
|
37
deploy/template/model/model.tpl
Normal file
37
deploy/template/model/model.tpl
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
package {{.pkg}}
|
||||||
|
{{if .withCache}}
|
||||||
|
import (
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
|
||||||
|
)
|
||||||
|
{{else}}
|
||||||
|
import (
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
{{end}}
|
||||||
|
var _ {{.upperStartCamelObject}}Model = (*custom{{.upperStartCamelObject}}Model)(nil)
|
||||||
|
|
||||||
|
type (
|
||||||
|
// {{.upperStartCamelObject}}Model is an interface to be customized, add more methods here,
|
||||||
|
// and implement the added methods in custom{{.upperStartCamelObject}}Model.
|
||||||
|
{{.upperStartCamelObject}}Model interface {
|
||||||
|
{{.lowerStartCamelObject}}Model
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
custom{{.upperStartCamelObject}}Model struct {
|
||||||
|
*default{{.upperStartCamelObject}}Model
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// New{{.upperStartCamelObject}}Model returns a model for the database table.
|
||||||
|
func New{{.upperStartCamelObject}}Model(conn sqlx.SqlConn{{if .withCache}}, c cache.CacheConf{{end}}) {{.upperStartCamelObject}}Model {
|
||||||
|
return &custom{{.upperStartCamelObject}}Model{
|
||||||
|
default{{.upperStartCamelObject}}Model: new{{.upperStartCamelObject}}Model(conn{{if .withCache}}, c{{end}}),
|
||||||
|
}
|
||||||
|
}
|
4
deploy/template/model/table-name.tpl
Normal file
4
deploy/template/model/table-name.tpl
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
func (m *default{{.upperStartCamelObject}}Model) tableName() string {
|
||||||
|
return m.table
|
||||||
|
}
|
1
deploy/template/model/tag.tpl
Normal file
1
deploy/template/model/tag.tpl
Normal file
@ -0,0 +1 @@
|
|||||||
|
`db:"{{.field}}"`
|
15
deploy/template/model/types.tpl
Normal file
15
deploy/template/model/types.tpl
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
type (
|
||||||
|
{{.lowerStartCamelObject}}Model interface{
|
||||||
|
{{.method}}
|
||||||
|
}
|
||||||
|
|
||||||
|
default{{.upperStartCamelObject}}Model struct {
|
||||||
|
{{if .withCache}}sqlc.CachedConn{{else}}conn sqlx.SqlConn{{end}}
|
||||||
|
table string
|
||||||
|
}
|
||||||
|
|
||||||
|
{{.upperStartCamelObject}} struct {
|
||||||
|
{{.fields}}
|
||||||
|
}
|
||||||
|
)
|
286
deploy/template/model/update.tpl
Normal file
286
deploy/template/model/update.tpl
Normal file
@ -0,0 +1,286 @@
|
|||||||
|
|
||||||
|
func (m *default{{.upperStartCamelObject}}Model) Update(ctx context.Context,session sqlx.Session, {{if .containsIndexCache}}newData{{else}}data{{end}} *{{.upperStartCamelObject}}) (sql.Result,error) {
|
||||||
|
{{if .withCache}}{{if .containsIndexCache}}data, err:=m.FindOne(ctx, newData.{{.upperStartCamelPrimaryKey}})
|
||||||
|
if err!=nil{
|
||||||
|
return nil,err
|
||||||
|
}
|
||||||
|
{{end}}{{.keys}}
|
||||||
|
return m.ExecCtx(ctx, func(ctx context.Context, conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||||
|
query := fmt.Sprintf("update %s set %s where {{.originalPrimaryKey}} = {{if .postgreSql}}$1{{else}}?{{end}}", m.table, {{.lowerStartCamelObject}}RowsWithPlaceHolder)
|
||||||
|
if session != nil{
|
||||||
|
return session.ExecCtx(ctx,query, {{.expressionValues}})
|
||||||
|
}
|
||||||
|
return conn.ExecCtx(ctx, query, {{.expressionValues}})
|
||||||
|
}, {{.keyValues}}){{else}}query := fmt.Sprintf("update %s set %s where {{.originalPrimaryKey}} = {{if .postgreSql}}$1{{else}}?{{end}}", m.table, {{.lowerStartCamelObject}}RowsWithPlaceHolder)
|
||||||
|
if session != nil{
|
||||||
|
return session.ExecCtx(ctx,query, {{.expressionValues}})
|
||||||
|
}
|
||||||
|
return m.conn.ExecCtx(ctx, query, {{.expressionValues}}){{end}}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *default{{.upperStartCamelObject}}Model) UpdateWithVersion(ctx context.Context,session sqlx.Session,{{if .containsIndexCache}}newData{{else}}data{{end}} *{{.upperStartCamelObject}}) error {
|
||||||
|
|
||||||
|
{{if .containsIndexCache}}
|
||||||
|
oldVersion := newData.Version
|
||||||
|
newData.Version += 1
|
||||||
|
{{else}}
|
||||||
|
oldVersion := data.Version
|
||||||
|
data.Version += 1
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
var sqlResult sql.Result
|
||||||
|
var err error
|
||||||
|
|
||||||
|
{{if .withCache}}{{if .containsIndexCache}}data, err:=m.FindOne(ctx, newData.{{.upperStartCamelPrimaryKey}})
|
||||||
|
if err!=nil{
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
{{end}}{{.keys}}
|
||||||
|
sqlResult,err = m.ExecCtx(ctx,func(ctx context.Context,conn sqlx.SqlConn) (result sql.Result, err error) {
|
||||||
|
query := fmt.Sprintf("update %s set %s where {{.originalPrimaryKey}} = {{if .postgreSql}}$1{{else}}?{{end}} and version = ? ", m.table, {{.lowerStartCamelObject}}RowsWithPlaceHolder)
|
||||||
|
if session != nil{
|
||||||
|
return session.ExecCtx(ctx,query, {{.expressionValues}},oldVersion)
|
||||||
|
}
|
||||||
|
return conn.ExecCtx(ctx,query, {{.expressionValues}},oldVersion)
|
||||||
|
}, {{.keyValues}}){{else}}query := fmt.Sprintf("update %s set %s where {{.originalPrimaryKey}} = {{if .postgreSql}}$1{{else}}?{{end}} and version = ? ", m.table, {{.lowerStartCamelObject}}RowsWithPlaceHolder)
|
||||||
|
if session != nil{
|
||||||
|
sqlResult,err = session.ExecCtx(ctx,query, {{.expressionValues}},oldVersion)
|
||||||
|
}else{
|
||||||
|
sqlResult,err = m.conn.ExecCtx(ctx,query, {{.expressionValues}},oldVersion)
|
||||||
|
}
|
||||||
|
{{end}}
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
updateCount , err := sqlResult.RowsAffected()
|
||||||
|
if err != nil{
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if updateCount == 0 {
|
||||||
|
return ErrNoRowsUpdate
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *default{{.upperStartCamelObject}}Model) DeleteSoft(ctx context.Context,session sqlx.Session,data *{{.upperStartCamelObject}}) error {
|
||||||
|
data.DelState = globalkey.DelStateYes
|
||||||
|
data.DeleteTime = time.Now()
|
||||||
|
if err:= m.UpdateWithVersion(ctx,session, data);err!= nil{
|
||||||
|
return errors.Wrapf(errors.New("delete soft failed "),"{{.upperStartCamelObject}}Model delete err : %+v",err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *default{{.upperStartCamelObject}}Model) FindSum(ctx context.Context,builder squirrel.SelectBuilder, field string) (float64,error) {
|
||||||
|
|
||||||
|
if len(field) == 0 {
|
||||||
|
return 0, errors.Wrapf(errors.New("FindSum Least One Field"), "FindSum Least One Field")
|
||||||
|
}
|
||||||
|
|
||||||
|
builder = builder.Columns("IFNULL(SUM(" + field + "),0)")
|
||||||
|
|
||||||
|
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).ToSql()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp float64
|
||||||
|
{{if .withCache}}err = m.QueryRowNoCacheCtx(ctx,&resp, query, values...){{else}}
|
||||||
|
err = m.conn.QueryRowCtx(ctx,&resp, query, values...)
|
||||||
|
{{end}}
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return resp, nil
|
||||||
|
default:
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *default{{.upperStartCamelObject}}Model) FindCount(ctx context.Context, builder squirrel.SelectBuilder, field string) (int64,error) {
|
||||||
|
|
||||||
|
if len(field) == 0 {
|
||||||
|
return 0, errors.Wrapf(errors.New("FindCount Least One Field"), "FindCount Least One Field")
|
||||||
|
}
|
||||||
|
|
||||||
|
builder = builder.Columns("COUNT(" + field + ")")
|
||||||
|
|
||||||
|
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).ToSql()
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp int64
|
||||||
|
{{if .withCache}}err = m.QueryRowNoCacheCtx(ctx,&resp, query, values...){{else}}
|
||||||
|
err = m.conn.QueryRowCtx(ctx,&resp, query, values...)
|
||||||
|
{{end}}
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return resp, nil
|
||||||
|
default:
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *default{{.upperStartCamelObject}}Model) FindAll(ctx context.Context,builder squirrel.SelectBuilder,orderBy string) ([]*{{.upperStartCamelObject}},error) {
|
||||||
|
|
||||||
|
builder = builder.Columns({{.lowerStartCamelObject}}Rows)
|
||||||
|
|
||||||
|
if orderBy == ""{
|
||||||
|
builder = builder.OrderBy("id DESC")
|
||||||
|
}else{
|
||||||
|
builder = builder.OrderBy(orderBy)
|
||||||
|
}
|
||||||
|
|
||||||
|
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).ToSql()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp []*{{.upperStartCamelObject}}
|
||||||
|
{{if .withCache}}err = m.QueryRowsNoCacheCtx(ctx,&resp, query, values...){{else}}
|
||||||
|
err = m.conn.QueryRowsCtx(ctx,&resp, query, values...)
|
||||||
|
{{end}}
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return resp, nil
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *default{{.upperStartCamelObject}}Model) FindPageListByPage(ctx context.Context,builder squirrel.SelectBuilder,page ,pageSize int64,orderBy string) ([]*{{.upperStartCamelObject}},error) {
|
||||||
|
|
||||||
|
builder = builder.Columns({{.lowerStartCamelObject}}Rows)
|
||||||
|
|
||||||
|
if orderBy == ""{
|
||||||
|
builder = builder.OrderBy("id DESC")
|
||||||
|
}else{
|
||||||
|
builder = builder.OrderBy(orderBy)
|
||||||
|
}
|
||||||
|
|
||||||
|
if page < 1{
|
||||||
|
page = 1
|
||||||
|
}
|
||||||
|
offset := (page - 1) * pageSize
|
||||||
|
|
||||||
|
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).Offset(uint64(offset)).Limit(uint64(pageSize)).ToSql()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp []*{{.upperStartCamelObject}}
|
||||||
|
{{if .withCache}}err = m.QueryRowsNoCacheCtx(ctx,&resp, query, values...){{else}}
|
||||||
|
err = m.conn.QueryRowsCtx(ctx,&resp, query, values...)
|
||||||
|
{{end}}
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return resp, nil
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (m *default{{.upperStartCamelObject}}Model) FindPageListByPageWithTotal(ctx context.Context,builder squirrel.SelectBuilder,page ,pageSize int64,orderBy string) ([]*{{.upperStartCamelObject}},int64,error) {
|
||||||
|
|
||||||
|
total, err := m.FindCount(ctx, builder, "id")
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
builder = builder.Columns({{.lowerStartCamelObject}}Rows)
|
||||||
|
|
||||||
|
if orderBy == ""{
|
||||||
|
builder = builder.OrderBy("id DESC")
|
||||||
|
}else{
|
||||||
|
builder = builder.OrderBy(orderBy)
|
||||||
|
}
|
||||||
|
|
||||||
|
if page < 1{
|
||||||
|
page = 1
|
||||||
|
}
|
||||||
|
offset := (page - 1) * pageSize
|
||||||
|
|
||||||
|
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).Offset(uint64(offset)).Limit(uint64(pageSize)).ToSql()
|
||||||
|
if err != nil {
|
||||||
|
return nil,total, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp []*{{.upperStartCamelObject}}
|
||||||
|
{{if .withCache}}err = m.QueryRowsNoCacheCtx(ctx,&resp, query, values...){{else}}
|
||||||
|
err = m.conn.QueryRowsCtx(ctx,&resp, query, values...)
|
||||||
|
{{end}}
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return resp,total, nil
|
||||||
|
default:
|
||||||
|
return nil,total, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *default{{.upperStartCamelObject}}Model) FindPageListByIdDESC(ctx context.Context,builder squirrel.SelectBuilder ,preMinId ,pageSize int64) ([]*{{.upperStartCamelObject}},error) {
|
||||||
|
|
||||||
|
builder = builder.Columns({{.lowerStartCamelObject}}Rows)
|
||||||
|
|
||||||
|
if preMinId > 0 {
|
||||||
|
builder = builder.Where(" id < ? " , preMinId)
|
||||||
|
}
|
||||||
|
|
||||||
|
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).OrderBy("id DESC").Limit(uint64(pageSize)).ToSql()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp []*{{.upperStartCamelObject}}
|
||||||
|
{{if .withCache}}err = m.QueryRowsNoCacheCtx(ctx,&resp, query, values...){{else}}
|
||||||
|
err = m.conn.QueryRowsCtx(ctx,&resp, query, values...)
|
||||||
|
{{end}}
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return resp, nil
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *default{{.upperStartCamelObject}}Model) FindPageListByIdASC(ctx context.Context,builder squirrel.SelectBuilder,preMaxId ,pageSize int64) ([]*{{.upperStartCamelObject}},error) {
|
||||||
|
|
||||||
|
builder = builder.Columns({{.lowerStartCamelObject}}Rows)
|
||||||
|
|
||||||
|
if preMaxId > 0 {
|
||||||
|
builder = builder.Where(" id > ? " , preMaxId)
|
||||||
|
}
|
||||||
|
|
||||||
|
query, values, err := builder.Where("del_state = ?", globalkey.DelStateNo).OrderBy("id ASC").Limit(uint64(pageSize)).ToSql()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var resp []*{{.upperStartCamelObject}}
|
||||||
|
{{if .withCache}}err = m.QueryRowsNoCacheCtx(ctx,&resp, query, values...){{else}}
|
||||||
|
err = m.conn.QueryRowsCtx(ctx,&resp, query, values...)
|
||||||
|
{{end}}
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return resp, nil
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *default{{.upperStartCamelObject}}Model) Trans(ctx context.Context,fn func(ctx context.Context,session sqlx.Session) error) error {
|
||||||
|
{{if .withCache}}
|
||||||
|
return m.TransactCtx(ctx,func(ctx context.Context,session sqlx.Session) error {
|
||||||
|
return fn(ctx,session)
|
||||||
|
})
|
||||||
|
{{else}}
|
||||||
|
return m.conn.TransactCtx(ctx,func(ctx context.Context,session sqlx.Session) error {
|
||||||
|
return fn(ctx,session)
|
||||||
|
})
|
||||||
|
{{end}}
|
||||||
|
}
|
||||||
|
|
||||||
|
func(m *default{{.upperStartCamelObject}}Model) SelectBuilder() squirrel.SelectBuilder {
|
||||||
|
return squirrel.Select().From(m.table)
|
||||||
|
}
|
9
deploy/template/model/var.tpl
Normal file
9
deploy/template/model/var.tpl
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
var (
|
||||||
|
{{.lowerStartCamelObject}}FieldNames = builder.RawFieldNames(&{{.upperStartCamelObject}}{}{{if .postgreSql}},true{{end}})
|
||||||
|
{{.lowerStartCamelObject}}Rows = strings.Join({{.lowerStartCamelObject}}FieldNames, ",")
|
||||||
|
{{.lowerStartCamelObject}}RowsExpectAutoSet = {{if .postgreSql}}strings.Join(stringx.Remove({{.lowerStartCamelObject}}FieldNames, {{if .autoIncrement}}"{{.originalPrimaryKey}}",{{end}} "create_time", "update_time"), ","){{else}}strings.Join(stringx.Remove({{.lowerStartCamelObject}}FieldNames, {{if .autoIncrement}}"{{.originalPrimaryKey}}",{{end}} "`create_time`", "`update_time`"), ","){{end}}
|
||||||
|
{{.lowerStartCamelObject}}RowsWithPlaceHolder = {{if .postgreSql}}builder.PostgreSqlJoin(stringx.Remove({{.lowerStartCamelObject}}FieldNames, "{{.originalPrimaryKey}}", "create_time", "update_time")){{else}}strings.Join(stringx.Remove({{.lowerStartCamelObject}}FieldNames, "{{.originalPrimaryKey}}", "`create_time`", "`update_time`"), "=?,") + "=?"{{end}}
|
||||||
|
|
||||||
|
{{if .withCache}}{{.cacheKeys}}{{end}}
|
||||||
|
)
|
12
deploy/template/mongo/err.tpl
Normal file
12
deploy/template/mongo/err.tpl
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/mon"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrNotFound = mon.ErrNotFound
|
||||||
|
ErrInvalidObjectId = errors.New("invalid objectId")
|
||||||
|
)
|
78
deploy/template/mongo/model.tpl
Normal file
78
deploy/template/mongo/model.tpl
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
// Code generated by goctl. DO NOT EDIT.
|
||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
{{if .Cache}}"github.com/zeromicro/go-zero/core/stores/monc"{{else}}"github.com/zeromicro/go-zero/core/stores/mon"{{end}}
|
||||||
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
|
)
|
||||||
|
|
||||||
|
{{if .Cache}}var prefix{{.Type}}CacheKey = "cache:{{.lowerType}}:"{{end}}
|
||||||
|
|
||||||
|
type {{.lowerType}}Model interface{
|
||||||
|
Insert(ctx context.Context,data *{{.Type}}) error
|
||||||
|
FindOne(ctx context.Context,id string) (*{{.Type}}, error)
|
||||||
|
Update(ctx context.Context,data *{{.Type}}) (*mongo.UpdateResult, error)
|
||||||
|
Delete(ctx context.Context,id string) (int64, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type default{{.Type}}Model struct {
|
||||||
|
conn {{if .Cache}}*monc.Model{{else}}*mon.Model{{end}}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newDefault{{.Type}}Model(conn {{if .Cache}}*monc.Model{{else}}*mon.Model{{end}}) *default{{.Type}}Model {
|
||||||
|
return &default{{.Type}}Model{conn: conn}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (m *default{{.Type}}Model) Insert(ctx context.Context, data *{{.Type}}) error {
|
||||||
|
if data.ID.IsZero() {
|
||||||
|
data.ID = primitive.NewObjectID()
|
||||||
|
data.CreateAt = time.Now()
|
||||||
|
data.UpdateAt = time.Now()
|
||||||
|
}
|
||||||
|
|
||||||
|
{{if .Cache}}key := prefix{{.Type}}CacheKey + data.ID.Hex(){{end}}
|
||||||
|
_, err := m.conn.InsertOne(ctx, {{if .Cache}}key, {{end}} data)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *default{{.Type}}Model) FindOne(ctx context.Context, id string) (*{{.Type}}, error) {
|
||||||
|
oid, err := primitive.ObjectIDFromHex(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, ErrInvalidObjectId
|
||||||
|
}
|
||||||
|
|
||||||
|
var data {{.Type}}
|
||||||
|
{{if .Cache}}key := prefix{{.Type}}CacheKey + id{{end}}
|
||||||
|
err = m.conn.FindOne(ctx, {{if .Cache}}key, {{end}}&data, bson.M{"_id": oid})
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return &data, nil
|
||||||
|
case {{if .Cache}}monc{{else}}mon{{end}}.ErrNotFound:
|
||||||
|
return nil, ErrNotFound
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *default{{.Type}}Model) Update(ctx context.Context, data *{{.Type}}) (*mongo.UpdateResult, error) {
|
||||||
|
data.UpdateAt = time.Now()
|
||||||
|
{{if .Cache}}key := prefix{{.Type}}CacheKey + data.ID.Hex(){{end}}
|
||||||
|
res, err := m.conn.UpdateOne(ctx, {{if .Cache}}key, {{end}}bson.M{"_id": data.ID}, bson.M{"$set": data})
|
||||||
|
return res, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *default{{.Type}}Model) Delete(ctx context.Context, id string) (int64, error) {
|
||||||
|
oid, err := primitive.ObjectIDFromHex(id)
|
||||||
|
if err != nil {
|
||||||
|
return 0, ErrInvalidObjectId
|
||||||
|
}
|
||||||
|
{{if .Cache}}key := prefix{{.Type}}CacheKey +id{{end}}
|
||||||
|
res, err := m.conn.DeleteOne(ctx, {{if .Cache}}key, {{end}}bson.M{"_id": oid})
|
||||||
|
return res, err
|
||||||
|
}
|
38
deploy/template/mongo/model_custom.tpl
Normal file
38
deploy/template/mongo/model_custom.tpl
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
{{if .Cache}}import (
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/cache"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/monc"
|
||||||
|
){{else}}import "github.com/zeromicro/go-zero/core/stores/mon"{{end}}
|
||||||
|
|
||||||
|
{{if .Easy}}
|
||||||
|
const {{.Type}}CollectionName = "{{.snakeType}}"
|
||||||
|
{{end}}
|
||||||
|
|
||||||
|
var _ {{.Type}}Model = (*custom{{.Type}}Model)(nil)
|
||||||
|
|
||||||
|
type (
|
||||||
|
// {{.Type}}Model is an interface to be customized, add more methods here,
|
||||||
|
// and implement the added methods in custom{{.Type}}Model.
|
||||||
|
{{.Type}}Model interface {
|
||||||
|
{{.lowerType}}Model
|
||||||
|
}
|
||||||
|
|
||||||
|
custom{{.Type}}Model struct {
|
||||||
|
*default{{.Type}}Model
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
// New{{.Type}}Model returns a model for the mongo.
|
||||||
|
{{if .Easy}}func New{{.Type}}Model(url, db string{{if .Cache}}, c cache.CacheConf{{end}}) {{.Type}}Model {
|
||||||
|
conn := {{if .Cache}}monc{{else}}mon{{end}}.MustNewModel(url, db, {{.Type}}CollectionName{{if .Cache}}, c{{end}})
|
||||||
|
return &custom{{.Type}}Model{
|
||||||
|
default{{.Type}}Model: newDefault{{.Type}}Model(conn),
|
||||||
|
}
|
||||||
|
}{{else}}func New{{.Type}}Model(url, db, collection string{{if .Cache}}, c cache.CacheConf{{end}}) {{.Type}}Model {
|
||||||
|
conn := {{if .Cache}}monc{{else}}mon{{end}}.MustNewModel(url, db, collection{{if .Cache}}, c{{end}})
|
||||||
|
return &custom{{.Type}}Model{
|
||||||
|
default{{.Type}}Model: newDefault{{.Type}}Model(conn),
|
||||||
|
}
|
||||||
|
}{{end}}
|
14
deploy/template/mongo/model_types.tpl
Normal file
14
deploy/template/mongo/model_types.tpl
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
||||||
|
)
|
||||||
|
|
||||||
|
type {{.Type}} struct {
|
||||||
|
ID primitive.ObjectID `bson:"_id,omitempty" json:"id,omitempty"`
|
||||||
|
// TODO: Fill your own fields
|
||||||
|
UpdateAt time.Time `bson:"updateAt,omitempty" json:"updateAt,omitempty"`
|
||||||
|
CreateAt time.Time `bson:"createAt,omitempty" json:"createAt,omitempty"`
|
||||||
|
}
|
12
deploy/template/newapi/newtemplate.tpl
Normal file
12
deploy/template/newapi/newtemplate.tpl
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
type Request {
|
||||||
|
Name string `path:"name,options=you|me"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Response {
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
service {{.name}}-api {
|
||||||
|
@handler {{.handler}}Handler
|
||||||
|
get /from/:name(Request) returns (Response)
|
||||||
|
}
|
33
deploy/template/rpc/call.tpl
Normal file
33
deploy/template/rpc/call.tpl
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
{{.head}}
|
||||||
|
|
||||||
|
package {{.filePackage}}
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
{{.pbPackage}}
|
||||||
|
{{if ne .pbPackage .protoGoPackage}}{{.protoGoPackage}}{{end}}
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/zrpc"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
{{.alias}}
|
||||||
|
|
||||||
|
{{.serviceName}} interface {
|
||||||
|
{{.interface}}
|
||||||
|
}
|
||||||
|
|
||||||
|
default{{.serviceName}} struct {
|
||||||
|
cli zrpc.Client
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func New{{.serviceName}}(cli zrpc.Client) {{.serviceName}} {
|
||||||
|
return &default{{.serviceName}}{
|
||||||
|
cli: cli,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{{.functions}}
|
7
deploy/template/rpc/config.tpl
Normal file
7
deploy/template/rpc/config.tpl
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import "github.com/zeromicro/go-zero/zrpc"
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
zrpc.RpcServerConf
|
||||||
|
}
|
6
deploy/template/rpc/etc.tpl
Normal file
6
deploy/template/rpc/etc.tpl
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
Name: {{.serviceName}}.rpc
|
||||||
|
ListenOn: 0.0.0.0:8080
|
||||||
|
Etcd:
|
||||||
|
Hosts:
|
||||||
|
- 127.0.0.1:2379
|
||||||
|
Key: {{.serviceName}}.rpc
|
6
deploy/template/rpc/logic-func.tpl
Normal file
6
deploy/template/rpc/logic-func.tpl
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{{if .hasComment}}{{.comment}}{{end}}
|
||||||
|
func (l *{{.logicName}}) {{.method}} ({{if .hasReq}}in {{.request}}{{if .stream}},stream {{.streamBody}}{{end}}{{else}}stream {{.streamBody}}{{end}}) ({{if .hasReply}}{{.response}},{{end}} error) {
|
||||||
|
// todo: add your logic here and delete this line
|
||||||
|
|
||||||
|
return {{if .hasReply}}&{{.responseType}}{},{{end}} nil
|
||||||
|
}
|
24
deploy/template/rpc/logic.tpl
Normal file
24
deploy/template/rpc/logic.tpl
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package {{.packageName}}
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
{{.imports}}
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type {{.logicName}} struct {
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
logx.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func New{{.logicName}}(ctx context.Context,svcCtx *svc.ServiceContext) *{{.logicName}} {
|
||||||
|
return &{{.logicName}}{
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{.functions}}
|
42
deploy/template/rpc/main.tpl
Normal file
42
deploy/template/rpc/main.tpl
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
{{.imports}}
|
||||||
|
"qnc-server/common/interceptor/rpcserver"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/conf"
|
||||||
|
"github.com/zeromicro/go-zero/core/service"
|
||||||
|
"github.com/zeromicro/go-zero/zrpc"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
"google.golang.org/grpc/reflection"
|
||||||
|
)
|
||||||
|
|
||||||
|
var configFile = flag.String("f", "etc/{{.serviceName}}.yaml", "the config file")
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
var c config.Config
|
||||||
|
conf.MustLoad(*configFile, &c)
|
||||||
|
ctx := svc.NewServiceContext(c)
|
||||||
|
|
||||||
|
s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) {
|
||||||
|
{{range .serviceNames}} {{.Pkg}}.Register{{.Service}}Server(grpcServer, {{.ServerPkg}}.New{{.Service}}Server(ctx))
|
||||||
|
{{end}}
|
||||||
|
if c.Mode == service.DevMode || c.Mode == service.TestMode {
|
||||||
|
reflection.Register(grpcServer)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
//rpc log
|
||||||
|
s.AddUnaryInterceptors(rpcserver.LoggerInterceptor)
|
||||||
|
|
||||||
|
defer s.Stop()
|
||||||
|
|
||||||
|
fmt.Printf("Starting rpc server at %s...\n", c.ListenOn)
|
||||||
|
s.Start()
|
||||||
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user