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