commit
204af245f9
55 changed files with 1188 additions and 0 deletions
@ -0,0 +1,17 @@ |
|||||
|
package config |
||||
|
import "github.com/zeromicro/go-zero/core/stores/cache" |
||||
|
import {{.authImport}} |
||||
|
|
||||
|
type Config struct { |
||||
|
rest.RestConf |
||||
|
{{.auth}} |
||||
|
{{.jwtTrans}} |
||||
|
MysqlConnStr string |
||||
|
PgConnStr string |
||||
|
CacheRedis cache.CacheConf |
||||
|
Auth struct { |
||||
|
AccessSecret string |
||||
|
AccessExpire int64 |
||||
|
} |
||||
|
VER string |
||||
|
} |
@ -0,0 +1,40 @@ |
|||||
|
package svc |
||||
|
|
||||
|
import ( |
||||
|
{{.configImport}} |
||||
|
"gorm.io/driver/mysql" |
||||
|
"gorm.io/gorm" |
||||
|
// xxx "{项目名称}/model/xxx" //原版注册方法 |
||||
|
|
||||
|
) |
||||
|
|
||||
|
type ServiceContext struct { |
||||
|
Config {{.config}} |
||||
|
{{.middleware}} |
||||
|
GormDb *gorm.DB |
||||
|
// XxxModel xxx.xxxModel //原版注册方法 |
||||
|
} |
||||
|
|
||||
|
func NewServiceContext(c {{.config}}) *ServiceContext { |
||||
|
// 初始化Gorm ORM |
||||
|
dsn := c.MysqlConnStr |
||||
|
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) |
||||
|
if err != nil { |
||||
|
panic(err) |
||||
|
} |
||||
|
|
||||
|
// // 原版初始化 XxxModel |
||||
|
//conn := sqlx.NewMysql(c.MysqlConnStr) |
||||
|
//if err != nil { |
||||
|
// panic(err) |
||||
|
//} |
||||
|
|
||||
|
|
||||
|
return &ServiceContext{ |
||||
|
Config: c, |
||||
|
GormDb: db, |
||||
|
{{.middlewareAssignment}} |
||||
|
//XxxModel: xxx.NewXxxModel(conn, c.CacheRedis), //原版注册方法 带缓存 |
||||
|
|
||||
|
} |
||||
|
} |
@ -0,0 +1,13 @@ |
|||||
|
Name: {{.serviceName}} |
||||
|
Host: {{.host}} |
||||
|
Port: {{.port}} |
||||
|
Auth: |
||||
|
AccessSecret: dev-gxxhygroup-com |
||||
|
AccessExpire: 604800 |
||||
|
MysqlConnStr: ${MysqlConnStr} |
||||
|
PgConnStr: ${PgConnStr} |
||||
|
CacheRedis: |
||||
|
- Host: ${CacheRedisHost} |
||||
|
Pass: ${CacheRedisPass} |
||||
|
Type: ${CacheRedisType} |
||||
|
VER: latest |
@ -0,0 +1,27 @@ |
|||||
|
package {{.PkgName}} |
||||
|
|
||||
|
import ( |
||||
|
"net/http" |
||||
|
|
||||
|
"github.com/zeromicro/go-zero/rest/httpx" |
||||
|
{{.ImportPackages}} |
||||
|
) |
||||
|
|
||||
|
{{if .HasDoc}}{{.Doc}}{{end}} |
||||
|
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 { |
||||
|
httpx.ErrorCtx(r.Context(), w, err) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
{{end}}l := {{.LogicName}}.New{{.LogicType}}(r.Context(), svcCtx) |
||||
|
{{if .HasResp}}resp, {{end}}err := l.{{.Call}}({{if .HasRequest}}&req{{end}}) |
||||
|
if err != nil { |
||||
|
httpx.ErrorCtx(r.Context(), w, err) |
||||
|
} else { |
||||
|
{{if .HasResp}}httpx.OkJsonCtx(r.Context(), w, resp){{else}}httpx.Ok(w){{end}} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,37 @@ |
|||||
|
package {{.pkgName}} |
||||
|
|
||||
|
import ( |
||||
|
{{.imports}} |
||||
|
) |
||||
|
|
||||
|
type {{.logic}} struct { |
||||
|
logx.Logger |
||||
|
ctx context.Context |
||||
|
svcCtx *svc.ServiceContext |
||||
|
} |
||||
|
|
||||
|
{{if .hasDoc}}{{.doc}}{{end}} |
||||
|
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}} { |
||||
|
// 这里编写业务逻辑,要注意错误处理,写好注释 |
||||
|
// 示例1. 查询 |
||||
|
// var xxx model.XXX |
||||
|
// err := l.svcCtx.Db.Model(model.XXX{}).Where("id = ?", id).Find(&xxx).Error |
||||
|
|
||||
|
|
||||
|
return &types.Response{ |
||||
|
Success: true, |
||||
|
Code : 200, |
||||
|
Msg: "{{if .hasDoc}}{{.doc}}{{end}}"+" success", |
||||
|
Data: nil, |
||||
|
},nil |
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,64 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"flag" |
||||
|
"fmt" |
||||
|
"net/http" |
||||
|
{{.importPackages}} |
||||
|
) |
||||
|
|
||||
|
var configFile = flag.String("f", "etc/{{.serviceName}}.yaml", "the config file") |
||||
|
|
||||
|
func main() { |
||||
|
flag.Parse() |
||||
|
|
||||
|
var c config.Config |
||||
|
conf.MustLoad(*configFile, &c,conf.UseEnv()) |
||||
|
|
||||
|
server := rest.MustNewServer(c.RestConf,rest.WithNotAllowedHandler(CorsHandler())) |
||||
|
defer server.Stop() |
||||
|
server.Use(CorsHandle) |
||||
|
ctx := svc.NewServiceContext(c) |
||||
|
handler.RegisterHandlers(server, ctx) |
||||
|
|
||||
|
fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port) |
||||
|
server.Start() |
||||
|
} |
||||
|
|
||||
|
// setHeader 设置响应头 |
||||
|
func setHeader(w http.ResponseWriter) { |
||||
|
w.Header().Set("Access-Control-Allow-Origin", "*") |
||||
|
w.Header().Set("Access-Control-Allow-Headers", "*") |
||||
|
w.Header().Set("Access-Control-Allow-Methods", "*") |
||||
|
w.Header().Set("Access-Control-Expose-Headers", "Content-Length, Content-Type, Access-Control-Allow-Origin, Access-Control-Allow-Headers") |
||||
|
w.Header().Set("Access-Control-Allow-Credentials", "true") |
||||
|
} |
||||
|
|
||||
|
// CorsHandler 跨域请求处理器 |
||||
|
func CorsHandler() http.Handler { |
||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
||||
|
setHeader(w) |
||||
|
|
||||
|
if r.Method == "OPTIONS" { |
||||
|
w.WriteHeader(http.StatusNoContent) |
||||
|
} else { |
||||
|
w.WriteHeader(http.StatusNotFound) |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// Handle 跨域请求处理 |
||||
|
func CorsHandle(next http.HandlerFunc) http.HandlerFunc { |
||||
|
return func(w http.ResponseWriter, r *http.Request) { |
||||
|
setHeader(w) |
||||
|
|
||||
|
// 放行所有 OPTIONS 方法 |
||||
|
if r.Method == "OPTIONS" { |
||||
|
w.WriteHeader(http.StatusNoContent) |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
// 处理请求 |
||||
|
next(w, r) |
||||
|
} |
||||
|
} |
@ -0,0 +1,19 @@ |
|||||
|
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) |
||||
|
} |
||||
|
} |
@ -0,0 +1,4 @@ |
|||||
|
|
||||
|
server.AddRoutes( |
||||
|
{{.routes}} {{.jwt}}{{.signature}} {{.prefix}} {{.timeout}} {{.maxBytes}} |
||||
|
) |
@ -0,0 +1,15 @@ |
|||||
|
// Code generated by goctl. DO NOT EDIT. |
||||
|
// goctl {{.version}} |
||||
|
|
||||
|
package handler |
||||
|
|
||||
|
import ( |
||||
|
"net/http"{{if .hasTimeout}} |
||||
|
"time"{{end}} |
||||
|
|
||||
|
{{.importPackages}} |
||||
|
) |
||||
|
|
||||
|
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) { |
||||
|
{{.routesAdditions}} |
||||
|
} |
@ -0,0 +1,31 @@ |
|||||
|
syntax = "v1" |
||||
|
|
||||
|
type request { |
||||
|
Id int `json:"id,default=0"` |
||||
|
Other string `json:"other,optional,default=xxx"` // 可选值 |
||||
|
} |
||||
|
|
||||
|
type response { |
||||
|
Success bool `json:"success"` // 是否成功 |
||||
|
Code int `json:"code"` // 状态码 |
||||
|
Msg string `json:"msg"` // 状态信息 |
||||
|
Data interface{} `json:"data"` // 返回数据 |
||||
|
} |
||||
|
|
||||
|
@server( |
||||
|
// group: xxx //代码分组 |
||||
|
prefix: / // 路由前缀 |
||||
|
timeout: 3s // 超时时间 |
||||
|
// middlewares: [ // TODO: add middlewares ] // 中间件 |
||||
|
// jwt: Auth // jwt 验证 |
||||
|
// signature: true // 通过 signature 关键字开启签名功能 |
||||
|
) |
||||
|
service {{.serviceName}} { |
||||
|
@doc( |
||||
|
summary: "ping" |
||||
|
description: "返回 pong" |
||||
|
) |
||||
|
@handler PingHander |
||||
|
get /ping returns(response) |
||||
|
|
||||
|
} |
@ -0,0 +1,8 @@ |
|||||
|
// Code generated by goctl. DO NOT EDIT. |
||||
|
// goctl {{.version}} |
||||
|
|
||||
|
package types{{if .containsTime}} |
||||
|
import ( |
||||
|
"time" |
||||
|
){{end}} |
||||
|
{{.types}} |
@ -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}}] |
@ -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 |
@ -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() |
||||
|
} |
@ -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/v2 |
||||
|
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 |
@ -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 |
@ -0,0 +1,14 @@ |
|||||
|
func (m *default{{.upperStartCamelObject}}Model) Delete(ctx context.Context, {{.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) |
||||
|
return conn.ExecCtx(ctx, query, {{.lowerStartCamelPrimaryKey}}) |
||||
|
}, {{.keyValues}}){{else}}query := fmt.Sprintf("delete from %s where {{.originalPrimaryKey}} = {{if .postgreSql}}$1{{else}}?{{end}}", m.table) |
||||
|
_,err:=m.conn.ExecCtx(ctx, query, {{.lowerStartCamelPrimaryKey}}){{end}} |
||||
|
return err |
||||
|
} |
@ -0,0 +1,5 @@ |
|||||
|
package {{.pkg}} |
||||
|
|
||||
|
import "github.com/zeromicro/go-zero/core/stores/sqlx" |
||||
|
|
||||
|
var ErrNotFound = sqlx.ErrNotFound |
@ -0,0 +1 @@ |
|||||
|
{{.name}} {{.type}} {{.tag}} {{if .hasComment}}// {{.comment}}{{end}} |
@ -0,0 +1,8 @@ |
|||||
|
func (m *default{{.upperStartCamelObject}}Model) formatPrimary(primary any) string { |
||||
|
return fmt.Sprintf("%s%v", {{.primaryKeyLeft}}, primary) |
||||
|
} |
||||
|
|
||||
|
func (m *default{{.upperStartCamelObject}}Model) queryPrimary(ctx context.Context, conn sqlx.SqlConn, v, primary any) error { |
||||
|
query := fmt.Sprintf("select %s from %s where {{.originalPrimaryField}} = {{if .postgreSql}}$1{{else}}?{{end}} limit 1", {{.lowerStartCamelObject}}Rows, m.table ) |
||||
|
return conn.QueryRowCtx(ctx, v, query, primary) |
||||
|
} |
@ -0,0 +1,30 @@ |
|||||
|
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 any) (i any, e error) { |
||||
|
query := fmt.Sprintf("select %s from %s where {{.originalField}} limit 1", {{.lowerStartCamelObject}}Rows, m.table) |
||||
|
if err := conn.QueryRowCtx(ctx, &resp, query, {{.lowerStartCamelField}}); 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}} limit 1", {{.lowerStartCamelObject}}Rows, m.table ) |
||||
|
err := m.conn.QueryRowCtx(ctx, &resp, query, {{.lowerStartCamelField}}) |
||||
|
switch err { |
||||
|
case nil: |
||||
|
return &resp, nil |
||||
|
case sqlx.ErrNotFound: |
||||
|
return nil, ErrNotFound |
||||
|
default: |
||||
|
return nil, err |
||||
|
} |
||||
|
}{{end}} |
@ -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 any) error { |
||||
|
query := fmt.Sprintf("select %s from %s where {{.originalPrimaryKey}} = {{if .postgreSql}}$1{{else}}?{{end}} limit 1", {{.lowerStartCamelObject}}Rows, m.table) |
||||
|
return conn.QueryRowCtx(ctx, v, query, {{.lowerStartCamelPrimaryKey}}) |
||||
|
}) |
||||
|
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}} limit 1", {{.lowerStartCamelObject}}Rows, m.table) |
||||
|
var resp {{.upperStartCamelObject}} |
||||
|
err := m.conn.QueryRowCtx(ctx, &resp, query, {{.lowerStartCamelPrimaryKey}}) |
||||
|
switch err { |
||||
|
case nil: |
||||
|
return &resp, nil |
||||
|
case sqlx.ErrNotFound: |
||||
|
return nil, ErrNotFound |
||||
|
default: |
||||
|
return nil, err |
||||
|
}{{end}} |
||||
|
} |
@ -0,0 +1,14 @@ |
|||||
|
import ( |
||||
|
"context" |
||||
|
"database/sql" |
||||
|
"fmt" |
||||
|
"strings" |
||||
|
{{if .time}}"time"{{end}} |
||||
|
|
||||
|
{{if .containsPQ}}"github.com/lib/pq"{{end}} |
||||
|
"github.com/zeromicro/go-zero/core/stores/builder" |
||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx" |
||||
|
"github.com/zeromicro/go-zero/core/stringx" |
||||
|
|
||||
|
{{.third}} |
||||
|
) |
@ -0,0 +1,16 @@ |
|||||
|
import ( |
||||
|
"context" |
||||
|
"database/sql" |
||||
|
"fmt" |
||||
|
"strings" |
||||
|
{{if .time}}"time"{{end}} |
||||
|
|
||||
|
{{if .containsPQ}}"github.com/lib/pq"{{end}} |
||||
|
"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" |
||||
|
|
||||
|
{{.third}} |
||||
|
) |
@ -0,0 +1,9 @@ |
|||||
|
func (m *default{{.upperStartCamelObject}}Model) Insert(ctx context.Context, data *{{.upperStartCamelObject}}) (sql.Result,error) { |
||||
|
{{if .withCache}}{{.keys}} |
||||
|
ret, err := 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) |
||||
|
return conn.ExecCtx(ctx, query, {{.expressionValues}}) |
||||
|
}, {{.keyValues}}){{else}}query := fmt.Sprintf("insert into %s (%s) values ({{.expression}})", m.table, {{.lowerStartCamelObject}}RowsExpectAutoSet) |
||||
|
ret,err:=m.conn.ExecCtx(ctx, query, {{.expressionValues}}){{end}} |
||||
|
return ret,err |
||||
|
} |
@ -0,0 +1 @@ |
|||||
|
Delete(ctx context.Context, {{.lowerStartCamelPrimaryKey}} {{.dataType}}) error |
@ -0,0 +1 @@ |
|||||
|
FindOneBy{{.upperField}}(ctx context.Context, {{.in}}) (*{{.upperStartCamelObject}}, error) |
@ -0,0 +1 @@ |
|||||
|
FindOne(ctx context.Context, {{.lowerStartCamelPrimaryKey}} {{.dataType}}) (*{{.upperStartCamelObject}}, error) |
@ -0,0 +1 @@ |
|||||
|
Insert(ctx context.Context, data *{{.upperStartCamelObject}}) (sql.Result,error) |
@ -0,0 +1 @@ |
|||||
|
Update(ctx context.Context, {{if .containsIndexCache}}newData{{else}}data{{end}} *{{.upperStartCamelObject}}) error |
@ -0,0 +1,16 @@ |
|||||
|
// Code generated by goctl. DO NOT EDIT. |
||||
|
// versions: |
||||
|
// goctl version: 1.7.3 |
||||
|
|
||||
|
package {{.pkg}} |
||||
|
{{.imports}} |
||||
|
{{.vars}} |
||||
|
{{.types}} |
||||
|
{{.new}} |
||||
|
{{.delete}} |
||||
|
{{.find}} |
||||
|
{{.insert}} |
||||
|
{{.update}} |
||||
|
{{.extraMethod}} |
||||
|
{{.tableName}} |
||||
|
{{.customized}} |
@ -0,0 +1,7 @@ |
|||||
|
func new{{.upperStartCamelObject}}Model(conn sqlx.SqlConn{{if .withCache}}, c cache.CacheConf, opts ...cache.Option{{end}}) *default{{.upperStartCamelObject}}Model { |
||||
|
return &default{{.upperStartCamelObject}}Model{ |
||||
|
{{if .withCache}}CachedConn: sqlc.NewConn(conn, c, opts...){{else}}conn:conn{{end}}, |
||||
|
table: {{.table}}, |
||||
|
} |
||||
|
} |
||||
|
|
@ -0,0 +1,131 @@ |
|||||
|
package {{.pkg}} |
||||
|
|
||||
|
{{if .withCache}} |
||||
|
import ( |
||||
|
"context" |
||||
|
"fmt" |
||||
|
sq "github.com/Masterminds/squirrel" |
||||
|
"github.com/zeromicro/go-zero/core/stores/cache" |
||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx" |
||||
|
"github.com/zeromicro/go-zero/core/stores/sqlc" |
||||
|
) |
||||
|
{{else}} |
||||
|
import ( |
||||
|
"context" |
||||
|
"fmt" |
||||
|
"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 |
||||
|
// 以下为自定义方法 |
||||
|
FindOneByName(ctx context.Context, name string) (*{{.upperStartCamelObject}}, error) |
||||
|
FindByName(ctx context.Context, name string) (*[]{{.upperStartCamelObject}}, error) |
||||
|
List(ctx context.Context, offset int, limit int) (*[]{{.upperStartCamelObject}}, error) |
||||
|
Count(ctx context.Context) (int64, error) |
||||
|
|
||||
|
{{if not .withCache}}withSession(session sqlx.Session) {{.upperStartCamelObject}}Model{{end}} |
||||
|
} |
||||
|
|
||||
|
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, opts ...cache.Option{{end}}) {{.upperStartCamelObject}}Model { |
||||
|
return &custom{{.upperStartCamelObject}}Model{ |
||||
|
default{{.upperStartCamelObject}}Model: new{{.upperStartCamelObject}}Model(conn{{if .withCache}}, c, opts...{{end}}), |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
|
||||
|
{{if not .withCache}} |
||||
|
func (m *custom{{.upperStartCamelObject}}Model) withSession(session sqlx.Session) {{.upperStartCamelObject}}Model { |
||||
|
return New{{.upperStartCamelObject}}Model(sqlx.NewSqlConnFromSession(session)) |
||||
|
} |
||||
|
{{end}} |
||||
|
|
||||
|
// 以下为自定义方法 |
||||
|
|
||||
|
// 示例: findOneByeName 根据name查找单条记录 |
||||
|
func (m *default{{.upperStartCamelObject}}Model) FindOneByName(ctx context.Context, name string) (*{{.upperStartCamelObject}}, error) { |
||||
|
var cacheKey = fmt.Sprintf("{{.lowerStartCamelObject}}:name:%s", name) // 缓存key |
||||
|
var resp {{.upperStartCamelObject}} |
||||
|
|
||||
|
// 缓存模式 |
||||
|
err := m.QueryRowCtx(ctx, &resp, cacheKey, func(ctx context.Context,conn sqlx.SqlConn, v interface{}) error { |
||||
|
query := fmt.Sprintf("select %s from %s where name = ?", {{.lowerStartCamelObject}}Rows, m.table) |
||||
|
return conn.QueryRowCtx(ctx,v, query, name) |
||||
|
}) |
||||
|
|
||||
|
// 非缓存模式 |
||||
|
// query := fmt.Sprintf("select %s from %s where name = ?", {{.lowerStartCamelObject}}Rows, m.table) |
||||
|
// query := "select * from {{.lowerStartCamelObject}} where name = ?" |
||||
|
// err := m.QueryRowNoCache(&resp, query, name) |
||||
|
|
||||
|
switch err { |
||||
|
case nil: |
||||
|
return &resp, nil |
||||
|
case sqlc.ErrNotFound: |
||||
|
return nil, ErrNotFound |
||||
|
default: |
||||
|
return nil, err |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 示例: findByeName 根据name查找多条记录 |
||||
|
func (m *default{{.upperStartCamelObject}}Model) FindByName(ctx context.Context, name string) (*[]{{.upperStartCamelObject}}, error) { |
||||
|
var resp []{{.upperStartCamelObject}} |
||||
|
// 非缓存模式,多条记录不建议缓存 |
||||
|
// query := "select * from {{.lowerStartCamelObject}} where name = ?" |
||||
|
query := fmt.Sprintf("select %s from %s where name = ?", {{.lowerStartCamelObject}}Rows, m.table) |
||||
|
err := m.QueryRowsNoCache(&resp, query, name) |
||||
|
switch err { |
||||
|
case nil: |
||||
|
return &resp, nil |
||||
|
case sqlc.ErrNotFound: |
||||
|
return nil, ErrNotFound |
||||
|
default: |
||||
|
return nil, err |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 示例: List 列表 |
||||
|
func (m *default{{.upperStartCamelObject}}Model) List(ctx context.Context, offset int, limit int) (*[]{{.upperStartCamelObject}}, error) { |
||||
|
var resp []{{.upperStartCamelObject}} |
||||
|
query := fmt.Sprintf("select %s from %s limit ? offset ?", {{.lowerStartCamelObject}}Rows, m.table) |
||||
|
// query := "select * from {{.lowerStartCamelObject}} limit ? offset ?" |
||||
|
err := m.QueryRowsNoCache(&resp, query, limit, offset) |
||||
|
switch err { |
||||
|
case nil: |
||||
|
return &resp, nil |
||||
|
case sqlc.ErrNotFound: |
||||
|
return nil, ErrNotFound |
||||
|
default: |
||||
|
return nil, err |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 示例: count 统计,返回总数,使用sql语法糖 |
||||
|
func (m *default{{.upperStartCamelObject}}Model) Count(ctx context.Context) (int64, error) { |
||||
|
sqlGen := sq.Select("count(*)").From(m.table) |
||||
|
query, args, _ := sqlGen.ToSql() |
||||
|
var count int64 |
||||
|
err := m.QueryRowsNoCacheCtx(ctx, &count, query, args) |
||||
|
switch err { |
||||
|
case nil: |
||||
|
return count, nil |
||||
|
case sqlc.ErrNotFound: |
||||
|
return 0, ErrNotFound |
||||
|
default: |
||||
|
return 0, err |
||||
|
} |
||||
|
} |
@ -0,0 +1,3 @@ |
|||||
|
func (m *default{{.upperStartCamelObject}}Model) tableName() string { |
||||
|
return m.table |
||||
|
} |
@ -0,0 +1 @@ |
|||||
|
`db:"{{.field}}"` |
@ -0,0 +1,14 @@ |
|||||
|
type ( |
||||
|
{{.lowerStartCamelObject}}Model interface{ |
||||
|
{{.method}} |
||||
|
} |
||||
|
|
||||
|
default{{.upperStartCamelObject}}Model struct { |
||||
|
{{if .withCache}}sqlc.CachedConn{{else}}conn sqlx.SqlConn{{end}} |
||||
|
table string |
||||
|
} |
||||
|
|
||||
|
{{.upperStartCamelObject}} struct { |
||||
|
{{.fields}} |
||||
|
} |
||||
|
) |
@ -0,0 +1,14 @@ |
|||||
|
func (m *default{{.upperStartCamelObject}}Model) Update(ctx context.Context, {{if .containsIndexCache}}newData{{else}}data{{end}} *{{.upperStartCamelObject}}) error { |
||||
|
{{if .withCache}}{{if .containsIndexCache}}data, err:=m.FindOne(ctx, newData.{{.upperStartCamelPrimaryKey}}) |
||||
|
if err!=nil{ |
||||
|
return err |
||||
|
} |
||||
|
|
||||
|
{{end}} {{.keys}} |
||||
|
_, {{if .containsIndexCache}}err{{else}}err:{{end}}= 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) |
||||
|
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) |
||||
|
_,err:=m.conn.ExecCtx(ctx, query, {{.expressionValues}}){{end}} |
||||
|
return err |
||||
|
} |
@ -0,0 +1,8 @@ |
|||||
|
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}} {{.ignoreColumns}}), ","){{else}}strings.Join(stringx.Remove({{.lowerStartCamelObject}}FieldNames, {{if .autoIncrement}}"{{.originalPrimaryKey}}", {{end}} {{.ignoreColumns}}), ","){{end}} |
||||
|
{{.lowerStartCamelObject}}RowsWithPlaceHolder = {{if .postgreSql}}builder.PostgreSqlJoin(stringx.Remove({{.lowerStartCamelObject}}FieldNames, "{{.originalPrimaryKey}}", {{.ignoreColumns}})){{else}}strings.Join(stringx.Remove({{.lowerStartCamelObject}}FieldNames, "{{.originalPrimaryKey}}", {{.ignoreColumns}}), "=?,") + "=?"{{end}} |
||||
|
|
||||
|
{{if .withCache}}{{.cacheKeys}}{{end}} |
||||
|
) |
@ -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") |
||||
|
) |
@ -0,0 +1,80 @@ |
|||||
|
// Code generated by goctl. DO NOT EDIT. |
||||
|
// goctl {{.version}} |
||||
|
|
||||
|
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 |
||||
|
} |
@ -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}} |
@ -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"` |
||||
|
} |
@ -0,0 +1,31 @@ |
|||||
|
syntax = "v1" |
||||
|
|
||||
|
type request { |
||||
|
Id int `json:"id,default=0"` |
||||
|
Who string `json:"Who,optional,options=you|me,default=you"` // 示例,可选值,you|me,默认you |
||||
|
} |
||||
|
|
||||
|
type response { |
||||
|
Success bool `json:"success"` // 是否成功 |
||||
|
Code int `json:"code"` // 状态码 |
||||
|
Msg string `json:"msg"` // 状态信息 |
||||
|
Data interface{} `json:"data"` // 返回数据 |
||||
|
} |
||||
|
|
||||
|
@server( |
||||
|
// group: xxx //代码分组 |
||||
|
// prefix: / // 路由前缀 |
||||
|
timeout: 3s // 超时时间 |
||||
|
// middlewares: [ // TODO: add middlewares ] // 中间件 |
||||
|
// jwt: Auth // jwt 验证 |
||||
|
// signature: true // 通过 signature 关键字开启签名功能 |
||||
|
) |
||||
|
service {{.name}}-api { |
||||
|
@doc( |
||||
|
summary: "ping" |
||||
|
description: "返回 pong" |
||||
|
) |
||||
|
@handler Ping |
||||
|
get /ping returns(response) |
||||
|
|
||||
|
} |
@ -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}} |
@ -0,0 +1,7 @@ |
|||||
|
package config |
||||
|
|
||||
|
import "github.com/zeromicro/go-zero/zrpc" |
||||
|
|
||||
|
type Config struct { |
||||
|
zrpc.RpcServerConf |
||||
|
} |
@ -0,0 +1,6 @@ |
|||||
|
Name: {{.serviceName}}.rpc |
||||
|
ListenOn: 0.0.0.0:8080 |
||||
|
Etcd: |
||||
|
Hosts: |
||||
|
- 127.0.0.1:2379 |
||||
|
Key: {{.serviceName}}.rpc |
@ -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 |
||||
|
} |
@ -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}} |
@ -0,0 +1,36 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"flag" |
||||
|
"fmt" |
||||
|
|
||||
|
{{.imports}} |
||||
|
|
||||
|
"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{{.GRPCService}}Server(grpcServer, {{.ServerPkg}}.New{{.Service}}Server(ctx)) |
||||
|
{{end}} |
||||
|
if c.Mode == service.DevMode || c.Mode == service.TestMode { |
||||
|
reflection.Register(grpcServer) |
||||
|
} |
||||
|
}) |
||||
|
defer s.Stop() |
||||
|
|
||||
|
fmt.Printf("Starting rpc server at %s...\n", c.ListenOn) |
||||
|
s.Start() |
||||
|
} |
@ -0,0 +1,6 @@ |
|||||
|
|
||||
|
{{if .hasComment}}{{.comment}}{{end}} |
||||
|
func (s *{{.server}}Server) {{.method}} ({{if .notStream}}ctx context.Context,{{if .hasReq}} in {{.request}}{{end}}{{else}}{{if .hasReq}} in {{.request}},{{end}}stream {{.streamBody}}{{end}}) ({{if .notStream}}{{.response}},{{end}}error) { |
||||
|
l := {{.logicPkg}}.New{{.logicName}}({{if .notStream}}ctx,{{else}}stream.Context(),{{end}}s.svcCtx) |
||||
|
return l.{{.method}}({{if .hasReq}}in{{if .stream}} ,stream{{end}}{{else}}{{if .stream}}stream{{end}}{{end}}) |
||||
|
} |
@ -0,0 +1,22 @@ |
|||||
|
{{.head}} |
||||
|
|
||||
|
package server |
||||
|
|
||||
|
import ( |
||||
|
{{if .notStream}}"context"{{end}} |
||||
|
|
||||
|
{{.imports}} |
||||
|
) |
||||
|
|
||||
|
type {{.server}}Server struct { |
||||
|
svcCtx *svc.ServiceContext |
||||
|
{{.unimplementedServer}} |
||||
|
} |
||||
|
|
||||
|
func New{{.server}}Server(svcCtx *svc.ServiceContext) *{{.server}}Server { |
||||
|
return &{{.server}}Server{ |
||||
|
svcCtx: svcCtx, |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
{{.funcs}} |
@ -0,0 +1,13 @@ |
|||||
|
package svc |
||||
|
|
||||
|
import {{.imports}} |
||||
|
|
||||
|
type ServiceContext struct { |
||||
|
Config config.Config |
||||
|
} |
||||
|
|
||||
|
func NewServiceContext(c config.Config) *ServiceContext { |
||||
|
return &ServiceContext{ |
||||
|
Config:c, |
||||
|
} |
||||
|
} |
@ -0,0 +1,16 @@ |
|||||
|
syntax = "proto3"; |
||||
|
|
||||
|
package {{.package}}; |
||||
|
option go_package="./{{.package}}"; |
||||
|
|
||||
|
message Request { |
||||
|
string ping = 1; |
||||
|
} |
||||
|
|
||||
|
message Response { |
||||
|
string pong = 1; |
||||
|
} |
||||
|
|
||||
|
service {{.serviceName}} { |
||||
|
rpc Ping(Request) returns(Response); |
||||
|
} |
@ -0,0 +1,22 @@ |
|||||
|
## 开始新项目 |
||||
|
- 检查环境 |
||||
|
```shell |
||||
|
goctl env check --install --verbose --force |
||||
|
``` |
||||
|
|
||||
|
- 创建项目,xxx 改为项目名 |
||||
|
```shell |
||||
|
mkdir xxx |
||||
|
cd xxx |
||||
|
go mod init xxx |
||||
|
go get -u github.com/zeromicro/go-zero@latest |
||||
|
go mod tidy |
||||
|
``` |
||||
|
- 创建服务 |
||||
|
```shell |
||||
|
mkdir api |
||||
|
cd api |
||||
|
goctl api new xxx --style go-zero --remote https://gitea.gxxhygroup.com/dark/zero-template |
||||
|
cd xxx |
||||
|
go mod tidy |
||||
|
``` |
Loading…
Reference in new issue