用DDD分项目模块
This commit is contained in:
2
server/.gitignore
vendored
2
server/.gitignore
vendored
@@ -2,3 +2,5 @@
|
||||
server/pkg/mod/
|
||||
server/pkg/cache/
|
||||
server/pkg/sumdb/
|
||||
|
||||
idea/
|
||||
96
server/api/article.api
Normal file
96
server/api/article.api
Normal file
@@ -0,0 +1,96 @@
|
||||
// 定义文章相关的结构体(与数据表字段映射)
|
||||
type (
|
||||
// 文章基础结构(对应数据表字段)
|
||||
Article {
|
||||
Id int64 `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Content string `json:"content"`
|
||||
Cover string `json:"cover"`
|
||||
CreateAt string `json:"create_at"` // 前端通常用字符串承载时间,可根据需求改为 time.Time
|
||||
UpdateAt string `json:"update_at"`
|
||||
IsDelete int `json:"is_delete"` // tinyint 映射为 int,1=已删除,0=未删除
|
||||
Topic string `json:"topic"`
|
||||
Excerpt string `json:"excerpt"`
|
||||
}
|
||||
// 1. 创建文章:请求体
|
||||
CreateArticleReq {
|
||||
Title string `json:"title"` // 文章标题
|
||||
Content string `json:"content"` // 文章内容
|
||||
Cover string `json:"cover"` // 封面图
|
||||
Topic string `json:"topic"` // 话题
|
||||
}
|
||||
// 创建文章:响应
|
||||
CreateArticleResp {
|
||||
Id int64 `json:"id"` // 新增文章的 ID
|
||||
Success bool `json:"success"` // 操作是否成功
|
||||
}
|
||||
// 2. 文章列表:请求(带分页/筛选)
|
||||
ListArticleReq {
|
||||
Page int `json:"page,optional"` // 页码(可选,默认第一页)
|
||||
Size int `json:"size,optional"` // 每页条数(可选,默认 10 条)
|
||||
Topic string `json:"topic,optional"` // 按话题筛选(可选)
|
||||
}
|
||||
// 文章列表:响应
|
||||
ListArticleResp {
|
||||
Total int64 `json:"total"` // 总条数
|
||||
List []Article `json:"list"` // 文章列表
|
||||
}
|
||||
// 3. 文章详情:请求(通过 ID 查询)
|
||||
DetailArticleReq {
|
||||
Id int64 `path:"id"` // 从路径参数取 ID,如 /api/articles/:id
|
||||
}
|
||||
// 文章详情:响应
|
||||
DetailArticleResp {
|
||||
Article Article `json:"article"` // 文章详情
|
||||
Success bool `json:"success"` // 操作是否成功
|
||||
}
|
||||
// 4. 更新文章:请求(部分字段可选更新)
|
||||
UpdateArticleReq {
|
||||
Id int64 `path:"id"` // 要更新的文章 ID
|
||||
Title string `json:"title,optional"`
|
||||
Content string `json:"content,optional"`
|
||||
Cover string `json:"cover,optional"`
|
||||
Topic string `json:"topic,optional"`
|
||||
Excerpt string `json:"excerpt,optional"`
|
||||
}
|
||||
// 更新文章:响应
|
||||
UpdateArticleResp {
|
||||
Success bool `json:"success"`
|
||||
}
|
||||
// 5. 删除文章(软删除:修改 is_delete 为 1):请求
|
||||
DeleteArticleReq {
|
||||
Id int64 `path:"id"` // 要删除的文章 ID
|
||||
}
|
||||
// 删除文章:响应
|
||||
DeleteArticleResp {
|
||||
Success bool `json:"success"`
|
||||
}
|
||||
)
|
||||
|
||||
// 文章服务的 API 分组与路由前缀
|
||||
@server (
|
||||
group: article
|
||||
prefix: /api/articles
|
||||
)
|
||||
service article-api {
|
||||
// 1. 创建文章(POST)
|
||||
@handler CreateArticleHandler
|
||||
post / (CreateArticleReq) returns (CreateArticleResp)
|
||||
|
||||
// 2. 查询文章列表(GET)
|
||||
@handler ListArticleHandler
|
||||
get / (ListArticleReq) returns (ListArticleResp)
|
||||
|
||||
// 3. 查询文章详情(GET)
|
||||
@handler DetailArticleHandler
|
||||
get /:id (DetailArticleReq) returns (DetailArticleResp)
|
||||
|
||||
// 4. 更新文章(PUT)
|
||||
@handler UpdateArticleHandler
|
||||
put /:id (UpdateArticleReq) returns (UpdateArticleResp)
|
||||
|
||||
// 5. 删除文章(软删除,DELETE)
|
||||
@handler DeleteArticleHandler
|
||||
delete /:id (DeleteArticleReq) returns (DeleteArticleResp)
|
||||
}
|
||||
|
||||
14
server/api/ping.api
Normal file
14
server/api/ping.api
Normal file
@@ -0,0 +1,14 @@
|
||||
type PingReq {}
|
||||
|
||||
type PingResp {
|
||||
Msg string `json:"message"`
|
||||
}
|
||||
|
||||
@server (
|
||||
group: ping
|
||||
)
|
||||
service ping-api {
|
||||
@handler PingHandler
|
||||
get /ping (PingReq) returns (PingResp)
|
||||
}
|
||||
|
||||
19
server/api/upload.api
Normal file
19
server/api/upload.api
Normal file
@@ -0,0 +1,19 @@
|
||||
type (
|
||||
UploadImageResp {
|
||||
Code int `json:"code"` // 业务状态码
|
||||
Message string `json:"message"` // 提示信息
|
||||
Data {
|
||||
Url string `json:"url"` // 图片访问地址
|
||||
} `json:"data"`
|
||||
}
|
||||
)
|
||||
|
||||
@server (
|
||||
group: upload
|
||||
prefix: /api
|
||||
)
|
||||
service upload-api {
|
||||
@handler UploadImageHandler
|
||||
post /upload/image returns (UploadImageResp)
|
||||
}
|
||||
|
||||
34
server/article.go
Normal file
34
server/article.go
Normal file
@@ -0,0 +1,34 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.9.1
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/config"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/handler"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/svc"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/conf"
|
||||
"github.com/zeromicro/go-zero/rest"
|
||||
)
|
||||
|
||||
var configFile = flag.String("f", "etc/article-api.yaml", "the config file")
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
var c config.Config
|
||||
conf.MustLoad(*configFile, &c)
|
||||
|
||||
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()
|
||||
}
|
||||
@@ -7,6 +7,7 @@ require (
|
||||
github.com/bytedance/sonic v1.14.0 // indirect
|
||||
github.com/bytedance/sonic/loader v0.3.0 // indirect
|
||||
github.com/cloudwego/base64x v0.1.6 // indirect
|
||||
github.com/fatih/color v1.18.0 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.8 // indirect
|
||||
github.com/gin-contrib/sse v1.1.0 // indirect
|
||||
github.com/gin-gonic/gin v1.11.0 // indirect
|
||||
@@ -18,14 +19,20 @@ require (
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/quic-go/qpack v0.5.1 // indirect
|
||||
github.com/quic-go/quic-go v0.54.0 // indirect
|
||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.3.0 // indirect
|
||||
github.com/zeromicro/go-zero v1.9.1 // indirect
|
||||
go.opentelemetry.io/otel v1.24.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.24.0 // indirect
|
||||
go.uber.org/automaxprocs v1.6.0 // indirect
|
||||
go.uber.org/mock v0.5.0 // indirect
|
||||
golang.org/x/arch v0.20.0 // indirect
|
||||
golang.org/x/crypto v0.40.0 // indirect
|
||||
@@ -36,6 +43,9 @@ require (
|
||||
golang.org/x/text v0.27.0 // indirect
|
||||
golang.org/x/time v0.13.0 // indirect
|
||||
golang.org/x/tools v0.34.0 // 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.36.9 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
@@ -8,6 +8,8 @@ github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI
|
||||
github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
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/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM=
|
||||
github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8=
|
||||
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
|
||||
@@ -31,10 +33,14 @@ github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzh
|
||||
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||
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/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 h1:ZqeYNhU3OHLH3mGKHDcjJRFFRrJa6eAM5H+CtDdOsPc=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
||||
@@ -44,6 +50,8 @@ github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI=
|
||||
github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg=
|
||||
github.com/quic-go/quic-go v0.54.0 h1:6s1YB9QotYI6Ospeiguknbp2Znb/jZYjZLRXn9kMQBg=
|
||||
github.com/quic-go/quic-go v0.54.0/go.mod h1:e68ZEaCdyviluZmy44P6Iey98v/Wfz6HCjQEm+l8zTY=
|
||||
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
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=
|
||||
@@ -55,6 +63,14 @@ github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go/codec v1.3.0 h1:Qd2W2sQawAfG8XSvzwhBeoGq71zXOC/Q1E9y/wUcsUA=
|
||||
github.com/ugorji/go/codec v1.3.0/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
|
||||
github.com/zeromicro/go-zero v1.9.1 h1:GZCl4jun/ZgZHnSvX3SSNDHf+tEGmEQ8x2Z23xjHa9g=
|
||||
github.com/zeromicro/go-zero v1.9.1/go.mod h1:bHOl7Xr7EV/iHZWEqsUNJwFc/9WgAMrPpPagYvOaMtY=
|
||||
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/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
|
||||
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
|
||||
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/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU=
|
||||
go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM=
|
||||
golang.org/x/arch v0.20.0 h1:dx1zTU0MAE98U+TQ8BLl7XsJbgze2WnNKF/8tGp/Q6c=
|
||||
@@ -67,6 +83,7 @@ golang.org/x/net v0.42.0 h1:jzkYrhi3YQWD6MLBJcsklgQsoAcw89EcZbJw8Z614hs=
|
||||
golang.org/x/net v0.42.0/go.mod h1:FF1RA5d3u7nAYA4z2TkclSCKh68eSXtiFwcWQpPXdt8=
|
||||
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
|
||||
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
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.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
|
||||
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
@@ -76,9 +93,15 @@ golang.org/x/time v0.13.0 h1:eUlYslOIt32DgYD6utsuUeHs4d7AsEYLuIAdg7FlYgI=
|
||||
golang.org/x/time v0.13.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
|
||||
golang.org/x/tools v0.34.0 h1:qIpSLOxeCYGg9TrcJokLBG4KFA6d795g0xkBkiESGlo=
|
||||
golang.org/x/tools v0.34.0/go.mod h1:pAP9OwEaY1CAW3HOmg3hLZC5Z0CCmzjAF2UQMSqNARg=
|
||||
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.36.9 h1:w2gp2mA27hUeUzj9Ex9FBjsBm40zfaDtEWow293U7Iw=
|
||||
google.golang.org/protobuf v1.36.9/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
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=
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.9.1
|
||||
|
||||
package article
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/logic/article"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/svc"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/types"
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
)
|
||||
|
||||
func CreateArticleHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.CreateArticleReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := article.NewCreateArticleLogic(r.Context(), svcCtx)
|
||||
resp, err := l.CreateArticle(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.9.1
|
||||
|
||||
package article
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/logic/article"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/svc"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/types"
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
)
|
||||
|
||||
func DeleteArticleHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.DeleteArticleReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := article.NewDeleteArticleLogic(r.Context(), svcCtx)
|
||||
resp, err := l.DeleteArticle(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.9.1
|
||||
|
||||
package article
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/logic/article"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/svc"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/types"
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
)
|
||||
|
||||
func DetailArticleHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.DetailArticleReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := article.NewDetailArticleLogic(r.Context(), svcCtx)
|
||||
resp, err := l.DetailArticle(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.9.1
|
||||
|
||||
package article
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/logic/article"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/svc"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/types"
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
)
|
||||
|
||||
func ListArticleHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.ListArticleReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := article.NewListArticleLogic(r.Context(), svcCtx)
|
||||
resp, err := l.ListArticle(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.9.1
|
||||
|
||||
package article
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/logic/article"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/svc"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/types"
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
)
|
||||
|
||||
func UpdateArticleHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.UpdateArticleReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := article.NewUpdateArticleLogic(r.Context(), svcCtx)
|
||||
resp, err := l.UpdateArticle(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.9.1
|
||||
|
||||
package article
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/svc"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type CreateArticleLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewCreateArticleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreateArticleLogic {
|
||||
return &CreateArticleLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *CreateArticleLogic) CreateArticle(req *types.CreateArticleReq) (resp *types.CreateArticleResp, err error) {
|
||||
// todo: add your logic here and delete this line
|
||||
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.9.1
|
||||
|
||||
package article
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/svc"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type DeleteArticleLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewDeleteArticleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DeleteArticleLogic {
|
||||
return &DeleteArticleLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *DeleteArticleLogic) DeleteArticle(req *types.DeleteArticleReq) (resp *types.DeleteArticleResp, err error) {
|
||||
// todo: add your logic here and delete this line
|
||||
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.9.1
|
||||
|
||||
package article
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/svc"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type DetailArticleLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewDetailArticleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DetailArticleLogic {
|
||||
return &DetailArticleLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *DetailArticleLogic) DetailArticle(req *types.DetailArticleReq) (resp *types.DetailArticleResp, err error) {
|
||||
// todo: add your logic here and delete this line
|
||||
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.9.1
|
||||
|
||||
package article
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/svc"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type ListArticleLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewListArticleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ListArticleLogic {
|
||||
return &ListArticleLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *ListArticleLogic) ListArticle(req *types.ListArticleReq) (resp *types.ListArticleResp, err error) {
|
||||
// todo: add your logic here and delete this line
|
||||
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.9.1
|
||||
|
||||
package article
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/svc"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/article/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type UpdateArticleLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewUpdateArticleLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateArticleLogic {
|
||||
return &UpdateArticleLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *UpdateArticleLogic) UpdateArticle(req *types.UpdateArticleReq) (resp *types.UpdateArticleResp, err error) {
|
||||
// todo: add your logic here and delete this line
|
||||
|
||||
return
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package articlemodel
|
||||
package model
|
||||
|
||||
import "github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// versions:
|
||||
// goctl version: 1.9.1
|
||||
|
||||
package articlemodel
|
||||
package model
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -1,4 +1,4 @@
|
||||
package articlemodel
|
||||
package model
|
||||
|
||||
import "github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
|
||||
69
server/internal/article/internal/types/types.go
Normal file
69
server/internal/article/internal/types/types.go
Normal file
@@ -0,0 +1,69 @@
|
||||
// Code generated by goctl. DO NOT EDIT.
|
||||
// goctl 1.9.1
|
||||
|
||||
package types
|
||||
|
||||
type Article struct {
|
||||
Id int64 `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Content string `json:"content"`
|
||||
Cover string `json:"cover"`
|
||||
CreateAt string `json:"create_at"` // 前端通常用字符串承载时间,可根据需求改为 time.Time
|
||||
UpdateAt string `json:"update_at"`
|
||||
IsDelete int `json:"is_delete"` // tinyint 映射为 int,1=已删除,0=未删除
|
||||
Topic string `json:"topic"`
|
||||
Excerpt string `json:"excerpt"`
|
||||
}
|
||||
|
||||
type CreateArticleReq struct {
|
||||
Title string `json:"title"` // 文章标题
|
||||
Content string `json:"content"` // 文章内容
|
||||
Cover string `json:"cover"` // 封面图
|
||||
Topic string `json:"topic"` // 话题
|
||||
}
|
||||
|
||||
type CreateArticleResp struct {
|
||||
Id int64 `json:"id"` // 新增文章的 ID
|
||||
Success bool `json:"success"` // 操作是否成功
|
||||
}
|
||||
|
||||
type DeleteArticleReq struct {
|
||||
Id int64 `path:"id"` // 要删除的文章 ID
|
||||
}
|
||||
|
||||
type DeleteArticleResp struct {
|
||||
Success bool `json:"success"`
|
||||
}
|
||||
|
||||
type DetailArticleReq struct {
|
||||
Id int64 `path:"id"` // 从路径参数取 ID,如 /api/articles/:id
|
||||
}
|
||||
|
||||
type DetailArticleResp struct {
|
||||
Article Article `json:"article"` // 文章详情
|
||||
Success bool `json:"success"` // 操作是否成功
|
||||
}
|
||||
|
||||
type ListArticleReq struct {
|
||||
Page int `json:"page,optional"` // 页码(可选,默认第一页)
|
||||
Size int `json:"size,optional"` // 每页条数(可选,默认 10 条)
|
||||
Topic string `json:"topic,optional"` // 按话题筛选(可选)
|
||||
}
|
||||
|
||||
type ListArticleResp struct {
|
||||
Total int64 `json:"total"` // 总条数
|
||||
List []Article `json:"list"` // 文章列表
|
||||
}
|
||||
|
||||
type UpdateArticleReq struct {
|
||||
Id int64 `path:"id"` // 要更新的文章 ID
|
||||
Title string `json:"title,optional"`
|
||||
Content string `json:"content,optional"`
|
||||
Cover string `json:"cover,optional"`
|
||||
Topic string `json:"topic,optional"`
|
||||
Excerpt string `json:"excerpt,optional"`
|
||||
}
|
||||
|
||||
type UpdateArticleResp struct {
|
||||
Success bool `json:"success"`
|
||||
}
|
||||
31
server/internal/handler/article/createarticlehandler.go
Normal file
31
server/internal/handler/article/createarticlehandler.go
Normal file
@@ -0,0 +1,31 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.9.1
|
||||
|
||||
package article
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/logic/article"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/svc"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/types"
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
)
|
||||
|
||||
func CreateArticleHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.CreateArticleReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := article.NewCreateArticleLogic(r.Context(), svcCtx)
|
||||
resp, err := l.CreateArticle(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
31
server/internal/handler/article/deletearticlehandler.go
Normal file
31
server/internal/handler/article/deletearticlehandler.go
Normal file
@@ -0,0 +1,31 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.9.1
|
||||
|
||||
package article
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/logic/article"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/svc"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/types"
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
)
|
||||
|
||||
func DeleteArticleHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.DeleteArticleReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := article.NewDeleteArticleLogic(r.Context(), svcCtx)
|
||||
resp, err := l.DeleteArticle(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
31
server/internal/handler/article/detailarticlehandler.go
Normal file
31
server/internal/handler/article/detailarticlehandler.go
Normal file
@@ -0,0 +1,31 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.9.1
|
||||
|
||||
package article
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/logic/article"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/svc"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/types"
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
)
|
||||
|
||||
func DetailArticleHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.DetailArticleReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := article.NewDetailArticleLogic(r.Context(), svcCtx)
|
||||
resp, err := l.DetailArticle(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
31
server/internal/handler/article/listarticlehandler.go
Normal file
31
server/internal/handler/article/listarticlehandler.go
Normal file
@@ -0,0 +1,31 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.9.1
|
||||
|
||||
package article
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/logic/article"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/svc"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/types"
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
)
|
||||
|
||||
func ListArticleHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.ListArticleReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := article.NewListArticleLogic(r.Context(), svcCtx)
|
||||
resp, err := l.ListArticle(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
31
server/internal/handler/article/updatearticlehandler.go
Normal file
31
server/internal/handler/article/updatearticlehandler.go
Normal file
@@ -0,0 +1,31 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.9.1
|
||||
|
||||
package article
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/logic/article"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/svc"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/types"
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
)
|
||||
|
||||
func UpdateArticleHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.UpdateArticleReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := article.NewUpdateArticleLogic(r.Context(), svcCtx)
|
||||
resp, err := l.UpdateArticle(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
31
server/internal/handler/ping/pinghandler.go
Normal file
31
server/internal/handler/ping/pinghandler.go
Normal file
@@ -0,0 +1,31 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.9.1
|
||||
|
||||
package ping
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/JACKYMYPERSON/hldrCenter/config"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/logic/ping"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/types"
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
)
|
||||
|
||||
func PingHandler(cfg *config.Config) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.PingReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := ping.NewPingLogic(r.Context(), cfg)
|
||||
resp, err := l.Ping(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
3
server/internal/ping/etc/ping-api.yaml
Normal file
3
server/internal/ping/etc/ping-api.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
Name: ping-api
|
||||
Host: 0.0.0.0
|
||||
Port: 8888
|
||||
10
server/internal/ping/internal/config/config.go
Normal file
10
server/internal/ping/internal/config/config.go
Normal file
@@ -0,0 +1,10 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.9.1
|
||||
|
||||
package config
|
||||
|
||||
import "github.com/zeromicro/go-zero/rest"
|
||||
|
||||
type Config struct {
|
||||
rest.RestConf
|
||||
}
|
||||
31
server/internal/ping/internal/handler/ping/pinghandler.go
Normal file
31
server/internal/ping/internal/handler/ping/pinghandler.go
Normal file
@@ -0,0 +1,31 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.9.1
|
||||
|
||||
package ping
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/ping/internal/logic/ping"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/ping/internal/svc"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/ping/internal/types"
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
)
|
||||
|
||||
func PingHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var req types.PingReq
|
||||
if err := httpx.Parse(r, &req); err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
return
|
||||
}
|
||||
|
||||
l := ping.NewPingLogic(r.Context(), svcCtx)
|
||||
resp, err := l.Ping(&req)
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
25
server/internal/ping/internal/handler/routes.go
Normal file
25
server/internal/ping/internal/handler/routes.go
Normal file
@@ -0,0 +1,25 @@
|
||||
// Code generated by goctl. DO NOT EDIT.
|
||||
// goctl 1.9.1
|
||||
|
||||
package handler
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
ping "github.com/JACKYMYPERSON/hldrCenter/internal/ping/internal/handler/ping"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/ping/internal/svc"
|
||||
|
||||
"github.com/zeromicro/go-zero/rest"
|
||||
)
|
||||
|
||||
func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
|
||||
server.AddRoutes(
|
||||
[]rest.Route{
|
||||
{
|
||||
Method: http.MethodGet,
|
||||
Path: "/ping",
|
||||
Handler: ping.PingHandler(serverCtx),
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
33
server/internal/ping/internal/logic/ping/pinglogic.go
Normal file
33
server/internal/ping/internal/logic/ping/pinglogic.go
Normal file
@@ -0,0 +1,33 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.9.1
|
||||
|
||||
package ping
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/ping/internal/svc"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/ping/internal/types"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type PingLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewPingLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PingLogic {
|
||||
return &PingLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *PingLogic) Ping(req *types.PingReq) (resp *types.PingResp, err error) {
|
||||
// todo: add your logic here and delete this line
|
||||
|
||||
return
|
||||
}
|
||||
18
server/internal/ping/internal/svc/servicecontext.go
Normal file
18
server/internal/ping/internal/svc/servicecontext.go
Normal file
@@ -0,0 +1,18 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.9.1
|
||||
|
||||
package svc
|
||||
|
||||
import (
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/ping/internal/config"
|
||||
)
|
||||
|
||||
type ServiceContext struct {
|
||||
Config config.Config
|
||||
}
|
||||
|
||||
func NewServiceContext(c config.Config) *ServiceContext {
|
||||
return &ServiceContext{
|
||||
Config: c,
|
||||
}
|
||||
}
|
||||
11
server/internal/ping/internal/types/types.go
Normal file
11
server/internal/ping/internal/types/types.go
Normal file
@@ -0,0 +1,11 @@
|
||||
// Code generated by goctl. DO NOT EDIT.
|
||||
// goctl 1.9.1
|
||||
|
||||
package types
|
||||
|
||||
type PingReq struct {
|
||||
}
|
||||
|
||||
type PingResp struct {
|
||||
Msg string `json:"message"`
|
||||
}
|
||||
34
server/internal/ping/ping.go
Normal file
34
server/internal/ping/ping.go
Normal file
@@ -0,0 +1,34 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.9.1
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/ping/internal/config"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/ping/internal/handler"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/ping/internal/svc"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/conf"
|
||||
"github.com/zeromicro/go-zero/rest"
|
||||
)
|
||||
|
||||
var configFile = flag.String("f", "etc/ping-api.yaml", "the config file")
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
var c config.Config
|
||||
conf.MustLoad(*configFile, &c)
|
||||
|
||||
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()
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.9.1
|
||||
|
||||
package upload
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/upload/internal/logic/upload"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/upload/internal/svc"
|
||||
"github.com/zeromicro/go-zero/rest/httpx"
|
||||
)
|
||||
|
||||
func UploadImageHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
l := upload.NewUploadImageLogic(r.Context(), svcCtx)
|
||||
resp, err := l.UploadImage()
|
||||
if err != nil {
|
||||
httpx.ErrorCtx(r.Context(), w, err)
|
||||
} else {
|
||||
httpx.OkJsonCtx(r.Context(), w, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
132
server/internal/upload/internal/logic/upload/uploadimagelogic.go
Normal file
132
server/internal/upload/internal/logic/upload/uploadimagelogic.go
Normal file
@@ -0,0 +1,132 @@
|
||||
// Code scaffolded by goctl. Safe to edit.
|
||||
// goctl 1.9.1
|
||||
|
||||
package upload
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/upload/internal/svc"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/upload/internal/types"
|
||||
"github.com/aliyun/aliyun-oss-go-sdk/oss"
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type UploadImageLogic struct {
|
||||
logx.Logger
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
func NewUploadImageLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UploadImageLogic {
|
||||
return &UploadImageLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
}
|
||||
}
|
||||
|
||||
func (l *UploadImageLogic) UploadImage() (resp *types.UploadImageResp, err error) {
|
||||
// 获取上传的图片文件
|
||||
fileHeader, err := c.FormFile("image")
|
||||
if err != nil {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"code": 400,
|
||||
"message": "获取图片失败,请重新上传",
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 打开文件
|
||||
file, err := fileHeader.Open()
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"code": 500,
|
||||
"message": "打开图片文件失败",
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// 检查文件大小(使用配置中的max_file_size)
|
||||
if fileHeader.Size > cfg.Upload.MaxFileSize {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"code": 400,
|
||||
"message": fmt.Sprintf("图片大小不能超过 %dMB", cfg.Upload.MaxFileSize>>20),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 检查文件类型(使用配置中的allow_image_types)
|
||||
fileType := fileHeader.Header.Get("Content-Type")
|
||||
if !strings.Contains(cfg.Upload.AllowImageTypes, fileType) {
|
||||
c.JSON(http.StatusBadRequest, gin.H{
|
||||
"code": 400,
|
||||
"message": fmt.Sprintf("不支持的图片类型,仅允许:%s", cfg.Upload.AllowImageTypes),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 初始化OSS客户端(使用配置中的OSS参数)
|
||||
client, err := oss.New(
|
||||
cfg.OSS.Endpoint,
|
||||
cfg.OSS.AccessKeyID,
|
||||
cfg.OSS.AccessKeySecret,
|
||||
)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"code": 500,
|
||||
"message": "初始化OSS客户端失败",
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 获取Bucket
|
||||
bucket, err := client.Bucket(cfg.OSS.BucketName)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"code": 500,
|
||||
"message": "获取Bucket失败",
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 生成唯一文件名
|
||||
timestamp := time.Now().Format("20060102150405")
|
||||
filename := fmt.Sprintf("%s_%s", timestamp, fileHeader.Filename)
|
||||
objectKey := cfg.OSS.ObjectPrefix + filename // OSS中的完整对象键
|
||||
|
||||
// 上传文件到OSS
|
||||
err = bucket.PutObject(objectKey, file)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{
|
||||
"code": 500,
|
||||
"message": "上传图片到OSS失败",
|
||||
"error": err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// 生成图片访问URL
|
||||
host := strings.TrimPrefix(cfg.OSS.Endpoint, "https://")
|
||||
imageURL := fmt.Sprintf("https://%s.%s/%s", cfg.OSS.BucketName, host, objectKey)
|
||||
|
||||
// 返回成功响应
|
||||
c.JSON(http.StatusOK, gin.H{
|
||||
"code": 200,
|
||||
"message": "图片上传成功",
|
||||
"data": gin.H{"url": imageURL},
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
12
server/internal/upload/internal/types/types.go
Normal file
12
server/internal/upload/internal/types/types.go
Normal file
@@ -0,0 +1,12 @@
|
||||
// Code generated by goctl. DO NOT EDIT.
|
||||
// goctl 1.9.1
|
||||
|
||||
package types
|
||||
|
||||
type UploadImageResp struct {
|
||||
Code int `json:"code"` // 业务状态码
|
||||
Message string `json:"message"` // 提示信息
|
||||
Data struct {
|
||||
Url string `json:"url"` // 图片访问地址
|
||||
} `json:"data"`
|
||||
}
|
||||
@@ -3,9 +3,9 @@ package main
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/JACKYMYPERSON/hldrCenter/config" // 替换为你的项目模块名
|
||||
"github.com/JACKYMYPERSON/hldrCenter/middleware" // 替换为你的项目模块名
|
||||
"github.com/JACKYMYPERSON/hldrCenter/router" // 替换为你的项目模块名
|
||||
"github.com/JACKYMYPERSON/hldrCenter/config"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/middleware"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/router"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
@@ -29,12 +29,6 @@ func CorsMiddleware(serverConfig *config.ServerConfig) gin.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 即使没有匹配到,也可以临时设置为*(仅测试用,生产环境需删除)
|
||||
// if allowOrigin == "" {
|
||||
// allowOrigin = "*"
|
||||
// }
|
||||
|
||||
// 5. 设置核心跨域头
|
||||
if allowOrigin != "" {
|
||||
c.Writer.Header().Set("Access-Control-Allow-Origin", allowOrigin)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,9 @@ package router
|
||||
|
||||
import (
|
||||
"github.com/JACKYMYPERSON/hldrCenter/config"
|
||||
handler "github.com/JACKYMYPERSON/hldrCenter/internal/handler/uploadimg"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/internal/handler/article"
|
||||
ping "github.com/JACKYMYPERSON/hldrCenter/internal/handler/ping"
|
||||
uploadimg "github.com/JACKYMYPERSON/hldrCenter/internal/handler/uploadimg"
|
||||
"github.com/JACKYMYPERSON/hldrCenter/middleware"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
@@ -17,8 +19,27 @@ func SetupRouter(cfg *config.Config) *gin.Engine {
|
||||
// 定义路由组(必须在中间件之后)
|
||||
api := r.Group("/api")
|
||||
{
|
||||
api.POST("/upload/image", handler.UploadImageHandler(cfg))
|
||||
api.POST("/upload/cover", handler.UploadImageHandler(cfg)) // 复用上传逻辑
|
||||
api.POST("/upload/image", uploadimg.UploadImageHandler(cfg))
|
||||
api.POST("/upload/cover", uploadimg.UploadImageHandler(cfg))
|
||||
api.GET("/ping", gin.WrapF(ping.PingHandler(cfg)))
|
||||
|
||||
articles := api.Group("/articles")
|
||||
{
|
||||
// 1. 创建文章(POST /api/articles)
|
||||
articles.POST("", gin.WrapH(article.CreateArticleHandler(svcCtx)))
|
||||
|
||||
// 2. 文章列表(GET /api/articles)
|
||||
articles.GET("", gin.WrapH(article.ListArticleHandler(svcCtx)))
|
||||
|
||||
// 3. 文章详情(GET /api/articles/:id)
|
||||
articles.GET("/:id", gin.WrapH(article.DetailArticleHandler(svcCtx)))
|
||||
|
||||
// 4. 更新文章(PUT /api/articles/:id)
|
||||
articles.PUT("/:id", gin.WrapH(article.UpdateArticleHandler(svcCtx)))
|
||||
|
||||
// 5. 删除文章(DELETE /api/articles/:id)
|
||||
articles.DELETE("/:id", gin.WrapH(article.DeleteArticleHandler(svcCtx)))
|
||||
}
|
||||
}
|
||||
|
||||
return r
|
||||
|
||||
Reference in New Issue
Block a user