diff --git a/Makefile b/Makefile index e41ed00b..4a23ba98 100644 --- a/Makefile +++ b/Makefile @@ -2,13 +2,14 @@ BUILD_VERSION := $(shell cat version) BUILD_DATE := $(shell date +'%Y-%m-%d %H:%M:%S') SHA_SHORT := $(shell git rev-parse --short HEAD) +TAGS = "" all: fmt build build: @go mod download @echo Build paopao-ce bash build.sh paopao-ce run: - @go run -ldflags "-X 'main.version=${BUILD_VERSION}' -X 'main.buildDate=${BUILD_DATE}' -X 'main.commitID=${SHA_SHORT}'" . + @go run -tags '$(TAGS)' -ldflags "-X 'main.version=${BUILD_VERSION}' -X 'main.buildDate=${BUILD_DATE}' -X 'main.commitID=${SHA_SHORT}'" . clean: @go clean @find ./dist -type f -exec rm -r {} + @@ -23,6 +24,10 @@ fmt: @go vet -composites=false ./pkg/... help: @echo "make: make" + @echo "make run: start api server" @echo "make build: build executables" + @echo "make build: build executables" + @echo "make run TAGS='embed': start api server and serve embed web frontend" + @echo "make build TAGS='embed': build executables with embed web frontend" .EXPORT_ALL_VARIABLES: GO111MODULE = on diff --git a/README.md b/README.md index 0b99f3d0..40ff3323 100644 --- a/README.md +++ b/README.md @@ -86,18 +86,25 @@ PaoPao主要由以下优秀的开源项目/工具构建 1. 导入项目根目录下的 `paopao.sql` 文件至MySQL数据库 2. 拷贝项目根目录下 `config.yaml.sample` 文件至 `config.yaml`,按照注释完成配置编辑 -3. 编译后端 - +3. 编译后端 + 编译api服务: ```sh - go mod download - go build -o paopao-api . + make build ``` + 编译api服务、内嵌web前端ui; 注意此步骤需要先编译web前端。 + ```sh + make build TAGS='embed' + ``` + 编译后在`dist`目录可以找到对应可执行文件。 -4. 启动后端 - +4. 启动后端 + 运行api服务: + ```sh + make run + ``` + 运行api服务、web前端ui服务: ```sh - chmod +x paopao-api - ./paopao-api + make run TAGS='embed' ``` #### 前端 diff --git a/build.sh b/build.sh index e6154804..f49c00c8 100644 --- a/build.sh +++ b/build.sh @@ -20,13 +20,13 @@ for pl in ${PLATFORMS}; do echo "build => ${TARGET}" if [ "${DEBUG_MODE}" == "debug" ]; then - go build -trimpath -gcflags "all=-N -l" -o "${TARGET}" \ + go build -trimpath -gcflags "all=-N -l" -o "${TARGET}" -tags "${TAGS}" \ -ldflags "-X 'main.version=${BUILD_VERSION}' \ -X 'main.buildDate=${BUILD_DATE}' \ -X 'main.commitID=${SHA_SHORT}'\ -w -s" else - go build -trimpath -o "${TARGET}" \ + go build -trimpath -o "${TARGET}" -tags "${TAGS}" \ -ldflags "-X 'main.version=${BUILD_VERSION}' \ -X 'main.buildDate=${BUILD_DATE}' \ -X 'main.commitID=${SHA_SHORT}'\ diff --git a/internal/routers/router.go b/internal/routers/router.go index 449f3e02..f735bc2a 100644 --- a/internal/routers/router.go +++ b/internal/routers/router.go @@ -10,16 +10,22 @@ import ( ) func NewRouter() *gin.Engine { - r := gin.New() - r.HandleMethodNotAllowed = true - r.Use(gin.Logger()) - r.Use(gin.Recovery()) + e := gin.New() + e.HandleMethodNotAllowed = true + e.Use(gin.Logger()) + e.Use(gin.Recovery()) // 跨域配置 corsConfig := cors.DefaultConfig() corsConfig.AllowAllOrigins = true corsConfig.AddAllowHeaders("Authorization") - r.Use(cors.New(corsConfig)) + e.Use(cors.New(corsConfig)) + + // 按需注册静态资源路由 + registerStatick(e) + + // v1 group api + r := e.Group("/v1") // 获取version r.GET("/", api.Version) @@ -163,18 +169,18 @@ func NewRouter() *gin.Engine { } // 默认404 - r.NoRoute(func(c *gin.Context) { + e.NoRoute(func(c *gin.Context) { c.JSON(http.StatusNotFound, gin.H{ "code": 404, "msg": "Not Found", }) }) // 默认405 - r.NoMethod(func(c *gin.Context) { + e.NoMethod(func(c *gin.Context) { c.JSON(http.StatusMethodNotAllowed, gin.H{ "code": 405, "msg": "Method Not Allowed", }) }) - return r + return e } diff --git a/internal/routers/statick.go b/internal/routers/statick.go new file mode 100644 index 00000000..c20d5059 --- /dev/null +++ b/internal/routers/statick.go @@ -0,0 +1,13 @@ +//go:build !embed +// +build !embed + +package routers + +import ( + "github.com/gin-gonic/gin" +) + +// registerStatick stub function for register static asset route +func registerStatick(e *gin.Engine) { + // empty +} diff --git a/internal/routers/statick_embed.go b/internal/routers/statick_embed.go new file mode 100644 index 00000000..2ea56171 --- /dev/null +++ b/internal/routers/statick_embed.go @@ -0,0 +1,27 @@ +//go:build embed +// +build embed + +package routers + +import ( + "net/http" + + "github.com/gin-gonic/gin" + "github.com/rocboss/paopao-ce/web" +) + +// registerStatick register static assets route +func registerStatick(e *gin.Engine) { + routeStatic(e, "/", "/index.html", "/favicon.ico", "/assets/*filepath") +} + +func routeStatic(e *gin.Engine, paths ...string) { + staticHandler := http.FileServer(web.NewFileSystem()) + handler := func(c *gin.Context) { + staticHandler.ServeHTTP(c.Writer, c.Request) + } + for _, path := range paths { + e.GET(path, handler) + e.HEAD(path, handler) + } +} diff --git a/web/.gitignore b/web/.gitignore index ba6b09ec..5e36b5b9 100644 --- a/web/.gitignore +++ b/web/.gitignore @@ -11,6 +11,7 @@ node_modules dist dist-ssr *.local +.env # Editor directories and files .vscode/* diff --git a/web/embed.go b/web/embed.go new file mode 100644 index 00000000..4866a53a --- /dev/null +++ b/web/embed.go @@ -0,0 +1,19 @@ +//go:build embed +// +build embed + +package web + +import ( + "embed" + "io/fs" + "net/http" +) + +//go:embed dist/* +var files embed.FS + +// NewFileSystem get an embed static assets http.FileSystem instance. +func NewFileSystem() http.FileSystem { + subfs, _ := fs.Sub(files, "dist") + return http.FS(subfs) +} diff --git a/web/src/api/auth.ts b/web/src/api/auth.ts index 904e9bba..4d5a066d 100644 --- a/web/src/api/auth.ts +++ b/web/src/api/auth.ts @@ -4,7 +4,7 @@ import { request } from '@/utils/request'; export const userLogin = (params: NetParams.AuthUserLogin): Promise => { return request({ method: 'post', - url: '/auth/login', + url: '/v1/auth/login', data: params, }); }; @@ -13,7 +13,7 @@ export const userLogin = (params: NetParams.AuthUserLogin): Promise => { return request({ method: 'post', - url: '/auth/register', + url: '/v1/auth/register', data: params, }); }; @@ -22,7 +22,7 @@ export const userRegister = (params: NetParams.AuthUserRegister): Promise => { return request({ method: 'get', - url: '/user/info', + url: '/v1/user/info', headers: { Authorization: `Bearer ${token}`, }, @@ -33,7 +33,7 @@ export const userInfo = (token: NetParams.AuthUserInfo = ""): Promise => { return request({ method: 'post', - url: '/api/user/password', + url: '/v1/api/user/password', data, }); }; diff --git a/web/src/api/post.ts b/web/src/api/post.ts index 49386cc6..7f2bc408 100644 --- a/web/src/api/post.ts +++ b/web/src/api/post.ts @@ -4,7 +4,7 @@ import { request } from '@/utils/request'; export const getPosts = (params: NetParams.PostGetPosts): Promise => { return request({ method: 'get', - url: '/posts', + url: '/v1/posts', params }); }; @@ -13,7 +13,7 @@ export const getPosts = (params: NetParams.PostGetPosts): Promise => { return request({ method: 'get', - url: '/tags', + url: '/v1/tags', params }); }; @@ -22,7 +22,7 @@ export const getTags = (params: NetParams.PostGetTags): Promise => { return request({ method: 'get', - url: '/post', + url: '/v1/post', params }); }; @@ -31,7 +31,7 @@ export const getPost = (params: NetParams.PostGetPost): Promise => { return request({ method: 'get', - url: '/post/star', + url: '/v1/post/star', params }); }; @@ -40,7 +40,7 @@ export const getPostStar = (params: NetParams.PostPostStar): Promise => { return request({ method: 'post', - url: '/post/star', + url: '/v1/post/star', data }); }; @@ -49,7 +49,7 @@ export const postStar = (data: NetParams.PostPostStar): Promise => { return request({ method: 'get', - url: '/post/collection', + url: '/v1/post/collection', params }); }; @@ -58,7 +58,7 @@ export const getPostCollection = (params: NetParams.PostGetPostCollection): Prom export const postCollection = (data: NetParams.PostPostCollection): Promise => { return request({ method: 'post', - url: '/post/collection', + url: '/v1/post/collection', data }); }; @@ -67,7 +67,7 @@ export const postCollection = (data: NetParams.PostPostCollection): Promise => { return request({ method: 'get', - url: '/post/comments', + url: '/v1/post/comments', params }); }; @@ -76,7 +76,7 @@ export const getPostComments = (params: NetParams.PostGetPostComments): Promise< export const createPost = (data: NetParams.PostCreatePost): Promise => { return request({ method: 'post', - url: '/post', + url: '/v1/post', data }); }; @@ -85,7 +85,7 @@ export const createPost = (data: NetParams.PostCreatePost): Promise => { return request({ method: 'delete', - url: '/post', + url: '/v1/post', data }); }; @@ -94,7 +94,7 @@ export const deletePost = (data: NetParams.PostDeletePost): Promise => { return request({ method: 'post', - url: '/post/lock', + url: '/v1/post/lock', data }); }; @@ -103,7 +103,7 @@ export const lockPost = (data: NetParams.PostLockPost): Promise => { return request({ method: 'post', - url: '/post/stick', + url: '/v1/post/stick', data }); }; @@ -112,7 +112,7 @@ export const stickPost = (data: NetParams.PostStickPost): Promise => { return request({ method: 'post', - url: '/post/comment', + url: '/v1/post/comment', data }); }; @@ -121,7 +121,7 @@ export const createComment = (data: NetParams.PostCreateComment): Promise => { return request({ method: 'delete', - url: '/post/comment', + url: '/v1/post/comment', data }); }; @@ -130,7 +130,7 @@ export const deleteComment = (data: NetParams.PostDeleteComment): Promise => { return request({ method: 'post', - url: '/post/comment/reply', + url: '/v1/post/comment/reply', data }); }; @@ -139,7 +139,7 @@ export const createCommentReply = (data: NetParams.PostCreateCommentReply): Prom export const deleteCommentReply = (data: NetParams.PostDeleteCommentReply): Promise => { return request({ method: 'delete', - url: '/post/comment/reply', + url: '/v1/post/comment/reply', data }); }; diff --git a/web/src/api/user.ts b/web/src/api/user.ts index 2828290c..ea6c1adf 100644 --- a/web/src/api/user.ts +++ b/web/src/api/user.ts @@ -4,7 +4,7 @@ import { request } from '@/utils/request'; export const getCaptcha = (params: NetParams.UserGetCaptcha = {}): Promise => { return request({ method: 'get', - url: '/captcha', + url: '/v1/captcha', params }); }; @@ -17,7 +17,7 @@ export const getCaptcha = (params: NetParams.UserGetCaptcha = {}): Promise { return request({ method: 'post', - url: '/captcha', + url: '/v1/captcha', data }); }; @@ -30,7 +30,7 @@ export const sendCaptcha = (data: any) => { export const sendUserWhisper = (data: NetParams.UserWhisper): Promise => { return request({ method: 'post', - url: '/user/whisper', + url: '/v1/user/whisper', data }); }; @@ -43,7 +43,7 @@ export const sendUserWhisper = (data: NetParams.UserWhisper): Promise => { return request({ method: 'post', - url: '/user/phone', + url: '/v1/user/phone', data }); }; @@ -52,7 +52,7 @@ export const bindUserPhone = (data: NetParams.UserBindUserPhone): Promise => { return request({ method: 'post', - url: '/user/password', + url: '/v1/user/password', data }); }; @@ -61,7 +61,7 @@ export const changePassword = (data: NetParams.UserChangePassword): Promise => { return request({ method: 'post', - url: '/user/nickname', + url: '/v1/user/nickname', data }); }; @@ -74,7 +74,7 @@ export const changeNickname = (data: NetParams.UserChangeNickname): Promise { return request({ method: 'post', - url: '/user/avatar', + url: '/v1/user/avatar', data }); }; @@ -83,7 +83,7 @@ export const changeAvatar = (data: any) => { export const getUnreadMsgCount = (params: NetParams.UserGetUnreadMsgCount = {}): Promise => { return request({ method: 'get', - url: '/user/msgcount/unread', + url: '/v1/user/msgcount/unread', params }); }; @@ -92,7 +92,7 @@ export const getUnreadMsgCount = (params: NetParams.UserGetUnreadMsgCount = {}): export const getMessages = (params: NetParams.UserGetMessages): Promise => { return request({ method: 'get', - url: '/user/messages', + url: '/v1/user/messages', params }); }; @@ -105,7 +105,7 @@ export const getMessages = (params: NetParams.UserGetMessages): Promise { return request({ method: 'post', - url: '/user/message/read', + url: '/v1/user/message/read', data }); }; @@ -114,7 +114,7 @@ export const readMessage = (data: any) => { export const getCollections = (params: NetParams.UserGetCollections): Promise => { return request({ method: 'get', - url: '/user/collections', + url: '/v1/user/collections', params }); }; @@ -123,7 +123,7 @@ export const getCollections = (params: NetParams.UserGetCollections): Promise => { return request({ method: 'get', - url: '/user/stars', + url: '/v1/user/stars', params }); }; @@ -132,7 +132,7 @@ export const getStars = (params: NetParams.UserGetStars): Promise => { return request({ method: 'get', - url: '/user/profile', + url: '/v1/user/profile', params }); }; @@ -141,7 +141,7 @@ export const getUserProfile = (params: NetParams.UserGetUserProfile): Promise => { return request({ method: 'get', - url: '/user/posts', + url: '/v1/user/posts', params }); }; @@ -150,7 +150,7 @@ export const getUserPosts = (params: NetParams.UserGetUserPosts): Promise => { return request({ method: 'get', - url: '/user/wallet/bills', + url: '/v1/user/wallet/bills', params }); }; @@ -163,7 +163,7 @@ export const getBills = (params: NetParams.UserGetBills): Promise => { return request({ method: 'post', - url: '/user/recharge', + url: '/v1/user/recharge', data }); }; @@ -176,7 +176,7 @@ export const reqRecharge = (data: NetParams.UserReqRecharge): Promise => { return request({ method: 'get', - url: '/user/recharge', + url: '/v1/user/recharge', params }); }; @@ -189,7 +189,7 @@ export const getRecharge = (params: NetParams.UserGetRecharge): Promise => { return request({ method: 'get', - url: '/suggest/users', + url: '/v1/suggest/users', params }); }; @@ -202,7 +202,7 @@ export const getSuggestUsers = (params: { k: string }): Promise => { return request({ method: 'get', - url: '/suggest/tags', + url: '/v1/suggest/tags', params }); }; @@ -215,7 +215,7 @@ export const getSuggestTags = (params: { k: string }): Promise => { return request({ method: 'get', - url: '/attachment/precheck', + url: '/v1/attachment/precheck', params }); }; @@ -228,7 +228,7 @@ export const precheckAttachment = (params: NetParams.UserPrecheckAttachment): Pr export const getAttachment = (params: NetParams.UserGetAttachment): Promise => { return request({ method: 'get', - url: '/attachment', + url: '/v1/attachment', params }); };