初始化项目
This commit is contained in:
26
.gitignore
vendored
Normal file
26
.gitignore
vendored
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# ---> Go
|
||||||
|
# Binaries for programs and plugins
|
||||||
|
*.exe
|
||||||
|
*.exe~
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Test binary, built with `go test -c`
|
||||||
|
*.test
|
||||||
|
|
||||||
|
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||||
|
*.out
|
||||||
|
|
||||||
|
# local config
|
||||||
|
*_local.yaml
|
||||||
|
|
||||||
|
# Dependency directories (remove the comment below to include it)
|
||||||
|
vendor/
|
||||||
|
|
||||||
|
builder/
|
||||||
|
logs/
|
||||||
|
static/
|
||||||
|
bin/
|
||||||
|
cert/
|
||||||
|
.idea/
|
||||||
31
Dockerfile
Normal file
31
Dockerfile
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
FROM golang:1.23.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 ./etc /app/etc
|
||||||
|
RUN go build -ldflags="-s -w" -o /app/novatask novatask.go
|
||||||
|
|
||||||
|
|
||||||
|
FROM scratch
|
||||||
|
|
||||||
|
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
|
||||||
|
COPY --from=builder /usr/share/zoneinfo/UTC /usr/share/zoneinfo/UTC
|
||||||
|
ENV TZ=UTC
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=builder /app/novatask /app/novatask
|
||||||
|
COPY --from=builder /app/etc /app/etc
|
||||||
|
|
||||||
|
CMD ["./novatask", "-f", "etc/novatask.yaml"]
|
||||||
65
Makefile
Normal file
65
Makefile
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
host ?= 192.168.2.108:3306
|
||||||
|
user ?= huangjie
|
||||||
|
pwd ?= jMDqPQM^a6hsAR
|
||||||
|
table ?=
|
||||||
|
cache ?=
|
||||||
|
database ?= "nova_home"
|
||||||
|
|
||||||
|
.PHONY: db
|
||||||
|
# 链接数据库生成模型代码
|
||||||
|
db:
|
||||||
|
goctl model mysql datasource -url="${user}:${pwd}@tcp(${host})/${database}" -table="${table}" --dir internal/model --strict --style go_zero ${cache}
|
||||||
|
|
||||||
|
.PHONY: init
|
||||||
|
# 初始化开发环境,安装依赖工具
|
||||||
|
init:
|
||||||
|
go install github.com/zeromicro/go-zero/tools/goctl@latest
|
||||||
|
goctl env check --install --verbose --force
|
||||||
|
go install github.com/zeromicro/goctl-swagger@latest
|
||||||
|
|
||||||
|
.PHONY: api-format
|
||||||
|
# 格式化api文件
|
||||||
|
api-format:
|
||||||
|
goctl api format --dir doc/api/
|
||||||
|
goctl api plugin -plugin goctl-swagger="swagger -filename nova-task.json" -api doc/api/nova-task.api -dir doc/swagger
|
||||||
|
|
||||||
|
.PHONY: api
|
||||||
|
# 根据api文件生成代码
|
||||||
|
api:
|
||||||
|
make api-format
|
||||||
|
goctl api go -api doc/api/nova-task.api --dir . --style go_zero
|
||||||
|
|
||||||
|
.PHONY: build
|
||||||
|
# 编译二进制可执行文件
|
||||||
|
build:
|
||||||
|
mkdir -p bin/ && go build -ldflags="-s -w" -o ./bin/ ./...
|
||||||
|
|
||||||
|
.PHONY: img
|
||||||
|
# 构建Docker镜像
|
||||||
|
img:
|
||||||
|
docker build --platform=amd64 -t nova-task:latest .
|
||||||
|
docker tag `docker images -aq -f "reference=nova-task:latest"` harbor.phantom-u3d002.com/nova/nova-task:latest
|
||||||
|
|
||||||
|
.PHONY: push
|
||||||
|
push:
|
||||||
|
docker push harbor.phantom-u3d002.com/nova/nova-task:latest
|
||||||
|
|
||||||
|
|
||||||
|
# 帮助信息
|
||||||
|
help:
|
||||||
|
@echo ''
|
||||||
|
@echo 'Usage:'
|
||||||
|
@echo ' make [target]'
|
||||||
|
@echo ''
|
||||||
|
@echo 'Targets:'
|
||||||
|
@awk '/^[a-zA-Z\-\0-9]+:/ { \
|
||||||
|
helpMessage = match(lastLine, /^# (.*)/); \
|
||||||
|
if (helpMessage) { \
|
||||||
|
helpCommand = substr($$1, 0, index($$1, ":")-1); \
|
||||||
|
helpMessage = substr(lastLine, RSTART + 2, RLENGTH); \
|
||||||
|
printf "\033[36m%-22s\033[0m %s\n", helpCommand,helpMessage; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
{ lastLine = $$0 }' $(MAKEFILE_LIST)
|
||||||
|
|
||||||
|
.DEFAULT_GOAL := help
|
||||||
21
README.md
Normal file
21
README.md
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# nova task 服务端
|
||||||
|
|
||||||
|
## 快速开始
|
||||||
|
1. 基于go-zero框架开发
|
||||||
|
2. golang 1.23.0+
|
||||||
|
3. 安装依赖工具: make init
|
||||||
|
|
||||||
|
## 组件依赖
|
||||||
|
1. MySQL 8.0+
|
||||||
|
2. Docker 27.1+
|
||||||
|
|
||||||
|
## 配置文件 [novatask.yaml](etc/saas.yaml)
|
||||||
|
1. 修改Mysql中的数据库地址以及账号密码
|
||||||
|
2. 其他配置项根据注释说明和实际需求自行修改
|
||||||
|
|
||||||
|
## 正式服部署
|
||||||
|
1. 将[docker-compose.yml](docker-compose.yml)文件拷贝到服务器上,并修改需要部署的镜像版本以及根据配置的端口修改端口映射
|
||||||
|
2. 在同一目录下创建文件夹etc, 并将[novatask.yaml](etc/saas.yaml)文件拷贝到etc目录下,并根据需求修改配置文件
|
||||||
|
3. 拉取镜像:``docker compose pull``
|
||||||
|
4. 起服:``docker compose up -d``
|
||||||
|
5. 配置http反向代理,将``/api/task``前缀的路由代理到映射出来的端口上
|
||||||
46
doc/api/nova-task.api
Normal file
46
doc/api/nova-task.api
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
syntax = "v1"
|
||||||
|
|
||||||
|
@server (
|
||||||
|
prefix: /api/task/v1
|
||||||
|
group: task
|
||||||
|
jwt: Auth
|
||||||
|
)
|
||||||
|
service novatask {
|
||||||
|
@doc "获取任务列表"
|
||||||
|
@handler GetTaskList
|
||||||
|
get /tasks (GetTaskListReq) returns (GetTaskListResp)
|
||||||
|
|
||||||
|
@doc "领取任务奖励"
|
||||||
|
@handler GetTaskReward
|
||||||
|
get /reward/:id (GetTaskRewardReq) returns (GetTaskRewardResp)
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetTaskListReq {
|
||||||
|
CommunityId uint `form:"community_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Task {
|
||||||
|
Id uint `json:"id"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
SubTitle string `json:"sub_title"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Points int `json:"points"`
|
||||||
|
ButtonText string `json:"button_text"`
|
||||||
|
Type int8 `json:"type"`
|
||||||
|
StartAt string `json:"start_at"`
|
||||||
|
EndAt string `json:"end_at"`
|
||||||
|
Status int8 `json:"status"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetTaskListResp {
|
||||||
|
Tasks []Task `json:"tasks"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetTaskRewardReq {
|
||||||
|
ID uint `path:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetTaskRewardResp {
|
||||||
|
Points int `json:"points"`
|
||||||
|
}
|
||||||
|
|
||||||
190
doc/swagger/nova-task.json
Normal file
190
doc/swagger/nova-task.json
Normal file
@@ -0,0 +1,190 @@
|
|||||||
|
{
|
||||||
|
"swagger": "2.0",
|
||||||
|
"info": {
|
||||||
|
"title": "",
|
||||||
|
"version": ""
|
||||||
|
},
|
||||||
|
"schemes": [
|
||||||
|
"http",
|
||||||
|
"https"
|
||||||
|
],
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"paths": {
|
||||||
|
"/api/task/v1/reward/{id}": {
|
||||||
|
"get": {
|
||||||
|
"summary": "领取任务奖励",
|
||||||
|
"operationId": "GetTaskReward",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A successful response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/GetTaskRewardResp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"task"
|
||||||
|
],
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"apiKey": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"/api/task/v1/tasks": {
|
||||||
|
"get": {
|
||||||
|
"summary": "获取任务列表",
|
||||||
|
"operationId": "GetTaskList",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A successful response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/GetTaskListResp"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "community_id",
|
||||||
|
"in": "query",
|
||||||
|
"required": true,
|
||||||
|
"type": "integer",
|
||||||
|
"format": "uint32"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"task"
|
||||||
|
],
|
||||||
|
"consumes": [
|
||||||
|
"multipart/form-data"
|
||||||
|
],
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"apiKey": []
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"definitions": {
|
||||||
|
"GetTaskListReq": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"community_id": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "uint32"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"title": "GetTaskListReq",
|
||||||
|
"required": [
|
||||||
|
"community_id"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"GetTaskListResp": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"tasks": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {
|
||||||
|
"$ref": "#/definitions/Task"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"title": "GetTaskListResp",
|
||||||
|
"required": [
|
||||||
|
"tasks"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"GetTaskRewardReq": {
|
||||||
|
"type": "object",
|
||||||
|
"title": "GetTaskRewardReq"
|
||||||
|
},
|
||||||
|
"GetTaskRewardResp": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"points": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int32"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"title": "GetTaskRewardResp",
|
||||||
|
"required": [
|
||||||
|
"points"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Task": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "uint32"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"sub_title": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"points": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int32"
|
||||||
|
},
|
||||||
|
"button_text": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int8"
|
||||||
|
},
|
||||||
|
"start_at": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"end_at": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"type": "integer",
|
||||||
|
"format": "int8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"title": "Task",
|
||||||
|
"required": [
|
||||||
|
"id",
|
||||||
|
"title",
|
||||||
|
"sub_title",
|
||||||
|
"description",
|
||||||
|
"points",
|
||||||
|
"button_text",
|
||||||
|
"type",
|
||||||
|
"start_at",
|
||||||
|
"end_at",
|
||||||
|
"status"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"securityDefinitions": {
|
||||||
|
"apiKey": {
|
||||||
|
"type": "apiKey",
|
||||||
|
"description": "Enter JWT Bearer token **_only_**",
|
||||||
|
"name": "Authorization",
|
||||||
|
"in": "header"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
13
docker-compose.yml
Normal file
13
docker-compose.yml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
services:
|
||||||
|
saas-server:
|
||||||
|
image: harbor.phantom-u3d002.com/nova/nova-task:latest
|
||||||
|
container_name: nova-task
|
||||||
|
privileged: true
|
||||||
|
restart: always
|
||||||
|
ports:
|
||||||
|
- "8888:8888"
|
||||||
|
volumes:
|
||||||
|
- ./logs:/app/logs
|
||||||
|
- ./etc:/app/etc
|
||||||
|
environment:
|
||||||
|
TZ: UTC
|
||||||
13
etc/novatask.yaml
Normal file
13
etc/novatask.yaml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
Name: novatask
|
||||||
|
Host: 0.0.0.0
|
||||||
|
Port: 8888
|
||||||
|
|
||||||
|
Auth: # js-sdk鉴权相关配置
|
||||||
|
AccessSecret: "ac2d27613e131be6286c0eb1713929dd" # 鉴权token密钥
|
||||||
|
AccessExpire: 168h # 鉴权token过期时间
|
||||||
|
|
||||||
|
MySql: # mysql相关配置
|
||||||
|
Addr: "127.0.0.1:3306" # mysql地址
|
||||||
|
User: "root" # mysql用户
|
||||||
|
Password: "123456" # mysql密码
|
||||||
|
Database: "nova_home" # 数据库名
|
||||||
53
go.mod
Normal file
53
go.mod
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
module nova_task
|
||||||
|
|
||||||
|
go 1.23.4
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/golang-jwt/jwt/v4 v4.5.1
|
||||||
|
github.com/spf13/cast v1.7.0
|
||||||
|
github.com/zeromicro/go-zero v1.7.4
|
||||||
|
)
|
||||||
|
|
||||||
|
require (
|
||||||
|
filippo.io/edwards25519 v1.1.0 // indirect
|
||||||
|
github.com/beorn7/perks v1.0.1 // indirect
|
||||||
|
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
|
github.com/fatih/color v1.18.0 // indirect
|
||||||
|
github.com/go-logr/logr v1.4.2 // indirect
|
||||||
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
|
github.com/go-sql-driver/mysql v1.8.1 // indirect
|
||||||
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 // indirect
|
||||||
|
github.com/klauspost/compress v1.17.9 // indirect
|
||||||
|
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||||
|
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||||
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||||
|
github.com/openzipkin/zipkin-go v0.4.3 // indirect
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||||
|
github.com/prometheus/client_golang v1.20.5 // indirect
|
||||||
|
github.com/prometheus/client_model v0.6.1 // indirect
|
||||||
|
github.com/prometheus/common v0.55.0 // indirect
|
||||||
|
github.com/prometheus/procfs v0.15.1 // indirect
|
||||||
|
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||||
|
go.opentelemetry.io/otel v1.24.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/exporters/jaeger v1.17.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.24.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/exporters/zipkin v1.24.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/metric v1.24.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/sdk v1.24.0 // indirect
|
||||||
|
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
||||||
|
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
|
||||||
|
go.uber.org/automaxprocs v1.6.0 // indirect
|
||||||
|
golang.org/x/net v0.31.0 // indirect
|
||||||
|
golang.org/x/sys v0.27.0 // indirect
|
||||||
|
golang.org/x/text v0.20.0 // indirect
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d // indirect
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect
|
||||||
|
google.golang.org/grpc v1.65.0 // indirect
|
||||||
|
google.golang.org/protobuf v1.35.2 // indirect
|
||||||
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
|
)
|
||||||
137
go.sum
Normal file
137
go.sum
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
|
||||||
|
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
|
||||||
|
github.com/DATA-DOG/go-sqlmock v1.5.2 h1:OcvFkGmslmlZibjAjaHm3L//6LiuBgolP7OputlJIzU=
|
||||||
|
github.com/DATA-DOG/go-sqlmock v1.5.2/go.mod h1:88MAG/4G7SMwSE3CeA0ZKzrT5CiOU3OJ+JlNzwDqpNU=
|
||||||
|
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
|
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||||
|
github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8=
|
||||||
|
github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE=
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||||
|
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||||
|
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||||
|
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||||
|
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
|
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||||
|
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||||
|
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||||
|
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||||
|
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
|
||||||
|
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
|
||||||
|
github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo=
|
||||||
|
github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||||
|
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||||
|
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
|
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||||
|
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0=
|
||||||
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k=
|
||||||
|
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
|
||||||
|
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
|
||||||
|
github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA=
|
||||||
|
github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw=
|
||||||
|
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||||
|
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||||
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
|
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
|
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||||
|
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||||
|
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||||
|
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||||
|
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||||
|
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||||
|
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||||
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
|
github.com/openzipkin/zipkin-go v0.4.3 h1:9EGwpqkgnwdEIJ+Od7QVSEIH+ocmm5nPat0G7sjsSdg=
|
||||||
|
github.com/openzipkin/zipkin-go v0.4.3/go.mod h1:M9wCJZFWCo2RiY+o1eBCEMe0Dp2S5LDHcMZmk3RmK7c=
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||||
|
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
|
||||||
|
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
|
||||||
|
github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y=
|
||||||
|
github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE=
|
||||||
|
github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E=
|
||||||
|
github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY=
|
||||||
|
github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc=
|
||||||
|
github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8=
|
||||||
|
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||||
|
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||||
|
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
|
||||||
|
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
|
||||||
|
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
||||||
|
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
|
github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w=
|
||||||
|
github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||||
|
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||||
|
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||||
|
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||||
|
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
|
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||||
|
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
|
github.com/zeromicro/go-zero v1.7.4 h1:lyIUsqbpVRzM4NmXu5pRM3XrdRdUuWOkQmHiNmJF0VU=
|
||||||
|
github.com/zeromicro/go-zero v1.7.4/go.mod h1:jmv4hTdUBkDn6kxgI+WrKQw0q6LKxDElGPMfCLOeeEY=
|
||||||
|
go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
|
||||||
|
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
|
||||||
|
go.opentelemetry.io/otel/exporters/jaeger v1.17.0 h1:D7UpUy2Xc2wsi1Ras6V40q806WM07rqoCWzXu7Sqy+4=
|
||||||
|
go.opentelemetry.io/otel/exporters/jaeger v1.17.0/go.mod h1:nPCqOnEH9rNLKqH/+rrUjiMzHJdV1BlpKcTwRTyKkKI=
|
||||||
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0 h1:t6wl9SPayj+c7lEIFgm4ooDBZVb01IhLB4InpomhRw8=
|
||||||
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.24.0/go.mod h1:iSDOcsnSA5INXzZtwaBPrKp/lWu/V14Dd+llD0oI2EA=
|
||||||
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0 h1:Mw5xcxMwlqoJd97vwPxA8isEaIoxsta9/Q51+TTJLGE=
|
||||||
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.24.0/go.mod h1:CQNu9bj7o7mC6U7+CA/schKEYakYXWr79ucDHTMGhCM=
|
||||||
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0 h1:Xw8U6u2f8DK2XAkGRFV7BBLENgnTGX9i4rQRxJf+/vs=
|
||||||
|
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.24.0/go.mod h1:6KW1Fm6R/s6Z3PGXwSJN2K4eT6wQB3vXX6CVnYX9NmM=
|
||||||
|
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.24.0 h1:s0PHtIkN+3xrbDOpt2M8OTG92cWqUESvzh2MxiR5xY8=
|
||||||
|
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.24.0/go.mod h1:hZlFbDbRt++MMPCCfSJfmhkGIWnX1h3XjkfxZUjLrIA=
|
||||||
|
go.opentelemetry.io/otel/exporters/zipkin v1.24.0 h1:3evrL5poBuh1KF51D9gO/S+N/1msnm4DaBqs/rpXUqY=
|
||||||
|
go.opentelemetry.io/otel/exporters/zipkin v1.24.0/go.mod h1:0EHgD8R0+8yRhUYJOGR8Hfg2dpiJQxDOszd5smVO9wM=
|
||||||
|
go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI=
|
||||||
|
go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
|
||||||
|
go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw=
|
||||||
|
go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg=
|
||||||
|
go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
|
||||||
|
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
|
||||||
|
go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0=
|
||||||
|
go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8=
|
||||||
|
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
|
||||||
|
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
|
||||||
|
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||||
|
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||||
|
golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo=
|
||||||
|
golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM=
|
||||||
|
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s=
|
||||||
|
golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
|
golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug=
|
||||||
|
golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4=
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d h1:kHjw/5UfflP/L5EbledDrcG4C2597RtymmGRZvHiCuY=
|
||||||
|
google.golang.org/genproto/googleapis/api v0.0.0-20240711142825-46eb208f015d/go.mod h1:mw8MG/Qz5wfgYr6VqVCiZcHe/GJEfI+oGGDCohaVgB0=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA=
|
||||||
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY=
|
||||||
|
google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc=
|
||||||
|
google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ=
|
||||||
|
google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io=
|
||||||
|
google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
|
gopkg.in/h2non/gock.v1 v1.1.2 h1:jBbHXgGBK/AoPVfJh5x4r/WxIrElvbLel8TCZkkZJoY=
|
||||||
|
gopkg.in/h2non/gock.v1 v1.1.2/go.mod h1:n7UGz/ckNChHiK05rDoiC4MYSunEC/lyaUm2WWaDva0=
|
||||||
|
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
|
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8 h1:pUdcCO1Lk/tbT5ztQWOBi5HBgbBP1J8+AsQnQCKsi8A=
|
||||||
|
k8s.io/utils v0.0.0-20240711033017-18e509b52bc8/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||||
159
goctl.yaml
Normal file
159
goctl.yaml
Normal file
@@ -0,0 +1,159 @@
|
|||||||
|
model:
|
||||||
|
types_map:
|
||||||
|
bigint:
|
||||||
|
null_type: sql.NullInt64
|
||||||
|
type: int64
|
||||||
|
unsigned_type: uint64
|
||||||
|
dec:
|
||||||
|
null_type: decimal.NullDecimal
|
||||||
|
pkg: github.com/shopspring/decimal
|
||||||
|
type: decimal.Decimal
|
||||||
|
decimal:
|
||||||
|
null_type: decimal.NullDecimal
|
||||||
|
pkg: github.com/shopspring/decimal
|
||||||
|
type: decimal.Decimal
|
||||||
|
double:
|
||||||
|
null_type: sql.NullFloat64
|
||||||
|
type: float64
|
||||||
|
float:
|
||||||
|
null_type: sql.NullFloat64
|
||||||
|
type: float64
|
||||||
|
float4:
|
||||||
|
null_type: sql.NullFloat64
|
||||||
|
type: float64
|
||||||
|
float8:
|
||||||
|
null_type: sql.NullFloat64
|
||||||
|
type: float64
|
||||||
|
int:
|
||||||
|
null_type: sql.NullInt64
|
||||||
|
type: int
|
||||||
|
unsigned_type: uint
|
||||||
|
int1:
|
||||||
|
null_type: sql.NullInt64
|
||||||
|
type: int64
|
||||||
|
unsigned_type: uint64
|
||||||
|
int2:
|
||||||
|
null_type: sql.NullInt64
|
||||||
|
type: int64
|
||||||
|
unsigned_type: uint64
|
||||||
|
int3:
|
||||||
|
null_type: sql.NullInt64
|
||||||
|
type: int64
|
||||||
|
unsigned_type: uint64
|
||||||
|
int4:
|
||||||
|
null_type: sql.NullInt64
|
||||||
|
type: int64
|
||||||
|
unsigned_type: uint64
|
||||||
|
int8:
|
||||||
|
null_type: sql.NullInt64
|
||||||
|
type: int64
|
||||||
|
unsigned_type: uint64
|
||||||
|
integer:
|
||||||
|
null_type: sql.NullInt64
|
||||||
|
type: int
|
||||||
|
unsigned_type: uint
|
||||||
|
mediumint:
|
||||||
|
null_type: sql.NullInt64
|
||||||
|
type: int64
|
||||||
|
unsigned_type: uint64
|
||||||
|
middleint:
|
||||||
|
null_type: sql.NullInt64
|
||||||
|
type: int64
|
||||||
|
unsigned_type: uint64
|
||||||
|
smallint:
|
||||||
|
null_type: sql.NullInt64
|
||||||
|
type: int64
|
||||||
|
unsigned_type: uint64
|
||||||
|
tinyint:
|
||||||
|
null_type: sql.NullInt16
|
||||||
|
type: int8
|
||||||
|
unsigned_type: uint8
|
||||||
|
date:
|
||||||
|
null_type: sql.NullTime
|
||||||
|
type: time.Time
|
||||||
|
datetime:
|
||||||
|
null_type: sql.NullTime
|
||||||
|
type: time.Time
|
||||||
|
timestamp:
|
||||||
|
null_type: sql.NullTime
|
||||||
|
type: time.Time
|
||||||
|
time:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
year:
|
||||||
|
null_type: sql.NullInt64
|
||||||
|
type: int64
|
||||||
|
unsigned_type: uint64
|
||||||
|
bit:
|
||||||
|
null_type: sql.NullByte
|
||||||
|
type: byte
|
||||||
|
unsigned_type: byte
|
||||||
|
bool:
|
||||||
|
null_type: sql.NullBool
|
||||||
|
type: bool
|
||||||
|
boolean:
|
||||||
|
null_type: sql.NullBool
|
||||||
|
type: bool
|
||||||
|
char:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
varchar:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
nvarchar:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
nchar:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
character:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
longvarchar:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
linestring:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
multilinestring:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
binary:
|
||||||
|
null_type: "[]byte"
|
||||||
|
type: "[]byte"
|
||||||
|
varbinary:
|
||||||
|
null_type: "[]byte"
|
||||||
|
type: "[]byte"
|
||||||
|
tinytext:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
text:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
mediumtext:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
longtext:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
set:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
json:
|
||||||
|
null_type: sql.NullString
|
||||||
|
type: string
|
||||||
|
blob:
|
||||||
|
null_type: "[]byte"
|
||||||
|
type: "[]byte"
|
||||||
|
longblob:
|
||||||
|
null_type: "[]byte"
|
||||||
|
type: "[]byte"
|
||||||
|
mediumblob:
|
||||||
|
null_type: "[]byte"
|
||||||
|
type: "[]byte"
|
||||||
|
tinyblob:
|
||||||
|
null_type: "[]byte"
|
||||||
|
type: "[]byte"
|
||||||
40
internal/config/config.go
Normal file
40
internal/config/config.go
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
"github.com/zeromicro/go-zero/rest"
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
rest.RestConf
|
||||||
|
MySql MySqlConf
|
||||||
|
Auth struct {
|
||||||
|
AccessSecret string
|
||||||
|
AccessExpire int64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MySqlConf mysql配置
|
||||||
|
type MySqlConf struct {
|
||||||
|
Addr string
|
||||||
|
User string
|
||||||
|
Password string
|
||||||
|
Database string
|
||||||
|
Loc string `json:",default=Local"`
|
||||||
|
Log string `json:",default=disableStmt,options=allow|disable|disableStmt"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m MySqlConf) Dsn() string {
|
||||||
|
return fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=utf8mb4&parseTime=True&loc=%s", m.User, m.Password, m.Addr, m.Database, url.QueryEscape(m.Loc))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m MySqlConf) Conn(opts ...sqlx.SqlOption) sqlx.SqlConn {
|
||||||
|
if m.Log == "disable" {
|
||||||
|
sqlx.DisableLog()
|
||||||
|
} else if m.Log == "disableStmt" {
|
||||||
|
sqlx.DisableStmtLog()
|
||||||
|
}
|
||||||
|
return sqlx.NewMysql(m.Dsn(), opts...)
|
||||||
|
}
|
||||||
34
internal/handler/routes.go
Normal file
34
internal/handler/routes.go
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
// Code generated by goctl. DO NOT EDIT.
|
||||||
|
// goctl 1.7.3
|
||||||
|
|
||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
task "nova_task/internal/handler/task"
|
||||||
|
"nova_task/internal/svc"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/rest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||||
|
server.AddRoutes(
|
||||||
|
[]rest.Route{
|
||||||
|
{
|
||||||
|
// 领取任务奖励
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Path: "/reward/:id",
|
||||||
|
Handler: task.GetTaskRewardHandler(serverCtx),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// 获取任务列表
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Path: "/tasks",
|
||||||
|
Handler: task.GetTaskListHandler(serverCtx),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
rest.WithJwt(serverCtx.Config.Auth.AccessSecret),
|
||||||
|
rest.WithPrefix("/api/task/v1"),
|
||||||
|
)
|
||||||
|
}
|
||||||
29
internal/handler/task/get_task_list_handler.go
Normal file
29
internal/handler/task/get_task_list_handler.go
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package task
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
|
"nova_task/internal/logic/task"
|
||||||
|
"nova_task/internal/svc"
|
||||||
|
"nova_task/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 获取任务列表
|
||||||
|
func GetTaskListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var req types.GetTaskListReq
|
||||||
|
if err := httpx.Parse(r, &req); err != nil {
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
l := task.NewGetTaskListLogic(r.Context(), svcCtx)
|
||||||
|
resp, err := l.GetTaskList(&req)
|
||||||
|
if err != nil {
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
} else {
|
||||||
|
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
29
internal/handler/task/get_task_reward_handler.go
Normal file
29
internal/handler/task/get_task_reward_handler.go
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package task
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
|
"nova_task/internal/logic/task"
|
||||||
|
"nova_task/internal/svc"
|
||||||
|
"nova_task/internal/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 领取任务奖励
|
||||||
|
func GetTaskRewardHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var req types.GetTaskRewardReq
|
||||||
|
if err := httpx.Parse(r, &req); err != nil {
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
l := task.NewGetTaskRewardLogic(r.Context(), svcCtx)
|
||||||
|
resp, err := l.GetTaskReward(&req)
|
||||||
|
if err != nil {
|
||||||
|
httpx.ErrorCtx(r.Context(), w, err)
|
||||||
|
} else {
|
||||||
|
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
53
internal/logic/task/get_task_list_logic.go
Normal file
53
internal/logic/task/get_task_list_logic.go
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
package task
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"nova_task/internal/pkg/errs"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"nova_task/internal/svc"
|
||||||
|
"nova_task/internal/types"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetTaskListLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewGetTaskListLogic 获取任务列表
|
||||||
|
func NewGetTaskListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetTaskListLogic {
|
||||||
|
return &GetTaskListLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *GetTaskListLogic) GetTaskList(req *types.GetTaskListReq) (*types.GetTaskListResp, error) {
|
||||||
|
tasks, err := l.svcCtx.TaskModel.FindTasksByCommunity(l.ctx, req.CommunityId)
|
||||||
|
if err != nil {
|
||||||
|
l.Errorw("get task list failed", logx.Field("err", err), logx.Field("communityId", req.CommunityId))
|
||||||
|
return nil, errs.InternalServer(errs.ErrDatabaseOperate, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp := &types.GetTaskListResp{}
|
||||||
|
for _, t := range tasks {
|
||||||
|
resp.Tasks = append(resp.Tasks, types.Task{
|
||||||
|
Id: t.Id,
|
||||||
|
Title: t.Title,
|
||||||
|
SubTitle: t.SubTitle,
|
||||||
|
Description: t.Description,
|
||||||
|
Points: t.Points,
|
||||||
|
ButtonText: t.ButtonText,
|
||||||
|
Type: t.Type,
|
||||||
|
StartAt: t.StartAt.Time.Format(time.DateTime),
|
||||||
|
EndAt: t.EndAt.Time.Format(time.DateTime),
|
||||||
|
Status: t.Status,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
31
internal/logic/task/get_task_reward_logic.go
Normal file
31
internal/logic/task/get_task_reward_logic.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package task
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"nova_task/internal/svc"
|
||||||
|
"nova_task/internal/types"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetTaskRewardLogic struct {
|
||||||
|
logx.Logger
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
}
|
||||||
|
|
||||||
|
// 领取任务奖励
|
||||||
|
func NewGetTaskRewardLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetTaskRewardLogic {
|
||||||
|
return &GetTaskRewardLogic{
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *GetTaskRewardLogic) GetTaskReward(req *types.GetTaskRewardReq) (resp *types.GetTaskRewardResp, err error) {
|
||||||
|
// todo: add your logic here and delete this line
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
45
internal/model/nh_task_model.go
Executable file
45
internal/model/nh_task_model.go
Executable file
@@ -0,0 +1,45 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ NhTaskModel = (*customNhTaskModel)(nil)
|
||||||
|
|
||||||
|
type (
|
||||||
|
// NhTaskModel is an interface to be customized, add more methods here,
|
||||||
|
// and implement the added methods in customNhTaskModel.
|
||||||
|
NhTaskModel interface {
|
||||||
|
nhTaskModel
|
||||||
|
withSession(session sqlx.Session) NhTaskModel
|
||||||
|
FindTasksByCommunity(ctx context.Context, communityId uint) ([]*NhTask, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
customNhTaskModel struct {
|
||||||
|
*defaultNhTaskModel
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (m *customNhTaskModel) FindTasksByCommunity(ctx context.Context, communityId uint) ([]*NhTask, error) {
|
||||||
|
query := fmt.Sprintf("select %s from %s where community_id = ?", nhTaskRows, m.table)
|
||||||
|
var tasks []*NhTask
|
||||||
|
err := m.conn.QueryRowsCtx(ctx, &tasks, query, communityId)
|
||||||
|
if err != nil && !errors.Is(err, sqlx.ErrNotFound) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return tasks, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewNhTaskModel returns a model for the database table.
|
||||||
|
func NewNhTaskModel(conn sqlx.SqlConn) NhTaskModel {
|
||||||
|
return &customNhTaskModel{
|
||||||
|
defaultNhTaskModel: newNhTaskModel(conn),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *customNhTaskModel) withSession(session sqlx.Session) NhTaskModel {
|
||||||
|
return NewNhTaskModel(sqlx.NewSqlConnFromSession(session))
|
||||||
|
}
|
||||||
97
internal/model/nh_task_model_gen.go
Executable file
97
internal/model/nh_task_model_gen.go
Executable file
@@ -0,0 +1,97 @@
|
|||||||
|
// Code generated by goctl. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// goctl version: 1.7.3
|
||||||
|
|
||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/builder"
|
||||||
|
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
"github.com/zeromicro/go-zero/core/stringx"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
nhTaskFieldNames = builder.RawFieldNames(&NhTask{})
|
||||||
|
nhTaskRows = strings.Join(nhTaskFieldNames, ",")
|
||||||
|
nhTaskRowsExpectAutoSet = strings.Join(stringx.Remove(nhTaskFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), ",")
|
||||||
|
nhTaskRowsWithPlaceHolder = strings.Join(stringx.Remove(nhTaskFieldNames, "`id`", "`create_at`", "`create_time`", "`created_at`", "`update_at`", "`update_time`", "`updated_at`"), "=?,") + "=?"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
nhTaskModel interface {
|
||||||
|
Insert(ctx context.Context, data *NhTask) (sql.Result, error)
|
||||||
|
FindOne(ctx context.Context, id uint) (*NhTask, error)
|
||||||
|
Update(ctx context.Context, data *NhTask) error
|
||||||
|
Delete(ctx context.Context, id uint) error
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultNhTaskModel struct {
|
||||||
|
conn sqlx.SqlConn
|
||||||
|
table string
|
||||||
|
}
|
||||||
|
|
||||||
|
NhTask struct {
|
||||||
|
Id uint `db:"id"`
|
||||||
|
CommunityId uint `db:"community_id"` // 合作社区ID,0=官方平台
|
||||||
|
Title string `db:"title"` // 大标题
|
||||||
|
SubTitle string `db:"sub_title"` // 子标题
|
||||||
|
Description string `db:"description"` // 描述
|
||||||
|
Points int `db:"points"` // 积分数量
|
||||||
|
ButtonText string `db:"button_text"` // 按钮上的文字
|
||||||
|
Type int8 `db:"type"` // 0=一次性任务,1=每天任务
|
||||||
|
Status int8 `db:"status"` // 0=不启用,1=启用
|
||||||
|
StartAt sql.NullTime `db:"start_at"` // 开始时间
|
||||||
|
EndAt sql.NullTime `db:"end_at"` // 结束时间
|
||||||
|
CreatedAt time.Time `db:"created_at"` // 创建时间
|
||||||
|
UpdatedAt time.Time `db:"updated_at"` // 修改时间
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func newNhTaskModel(conn sqlx.SqlConn) *defaultNhTaskModel {
|
||||||
|
return &defaultNhTaskModel{
|
||||||
|
conn: conn,
|
||||||
|
table: "`nh_task`",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultNhTaskModel) Delete(ctx context.Context, id uint) error {
|
||||||
|
query := fmt.Sprintf("delete from %s where `id` = ?", m.table)
|
||||||
|
_, err := m.conn.ExecCtx(ctx, query, id)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultNhTaskModel) FindOne(ctx context.Context, id uint) (*NhTask, error) {
|
||||||
|
query := fmt.Sprintf("select %s from %s where `id` = ? limit 1", nhTaskRows, m.table)
|
||||||
|
var resp NhTask
|
||||||
|
err := m.conn.QueryRowCtx(ctx, &resp, query, id)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
return &resp, nil
|
||||||
|
case sqlx.ErrNotFound:
|
||||||
|
return nil, ErrNotFound
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultNhTaskModel) Insert(ctx context.Context, data *NhTask) (sql.Result, error) {
|
||||||
|
query := fmt.Sprintf("insert into %s (%s) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", m.table, nhTaskRowsExpectAutoSet)
|
||||||
|
ret, err := m.conn.ExecCtx(ctx, query, data.CommunityId, data.Title, data.SubTitle, data.Description, data.Points, data.ButtonText, data.Type, data.Status, data.StartAt, data.EndAt)
|
||||||
|
return ret, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultNhTaskModel) Update(ctx context.Context, data *NhTask) error {
|
||||||
|
query := fmt.Sprintf("update %s set %s where `id` = ?", m.table, nhTaskRowsWithPlaceHolder)
|
||||||
|
_, err := m.conn.ExecCtx(ctx, query, data.CommunityId, data.Title, data.SubTitle, data.Description, data.Points, data.ButtonText, data.Type, data.Status, data.StartAt, data.EndAt, data.Id)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultNhTaskModel) tableName() string {
|
||||||
|
return m.table
|
||||||
|
}
|
||||||
5
internal/model/vars.go
Normal file
5
internal/model/vars.go
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import "github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||||
|
|
||||||
|
var ErrNotFound = sqlx.ErrNotFound
|
||||||
106
internal/pkg/encrypt/jwt/jwt.go
Normal file
106
internal/pkg/encrypt/jwt/jwt.go
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
package jwt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
jwt "github.com/golang-jwt/jwt/v4"
|
||||||
|
"github.com/spf13/cast"
|
||||||
|
"github.com/zeromicro/go-zero/rest/token"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
AccessSecret string `json:",default=ac2d27613e131be6286c0eb17139293d"`
|
||||||
|
AccessExpire time.Duration `json:",default=24h"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TokenBuilder struct {
|
||||||
|
config Config
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTokenBuilder(config Config) *TokenBuilder {
|
||||||
|
return &TokenBuilder{config: config}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenerateToken 生成token
|
||||||
|
func (b *TokenBuilder) GenerateToken(kvs map[string]any) (string, int64, error) {
|
||||||
|
// 创建一个新的 Token
|
||||||
|
tok := jwt.New(jwt.SigningMethodHS256)
|
||||||
|
// 设置 Token 的声明(Payload)
|
||||||
|
claims := tok.Claims.(jwt.MapClaims)
|
||||||
|
for k, v := range kvs {
|
||||||
|
claims[k] = v
|
||||||
|
}
|
||||||
|
expiredAt := time.Now().Add(b.config.AccessExpire).Unix()
|
||||||
|
claims["exp"] = expiredAt // 设置过期时间
|
||||||
|
|
||||||
|
// 使用密钥签名 Token
|
||||||
|
tkStr, err := tok.SignedString([]byte(b.config.AccessSecret))
|
||||||
|
return tkStr, expiredAt, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *TokenBuilder) ParseUidFromToken(tokenStr string) (string, string, string, int64, error) {
|
||||||
|
r := &http.Request{Header: http.Header{}}
|
||||||
|
r.Header.Set("Authorization", fmt.Sprintf("Bearer %s", tokenStr))
|
||||||
|
parser := token.NewTokenParser()
|
||||||
|
tok, err := parser.ParseToken(r, b.config.AccessSecret, "")
|
||||||
|
if err != nil {
|
||||||
|
return "", "", "", 0, err
|
||||||
|
}
|
||||||
|
if !tok.Valid {
|
||||||
|
return "", "", "", 0, errors.New("token is invalid")
|
||||||
|
}
|
||||||
|
var appid, userId, tgId string
|
||||||
|
var expiredAt int64
|
||||||
|
if claims, ok := tok.Claims.(jwt.MapClaims); ok {
|
||||||
|
if uid, ok := claims["uid"]; ok {
|
||||||
|
userId = cast.ToString(uid)
|
||||||
|
}
|
||||||
|
if aid, ok := claims["app_id"]; ok {
|
||||||
|
appid = cast.ToString(aid)
|
||||||
|
}
|
||||||
|
if tid, ok := claims["tg_id"]; ok {
|
||||||
|
tgId = cast.ToString(tid)
|
||||||
|
}
|
||||||
|
if exp, ok := claims["exp"]; ok {
|
||||||
|
expiredAt = cast.ToInt64(exp)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return appid, userId, tgId, expiredAt, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
//// ParseUid 解析出uid
|
||||||
|
//func (b *TokenBuilder) ParseUid(r *http.Request) (string, error) {
|
||||||
|
// parser := token.NewTokenParser()
|
||||||
|
// tok, err := parser.ParseToken(r, b.config.AccessSecret, "")
|
||||||
|
// if err != nil {
|
||||||
|
// return "", err
|
||||||
|
// }
|
||||||
|
// if !tok.Valid {
|
||||||
|
// return "", errors.New("token is invalid")
|
||||||
|
// }
|
||||||
|
// if claims, ok := tok.Claims.(jwt.MapClaims); ok {
|
||||||
|
// if uid, ok := claims["uid"]; ok {
|
||||||
|
// return cast.ToString(uid), nil
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return "", errors.New("token not exist uid")
|
||||||
|
//}
|
||||||
|
|
||||||
|
//func ParseUid(r *http.Request, accessSecret string) (string, error) {
|
||||||
|
// parser := token.NewTokenParser()
|
||||||
|
// tok, err := parser.ParseToken(r, accessSecret, "")
|
||||||
|
// if err != nil {
|
||||||
|
// return "", err
|
||||||
|
// }
|
||||||
|
// if !tok.Valid {
|
||||||
|
// return "", errors.New("token is invalid")
|
||||||
|
// }
|
||||||
|
// if claims, ok := tok.Claims.(jwt.MapClaims); ok {
|
||||||
|
// if uid, ok := claims["uid"]; ok {
|
||||||
|
// return cast.ToString(uid), nil
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// return "", errors.New("token not exist uid")
|
||||||
|
//}
|
||||||
31
internal/pkg/encrypt/md5/md5.go
Normal file
31
internal/pkg/encrypt/md5/md5.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package md5
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/md5"
|
||||||
|
"encoding/hex"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Md5(src []byte) string {
|
||||||
|
has := md5.Sum(src)
|
||||||
|
md5Str := hex.EncodeToString(has[:])
|
||||||
|
return md5Str
|
||||||
|
}
|
||||||
|
|
||||||
|
func Md5str(src string) string {
|
||||||
|
return Md5([]byte(src))
|
||||||
|
}
|
||||||
|
|
||||||
|
func Md516(src string) string {
|
||||||
|
data := []byte(src)
|
||||||
|
has := md5.Sum(data)
|
||||||
|
md5Str := hex.EncodeToString(has[:])
|
||||||
|
return md5Str[8:24]
|
||||||
|
}
|
||||||
|
|
||||||
|
func Md516Upper(src string) string {
|
||||||
|
data := []byte(src)
|
||||||
|
has := md5.Sum(data)
|
||||||
|
md5Str := fmt.Sprintf("%X", has)
|
||||||
|
return md5Str[8:24]
|
||||||
|
}
|
||||||
30
internal/pkg/encrypt/sha/sha.go
Normal file
30
internal/pkg/encrypt/sha/sha.go
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package sha
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/hmac"
|
||||||
|
"crypto/sha1"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/hex"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Sha1(src string) string {
|
||||||
|
h := sha1.New()
|
||||||
|
h.Write([]byte(src))
|
||||||
|
sh := hex.EncodeToString(h.Sum(nil))
|
||||||
|
return sh
|
||||||
|
}
|
||||||
|
|
||||||
|
func Sha256(src string) string {
|
||||||
|
m := sha256.New()
|
||||||
|
m.Write([]byte(src))
|
||||||
|
res := hex.EncodeToString(m.Sum(nil))
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func HmacSha256Base64(src, secret string) string {
|
||||||
|
h := hmac.New(sha256.New, []byte(secret))
|
||||||
|
h.Write([]byte(src))
|
||||||
|
sign := base64.StdEncoding.EncodeToString(h.Sum(nil))
|
||||||
|
return sign
|
||||||
|
}
|
||||||
40
internal/pkg/errs/error.go
Normal file
40
internal/pkg/errs/error.go
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package errs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/spf13/cast"
|
||||||
|
)
|
||||||
|
|
||||||
|
type err struct {
|
||||||
|
code int
|
||||||
|
reason Reason
|
||||||
|
msg string
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(code int, reason Reason, message any) error {
|
||||||
|
return err{
|
||||||
|
code: code,
|
||||||
|
reason: reason,
|
||||||
|
msg: cast.ToString(message),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error error
|
||||||
|
func (e err) Error() string {
|
||||||
|
return fmt.Sprintf("code=%d msg=%s", e.code, e.msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Code return code
|
||||||
|
func (e err) Code() int {
|
||||||
|
return e.code
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reason return reason
|
||||||
|
func (e err) Reason() Reason {
|
||||||
|
return e.reason
|
||||||
|
}
|
||||||
|
|
||||||
|
// Message return message
|
||||||
|
func (e err) Message() string {
|
||||||
|
return e.msg
|
||||||
|
}
|
||||||
56
internal/pkg/errs/errors.go
Normal file
56
internal/pkg/errs/errors.go
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package errs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Success() error {
|
||||||
|
return New(http.StatusOK, ErrSucceed, "success")
|
||||||
|
}
|
||||||
|
|
||||||
|
func NotFound(reason Reason, v any) error {
|
||||||
|
return New(http.StatusNotFound, reason, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func BadRequest(reason Reason, v any) error {
|
||||||
|
return New(http.StatusBadRequest, reason, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
func InternalServer(reason Reason, v any) error {
|
||||||
|
return New(http.StatusInternalServerError, reason, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unauthorized new Unauthorized error that is mapped to a 401 response.
|
||||||
|
func Unauthorized(reason Reason, v any) error {
|
||||||
|
return New(http.StatusUnauthorized, reason, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Forbidden new Forbidden error that is mapped to a 403 response.
|
||||||
|
func Forbidden(reason Reason, v any) error {
|
||||||
|
return New(http.StatusForbidden, reason, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Conflict new Conflict error that is mapped to a 409 response.
|
||||||
|
func Conflict(reason Reason, v any) error {
|
||||||
|
return New(http.StatusConflict, reason, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServiceUnavailable new ServiceUnavailable error that is mapped to an HTTP 503 response.
|
||||||
|
func ServiceUnavailable(reason Reason, v any) error {
|
||||||
|
return New(http.StatusServiceUnavailable, reason, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GatewayTimeout new GatewayTimeout error that is mapped to an HTTP 504 response.
|
||||||
|
func GatewayTimeout(reason Reason, v any) error {
|
||||||
|
return New(http.StatusGatewayTimeout, reason, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// BadGateway new BadGateway error that is mapped to an HTTP 504 response.
|
||||||
|
func BadGateway(reason Reason, v any) error {
|
||||||
|
return New(http.StatusBadGateway, reason, v)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ClientClosed new ClientClosed error that is mapped to an HTTP 499 response.
|
||||||
|
func ClientClosed(reason Reason, v any) error {
|
||||||
|
return New(499, reason, v)
|
||||||
|
}
|
||||||
64
internal/pkg/errs/http_respone.go
Normal file
64
internal/pkg/errs/http_respone.go
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
package errs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/zeromicro/go-zero/rest/httpx"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var debug bool
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
if strings.ToLower(os.Getenv("VANS_API_DEBUG")) == "on" {
|
||||||
|
debug = true
|
||||||
|
}
|
||||||
|
httpx.SetErrorHandlerCtx(ErrorHandleCtx)
|
||||||
|
httpx.SetErrorHandler(ErrorHandle)
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetDebug(d bool) {
|
||||||
|
debug = d
|
||||||
|
}
|
||||||
|
|
||||||
|
func ErrorHandle(err error) (int, any) {
|
||||||
|
return ErrorHandleCtx(context.Background(), err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ErrorHandleCtx(ctx context.Context, err error) (int, any) {
|
||||||
|
code := http.StatusBadRequest
|
||||||
|
reason := ErrInternalServer
|
||||||
|
var msg string
|
||||||
|
if ec, ok := err.(interface{ Code() int }); ok {
|
||||||
|
code = ec.Code()
|
||||||
|
}
|
||||||
|
if ec, ok := err.(interface{ Message() string }); ok {
|
||||||
|
msg = ec.Message()
|
||||||
|
} else {
|
||||||
|
msg = err.Error()
|
||||||
|
}
|
||||||
|
if ec, ok := err.(interface{ Reason() Reason }); ok {
|
||||||
|
reason = ec.Reason()
|
||||||
|
}
|
||||||
|
|
||||||
|
var errMsg string
|
||||||
|
if reason < ErrUnknownLogicError && reason != ErrSucceed {
|
||||||
|
errMsg = msg
|
||||||
|
msg = "system error"
|
||||||
|
}
|
||||||
|
|
||||||
|
body := map[string]any{
|
||||||
|
"code": reason,
|
||||||
|
"message": msg,
|
||||||
|
}
|
||||||
|
if errMsg != "" && debug {
|
||||||
|
body["err"] = errMsg
|
||||||
|
}
|
||||||
|
if ec, ok := err.(interface{ Metadata() any }); ok {
|
||||||
|
if md := ec.Metadata(); md != nil {
|
||||||
|
body["metadata"] = md
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return code, body
|
||||||
|
}
|
||||||
33
internal/pkg/errs/reason.go
Normal file
33
internal/pkg/errs/reason.go
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
package errs
|
||||||
|
|
||||||
|
type Reason int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// ======= 系统错误:0~999 =======
|
||||||
|
ErrUnknownReason Reason = 0 // 未知错误
|
||||||
|
ErrSucceed Reason = 200 // 成功
|
||||||
|
ErrOverload Reason = 403 // 请求超载
|
||||||
|
|
||||||
|
// ======= 服务器内部错误:1000~9999 =======
|
||||||
|
ErrInternalServer Reason = 1000 // 未知的服务器内部错误
|
||||||
|
ErrDatabaseOperate Reason = 1001 // 数据库错误
|
||||||
|
ErrRedisOperate Reason = 1002 // redis错误
|
||||||
|
ErrEncodePassword Reason = 1003 // 密码加密错误
|
||||||
|
ErrGenerateUUid Reason = 1004 // 生成uuid错误
|
||||||
|
ErrGenerateToken Reason = 1005 // 生成token错误
|
||||||
|
ErrGetExchangeRate Reason = 1005 // 获取汇率错误
|
||||||
|
|
||||||
|
// ======= 业务层错误:10000~99999 =======
|
||||||
|
ErrUnknownLogicError Reason = 10000 // 未知的业务错误
|
||||||
|
ErrInvalidParam Reason = 10001 // 无效参数错误
|
||||||
|
ErrInvalidSignature Reason = 10002 // 无效签名错误
|
||||||
|
ErrInvalidToken Reason = 10003 // 无效的token
|
||||||
|
ErrInvoiceHasPaid Reason = 10004 // 订单已支付
|
||||||
|
ErrInvalidAppId Reason = 10005 // 应用id无效
|
||||||
|
ErrUserNotHasInviter Reason = 10006 // 用户没有邀请人
|
||||||
|
|
||||||
|
// ========= admin 业务相关错误码: 30000~39999 =========
|
||||||
|
ErrUnknownAdminError Reason = 30000 // 未知的admin错误
|
||||||
|
ErrInvalidPassword Reason = 30001 // 无效密码
|
||||||
|
ErrInvalidAccount Reason = 30002 // 无效账号
|
||||||
|
)
|
||||||
18
internal/svc/service_context.go
Normal file
18
internal/svc/service_context.go
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package svc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"nova_task/internal/config"
|
||||||
|
"nova_task/internal/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ServiceContext struct {
|
||||||
|
Config config.Config
|
||||||
|
TaskModel model.NhTaskModel
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewServiceContext(c config.Config) *ServiceContext {
|
||||||
|
return &ServiceContext{
|
||||||
|
Config: c,
|
||||||
|
TaskModel: model.NewNhTaskModel(c.MySql.Conn()),
|
||||||
|
}
|
||||||
|
}
|
||||||
33
internal/types/types.go
Normal file
33
internal/types/types.go
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
// Code generated by goctl. DO NOT EDIT.
|
||||||
|
// goctl 1.7.3
|
||||||
|
|
||||||
|
package types
|
||||||
|
|
||||||
|
type GetTaskListReq struct {
|
||||||
|
CommunityId uint `form:"community_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetTaskListResp struct {
|
||||||
|
Tasks []Task `json:"tasks"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetTaskRewardReq struct {
|
||||||
|
ID uint `path:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetTaskRewardResp struct {
|
||||||
|
Points int `json:"points"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Task struct {
|
||||||
|
Id uint `json:"id"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
SubTitle string `json:"sub_title"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Points int `json:"points"`
|
||||||
|
ButtonText string `json:"button_text"`
|
||||||
|
Type int8 `json:"type"`
|
||||||
|
StartAt string `json:"start_at"`
|
||||||
|
EndAt string `json:"end_at"`
|
||||||
|
Status int8 `json:"status"`
|
||||||
|
}
|
||||||
32
novatask.go
Normal file
32
novatask.go
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"nova_task/internal/config"
|
||||||
|
"nova_task/internal/handler"
|
||||||
|
"nova_task/internal/svc"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/conf"
|
||||||
|
"github.com/zeromicro/go-zero/rest"
|
||||||
|
)
|
||||||
|
|
||||||
|
var configFile = flag.String("f", "etc/novatask.yaml", "the config file")
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
var c config.Config
|
||||||
|
conf.MustLoad(*configFile, &c)
|
||||||
|
c.MustSetUp()
|
||||||
|
|
||||||
|
server := rest.MustNewServer(c.RestConf)
|
||||||
|
defer server.Stop()
|
||||||
|
|
||||||
|
ctx := svc.NewServiceContext(c)
|
||||||
|
handler.RegisterHandlers(server, ctx)
|
||||||
|
|
||||||
|
fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)
|
||||||
|
server.Start()
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user