Merge pull request #196 from rocboss/feature/mir

引入go-mir重构paopao-ce的接入层与业务逻辑层
pull/199/head
Michael Li 3 years ago committed by GitHub
commit e0d0e254c6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -68,6 +68,28 @@ windows-x64:
@echo Build paopao-ce [windows-x64] CGO_ENABLED=$(CGO_ENABLED) @echo Build paopao-ce [windows-x64] CGO_ENABLED=$(CGO_ENABLED)
@CGO_ENABLED=$(CGO_ENABLED) GOOS=windows GOARCH=amd64 go build -trimpath -tags '$(TAGS)' -ldflags '$(LDFLAGS)' -o $(RELEASE_WINDOWS_AMD64)/$(basename $(TARGET)).exe @CGO_ENABLED=$(CGO_ENABLED) GOOS=windows GOARCH=amd64 go build -trimpath -tags '$(TAGS)' -ldflags '$(LDFLAGS)' -o $(RELEASE_WINDOWS_AMD64)/$(basename $(TARGET)).exe
.PHONY: generate
generate: gen-mir gen-grpc
.PHONY: gen-mir
gen-mir:
@go generate mirc/main.go
@go fmt ./auto/api/...
.PHONY: gen-grpc
gen-grpc:
@rm -rf auto/rpc
@buf generate proto
@go fmt ./auto/rpc/...
.PHONY: proto-mod
proto-mod:
@cd proto/ && buf mod update
.PHONY: proto-lint
proto-lint:
@cd proto/ && buf lint
clean: clean:
@go clean @go clean
@find ./release -type f -exec rm -r {} + @find ./release -type f -exec rm -r {} +
@ -83,7 +105,15 @@ test:
@go test ./... @go test ./...
pre-commit: fmt pre-commit: fmt
go mod tidy @go mod tidy
.PHONY: install-protobuf-plugins
install-protobuf-plugins:
@go install github.com/bufbuild/buf/cmd/buf@v1.11.0
@go install github.com/bufbuild/buf/cmd/protoc-gen-buf-breaking@v1.11.0
@go install github.com/bufbuild/buf/cmd/protoc-gen-buf-lint@v1.11.0
@go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
@go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
help: help:
@echo "make: make" @echo "make: make"

@ -46,13 +46,19 @@ Web端
## 🛠 技术栈 ## 🛠 技术栈
PaoPao主要由以下优秀的开源项目/工具构建 PaoPao主要由以下优秀的开源项目/工具构建
#### 后端:
* [Go](https://go.dev/) * [Go](https://go.dev/ 'go')
* [Gin](https://gin-gonic.com/) * [Gin](https://gin-gonic.com/ 'gin')
* [Zinc](https://zinclabs.io/) * [Mir](https://github.com/alimy/mir 'go-mir')
* [Buf](https://github.com/bufbuild/buf 'buf')
* [gRPC](https://github.com/grpc/grpc-go 'grpc-go')
* [Zinc](https://zinclabs.io/ 'zinc')
#### 前端:
* [Naive UI](https://www.naiveui.com/) * [Naive UI](https://www.naiveui.com/)
* [Vue.js](https://vuejs.org/) * [Vue.js](https://vuejs.org/)
* [Vite.js](https://vitejs.dev/) * [Vite.js](https://vitejs.dev/)
* [tauri](https://github.com/tauri-apps/tauri 'tauri')
<!-- GETTING STARTED --> <!-- GETTING STARTED -->
## 🏗 快速开始 ## 🏗 快速开始
@ -316,13 +322,15 @@ release/paopao-ce --no-default-features --features sqlite3,localoss,loggerfile,r
目前支持的功能集合: 目前支持的功能集合:
| 功能项 | 类别 | 状态 | 备注 | | 功能项 | 类别 | 状态 | 备注 |
| ----- | ----- | ----- | ----- | | ----- | ----- | ----- | ----- |
|`OldWeb` | 子服务 | 稳定(默认) | 开启旧的Web服务 | |`Web` | 子服务 | 内测 | 开启Web服务|
|`Web` | 子服务 | WIP | 开启Web服务|
|`Admin` | 子服务 | WIP | 开启Admin后台运维服务| |`Admin` | 子服务 | WIP | 开启Admin后台运维服务|
|`SpaceX` | 子服务 | WIP | 开启SpaceX服务| |`SpaceX` | 子服务 | WIP | 开启SpaceX服务|
|`Bot` | 子服务 | WIP | 开启Bot服务| |`Bot` | 子服务 | WIP | 开启Bot服务|
|`NativeOBS` | 子服务 | WIP | 开启NativeOBS服务| |`NativeOBS` | 子服务 | WIP | 开启NativeOBS服务|
|`Deprecated:Web` | 子服务 | 稳定 | Deprecated(关闭) OldWeb服务| |`Docs` | 子服务 | WIP | 开启开发者文档服务|
|`Frontend:Web` | 子服务 | 内测 | 开启独立前端服务|
|`Frontend:EmbedWeb` | 子服务 | 内测 | 开启内嵌于后端Web API服务中的前端服务|
|`Deprecated:Web` | 子服务 | 稳定 | 开启旧的Web服务|
|`Gorm` | 数据库 | 稳定(默认) | 使用[gorm](https://github.com/go-gorm/gorm)作为数据库的ORM默认使用 `Gorm` + `MySQL`组合| |`Gorm` | 数据库 | 稳定(默认) | 使用[gorm](https://github.com/go-gorm/gorm)作为数据库的ORM默认使用 `Gorm` + `MySQL`组合|
|`Sqlx`| 数据库 | WIP | 使用[sqlx](https://github.com/jmoiron/sqlx)作为数据库的ORM| |`Sqlx`| 数据库 | WIP | 使用[sqlx](https://github.com/jmoiron/sqlx)作为数据库的ORM|
|`MySQL`| 数据库 | 稳定(默认) | 使用MySQL作为数据库| |`MySQL`| 数据库 | 稳定(默认) | 使用MySQL作为数据库|

@ -4,12 +4,12 @@ paopao-ce roadmap.
### v0.2.0 ### v0.2.0
* [x] add `Friendship` feature * [x] add `Friendship` feature
* [ ] add `Lightship` feature * [ ] add `Lightship` feature
* [ ] add `sqlx` feature * [ ] add `Sqlx` feature
* [ ] add new `web` service * [x] add new `Web` service
* [ ] add `deprecated:web` feature * [x] add `Frontend:Web` feature
* [ ] support run multiple service in single paopao-ce instance * [x] add `Deprecated:OldWeb` feature
* [ ] use [go-mir](https://github.com/alimy/mir) optimize paopao-ce source code architecture * [x] support run multiple service in single paopao-ce instance
* [x] use [go-mir](https://github.com/alimy/mir) optimize paopao-ce source code architecture
### Next ### Next
* [ ] add `Followship` feature * [ ] add `Followship` feature
@ -29,4 +29,3 @@ paopao-ce roadmap.
* [ ] optimize topics service * [ ] optimize topics service
* [ ] optimize backend data logic service(optimize database CRUD operate) * [ ] optimize backend data logic service(optimize database CRUD operate)
* [ ] optimize search logic service * [ ] optimize search logic service

@ -0,0 +1,140 @@
// Code generated by go-mir. DO NOT EDIT.
package v1
import (
"net/http"
"github.com/alimy/mir/v3"
"github.com/gin-gonic/gin"
)
type LoginReq struct {
AgentInfo AgentInfo `json:"agent_info"`
Name string `json:"name"`
Passwd string `json:"passwd"`
}
type AgentInfo struct {
Platform string `json:"platform"`
UserAgent string `json:"user_agent"`
}
type LoginResp struct {
UserInfo
ServerInfo ServerInfo `json:"server_info"`
JwtToken string `json:"jwt_token"`
}
type ServerInfo struct {
ApiVer string `json:"api_ver"`
}
type UserInfo struct {
Name string `json:"name"`
}
type User interface {
// Chain provide handlers chain for gin
Chain() gin.HandlersChain
Logout() mir.Error
Login(*LoginReq) (*LoginResp, mir.Error)
mustEmbedUnimplementedUserServant()
}
type UserBinding interface {
BindLogin(*gin.Context) (*LoginReq, mir.Error)
mustEmbedUnimplementedUserBinding()
}
type UserRender interface {
RenderLogout(*gin.Context, mir.Error)
RenderLogin(*gin.Context, *LoginResp, mir.Error)
mustEmbedUnimplementedUserRender()
}
// RegisterUserServant register User servant to gin
func RegisterUserServant(e *gin.Engine, s User, b UserBinding, r UserRender) {
router := e.Group("m/v1")
// use chain for router
middlewares := s.Chain()
router.Use(middlewares...)
// register routes info to router
router.Handle("POST", "/user/logout/", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
r.RenderLogout(c, s.Logout())
})
router.Handle("POST", "/user/login/", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindLogin(c)
if err != nil {
r.RenderLogin(c, nil, err)
return
}
resp, err := s.Login(req)
r.RenderLogin(c, resp, err)
})
}
// UnimplementedUserServant can be embedded to have forward compatible implementations.
type UnimplementedUserServant struct {
}
func (UnimplementedUserServant) Chain() gin.HandlersChain {
return nil
}
func (UnimplementedUserServant) Logout() mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedUserServant) Login(req *LoginReq) (*LoginResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedUserServant) mustEmbedUnimplementedUserServant() {}
// UnimplementedUserRender can be embedded to have forward compatible implementations.
type UnimplementedUserRender struct {
RenderAny func(*gin.Context, any, mir.Error)
}
func (r *UnimplementedUserRender) RenderLogout(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
func (r *UnimplementedUserRender) RenderLogin(c *gin.Context, data *LoginResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedUserRender) mustEmbedUnimplementedUserRender() {}
// UnimplementedUserBinding can be embedded to have forward compatible implementations.
type UnimplementedUserBinding struct {
BindAny func(*gin.Context, any) mir.Error
}
func (b *UnimplementedUserBinding) BindLogin(c *gin.Context) (*LoginReq, mir.Error) {
obj := new(LoginReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedUserBinding) mustEmbedUnimplementedUserBinding() {}

@ -0,0 +1,140 @@
// Code generated by go-mir. DO NOT EDIT.
package v1
import (
"net/http"
"github.com/alimy/mir/v3"
"github.com/gin-gonic/gin"
)
type LoginReq struct {
AgentInfo AgentInfo `json:"agent_info"`
Name string `json:"name"`
Passwd string `json:"passwd"`
}
type AgentInfo struct {
Platform string `json:"platform"`
UserAgent string `json:"user_agent"`
}
type LoginResp struct {
UserInfo
ServerInfo ServerInfo `json:"server_info"`
JwtToken string `json:"jwt_token"`
}
type ServerInfo struct {
ApiVer string `json:"api_ver"`
}
type UserInfo struct {
Name string `json:"name"`
}
type User interface {
// Chain provide handlers chain for gin
Chain() gin.HandlersChain
Logout() mir.Error
Login(*LoginReq) (*LoginResp, mir.Error)
mustEmbedUnimplementedUserServant()
}
type UserBinding interface {
BindLogin(*gin.Context) (*LoginReq, mir.Error)
mustEmbedUnimplementedUserBinding()
}
type UserRender interface {
RenderLogout(*gin.Context, mir.Error)
RenderLogin(*gin.Context, *LoginResp, mir.Error)
mustEmbedUnimplementedUserRender()
}
// RegisterUserServant register User servant to gin
func RegisterUserServant(e *gin.Engine, s User, b UserBinding, r UserRender) {
router := e.Group("r/v1")
// use chain for router
middlewares := s.Chain()
router.Use(middlewares...)
// register routes info to router
router.Handle("POST", "/user/logout/", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
r.RenderLogout(c, s.Logout())
})
router.Handle("POST", "/user/login/", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindLogin(c)
if err != nil {
r.RenderLogin(c, nil, err)
return
}
resp, err := s.Login(req)
r.RenderLogin(c, resp, err)
})
}
// UnimplementedUserServant can be embedded to have forward compatible implementations.
type UnimplementedUserServant struct {
}
func (UnimplementedUserServant) Chain() gin.HandlersChain {
return nil
}
func (UnimplementedUserServant) Logout() mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedUserServant) Login(req *LoginReq) (*LoginResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedUserServant) mustEmbedUnimplementedUserServant() {}
// UnimplementedUserRender can be embedded to have forward compatible implementations.
type UnimplementedUserRender struct {
RenderAny func(*gin.Context, any, mir.Error)
}
func (r *UnimplementedUserRender) RenderLogout(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
func (r *UnimplementedUserRender) RenderLogin(c *gin.Context, data *LoginResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedUserRender) mustEmbedUnimplementedUserRender() {}
// UnimplementedUserBinding can be embedded to have forward compatible implementations.
type UnimplementedUserBinding struct {
BindAny func(*gin.Context, any) mir.Error
}
func (b *UnimplementedUserBinding) BindLogin(c *gin.Context) (*LoginReq, mir.Error) {
obj := new(LoginReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedUserBinding) mustEmbedUnimplementedUserBinding() {}

@ -0,0 +1,150 @@
// Code generated by go-mir. DO NOT EDIT.
package v1
import (
"net/http"
"github.com/alimy/mir/v3"
"github.com/gin-gonic/gin"
)
type LoginReq struct {
AgentInfo AgentInfo `json:"agent_info"`
Name string `json:"name"`
Passwd string `json:"passwd"`
}
type AgentInfo struct {
Platform string `json:"platform"`
UserAgent string `json:"user_agent"`
}
type LoginResp struct {
UserInfo
ServerInfo ServerInfo `json:"server_info"`
JwtToken string `json:"jwt_token"`
}
type ServerInfo struct {
ApiVer string `json:"api_ver"`
}
type UserInfo struct {
Name string `json:"name"`
}
type User interface {
Logout() mir.Error
Login(*LoginReq) (*LoginResp, mir.Error)
Index() mir.Error
mustEmbedUnimplementedUserServant()
}
type UserBinding interface {
BindLogin(*gin.Context) (*LoginReq, mir.Error)
mustEmbedUnimplementedUserBinding()
}
type UserRender interface {
RenderLogout(*gin.Context, mir.Error)
RenderLogin(*gin.Context, *LoginResp, mir.Error)
RenderIndex(*gin.Context, mir.Error)
mustEmbedUnimplementedUserRender()
}
// RegisterUserServant register User servant to gin
func RegisterUserServant(e *gin.Engine, s User, b UserBinding, r UserRender) {
router := e.Group("s/v1")
// register routes info to router
router.Handle("POST", "/user/logout/", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
r.RenderLogout(c, s.Logout())
})
router.Handle("POST", "/user/login/", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindLogin(c)
if err != nil {
r.RenderLogin(c, nil, err)
return
}
resp, err := s.Login(req)
r.RenderLogin(c, resp, err)
})
router.Handle("GET", "/index/", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
r.RenderIndex(c, s.Index())
})
}
// UnimplementedUserServant can be embedded to have forward compatible implementations.
type UnimplementedUserServant struct {
}
func (UnimplementedUserServant) Logout() mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedUserServant) Login(req *LoginReq) (*LoginResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedUserServant) Index() mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedUserServant) mustEmbedUnimplementedUserServant() {}
// UnimplementedUserRender can be embedded to have forward compatible implementations.
type UnimplementedUserRender struct {
RenderAny func(*gin.Context, any, mir.Error)
}
func (r *UnimplementedUserRender) RenderLogout(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
func (r *UnimplementedUserRender) RenderLogin(c *gin.Context, data *LoginResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedUserRender) RenderIndex(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
func (r *UnimplementedUserRender) mustEmbedUnimplementedUserRender() {}
// UnimplementedUserBinding can be embedded to have forward compatible implementations.
type UnimplementedUserBinding struct {
BindAny func(*gin.Context, any) mir.Error
}
func (b *UnimplementedUserBinding) BindLogin(c *gin.Context) (*LoginReq, mir.Error) {
obj := new(LoginReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedUserBinding) mustEmbedUnimplementedUserBinding() {}

@ -0,0 +1,95 @@
// Code generated by go-mir. DO NOT EDIT.
package v1
import (
"net/http"
"github.com/alimy/mir/v3"
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/model/web"
)
type Admin interface {
// Chain provide handlers chain for gin
Chain() gin.HandlersChain
ChangeUserStatus(*web.ChangeUserStatusReq) mir.Error
mustEmbedUnimplementedAdminServant()
}
type AdminBinding interface {
BindChangeUserStatus(*gin.Context) (*web.ChangeUserStatusReq, mir.Error)
mustEmbedUnimplementedAdminBinding()
}
type AdminRender interface {
RenderChangeUserStatus(*gin.Context, mir.Error)
mustEmbedUnimplementedAdminRender()
}
// RegisterAdminServant register Admin servant to gin
func RegisterAdminServant(e *gin.Engine, s Admin, b AdminBinding, r AdminRender) {
router := e.Group("v1")
// use chain for router
middlewares := s.Chain()
router.Use(middlewares...)
// register routes info to router
router.Handle("POST", "/admin/user/status", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindChangeUserStatus(c)
if err != nil {
r.RenderChangeUserStatus(c, err)
return
}
r.RenderChangeUserStatus(c, s.ChangeUserStatus(req))
})
}
// UnimplementedAdminServant can be embedded to have forward compatible implementations.
type UnimplementedAdminServant struct {
}
func (UnimplementedAdminServant) Chain() gin.HandlersChain {
return nil
}
func (UnimplementedAdminServant) ChangeUserStatus(req *web.ChangeUserStatusReq) mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedAdminServant) mustEmbedUnimplementedAdminServant() {}
// UnimplementedAdminRender can be embedded to have forward compatible implementations.
type UnimplementedAdminRender struct {
RenderAny func(*gin.Context, any, mir.Error)
}
func (r *UnimplementedAdminRender) RenderChangeUserStatus(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
func (r *UnimplementedAdminRender) mustEmbedUnimplementedAdminRender() {}
// UnimplementedAdminBinding can be embedded to have forward compatible implementations.
type UnimplementedAdminBinding struct {
BindAny func(*gin.Context, any) mir.Error
}
func (b *UnimplementedAdminBinding) BindChangeUserStatus(c *gin.Context) (*web.ChangeUserStatusReq, mir.Error) {
obj := new(web.ChangeUserStatusReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedAdminBinding) mustEmbedUnimplementedAdminBinding() {}

@ -0,0 +1,162 @@
// Code generated by go-mir. DO NOT EDIT.
package v1
import (
"net/http"
"github.com/alimy/mir/v3"
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/model/web"
)
type AlipayPriv interface {
// Chain provide handlers chain for gin
Chain() gin.HandlersChain
UserWalletBills(*web.UserWalletBillsReq) (*web.UserWalletBillsResp, mir.Error)
UserRechargeResult(*web.UserRechargeResultReq) (*web.UserRechargeResultResp, mir.Error)
UserRechargeLink(*web.UserRechargeLinkReq) (*web.UserRechargeLinkResp, mir.Error)
mustEmbedUnimplementedAlipayPrivServant()
}
type AlipayPrivBinding interface {
BindUserWalletBills(*gin.Context) (*web.UserWalletBillsReq, mir.Error)
BindUserRechargeResult(*gin.Context) (*web.UserRechargeResultReq, mir.Error)
BindUserRechargeLink(*gin.Context) (*web.UserRechargeLinkReq, mir.Error)
mustEmbedUnimplementedAlipayPrivBinding()
}
type AlipayPrivRender interface {
RenderUserWalletBills(*gin.Context, *web.UserWalletBillsResp, mir.Error)
RenderUserRechargeResult(*gin.Context, *web.UserRechargeResultResp, mir.Error)
RenderUserRechargeLink(*gin.Context, *web.UserRechargeLinkResp, mir.Error)
mustEmbedUnimplementedAlipayPrivRender()
}
// RegisterAlipayPrivServant register AlipayPriv servant to gin
func RegisterAlipayPrivServant(e *gin.Engine, s AlipayPriv, b AlipayPrivBinding, r AlipayPrivRender) {
router := e.Group("v1")
// use chain for router
middlewares := s.Chain()
router.Use(middlewares...)
// register routes info to router
router.Handle("GET", "/user/wallet/bills", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindUserWalletBills(c)
if err != nil {
r.RenderUserWalletBills(c, nil, err)
return
}
resp, err := s.UserWalletBills(req)
r.RenderUserWalletBills(c, resp, err)
})
router.Handle("GET", "/user/recharge", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindUserRechargeResult(c)
if err != nil {
r.RenderUserRechargeResult(c, nil, err)
return
}
resp, err := s.UserRechargeResult(req)
r.RenderUserRechargeResult(c, resp, err)
})
router.Handle("POST", "/user/recharge", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindUserRechargeLink(c)
if err != nil {
r.RenderUserRechargeLink(c, nil, err)
return
}
resp, err := s.UserRechargeLink(req)
r.RenderUserRechargeLink(c, resp, err)
})
}
// UnimplementedAlipayPrivServant can be embedded to have forward compatible implementations.
type UnimplementedAlipayPrivServant struct {
}
func (UnimplementedAlipayPrivServant) Chain() gin.HandlersChain {
return nil
}
func (UnimplementedAlipayPrivServant) UserWalletBills(req *web.UserWalletBillsReq) (*web.UserWalletBillsResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedAlipayPrivServant) UserRechargeResult(req *web.UserRechargeResultReq) (*web.UserRechargeResultResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedAlipayPrivServant) UserRechargeLink(req *web.UserRechargeLinkReq) (*web.UserRechargeLinkResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedAlipayPrivServant) mustEmbedUnimplementedAlipayPrivServant() {}
// UnimplementedAlipayPrivRender can be embedded to have forward compatible implementations.
type UnimplementedAlipayPrivRender struct {
RenderAny func(*gin.Context, any, mir.Error)
}
func (r *UnimplementedAlipayPrivRender) RenderUserWalletBills(c *gin.Context, data *web.UserWalletBillsResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedAlipayPrivRender) RenderUserRechargeResult(c *gin.Context, data *web.UserRechargeResultResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedAlipayPrivRender) RenderUserRechargeLink(c *gin.Context, data *web.UserRechargeLinkResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedAlipayPrivRender) mustEmbedUnimplementedAlipayPrivRender() {}
// UnimplementedAlipayPrivBinding can be embedded to have forward compatible implementations.
type UnimplementedAlipayPrivBinding struct {
BindAny func(*gin.Context, any) mir.Error
}
func (b *UnimplementedAlipayPrivBinding) BindUserWalletBills(c *gin.Context) (*web.UserWalletBillsReq, mir.Error) {
obj := new(web.UserWalletBillsReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedAlipayPrivBinding) BindUserRechargeResult(c *gin.Context) (*web.UserRechargeResultReq, mir.Error) {
obj := new(web.UserRechargeResultReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedAlipayPrivBinding) BindUserRechargeLink(c *gin.Context) (*web.UserRechargeLinkReq, mir.Error) {
obj := new(web.UserRechargeLinkReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedAlipayPrivBinding) mustEmbedUnimplementedAlipayPrivBinding() {}

@ -0,0 +1,85 @@
// Code generated by go-mir. DO NOT EDIT.
package v1
import (
"net/http"
"github.com/alimy/mir/v3"
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/model/web"
)
type AlipayPub interface {
AlipayNotify(*web.AlipayNotifyReq) mir.Error
mustEmbedUnimplementedAlipayPubServant()
}
type AlipayPubBinding interface {
BindAlipayNotify(*gin.Context) (*web.AlipayNotifyReq, mir.Error)
mustEmbedUnimplementedAlipayPubBinding()
}
type AlipayPubRender interface {
RenderAlipayNotify(*gin.Context, mir.Error)
mustEmbedUnimplementedAlipayPubRender()
}
// RegisterAlipayPubServant register AlipayPub servant to gin
func RegisterAlipayPubServant(e *gin.Engine, s AlipayPub, b AlipayPubBinding, r AlipayPubRender) {
router := e.Group("v1")
// register routes info to router
router.Handle("POST", "/alipay/notify", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindAlipayNotify(c)
if err != nil {
r.RenderAlipayNotify(c, err)
return
}
r.RenderAlipayNotify(c, s.AlipayNotify(req))
})
}
// UnimplementedAlipayPubServant can be embedded to have forward compatible implementations.
type UnimplementedAlipayPubServant struct {
}
func (UnimplementedAlipayPubServant) AlipayNotify(req *web.AlipayNotifyReq) mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedAlipayPubServant) mustEmbedUnimplementedAlipayPubServant() {}
// UnimplementedAlipayPubRender can be embedded to have forward compatible implementations.
type UnimplementedAlipayPubRender struct {
RenderAny func(*gin.Context, any, mir.Error)
}
func (r *UnimplementedAlipayPubRender) RenderAlipayNotify(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
func (r *UnimplementedAlipayPubRender) mustEmbedUnimplementedAlipayPubRender() {}
// UnimplementedAlipayPubBinding can be embedded to have forward compatible implementations.
type UnimplementedAlipayPubBinding struct {
BindAny func(*gin.Context, any) mir.Error
}
func (b *UnimplementedAlipayPubBinding) BindAlipayNotify(c *gin.Context) (*web.AlipayNotifyReq, mir.Error) {
obj := new(web.AlipayNotifyReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedAlipayPubBinding) mustEmbedUnimplementedAlipayPubBinding() {}

@ -0,0 +1,584 @@
// Code generated by go-mir. DO NOT EDIT.
package v1
import (
"net/http"
"github.com/alimy/mir/v3"
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/model/web"
)
type Core interface {
// Chain provide handlers chain for gin
Chain() gin.HandlersChain
TweetCollectionStatus(*web.TweetCollectionStatusReq) (*web.TweetCollectionStatusResp, mir.Error)
TweetStarStatus(*web.TweetStarStatusReq) (*web.TweetStarStatusResp, mir.Error)
SuggestTags(*web.SuggestTagsReq) (*web.SuggestTagsResp, mir.Error)
SuggestUsers(*web.SuggestUsersReq) (*web.SuggestUsersResp, mir.Error)
ChangeAvatar(*web.ChangeAvatarReq) mir.Error
ChangeNickname(*web.ChangeNicknameReq) mir.Error
ChangePassword(*web.ChangePasswordReq) mir.Error
UserPhoneBind(*web.UserPhoneBindReq) mir.Error
GetStars(*web.GetStarsReq) (*web.GetStarsResp, mir.Error)
GetCollections(*web.GetCollectionsReq) (*web.GetCollectionsResp, mir.Error)
SendUserWhisper(*web.SendWhisperReq) mir.Error
ReadMessage(*web.ReadMessageReq) mir.Error
GetMessages(*web.GetMessagesReq) (*web.GetMessagesResp, mir.Error)
GetUnreadMsgCount(*web.GetUnreadMsgCountReq) (*web.GetUnreadMsgCountResp, mir.Error)
GetUserInfo(*web.UserInfoReq) (*web.UserInfoResp, mir.Error)
SyncSearchIndex(*web.SyncSearchIndexReq) mir.Error
mustEmbedUnimplementedCoreServant()
}
type CoreBinding interface {
BindTweetCollectionStatus(*gin.Context) (*web.TweetCollectionStatusReq, mir.Error)
BindTweetStarStatus(*gin.Context) (*web.TweetStarStatusReq, mir.Error)
BindSuggestTags(*gin.Context) (*web.SuggestTagsReq, mir.Error)
BindSuggestUsers(*gin.Context) (*web.SuggestUsersReq, mir.Error)
BindChangeAvatar(*gin.Context) (*web.ChangeAvatarReq, mir.Error)
BindChangeNickname(*gin.Context) (*web.ChangeNicknameReq, mir.Error)
BindChangePassword(*gin.Context) (*web.ChangePasswordReq, mir.Error)
BindUserPhoneBind(*gin.Context) (*web.UserPhoneBindReq, mir.Error)
BindGetStars(*gin.Context) (*web.GetStarsReq, mir.Error)
BindGetCollections(*gin.Context) (*web.GetCollectionsReq, mir.Error)
BindSendUserWhisper(*gin.Context) (*web.SendWhisperReq, mir.Error)
BindReadMessage(*gin.Context) (*web.ReadMessageReq, mir.Error)
BindGetMessages(*gin.Context) (*web.GetMessagesReq, mir.Error)
BindGetUnreadMsgCount(*gin.Context) (*web.GetUnreadMsgCountReq, mir.Error)
BindGetUserInfo(*gin.Context) (*web.UserInfoReq, mir.Error)
BindSyncSearchIndex(*gin.Context) (*web.SyncSearchIndexReq, mir.Error)
mustEmbedUnimplementedCoreBinding()
}
type CoreRender interface {
RenderTweetCollectionStatus(*gin.Context, *web.TweetCollectionStatusResp, mir.Error)
RenderTweetStarStatus(*gin.Context, *web.TweetStarStatusResp, mir.Error)
RenderSuggestTags(*gin.Context, *web.SuggestTagsResp, mir.Error)
RenderSuggestUsers(*gin.Context, *web.SuggestUsersResp, mir.Error)
RenderChangeAvatar(*gin.Context, mir.Error)
RenderChangeNickname(*gin.Context, mir.Error)
RenderChangePassword(*gin.Context, mir.Error)
RenderUserPhoneBind(*gin.Context, mir.Error)
RenderGetStars(*gin.Context, *web.GetStarsResp, mir.Error)
RenderGetCollections(*gin.Context, *web.GetCollectionsResp, mir.Error)
RenderSendUserWhisper(*gin.Context, mir.Error)
RenderReadMessage(*gin.Context, mir.Error)
RenderGetMessages(*gin.Context, *web.GetMessagesResp, mir.Error)
RenderGetUnreadMsgCount(*gin.Context, *web.GetUnreadMsgCountResp, mir.Error)
RenderGetUserInfo(*gin.Context, *web.UserInfoResp, mir.Error)
RenderSyncSearchIndex(*gin.Context, mir.Error)
mustEmbedUnimplementedCoreRender()
}
// RegisterCoreServant register Core servant to gin
func RegisterCoreServant(e *gin.Engine, s Core, b CoreBinding, r CoreRender) {
router := e.Group("v1")
// use chain for router
middlewares := s.Chain()
router.Use(middlewares...)
// register routes info to router
router.Handle("GET", "/post/collection", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindTweetCollectionStatus(c)
if err != nil {
r.RenderTweetCollectionStatus(c, nil, err)
return
}
resp, err := s.TweetCollectionStatus(req)
r.RenderTweetCollectionStatus(c, resp, err)
})
router.Handle("GET", "/post/star", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindTweetStarStatus(c)
if err != nil {
r.RenderTweetStarStatus(c, nil, err)
return
}
resp, err := s.TweetStarStatus(req)
r.RenderTweetStarStatus(c, resp, err)
})
router.Handle("GET", "/suggest/tags", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindSuggestTags(c)
if err != nil {
r.RenderSuggestTags(c, nil, err)
return
}
resp, err := s.SuggestTags(req)
r.RenderSuggestTags(c, resp, err)
})
router.Handle("GET", "/suggest/users", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindSuggestUsers(c)
if err != nil {
r.RenderSuggestUsers(c, nil, err)
return
}
resp, err := s.SuggestUsers(req)
r.RenderSuggestUsers(c, resp, err)
})
router.Handle("POST", "/user/avatar", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindChangeAvatar(c)
if err != nil {
r.RenderChangeAvatar(c, err)
return
}
r.RenderChangeAvatar(c, s.ChangeAvatar(req))
})
router.Handle("POST", "/user/nickname", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindChangeNickname(c)
if err != nil {
r.RenderChangeNickname(c, err)
return
}
r.RenderChangeNickname(c, s.ChangeNickname(req))
})
router.Handle("POST", "/user/password", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindChangePassword(c)
if err != nil {
r.RenderChangePassword(c, err)
return
}
r.RenderChangePassword(c, s.ChangePassword(req))
})
router.Handle("POST", "/user/phone", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindUserPhoneBind(c)
if err != nil {
r.RenderUserPhoneBind(c, err)
return
}
r.RenderUserPhoneBind(c, s.UserPhoneBind(req))
})
router.Handle("GET", "/user/stars", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindGetStars(c)
if err != nil {
r.RenderGetStars(c, nil, err)
return
}
resp, err := s.GetStars(req)
r.RenderGetStars(c, resp, err)
})
router.Handle("GET", "/user/collections", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindGetCollections(c)
if err != nil {
r.RenderGetCollections(c, nil, err)
return
}
resp, err := s.GetCollections(req)
r.RenderGetCollections(c, resp, err)
})
router.Handle("POST", "/user/whisper", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindSendUserWhisper(c)
if err != nil {
r.RenderSendUserWhisper(c, err)
return
}
r.RenderSendUserWhisper(c, s.SendUserWhisper(req))
})
router.Handle("POST", "/user/message/read", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindReadMessage(c)
if err != nil {
r.RenderReadMessage(c, err)
return
}
r.RenderReadMessage(c, s.ReadMessage(req))
})
router.Handle("GET", "/user/messages", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindGetMessages(c)
if err != nil {
r.RenderGetMessages(c, nil, err)
return
}
resp, err := s.GetMessages(req)
r.RenderGetMessages(c, resp, err)
})
router.Handle("GET", "/user/msgcount/unread", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindGetUnreadMsgCount(c)
if err != nil {
r.RenderGetUnreadMsgCount(c, nil, err)
return
}
resp, err := s.GetUnreadMsgCount(req)
r.RenderGetUnreadMsgCount(c, resp, err)
})
router.Handle("GET", "/user/info", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindGetUserInfo(c)
if err != nil {
r.RenderGetUserInfo(c, nil, err)
return
}
resp, err := s.GetUserInfo(req)
r.RenderGetUserInfo(c, resp, err)
})
router.Handle("GET", "/sync/index", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindSyncSearchIndex(c)
if err != nil {
r.RenderSyncSearchIndex(c, err)
return
}
r.RenderSyncSearchIndex(c, s.SyncSearchIndex(req))
})
}
// UnimplementedCoreServant can be embedded to have forward compatible implementations.
type UnimplementedCoreServant struct {
}
func (UnimplementedCoreServant) Chain() gin.HandlersChain {
return nil
}
func (UnimplementedCoreServant) TweetCollectionStatus(req *web.TweetCollectionStatusReq) (*web.TweetCollectionStatusResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedCoreServant) TweetStarStatus(req *web.TweetStarStatusReq) (*web.TweetStarStatusResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedCoreServant) SuggestTags(req *web.SuggestTagsReq) (*web.SuggestTagsResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedCoreServant) SuggestUsers(req *web.SuggestUsersReq) (*web.SuggestUsersResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedCoreServant) ChangeAvatar(req *web.ChangeAvatarReq) mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedCoreServant) ChangeNickname(req *web.ChangeNicknameReq) mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedCoreServant) ChangePassword(req *web.ChangePasswordReq) mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedCoreServant) UserPhoneBind(req *web.UserPhoneBindReq) mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedCoreServant) GetStars(req *web.GetStarsReq) (*web.GetStarsResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedCoreServant) GetCollections(req *web.GetCollectionsReq) (*web.GetCollectionsResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedCoreServant) SendUserWhisper(req *web.SendWhisperReq) mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedCoreServant) ReadMessage(req *web.ReadMessageReq) mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedCoreServant) GetMessages(req *web.GetMessagesReq) (*web.GetMessagesResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedCoreServant) GetUnreadMsgCount(req *web.GetUnreadMsgCountReq) (*web.GetUnreadMsgCountResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedCoreServant) GetUserInfo(req *web.UserInfoReq) (*web.UserInfoResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedCoreServant) SyncSearchIndex(req *web.SyncSearchIndexReq) mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedCoreServant) mustEmbedUnimplementedCoreServant() {}
// UnimplementedCoreRender can be embedded to have forward compatible implementations.
type UnimplementedCoreRender struct {
RenderAny func(*gin.Context, any, mir.Error)
}
func (r *UnimplementedCoreRender) RenderTweetCollectionStatus(c *gin.Context, data *web.TweetCollectionStatusResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedCoreRender) RenderTweetStarStatus(c *gin.Context, data *web.TweetStarStatusResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedCoreRender) RenderSuggestTags(c *gin.Context, data *web.SuggestTagsResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedCoreRender) RenderSuggestUsers(c *gin.Context, data *web.SuggestUsersResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedCoreRender) RenderChangeAvatar(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
func (r *UnimplementedCoreRender) RenderChangeNickname(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
func (r *UnimplementedCoreRender) RenderChangePassword(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
func (r *UnimplementedCoreRender) RenderUserPhoneBind(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
func (r *UnimplementedCoreRender) RenderGetStars(c *gin.Context, data *web.GetStarsResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedCoreRender) RenderGetCollections(c *gin.Context, data *web.GetCollectionsResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedCoreRender) RenderSendUserWhisper(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
func (r *UnimplementedCoreRender) RenderReadMessage(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
func (r *UnimplementedCoreRender) RenderGetMessages(c *gin.Context, data *web.GetMessagesResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedCoreRender) RenderGetUnreadMsgCount(c *gin.Context, data *web.GetUnreadMsgCountResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedCoreRender) RenderGetUserInfo(c *gin.Context, data *web.UserInfoResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedCoreRender) RenderSyncSearchIndex(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
func (r *UnimplementedCoreRender) mustEmbedUnimplementedCoreRender() {}
// UnimplementedCoreBinding can be embedded to have forward compatible implementations.
type UnimplementedCoreBinding struct {
BindAny func(*gin.Context, any) mir.Error
}
func (b *UnimplementedCoreBinding) BindTweetCollectionStatus(c *gin.Context) (*web.TweetCollectionStatusReq, mir.Error) {
obj := new(web.TweetCollectionStatusReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedCoreBinding) BindTweetStarStatus(c *gin.Context) (*web.TweetStarStatusReq, mir.Error) {
obj := new(web.TweetStarStatusReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedCoreBinding) BindSuggestTags(c *gin.Context) (*web.SuggestTagsReq, mir.Error) {
obj := new(web.SuggestTagsReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedCoreBinding) BindSuggestUsers(c *gin.Context) (*web.SuggestUsersReq, mir.Error) {
obj := new(web.SuggestUsersReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedCoreBinding) BindChangeAvatar(c *gin.Context) (*web.ChangeAvatarReq, mir.Error) {
obj := new(web.ChangeAvatarReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedCoreBinding) BindChangeNickname(c *gin.Context) (*web.ChangeNicknameReq, mir.Error) {
obj := new(web.ChangeNicknameReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedCoreBinding) BindChangePassword(c *gin.Context) (*web.ChangePasswordReq, mir.Error) {
obj := new(web.ChangePasswordReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedCoreBinding) BindUserPhoneBind(c *gin.Context) (*web.UserPhoneBindReq, mir.Error) {
obj := new(web.UserPhoneBindReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedCoreBinding) BindGetStars(c *gin.Context) (*web.GetStarsReq, mir.Error) {
obj := new(web.GetStarsReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedCoreBinding) BindGetCollections(c *gin.Context) (*web.GetCollectionsReq, mir.Error) {
obj := new(web.GetCollectionsReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedCoreBinding) BindSendUserWhisper(c *gin.Context) (*web.SendWhisperReq, mir.Error) {
obj := new(web.SendWhisperReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedCoreBinding) BindReadMessage(c *gin.Context) (*web.ReadMessageReq, mir.Error) {
obj := new(web.ReadMessageReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedCoreBinding) BindGetMessages(c *gin.Context) (*web.GetMessagesReq, mir.Error) {
obj := new(web.GetMessagesReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedCoreBinding) BindGetUnreadMsgCount(c *gin.Context) (*web.GetUnreadMsgCountReq, mir.Error) {
obj := new(web.GetUnreadMsgCountReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedCoreBinding) BindGetUserInfo(c *gin.Context) (*web.UserInfoReq, mir.Error) {
obj := new(web.UserInfoReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedCoreBinding) BindSyncSearchIndex(c *gin.Context) (*web.SyncSearchIndexReq, mir.Error) {
obj := new(web.SyncSearchIndexReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedCoreBinding) mustEmbedUnimplementedCoreBinding() {}

@ -0,0 +1,193 @@
// Code generated by go-mir. DO NOT EDIT.
package v1
import (
"net/http"
"github.com/alimy/mir/v3"
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/model/web"
)
type Followship interface {
// Chain provide handlers chain for gin
Chain() gin.HandlersChain
ListFollowers(*web.ListFollowersReq) (*web.ListFollowersResp, mir.Error)
ListFollowings(*web.ListFollowingsReq) (*web.ListFollowingsResp, mir.Error)
DeleteFollowing(*web.DeleteFollowingReq) mir.Error
AddFollowing(*web.AddFollowingReq) mir.Error
mustEmbedUnimplementedFollowshipServant()
}
type FollowshipBinding interface {
BindListFollowers(*gin.Context) (*web.ListFollowersReq, mir.Error)
BindListFollowings(*gin.Context) (*web.ListFollowingsReq, mir.Error)
BindDeleteFollowing(*gin.Context) (*web.DeleteFollowingReq, mir.Error)
BindAddFollowing(*gin.Context) (*web.AddFollowingReq, mir.Error)
mustEmbedUnimplementedFollowshipBinding()
}
type FollowshipRender interface {
RenderListFollowers(*gin.Context, *web.ListFollowersResp, mir.Error)
RenderListFollowings(*gin.Context, *web.ListFollowingsResp, mir.Error)
RenderDeleteFollowing(*gin.Context, mir.Error)
RenderAddFollowing(*gin.Context, mir.Error)
mustEmbedUnimplementedFollowshipRender()
}
// RegisterFollowshipServant register Followship servant to gin
func RegisterFollowshipServant(e *gin.Engine, s Followship, b FollowshipBinding, r FollowshipRender) {
router := e.Group("v1")
// use chain for router
middlewares := s.Chain()
router.Use(middlewares...)
// register routes info to router
router.Handle("GET", "/follower/list", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindListFollowers(c)
if err != nil {
r.RenderListFollowers(c, nil, err)
return
}
resp, err := s.ListFollowers(req)
r.RenderListFollowers(c, resp, err)
})
router.Handle("GET", "/following/list", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindListFollowings(c)
if err != nil {
r.RenderListFollowings(c, nil, err)
return
}
resp, err := s.ListFollowings(req)
r.RenderListFollowings(c, resp, err)
})
router.Handle("POST", "/following/delete", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindDeleteFollowing(c)
if err != nil {
r.RenderDeleteFollowing(c, err)
return
}
r.RenderDeleteFollowing(c, s.DeleteFollowing(req))
})
router.Handle("POST", "/following/add", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindAddFollowing(c)
if err != nil {
r.RenderAddFollowing(c, err)
return
}
r.RenderAddFollowing(c, s.AddFollowing(req))
})
}
// UnimplementedFollowshipServant can be embedded to have forward compatible implementations.
type UnimplementedFollowshipServant struct {
}
func (UnimplementedFollowshipServant) Chain() gin.HandlersChain {
return nil
}
func (UnimplementedFollowshipServant) ListFollowers(req *web.ListFollowersReq) (*web.ListFollowersResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedFollowshipServant) ListFollowings(req *web.ListFollowingsReq) (*web.ListFollowingsResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedFollowshipServant) DeleteFollowing(req *web.DeleteFollowingReq) mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedFollowshipServant) AddFollowing(req *web.AddFollowingReq) mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedFollowshipServant) mustEmbedUnimplementedFollowshipServant() {}
// UnimplementedFollowshipRender can be embedded to have forward compatible implementations.
type UnimplementedFollowshipRender struct {
RenderAny func(*gin.Context, any, mir.Error)
}
func (r *UnimplementedFollowshipRender) RenderListFollowers(c *gin.Context, data *web.ListFollowersResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedFollowshipRender) RenderListFollowings(c *gin.Context, data *web.ListFollowingsResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedFollowshipRender) RenderDeleteFollowing(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
func (r *UnimplementedFollowshipRender) RenderAddFollowing(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
func (r *UnimplementedFollowshipRender) mustEmbedUnimplementedFollowshipRender() {}
// UnimplementedFollowshipBinding can be embedded to have forward compatible implementations.
type UnimplementedFollowshipBinding struct {
BindAny func(*gin.Context, any) mir.Error
}
func (b *UnimplementedFollowshipBinding) BindListFollowers(c *gin.Context) (*web.ListFollowersReq, mir.Error) {
obj := new(web.ListFollowersReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedFollowshipBinding) BindListFollowings(c *gin.Context) (*web.ListFollowingsReq, mir.Error) {
obj := new(web.ListFollowingsReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedFollowshipBinding) BindDeleteFollowing(c *gin.Context) (*web.DeleteFollowingReq, mir.Error) {
obj := new(web.DeleteFollowingReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedFollowshipBinding) BindAddFollowing(c *gin.Context) (*web.AddFollowingReq, mir.Error) {
obj := new(web.AddFollowingReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedFollowshipBinding) mustEmbedUnimplementedFollowshipBinding() {}

@ -0,0 +1,224 @@
// Code generated by go-mir. DO NOT EDIT.
package v1
import (
"net/http"
"github.com/alimy/mir/v3"
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/model/web"
)
type Friendship interface {
// Chain provide handlers chain for gin
Chain() gin.HandlersChain
GetContacts(*web.GetContactsReq) (*web.GetContactsResp, mir.Error)
DeleteFriend(*web.DeleteFriendReq) mir.Error
RejectFriend(*web.RejectFriendReq) mir.Error
AddFriend(*web.AddFriendReq) mir.Error
RequestingFriend(*web.RequestingFriendReq) mir.Error
mustEmbedUnimplementedFriendshipServant()
}
type FriendshipBinding interface {
BindGetContacts(*gin.Context) (*web.GetContactsReq, mir.Error)
BindDeleteFriend(*gin.Context) (*web.DeleteFriendReq, mir.Error)
BindRejectFriend(*gin.Context) (*web.RejectFriendReq, mir.Error)
BindAddFriend(*gin.Context) (*web.AddFriendReq, mir.Error)
BindRequestingFriend(*gin.Context) (*web.RequestingFriendReq, mir.Error)
mustEmbedUnimplementedFriendshipBinding()
}
type FriendshipRender interface {
RenderGetContacts(*gin.Context, *web.GetContactsResp, mir.Error)
RenderDeleteFriend(*gin.Context, mir.Error)
RenderRejectFriend(*gin.Context, mir.Error)
RenderAddFriend(*gin.Context, mir.Error)
RenderRequestingFriend(*gin.Context, mir.Error)
mustEmbedUnimplementedFriendshipRender()
}
// RegisterFriendshipServant register Friendship servant to gin
func RegisterFriendshipServant(e *gin.Engine, s Friendship, b FriendshipBinding, r FriendshipRender) {
router := e.Group("v1")
// use chain for router
middlewares := s.Chain()
router.Use(middlewares...)
// register routes info to router
router.Handle("GET", "/user/contacts", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindGetContacts(c)
if err != nil {
r.RenderGetContacts(c, nil, err)
return
}
resp, err := s.GetContacts(req)
r.RenderGetContacts(c, resp, err)
})
router.Handle("POST", "/friend/delete", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindDeleteFriend(c)
if err != nil {
r.RenderDeleteFriend(c, err)
return
}
r.RenderDeleteFriend(c, s.DeleteFriend(req))
})
router.Handle("POST", "/friend/reject", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindRejectFriend(c)
if err != nil {
r.RenderRejectFriend(c, err)
return
}
r.RenderRejectFriend(c, s.RejectFriend(req))
})
router.Handle("POST", "/friend/add", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindAddFriend(c)
if err != nil {
r.RenderAddFriend(c, err)
return
}
r.RenderAddFriend(c, s.AddFriend(req))
})
router.Handle("POST", "/friend/requesting", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindRequestingFriend(c)
if err != nil {
r.RenderRequestingFriend(c, err)
return
}
r.RenderRequestingFriend(c, s.RequestingFriend(req))
})
}
// UnimplementedFriendshipServant can be embedded to have forward compatible implementations.
type UnimplementedFriendshipServant struct {
}
func (UnimplementedFriendshipServant) Chain() gin.HandlersChain {
return nil
}
func (UnimplementedFriendshipServant) GetContacts(req *web.GetContactsReq) (*web.GetContactsResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedFriendshipServant) DeleteFriend(req *web.DeleteFriendReq) mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedFriendshipServant) RejectFriend(req *web.RejectFriendReq) mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedFriendshipServant) AddFriend(req *web.AddFriendReq) mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedFriendshipServant) RequestingFriend(req *web.RequestingFriendReq) mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedFriendshipServant) mustEmbedUnimplementedFriendshipServant() {}
// UnimplementedFriendshipRender can be embedded to have forward compatible implementations.
type UnimplementedFriendshipRender struct {
RenderAny func(*gin.Context, any, mir.Error)
}
func (r *UnimplementedFriendshipRender) RenderGetContacts(c *gin.Context, data *web.GetContactsResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedFriendshipRender) RenderDeleteFriend(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
func (r *UnimplementedFriendshipRender) RenderRejectFriend(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
func (r *UnimplementedFriendshipRender) RenderAddFriend(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
func (r *UnimplementedFriendshipRender) RenderRequestingFriend(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
func (r *UnimplementedFriendshipRender) mustEmbedUnimplementedFriendshipRender() {}
// UnimplementedFriendshipBinding can be embedded to have forward compatible implementations.
type UnimplementedFriendshipBinding struct {
BindAny func(*gin.Context, any) mir.Error
}
func (b *UnimplementedFriendshipBinding) BindGetContacts(c *gin.Context) (*web.GetContactsReq, mir.Error) {
obj := new(web.GetContactsReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedFriendshipBinding) BindDeleteFriend(c *gin.Context) (*web.DeleteFriendReq, mir.Error) {
obj := new(web.DeleteFriendReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedFriendshipBinding) BindRejectFriend(c *gin.Context) (*web.RejectFriendReq, mir.Error) {
obj := new(web.RejectFriendReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedFriendshipBinding) BindAddFriend(c *gin.Context) (*web.AddFriendReq, mir.Error) {
obj := new(web.AddFriendReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedFriendshipBinding) BindRequestingFriend(c *gin.Context) (*web.RequestingFriendReq, mir.Error) {
obj := new(web.RequestingFriendReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedFriendshipBinding) mustEmbedUnimplementedFriendshipBinding() {}

@ -0,0 +1,162 @@
// Code generated by go-mir. DO NOT EDIT.
package v1
import (
"net/http"
"github.com/alimy/mir/v3"
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/model/web"
)
type Loose interface {
// Chain provide handlers chain for gin
Chain() gin.HandlersChain
GetUserProfile(*web.GetUserProfileReq) (*web.GetUserProfileResp, mir.Error)
GetUserTweets(*web.GetUserTweetsReq) (*web.GetUserTweetsResp, mir.Error)
Timeline(*web.TimelineReq) (*web.TimelineResp, mir.Error)
mustEmbedUnimplementedLooseServant()
}
type LooseBinding interface {
BindGetUserProfile(*gin.Context) (*web.GetUserProfileReq, mir.Error)
BindGetUserTweets(*gin.Context) (*web.GetUserTweetsReq, mir.Error)
BindTimeline(*gin.Context) (*web.TimelineReq, mir.Error)
mustEmbedUnimplementedLooseBinding()
}
type LooseRender interface {
RenderGetUserProfile(*gin.Context, *web.GetUserProfileResp, mir.Error)
RenderGetUserTweets(*gin.Context, *web.GetUserTweetsResp, mir.Error)
RenderTimeline(*gin.Context, *web.TimelineResp, mir.Error)
mustEmbedUnimplementedLooseRender()
}
// RegisterLooseServant register Loose servant to gin
func RegisterLooseServant(e *gin.Engine, s Loose, b LooseBinding, r LooseRender) {
router := e.Group("v1")
// use chain for router
middlewares := s.Chain()
router.Use(middlewares...)
// register routes info to router
router.Handle("GET", "/user/profile", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindGetUserProfile(c)
if err != nil {
r.RenderGetUserProfile(c, nil, err)
return
}
resp, err := s.GetUserProfile(req)
r.RenderGetUserProfile(c, resp, err)
})
router.Handle("GET", "/user/posts", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindGetUserTweets(c)
if err != nil {
r.RenderGetUserTweets(c, nil, err)
return
}
resp, err := s.GetUserTweets(req)
r.RenderGetUserTweets(c, resp, err)
})
router.Handle("GET", "/posts", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindTimeline(c)
if err != nil {
r.RenderTimeline(c, nil, err)
return
}
resp, err := s.Timeline(req)
r.RenderTimeline(c, resp, err)
})
}
// UnimplementedLooseServant can be embedded to have forward compatible implementations.
type UnimplementedLooseServant struct {
}
func (UnimplementedLooseServant) Chain() gin.HandlersChain {
return nil
}
func (UnimplementedLooseServant) GetUserProfile(req *web.GetUserProfileReq) (*web.GetUserProfileResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedLooseServant) GetUserTweets(req *web.GetUserTweetsReq) (*web.GetUserTweetsResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedLooseServant) Timeline(req *web.TimelineReq) (*web.TimelineResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedLooseServant) mustEmbedUnimplementedLooseServant() {}
// UnimplementedLooseRender can be embedded to have forward compatible implementations.
type UnimplementedLooseRender struct {
RenderAny func(*gin.Context, any, mir.Error)
}
func (r *UnimplementedLooseRender) RenderGetUserProfile(c *gin.Context, data *web.GetUserProfileResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedLooseRender) RenderGetUserTweets(c *gin.Context, data *web.GetUserTweetsResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedLooseRender) RenderTimeline(c *gin.Context, data *web.TimelineResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedLooseRender) mustEmbedUnimplementedLooseRender() {}
// UnimplementedLooseBinding can be embedded to have forward compatible implementations.
type UnimplementedLooseBinding struct {
BindAny func(*gin.Context, any) mir.Error
}
func (b *UnimplementedLooseBinding) BindGetUserProfile(c *gin.Context) (*web.GetUserProfileReq, mir.Error) {
obj := new(web.GetUserProfileReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedLooseBinding) BindGetUserTweets(c *gin.Context) (*web.GetUserTweetsReq, mir.Error) {
obj := new(web.GetUserTweetsReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedLooseBinding) BindTimeline(c *gin.Context) (*web.TimelineReq, mir.Error) {
obj := new(web.TimelineReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedLooseBinding) mustEmbedUnimplementedLooseBinding() {}

@ -0,0 +1,522 @@
// Code generated by go-mir. DO NOT EDIT.
package v1
import (
"net/http"
"github.com/alimy/mir/v3"
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/model/web"
)
type Priv interface {
// Chain provide handlers chain for gin
Chain() gin.HandlersChain
DeleteCommentReply(*web.DeleteCommentReplyReq) mir.Error
CreateCommentReply(*web.CreateCommentReplyReq) (*web.CreateCommentReplyResp, mir.Error)
DeleteComment(*web.DeleteCommentReq) mir.Error
CreateComment(*web.CreateCommentReq) (*web.CreateCommentResp, mir.Error)
VisibleTweet(*web.VisibleTweetReq) (*web.VisibleTweetResp, mir.Error)
StickTweet(*web.StickTweetReq) (*web.StickTweetResp, mir.Error)
LockTweet(*web.LockTweetReq) (*web.LockTweetResp, mir.Error)
CollectionTweet(*web.CollectionTweetReq) (*web.CollectionTweetResp, mir.Error)
StarTweet(*web.StarTweetReq) (*web.StarTweetResp, mir.Error)
DeleteTweet(*web.DeleteTweetReq) mir.Error
CreateTweet(*web.CreateTweetReq) (*web.CreateTweetResp, mir.Error)
DownloadAttachment(*web.DownloadAttachmentReq) (*web.DownloadAttachmentResp, mir.Error)
DownloadAttachmentPrecheck(*web.DownloadAttachmentPrecheckReq) (*web.DownloadAttachmentPrecheckResp, mir.Error)
UploadAttachment(*web.UploadAttachmentReq) (*web.UploadAttachmentResp, mir.Error)
mustEmbedUnimplementedPrivServant()
}
type PrivBinding interface {
BindDeleteCommentReply(*gin.Context) (*web.DeleteCommentReplyReq, mir.Error)
BindCreateCommentReply(*gin.Context) (*web.CreateCommentReplyReq, mir.Error)
BindDeleteComment(*gin.Context) (*web.DeleteCommentReq, mir.Error)
BindCreateComment(*gin.Context) (*web.CreateCommentReq, mir.Error)
BindVisibleTweet(*gin.Context) (*web.VisibleTweetReq, mir.Error)
BindStickTweet(*gin.Context) (*web.StickTweetReq, mir.Error)
BindLockTweet(*gin.Context) (*web.LockTweetReq, mir.Error)
BindCollectionTweet(*gin.Context) (*web.CollectionTweetReq, mir.Error)
BindStarTweet(*gin.Context) (*web.StarTweetReq, mir.Error)
BindDeleteTweet(*gin.Context) (*web.DeleteTweetReq, mir.Error)
BindCreateTweet(*gin.Context) (*web.CreateTweetReq, mir.Error)
BindDownloadAttachment(*gin.Context) (*web.DownloadAttachmentReq, mir.Error)
BindDownloadAttachmentPrecheck(*gin.Context) (*web.DownloadAttachmentPrecheckReq, mir.Error)
BindUploadAttachment(*gin.Context) (*web.UploadAttachmentReq, mir.Error)
mustEmbedUnimplementedPrivBinding()
}
type PrivRender interface {
RenderDeleteCommentReply(*gin.Context, mir.Error)
RenderCreateCommentReply(*gin.Context, *web.CreateCommentReplyResp, mir.Error)
RenderDeleteComment(*gin.Context, mir.Error)
RenderCreateComment(*gin.Context, *web.CreateCommentResp, mir.Error)
RenderVisibleTweet(*gin.Context, *web.VisibleTweetResp, mir.Error)
RenderStickTweet(*gin.Context, *web.StickTweetResp, mir.Error)
RenderLockTweet(*gin.Context, *web.LockTweetResp, mir.Error)
RenderCollectionTweet(*gin.Context, *web.CollectionTweetResp, mir.Error)
RenderStarTweet(*gin.Context, *web.StarTweetResp, mir.Error)
RenderDeleteTweet(*gin.Context, mir.Error)
RenderCreateTweet(*gin.Context, *web.CreateTweetResp, mir.Error)
RenderDownloadAttachment(*gin.Context, *web.DownloadAttachmentResp, mir.Error)
RenderDownloadAttachmentPrecheck(*gin.Context, *web.DownloadAttachmentPrecheckResp, mir.Error)
RenderUploadAttachment(*gin.Context, *web.UploadAttachmentResp, mir.Error)
mustEmbedUnimplementedPrivRender()
}
// RegisterPrivServant register Priv servant to gin
func RegisterPrivServant(e *gin.Engine, s Priv, b PrivBinding, r PrivRender) {
router := e.Group("v1")
// use chain for router
middlewares := s.Chain()
router.Use(middlewares...)
// register routes info to router
router.Handle("DELETE", "/post/comment/reply", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindDeleteCommentReply(c)
if err != nil {
r.RenderDeleteCommentReply(c, err)
return
}
r.RenderDeleteCommentReply(c, s.DeleteCommentReply(req))
})
router.Handle("POST", "/post/comment/reply", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindCreateCommentReply(c)
if err != nil {
r.RenderCreateCommentReply(c, nil, err)
return
}
resp, err := s.CreateCommentReply(req)
r.RenderCreateCommentReply(c, resp, err)
})
router.Handle("DELETE", "/post/comment", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindDeleteComment(c)
if err != nil {
r.RenderDeleteComment(c, err)
return
}
r.RenderDeleteComment(c, s.DeleteComment(req))
})
router.Handle("POST", "/post/comment", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindCreateComment(c)
if err != nil {
r.RenderCreateComment(c, nil, err)
return
}
resp, err := s.CreateComment(req)
r.RenderCreateComment(c, resp, err)
})
router.Handle("POST", "/post/visibility", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindVisibleTweet(c)
if err != nil {
r.RenderVisibleTweet(c, nil, err)
return
}
resp, err := s.VisibleTweet(req)
r.RenderVisibleTweet(c, resp, err)
})
router.Handle("POST", "/post/stick", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindStickTweet(c)
if err != nil {
r.RenderStickTweet(c, nil, err)
return
}
resp, err := s.StickTweet(req)
r.RenderStickTweet(c, resp, err)
})
router.Handle("POST", "/post/lock", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindLockTweet(c)
if err != nil {
r.RenderLockTweet(c, nil, err)
return
}
resp, err := s.LockTweet(req)
r.RenderLockTweet(c, resp, err)
})
router.Handle("POST", "/post/collection", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindCollectionTweet(c)
if err != nil {
r.RenderCollectionTweet(c, nil, err)
return
}
resp, err := s.CollectionTweet(req)
r.RenderCollectionTweet(c, resp, err)
})
router.Handle("POST", "/post/start", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindStarTweet(c)
if err != nil {
r.RenderStarTweet(c, nil, err)
return
}
resp, err := s.StarTweet(req)
r.RenderStarTweet(c, resp, err)
})
router.Handle("DELETE", "/post", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindDeleteTweet(c)
if err != nil {
r.RenderDeleteTweet(c, err)
return
}
r.RenderDeleteTweet(c, s.DeleteTweet(req))
})
router.Handle("POST", "/post", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindCreateTweet(c)
if err != nil {
r.RenderCreateTweet(c, nil, err)
return
}
resp, err := s.CreateTweet(req)
r.RenderCreateTweet(c, resp, err)
})
router.Handle("GET", "/attachment", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindDownloadAttachment(c)
if err != nil {
r.RenderDownloadAttachment(c, nil, err)
return
}
resp, err := s.DownloadAttachment(req)
r.RenderDownloadAttachment(c, resp, err)
})
router.Handle("GET", "/attachment/precheck", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindDownloadAttachmentPrecheck(c)
if err != nil {
r.RenderDownloadAttachmentPrecheck(c, nil, err)
return
}
resp, err := s.DownloadAttachmentPrecheck(req)
r.RenderDownloadAttachmentPrecheck(c, resp, err)
})
router.Handle("POST", "/attachment", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindUploadAttachment(c)
if err != nil {
r.RenderUploadAttachment(c, nil, err)
return
}
resp, err := s.UploadAttachment(req)
r.RenderUploadAttachment(c, resp, err)
})
}
// UnimplementedPrivServant can be embedded to have forward compatible implementations.
type UnimplementedPrivServant struct {
}
func (UnimplementedPrivServant) Chain() gin.HandlersChain {
return nil
}
func (UnimplementedPrivServant) DeleteCommentReply(req *web.DeleteCommentReplyReq) mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedPrivServant) CreateCommentReply(req *web.CreateCommentReplyReq) (*web.CreateCommentReplyResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedPrivServant) DeleteComment(req *web.DeleteCommentReq) mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedPrivServant) CreateComment(req *web.CreateCommentReq) (*web.CreateCommentResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedPrivServant) VisibleTweet(req *web.VisibleTweetReq) (*web.VisibleTweetResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedPrivServant) StickTweet(req *web.StickTweetReq) (*web.StickTweetResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedPrivServant) LockTweet(req *web.LockTweetReq) (*web.LockTweetResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedPrivServant) CollectionTweet(req *web.CollectionTweetReq) (*web.CollectionTweetResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedPrivServant) StarTweet(req *web.StarTweetReq) (*web.StarTweetResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedPrivServant) DeleteTweet(req *web.DeleteTweetReq) mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedPrivServant) CreateTweet(req *web.CreateTweetReq) (*web.CreateTweetResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedPrivServant) DownloadAttachment(req *web.DownloadAttachmentReq) (*web.DownloadAttachmentResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedPrivServant) DownloadAttachmentPrecheck(req *web.DownloadAttachmentPrecheckReq) (*web.DownloadAttachmentPrecheckResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedPrivServant) UploadAttachment(req *web.UploadAttachmentReq) (*web.UploadAttachmentResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedPrivServant) mustEmbedUnimplementedPrivServant() {}
// UnimplementedPrivRender can be embedded to have forward compatible implementations.
type UnimplementedPrivRender struct {
RenderAny func(*gin.Context, any, mir.Error)
}
func (r *UnimplementedPrivRender) RenderDeleteCommentReply(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
func (r *UnimplementedPrivRender) RenderCreateCommentReply(c *gin.Context, data *web.CreateCommentReplyResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedPrivRender) RenderDeleteComment(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
func (r *UnimplementedPrivRender) RenderCreateComment(c *gin.Context, data *web.CreateCommentResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedPrivRender) RenderVisibleTweet(c *gin.Context, data *web.VisibleTweetResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedPrivRender) RenderStickTweet(c *gin.Context, data *web.StickTweetResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedPrivRender) RenderLockTweet(c *gin.Context, data *web.LockTweetResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedPrivRender) RenderCollectionTweet(c *gin.Context, data *web.CollectionTweetResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedPrivRender) RenderStarTweet(c *gin.Context, data *web.StarTweetResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedPrivRender) RenderDeleteTweet(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
func (r *UnimplementedPrivRender) RenderCreateTweet(c *gin.Context, data *web.CreateTweetResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedPrivRender) RenderDownloadAttachment(c *gin.Context, data *web.DownloadAttachmentResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedPrivRender) RenderDownloadAttachmentPrecheck(c *gin.Context, data *web.DownloadAttachmentPrecheckResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedPrivRender) RenderUploadAttachment(c *gin.Context, data *web.UploadAttachmentResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedPrivRender) mustEmbedUnimplementedPrivRender() {}
// UnimplementedPrivBinding can be embedded to have forward compatible implementations.
type UnimplementedPrivBinding struct {
BindAny func(*gin.Context, any) mir.Error
}
func (b *UnimplementedPrivBinding) BindDeleteCommentReply(c *gin.Context) (*web.DeleteCommentReplyReq, mir.Error) {
obj := new(web.DeleteCommentReplyReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedPrivBinding) BindCreateCommentReply(c *gin.Context) (*web.CreateCommentReplyReq, mir.Error) {
obj := new(web.CreateCommentReplyReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedPrivBinding) BindDeleteComment(c *gin.Context) (*web.DeleteCommentReq, mir.Error) {
obj := new(web.DeleteCommentReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedPrivBinding) BindCreateComment(c *gin.Context) (*web.CreateCommentReq, mir.Error) {
obj := new(web.CreateCommentReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedPrivBinding) BindVisibleTweet(c *gin.Context) (*web.VisibleTweetReq, mir.Error) {
obj := new(web.VisibleTweetReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedPrivBinding) BindStickTweet(c *gin.Context) (*web.StickTweetReq, mir.Error) {
obj := new(web.StickTweetReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedPrivBinding) BindLockTweet(c *gin.Context) (*web.LockTweetReq, mir.Error) {
obj := new(web.LockTweetReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedPrivBinding) BindCollectionTweet(c *gin.Context) (*web.CollectionTweetReq, mir.Error) {
obj := new(web.CollectionTweetReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedPrivBinding) BindStarTweet(c *gin.Context) (*web.StarTweetReq, mir.Error) {
obj := new(web.StarTweetReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedPrivBinding) BindDeleteTweet(c *gin.Context) (*web.DeleteTweetReq, mir.Error) {
obj := new(web.DeleteTweetReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedPrivBinding) BindCreateTweet(c *gin.Context) (*web.CreateTweetReq, mir.Error) {
obj := new(web.CreateTweetReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedPrivBinding) BindDownloadAttachment(c *gin.Context) (*web.DownloadAttachmentReq, mir.Error) {
obj := new(web.DownloadAttachmentReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedPrivBinding) BindDownloadAttachmentPrecheck(c *gin.Context) (*web.DownloadAttachmentPrecheckReq, mir.Error) {
obj := new(web.DownloadAttachmentPrecheckReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedPrivBinding) BindUploadAttachment(c *gin.Context) (*web.UploadAttachmentReq, mir.Error) {
obj := new(web.UploadAttachmentReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedPrivBinding) mustEmbedUnimplementedPrivBinding() {}

@ -0,0 +1,292 @@
// Code generated by go-mir. DO NOT EDIT.
package v1
import (
"net/http"
"github.com/alimy/mir/v3"
"github.com/gin-gonic/gin"
"github.com/rocboss/paopao-ce/internal/model/web"
)
type Pub interface {
TopicList(*web.TopicListReq) (*web.TopicListResp, mir.Error)
TweetComments(*web.TweetCommentsReq) (*web.TweetCommentsResp, mir.Error)
TweetDetail(*web.TweetDetailReq) (*web.TweetDetailResp, mir.Error)
SendCaptcha(*web.SendCaptchaReq) mir.Error
GetCaptcha() (*web.GetCaptchaResp, mir.Error)
Register(*web.RegisterReq) (*web.RegisterResp, mir.Error)
Login(*web.LoginReq) (*web.LoginResp, mir.Error)
Version() (*web.VersionResp, mir.Error)
mustEmbedUnimplementedPubServant()
}
type PubBinding interface {
BindTopicList(*gin.Context) (*web.TopicListReq, mir.Error)
BindTweetComments(*gin.Context) (*web.TweetCommentsReq, mir.Error)
BindTweetDetail(*gin.Context) (*web.TweetDetailReq, mir.Error)
BindSendCaptcha(*gin.Context) (*web.SendCaptchaReq, mir.Error)
BindRegister(*gin.Context) (*web.RegisterReq, mir.Error)
BindLogin(*gin.Context) (*web.LoginReq, mir.Error)
mustEmbedUnimplementedPubBinding()
}
type PubRender interface {
RenderTopicList(*gin.Context, *web.TopicListResp, mir.Error)
RenderTweetComments(*gin.Context, *web.TweetCommentsResp, mir.Error)
RenderTweetDetail(*gin.Context, *web.TweetDetailResp, mir.Error)
RenderSendCaptcha(*gin.Context, mir.Error)
RenderGetCaptcha(*gin.Context, *web.GetCaptchaResp, mir.Error)
RenderRegister(*gin.Context, *web.RegisterResp, mir.Error)
RenderLogin(*gin.Context, *web.LoginResp, mir.Error)
RenderVersion(*gin.Context, *web.VersionResp, mir.Error)
mustEmbedUnimplementedPubRender()
}
// RegisterPubServant register Pub servant to gin
func RegisterPubServant(e *gin.Engine, s Pub, b PubBinding, r PubRender) {
router := e.Group("v1")
// register routes info to router
router.Handle("GET", "/tags", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindTopicList(c)
if err != nil {
r.RenderTopicList(c, nil, err)
return
}
resp, err := s.TopicList(req)
r.RenderTopicList(c, resp, err)
})
router.Handle("GET", "/post/comments", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindTweetComments(c)
if err != nil {
r.RenderTweetComments(c, nil, err)
return
}
resp, err := s.TweetComments(req)
r.RenderTweetComments(c, resp, err)
})
router.Handle("GET", "/post", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindTweetDetail(c)
if err != nil {
r.RenderTweetDetail(c, nil, err)
return
}
resp, err := s.TweetDetail(req)
r.RenderTweetDetail(c, resp, err)
})
router.Handle("POST", "/captcha", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindSendCaptcha(c)
if err != nil {
r.RenderSendCaptcha(c, err)
return
}
r.RenderSendCaptcha(c, s.SendCaptcha(req))
})
router.Handle("GET", "/captcha", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
resp, err := s.GetCaptcha()
r.RenderGetCaptcha(c, resp, err)
})
router.Handle("POST", "/auth/register", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindRegister(c)
if err != nil {
r.RenderRegister(c, nil, err)
return
}
resp, err := s.Register(req)
r.RenderRegister(c, resp, err)
})
router.Handle("POST", "/auth/login", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindLogin(c)
if err != nil {
r.RenderLogin(c, nil, err)
return
}
resp, err := s.Login(req)
r.RenderLogin(c, resp, err)
})
router.Handle("GET", "/", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
resp, err := s.Version()
r.RenderVersion(c, resp, err)
})
}
// UnimplementedPubServant can be embedded to have forward compatible implementations.
type UnimplementedPubServant struct {
}
func (UnimplementedPubServant) TopicList(req *web.TopicListReq) (*web.TopicListResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedPubServant) TweetComments(req *web.TweetCommentsReq) (*web.TweetCommentsResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedPubServant) TweetDetail(req *web.TweetDetailReq) (*web.TweetDetailResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedPubServant) SendCaptcha(req *web.SendCaptchaReq) mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedPubServant) GetCaptcha() (*web.GetCaptchaResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedPubServant) Register(req *web.RegisterReq) (*web.RegisterResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedPubServant) Login(req *web.LoginReq) (*web.LoginResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedPubServant) Version() (*web.VersionResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedPubServant) mustEmbedUnimplementedPubServant() {}
// UnimplementedPubRender can be embedded to have forward compatible implementations.
type UnimplementedPubRender struct {
RenderAny func(*gin.Context, any, mir.Error)
}
func (r *UnimplementedPubRender) RenderTopicList(c *gin.Context, data *web.TopicListResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedPubRender) RenderTweetComments(c *gin.Context, data *web.TweetCommentsResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedPubRender) RenderTweetDetail(c *gin.Context, data *web.TweetDetailResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedPubRender) RenderSendCaptcha(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
func (r *UnimplementedPubRender) RenderGetCaptcha(c *gin.Context, data *web.GetCaptchaResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedPubRender) RenderRegister(c *gin.Context, data *web.RegisterResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedPubRender) RenderLogin(c *gin.Context, data *web.LoginResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedPubRender) RenderVersion(c *gin.Context, data *web.VersionResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedPubRender) mustEmbedUnimplementedPubRender() {}
// UnimplementedPubBinding can be embedded to have forward compatible implementations.
type UnimplementedPubBinding struct {
BindAny func(*gin.Context, any) mir.Error
}
func (b *UnimplementedPubBinding) BindTopicList(c *gin.Context) (*web.TopicListReq, mir.Error) {
obj := new(web.TopicListReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedPubBinding) BindTweetComments(c *gin.Context) (*web.TweetCommentsReq, mir.Error) {
obj := new(web.TweetCommentsReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedPubBinding) BindTweetDetail(c *gin.Context) (*web.TweetDetailReq, mir.Error) {
obj := new(web.TweetDetailReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedPubBinding) BindSendCaptcha(c *gin.Context) (*web.SendCaptchaReq, mir.Error) {
obj := new(web.SendCaptchaReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedPubBinding) BindRegister(c *gin.Context) (*web.RegisterReq, mir.Error) {
obj := new(web.RegisterReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedPubBinding) BindLogin(c *gin.Context) (*web.LoginReq, mir.Error) {
obj := new(web.LoginReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedPubBinding) mustEmbedUnimplementedPubBinding() {}

@ -0,0 +1,140 @@
// Code generated by go-mir. DO NOT EDIT.
package v1
import (
"net/http"
"github.com/alimy/mir/v3"
"github.com/gin-gonic/gin"
)
type LoginReq struct {
AgentInfo AgentInfo `json:"agent_info"`
Name string `json:"name"`
Passwd string `json:"passwd"`
}
type AgentInfo struct {
Platform string `json:"platform"`
UserAgent string `json:"user_agent"`
}
type LoginResp struct {
UserInfo
ServerInfo ServerInfo `json:"server_info"`
JwtToken string `json:"jwt_token"`
}
type ServerInfo struct {
ApiVer string `json:"api_ver"`
}
type UserInfo struct {
Name string `json:"name"`
}
type User interface {
// Chain provide handlers chain for gin
Chain() gin.HandlersChain
Logout() mir.Error
Login(*LoginReq) (*LoginResp, mir.Error)
mustEmbedUnimplementedUserServant()
}
type UserBinding interface {
BindLogin(*gin.Context) (*LoginReq, mir.Error)
mustEmbedUnimplementedUserBinding()
}
type UserRender interface {
RenderLogout(*gin.Context, mir.Error)
RenderLogin(*gin.Context, *LoginResp, mir.Error)
mustEmbedUnimplementedUserRender()
}
// RegisterUserServant register User servant to gin
func RegisterUserServant(e *gin.Engine, s User, b UserBinding, r UserRender) {
router := e.Group("x/v1")
// use chain for router
middlewares := s.Chain()
router.Use(middlewares...)
// register routes info to router
router.Handle("POST", "/user/logout/", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
r.RenderLogout(c, s.Logout())
})
router.Handle("POST", "/user/login/", func(c *gin.Context) {
select {
case <-c.Request.Context().Done():
return
default:
}
req, err := b.BindLogin(c)
if err != nil {
r.RenderLogin(c, nil, err)
return
}
resp, err := s.Login(req)
r.RenderLogin(c, resp, err)
})
}
// UnimplementedUserServant can be embedded to have forward compatible implementations.
type UnimplementedUserServant struct {
}
func (UnimplementedUserServant) Chain() gin.HandlersChain {
return nil
}
func (UnimplementedUserServant) Logout() mir.Error {
return mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedUserServant) Login(req *LoginReq) (*LoginResp, mir.Error) {
return nil, mir.Errorln(http.StatusNotImplemented, http.StatusText(http.StatusNotImplemented))
}
func (UnimplementedUserServant) mustEmbedUnimplementedUserServant() {}
// UnimplementedUserRender can be embedded to have forward compatible implementations.
type UnimplementedUserRender struct {
RenderAny func(*gin.Context, any, mir.Error)
}
func (r *UnimplementedUserRender) RenderLogout(c *gin.Context, err mir.Error) {
r.RenderAny(c, nil, err)
}
func (r *UnimplementedUserRender) RenderLogin(c *gin.Context, data *LoginResp, err mir.Error) {
r.RenderAny(c, data, err)
}
func (r *UnimplementedUserRender) mustEmbedUnimplementedUserRender() {}
// UnimplementedUserBinding can be embedded to have forward compatible implementations.
type UnimplementedUserBinding struct {
BindAny func(*gin.Context, any) mir.Error
}
func (b *UnimplementedUserBinding) BindLogin(c *gin.Context) (*LoginReq, mir.Error) {
obj := new(LoginReq)
err := b.BindAny(c, obj)
return obj, err
}
func (b *UnimplementedUserBinding) mustEmbedUnimplementedUserBinding() {}

@ -0,0 +1,371 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.28.1
// protoc (unknown)
// source: v1/auth.proto
package v1
import (
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
type User struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
PhoneNum string `protobuf:"bytes,1,opt,name=phoneNum,proto3" json:"phoneNum,omitempty"`
}
func (x *User) Reset() {
*x = User{}
if protoimpl.UnsafeEnabled {
mi := &file_v1_auth_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *User) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*User) ProtoMessage() {}
func (x *User) ProtoReflect() protoreflect.Message {
mi := &file_v1_auth_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use User.ProtoReflect.Descriptor instead.
func (*User) Descriptor() ([]byte, []int) {
return file_v1_auth_proto_rawDescGZIP(), []int{0}
}
func (x *User) GetPhoneNum() string {
if x != nil {
return x.PhoneNum
}
return ""
}
type UserVerify struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
PhoneNum string `protobuf:"bytes,1,opt,name=phoneNum,proto3" json:"phoneNum,omitempty"`
VerificationCode string `protobuf:"bytes,2,opt,name=VerificationCode,proto3" json:"VerificationCode,omitempty"`
}
func (x *UserVerify) Reset() {
*x = UserVerify{}
if protoimpl.UnsafeEnabled {
mi := &file_v1_auth_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *UserVerify) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*UserVerify) ProtoMessage() {}
func (x *UserVerify) ProtoReflect() protoreflect.Message {
mi := &file_v1_auth_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use UserVerify.ProtoReflect.Descriptor instead.
func (*UserVerify) Descriptor() ([]byte, []int) {
return file_v1_auth_proto_rawDescGZIP(), []int{1}
}
func (x *UserVerify) GetPhoneNum() string {
if x != nil {
return x.PhoneNum
}
return ""
}
func (x *UserVerify) GetVerificationCode() string {
if x != nil {
return x.VerificationCode
}
return ""
}
type LoginReply struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
StatuCode int32 `protobuf:"varint,1,opt,name=statuCode,proto3" json:"statuCode,omitempty"`
Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"`
}
func (x *LoginReply) Reset() {
*x = LoginReply{}
if protoimpl.UnsafeEnabled {
mi := &file_v1_auth_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *LoginReply) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*LoginReply) ProtoMessage() {}
func (x *LoginReply) ProtoReflect() protoreflect.Message {
mi := &file_v1_auth_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use LoginReply.ProtoReflect.Descriptor instead.
func (*LoginReply) Descriptor() ([]byte, []int) {
return file_v1_auth_proto_rawDescGZIP(), []int{2}
}
func (x *LoginReply) GetStatuCode() int32 {
if x != nil {
return x.StatuCode
}
return 0
}
func (x *LoginReply) GetToken() string {
if x != nil {
return x.Token
}
return ""
}
type ActionReply struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
StatusCode int32 `protobuf:"varint,1,opt,name=statusCode,proto3" json:"statusCode,omitempty"`
}
func (x *ActionReply) Reset() {
*x = ActionReply{}
if protoimpl.UnsafeEnabled {
mi := &file_v1_auth_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *ActionReply) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*ActionReply) ProtoMessage() {}
func (x *ActionReply) ProtoReflect() protoreflect.Message {
mi := &file_v1_auth_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use ActionReply.ProtoReflect.Descriptor instead.
func (*ActionReply) Descriptor() ([]byte, []int) {
return file_v1_auth_proto_rawDescGZIP(), []int{3}
}
func (x *ActionReply) GetStatusCode() int32 {
if x != nil {
return x.StatusCode
}
return 0
}
var File_v1_auth_proto protoreflect.FileDescriptor
var file_v1_auth_proto_rawDesc = []byte{
0x0a, 0x0d, 0x76, 0x31, 0x2f, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12,
0x04, 0x61, 0x75, 0x74, 0x68, 0x22, 0x22, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1a, 0x0a,
0x08, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x08, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x4e, 0x75, 0x6d, 0x22, 0x54, 0x0a, 0x0a, 0x55, 0x73, 0x65,
0x72, 0x56, 0x65, 0x72, 0x69, 0x66, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x68, 0x6f, 0x6e, 0x65,
0x4e, 0x75, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x68, 0x6f, 0x6e, 0x65,
0x4e, 0x75, 0x6d, 0x12, 0x2a, 0x0a, 0x10, 0x56, 0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x56,
0x65, 0x72, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x64, 0x65, 0x22,
0x40, 0x0a, 0x0a, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x1c, 0x0a,
0x09, 0x73, 0x74, 0x61, 0x74, 0x75, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05,
0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x75, 0x43, 0x6f, 0x64, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74,
0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65,
0x6e, 0x22, 0x2d, 0x0a, 0x0b, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79,
0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65, 0x18, 0x01,
0x20, 0x01, 0x28, 0x05, 0x52, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x43, 0x6f, 0x64, 0x65,
0x32, 0x89, 0x01, 0x0a, 0x0c, 0x41, 0x75, 0x74, 0x68, 0x65, 0x6e, 0x74, 0x69, 0x63, 0x61, 0x74,
0x65, 0x12, 0x29, 0x0a, 0x08, 0x70, 0x72, 0x65, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x0a, 0x2e,
0x61, 0x75, 0x74, 0x68, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x1a, 0x11, 0x2e, 0x61, 0x75, 0x74, 0x68,
0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x25, 0x0a, 0x05,
0x6c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x0a, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x55, 0x73, 0x65,
0x72, 0x1a, 0x10, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65,
0x70, 0x6c, 0x79, 0x12, 0x27, 0x0a, 0x06, 0x6c, 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x12, 0x0a, 0x2e,
0x61, 0x75, 0x74, 0x68, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x1a, 0x11, 0x2e, 0x61, 0x75, 0x74, 0x68,
0x2e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x42, 0x6f, 0x0a, 0x08,
0x63, 0x6f, 0x6d, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x42, 0x09, 0x41, 0x75, 0x74, 0x68, 0x50, 0x72,
0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f,
0x6d, 0x2f, 0x72, 0x6f, 0x63, 0x62, 0x6f, 0x73, 0x73, 0x2f, 0x70, 0x61, 0x6f, 0x70, 0x61, 0x6f,
0x2d, 0x63, 0x65, 0x2f, 0x61, 0x75, 0x74, 0x6f, 0x2f, 0x72, 0x70, 0x63, 0x2f, 0x76, 0x31, 0xa2,
0x02, 0x03, 0x41, 0x58, 0x58, 0xaa, 0x02, 0x04, 0x41, 0x75, 0x74, 0x68, 0xca, 0x02, 0x04, 0x41,
0x75, 0x74, 0x68, 0xe2, 0x02, 0x10, 0x41, 0x75, 0x74, 0x68, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65,
0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x04, 0x41, 0x75, 0x74, 0x68, 0x62, 0x06, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
file_v1_auth_proto_rawDescOnce sync.Once
file_v1_auth_proto_rawDescData = file_v1_auth_proto_rawDesc
)
func file_v1_auth_proto_rawDescGZIP() []byte {
file_v1_auth_proto_rawDescOnce.Do(func() {
file_v1_auth_proto_rawDescData = protoimpl.X.CompressGZIP(file_v1_auth_proto_rawDescData)
})
return file_v1_auth_proto_rawDescData
}
var file_v1_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
var file_v1_auth_proto_goTypes = []interface{}{
(*User)(nil), // 0: auth.User
(*UserVerify)(nil), // 1: auth.UserVerify
(*LoginReply)(nil), // 2: auth.LoginReply
(*ActionReply)(nil), // 3: auth.ActionReply
}
var file_v1_auth_proto_depIdxs = []int32{
0, // 0: auth.Authenticate.preLogin:input_type -> auth.User
0, // 1: auth.Authenticate.login:input_type -> auth.User
0, // 2: auth.Authenticate.logout:input_type -> auth.User
3, // 3: auth.Authenticate.preLogin:output_type -> auth.ActionReply
2, // 4: auth.Authenticate.login:output_type -> auth.LoginReply
3, // 5: auth.Authenticate.logout:output_type -> auth.ActionReply
3, // [3:6] is the sub-list for method output_type
0, // [0:3] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_v1_auth_proto_init() }
func file_v1_auth_proto_init() {
if File_v1_auth_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_v1_auth_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*User); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_v1_auth_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*UserVerify); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_v1_auth_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*LoginReply); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_v1_auth_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ActionReply); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_v1_auth_proto_rawDesc,
NumEnums: 0,
NumMessages: 4,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_v1_auth_proto_goTypes,
DependencyIndexes: file_v1_auth_proto_depIdxs,
MessageInfos: file_v1_auth_proto_msgTypes,
}.Build()
File_v1_auth_proto = out.File
file_v1_auth_proto_rawDesc = nil
file_v1_auth_proto_goTypes = nil
file_v1_auth_proto_depIdxs = nil
}

@ -0,0 +1,177 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
// versions:
// - protoc-gen-go-grpc v1.2.0
// - protoc (unknown)
// source: v1/auth.proto
package v1
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
// AuthenticateClient is the client API for Authenticate service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type AuthenticateClient interface {
PreLogin(ctx context.Context, in *User, opts ...grpc.CallOption) (*ActionReply, error)
Login(ctx context.Context, in *User, opts ...grpc.CallOption) (*LoginReply, error)
Logout(ctx context.Context, in *User, opts ...grpc.CallOption) (*ActionReply, error)
}
type authenticateClient struct {
cc grpc.ClientConnInterface
}
func NewAuthenticateClient(cc grpc.ClientConnInterface) AuthenticateClient {
return &authenticateClient{cc}
}
func (c *authenticateClient) PreLogin(ctx context.Context, in *User, opts ...grpc.CallOption) (*ActionReply, error) {
out := new(ActionReply)
err := c.cc.Invoke(ctx, "/auth.Authenticate/preLogin", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *authenticateClient) Login(ctx context.Context, in *User, opts ...grpc.CallOption) (*LoginReply, error) {
out := new(LoginReply)
err := c.cc.Invoke(ctx, "/auth.Authenticate/login", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
func (c *authenticateClient) Logout(ctx context.Context, in *User, opts ...grpc.CallOption) (*ActionReply, error) {
out := new(ActionReply)
err := c.cc.Invoke(ctx, "/auth.Authenticate/logout", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// AuthenticateServer is the server API for Authenticate service.
// All implementations must embed UnimplementedAuthenticateServer
// for forward compatibility
type AuthenticateServer interface {
PreLogin(context.Context, *User) (*ActionReply, error)
Login(context.Context, *User) (*LoginReply, error)
Logout(context.Context, *User) (*ActionReply, error)
mustEmbedUnimplementedAuthenticateServer()
}
// UnimplementedAuthenticateServer must be embedded to have forward compatible implementations.
type UnimplementedAuthenticateServer struct {
}
func (UnimplementedAuthenticateServer) PreLogin(context.Context, *User) (*ActionReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method PreLogin not implemented")
}
func (UnimplementedAuthenticateServer) Login(context.Context, *User) (*LoginReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method Login not implemented")
}
func (UnimplementedAuthenticateServer) Logout(context.Context, *User) (*ActionReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method Logout not implemented")
}
func (UnimplementedAuthenticateServer) mustEmbedUnimplementedAuthenticateServer() {}
// UnsafeAuthenticateServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to AuthenticateServer will
// result in compilation errors.
type UnsafeAuthenticateServer interface {
mustEmbedUnimplementedAuthenticateServer()
}
func RegisterAuthenticateServer(s grpc.ServiceRegistrar, srv AuthenticateServer) {
s.RegisterService(&Authenticate_ServiceDesc, srv)
}
func _Authenticate_PreLogin_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(User)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AuthenticateServer).PreLogin(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/auth.Authenticate/preLogin",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AuthenticateServer).PreLogin(ctx, req.(*User))
}
return interceptor(ctx, in, info, handler)
}
func _Authenticate_Login_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(User)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AuthenticateServer).Login(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/auth.Authenticate/login",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AuthenticateServer).Login(ctx, req.(*User))
}
return interceptor(ctx, in, info, handler)
}
func _Authenticate_Logout_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(User)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(AuthenticateServer).Logout(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/auth.Authenticate/logout",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(AuthenticateServer).Logout(ctx, req.(*User))
}
return interceptor(ctx, in, info, handler)
}
// Authenticate_ServiceDesc is the grpc.ServiceDesc for Authenticate service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var Authenticate_ServiceDesc = grpc.ServiceDesc{
ServiceName: "auth.Authenticate",
HandlerType: (*AuthenticateServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "preLogin",
Handler: _Authenticate_PreLogin_Handler,
},
{
MethodName: "login",
Handler: _Authenticate_Login_Handler,
},
{
MethodName: "logout",
Handler: _Authenticate_Logout_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "v1/auth.proto",
}

@ -0,0 +1,16 @@
version: v1
managed:
enabled: true
go_package_prefix:
default: github.com/rocboss/paopao-ce/auto/rpc
except:
- buf.build/googleapis/googleapis
plugins:
- plugin: go
out: auto/rpc
opt: paths=source_relative
- plugin: go-grpc
out: auto/rpc
opt:
- paths=source_relative
- require_unimplemented_servers=true

@ -0,0 +1,3 @@
version: v1
directories:
- proto

@ -1,4 +1,5 @@
App: # APP基础设置项 App: # APP基础设置项
RunMode: debug
AttachmentIncomeRate: 0.8 AttachmentIncomeRate: 0.8
MaxCommentCount: 10 MaxCommentCount: 10
DefaultContextTimeout: 60 DefaultContextTimeout: 60
@ -11,14 +12,54 @@ Server: # 服务设置
ReadTimeout: 60 ReadTimeout: 60
WriteTimeout: 60 WriteTimeout: 60
Features: Features:
Default: ["Base", "MySQL", "Option", "Zinc", "LocalOSS", "LoggerFile", "Friendship"] Default: ["Base", "MySQL", "Option", "Zinc", "LocalOSS", "LoggerFile", "Friendship", "Deprecated"]
Develop: ["Base", "MySQL", "BigCacheIndex", "Meili", "Sms", "AliOSS", "LoggerMeili", "OSS:Retention"] Develop: ["Base", "MySQL", "BigCacheIndex", "Meili", "Sms", "AliOSS", "LoggerMeili", "OSS:Retention"]
Demo: ["Base", "MySQL", "Option", "Zinc", "Sms", "MinIO", "LoggerZinc", "Migration"] Demo: ["Base", "MySQL", "Option", "Zinc", "Sms", "MinIO", "LoggerZinc", "Migration"]
Slim: ["Base", "Sqlite3", "LocalOSS", "LoggerFile", "OSS:TempDir"] Slim: ["Base", "Sqlite3", "LocalOSS", "LoggerFile", "OSS:TempDir"]
Base: ["Redis", "PhoneBind"] Base: ["Redis", "PhoneBind"]
Docs: ["Docs:OpenAPI"] Docs: ["Docs:OpenAPI"]
Deprecated: ["Deprecated:OldWeb"]
Service: ["Web", "Admin", "SpaceX", "Bot", "LocalOSS", "Mobile", "Frontend:Web", "Fronetend:EmbedWeb", "Docs"]
Option: ["SimpleCacheIndex"] Option: ["SimpleCacheIndex"]
Sms: "SmsJuhe" Sms: "SmsJuhe"
WebServer: # Web服务
HttpIp: 0.0.0.0
HttpPort: 8010
ReadTimeout: 60
WriteTimeout: 60
AdminServer: # Admin后台运维服务
HttpIp: 0.0.0.0
HttpPort: 8014
ReadTimeout: 60
WriteTimeout: 60
SpaceXServer: # SpaceX服务
HttpIp: 0.0.0.0
HttpPort: 8012
ReadTimeout: 60
WriteTimeout: 60
BotServer: # Bot服务
HttpIp: 0.0.0.0
HttpPort: 8016
ReadTimeout: 60
WriteTimeout: 60
LocalossServer: # Localoss服务
HttpIp: 0.0.0.0
HttpPort: 8018
ReadTimeout: 60
WriteTimeout: 60
FrontendWebServer: # Web前端服务
HttpIp: 0.0.0.0
HttpPort: 8006
ReadTimeout: 60
WriteTimeout: 60
DocsServer: # 开发文档服务
HttpIp: 0.0.0.0
HttpPort: 8011
ReadTimeout: 60
WriteTimeout: 60
MobileServer: # 移动端grpc api服务
Host: 0.0.0.0
Port: 8020
SmsJuhe: SmsJuhe:
Gateway: https://v.juhe.cn/sms/send Gateway: https://v.juhe.cn/sms/send
Key: Key:

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
//go:build docs //go:build docs
// +build docs // +build docs

@ -40,7 +40,7 @@ paopao-ce在代码实现上采用 **单体架构模式、分层设计、功能
## 从人文角度思考 ## 从人文角度思考
现在的互联网世界已经非常精彩各种社交媒体平台琳琅满目使用体验也非常友好。每个社交平台都有自己的运营方式都有自己的核心用户群体也有自己的产品灵魂都在不断的进行生态演进。比如Twitter、微博都已经从最初的推文分享服务演进到一个成熟的传媒平台注册用户非常庞大日均访问PV也是一个惊人的数字这就注定了平台的运营思维是多维度考量均衡的结果只能做到让用户群体的大多数人用户体验友好并不能满足所有人的需求。大平台有大平台的运营模式小站点有小站点的维系空间。对于类似Twitter这样的推文分享服务paopao-ce提供一种小站点部署模式采用类似WordPress的运维模式**个人/小组织** 能快速、便捷的拥有一个提供推文分享服务的小站点,以填补那些在大平台下难以享受到的用户体验,享受小圈子内的自由空间。 现在的互联网世界已经非常精彩各种社交媒体平台琳琅满目使用体验也非常友好。每个社交平台都有自己的运营方式都有自己的核心用户群体也有自己的产品灵魂都在不断的进行生态演进。比如Twitter、微博都已经从最初的推文分享服务演进到一个成熟的传媒平台注册用户非常庞大日均访问PV也是一个惊人的数字这就注定了平台的运营思维是多维度考量均衡的结果只能做到让用户群体的大多数人用户体验友好并不能满足所有人的需求。大平台有大平台的运营模式小站点有小站点的维系空间。对于类似Twitter这样的推文分享服务paopao-ce提供一种小站点部署模式采用类似WordPress的运维模式**个人/小组织** 能快速、便捷的拥有一个提供推文分享服务的小站点,以填补那些在大平台下难以享受到的用户体验,享受小圈子内的自由空间。
就像许巍唱的「曾经的你」这首歌中所说:"曾梦想仗剑走天涯~ 看一看世界的繁华~ 年少的心总有些轻狂~ 如今你四海为家~ ......" 曾经的你我也在 疯狂刷朋友圈、狂奔微博空间、畅游Twitter世界但是随着环境的改变、岁月的洗礼、心路的淬炼后你我可能已经不复当年的热情逐渐淡出朋友圈、沦为微博的稀客或许Twitter世界还有点吸引力但是总感觉表达的欲望不复从前了。是什么原因变成这样的呢原因可能很多也各自有自己的不同情形所至于此。但是总归一条那就是 **自由**; 如果有那么一个有限空间内,可以自由的 *谈天说地、品头论足、唠唠叨叨亦或自言自语*你我是否又能燃起表达的激情呢从这个角度来说paopao-ce就很契合这种需求曾经你我想拥有一个自己的博客小站点而使用WordPress那么今天想拥有一个自己的类似Twitter的推文分享服务小站点部署paopao-ce或许也是一个不错的选择。 就像许巍唱的「曾经的你」这首歌中所说:*"曾梦想仗剑走天涯~ 看一看世界的繁华~ 年少的心总有些轻狂~ 如今你四海为家~ ......"* 曾经的你我也在 疯狂刷朋友圈、狂奔微博空间、畅游Twitter世界但是随着环境的改变、岁月的洗礼、心路的淬炼后你我可能已经不复当年的热情逐渐淡出朋友圈、沦为微博的稀客或许Twitter世界还有点吸引力但是总感觉表达的欲望不复从前了。是什么原因变成这样的呢原因可能很多也各自有自己的不同情形所至于此。但是总归一条那就是 **自由**; 如果有那么一个有限空间内,可以自由的 **谈天说地、品头论足、唠唠叨叨亦或自言自语**你我是否又能燃起表达的激情呢从这个角度来说paopao-ce就很契合这种需求曾经你我想拥有一个自己的博客小站点而使用WordPress那么今天想拥有一个自己的类似Twitter的推文分享服务小站点部署paopao-ce或许也是一个不错的选择。
一个产品应该有一个**属于自己的灵魂**,可以说 paopao-ce的宗旨就是 **打造一个清新文艺的微社区**。 一个产品应该有一个**属于自己的灵魂**,可以说 paopao-ce的宗旨就是 **打造一个清新文艺的微社区**。
@ -54,7 +54,7 @@ paopao-ce在代码实现上采用 **单体架构模式、分层设计、功能
1. paopao-ce在代码实现上为什么采用单体架构模式 1. paopao-ce在代码实现上为什么采用单体架构模式
一个项目的架构设计是多方面考量均衡的结果,最终的目的是满足项目的需求与长远发展。 一个项目的架构设计是多方面考量均衡的结果,最终的目的是满足项目的需求与长远发展。
* 从架构模式的角度来说单体架构模式可以满足paopao-ce对自身服务定位的需求完全有能力承载预期的用户流量QPS所以采用单体模式架构设计是没有问题的 * 从架构模式的角度来说单体架构模式可以满足paopao-ce对自身服务定位的需求完全有能力承载预期的用户流量QPS所以采用单体模式架构设计是没有问题的
* 从运营者的角度来说,在能保障服务质量的前提下,最看重的还是运营成本的考量。提供一项保质保量的服务,可持续性是评价一项服务的重要指标。单体架构模式的项目部署简单,成本相对于分布式架构模式的项目也更低,假设门槛也没有那么高。黑猫白猫,能抓老鼠就是好猫 在什么阶段就用什么技术,根据部署运营场景选择适合的技术来支撑服务,才是运营者明智的选择。 * 从运营者的角度来说,在能保障服务质量的前提下,最看重的还是运营成本的考量。提供一项保质保量的服务,可持续性是评价一项服务的重要指标。单体架构模式的项目部署简单,成本相对于分布式架构模式的项目也更低,架设门槛也没有那么高。*黑猫白猫,能抓老鼠就是好猫* 在什么阶段就用什么技术,根据部署运营场景选择适合的技术来支撑服务,才是运营者明智的选择。
* 现在不管是单体架构模式亦或是云原生的分布式架构模式相应的技术栈生态都已经非常成熟技术本身没有优劣之分需要根据具体环境来适配合适的技术这样才能在你保证服务质量的同时保证服务的可持续性与经济性。说白了就是paopao-ce目前采用单体架构模式的设计满足优质服务的同时性价比最高。 * 现在不管是单体架构模式亦或是云原生的分布式架构模式相应的技术栈生态都已经非常成熟技术本身没有优劣之分需要根据具体环境来适配合适的技术这样才能在你保证服务质量的同时保证服务的可持续性与经济性。说白了就是paopao-ce目前采用单体架构模式的设计满足优质服务的同时性价比最高。
1. 如果一个paopao-ce部署站点运营一段时间后QPS逐渐提高到一定程度目前架构的paopao-ce无法满足进一步的用户流量冲击是否会采用分布式技术栈进行优化 1. 如果一个paopao-ce部署站点运营一段时间后QPS逐渐提高到一定程度目前架构的paopao-ce无法满足进一步的用户流量冲击是否会采用分布式技术栈进行优化
不会。paopao-ce将保守的采用目前的单体架构模式提供极致的QPS用户体验如果确实需要超高QPS需求的实例部署将另起炉灶开发另一款相应的产品或许会采用云原生的分布式技术栈生态进行架构设计这将是另一个paopao产品的故事序章了(前提是paopao能火出圈)。 不会。paopao-ce将保守的采用目前的单体架构模式提供极致的QPS用户体验如果确实需要超高QPS需求的实例部署将另起炉灶开发另一款相应的产品或许会采用云原生的分布式技术栈生态进行架构设计这将是另一个paopao产品的故事序章了(前提是paopao能火出圈)。

@ -1,6 +1,6 @@
| 编号 | 作者 | 发表时间 | 变更时间 | 版本 | 状态 | | 编号 | 作者 | 发表时间 | 变更时间 | 版本 | 状态 |
| ----- | ----- | ----- | ----- | ----- | ----- | | ----- | ----- | ----- | ----- | ----- | ----- |
| 002| 北野 | 2022-11-04 | 2022-11-06 | v0.2 | 提议 | | 002| 北野 | 2022-11-04 | 2023-01-04 | v1.0 | 提议 |
### Friendship功能项的设计概要 ### Friendship功能项的设计概要
Friendship功能提供好友间分享推文信息的机制更好的帮助用户建立自己的推文分享小圈子。Friendship本质上想优化的是泡泡广场页面推文列表的生成机制开启功能后推文列表只能获取 `公开/私密/好友` 的推文,每个用户都有属于自己的个性化推文列表。在提供个性化推文列表生成机制的同时,好友体系的建立也顺便帮助用户建立自己的个性化有限范围内的灵魂社交小圈子,只有相互间拥有个性化认同感的用户才能互为好友。 Friendship功能提供好友间分享推文信息的机制更好的帮助用户建立自己的推文分享小圈子。Friendship本质上想优化的是泡泡广场页面推文列表的生成机制开启功能后推文列表只能获取 `公开/私密/好友` 的推文,每个用户都有属于自己的个性化推文列表。在提供个性化推文列表生成机制的同时,好友体系的建立也顺便帮助用户建立自己的个性化有限范围内的灵魂社交小圈子,只有相互间拥有个性化认同感的用户才能互为好友。
@ -27,6 +27,8 @@ Friendship功能提供好友间分享推文信息的机制更好的帮助用
* 推文展示时标记推文的可见性描述; * 推文展示时标记推文的可见性描述;
#### 设计细节 #### 设计细节
* 参考实现(PR):
[add support Friendship feature #192](https://github.com/rocboss/paopao-ce/pull/192)
* 预览 * 预览
@ -36,6 +38,7 @@ Friendship功能提供好友间分享推文信息的机制更好的帮助用
| ![](.assets/002-02.png)![](.assets/002-01.png)| | ![](.assets/002-02.png)![](.assets/002-01.png)|
| ![](.assets/002-07.png)| | ![](.assets/002-07.png)|
| ![](.assets/002-08.png)| | ![](.assets/002-08.png)|
### 疑问 ### 疑问
1. 什么是弱关系好友体系? 1. 什么是弱关系好友体系?
@ -59,3 +62,6 @@ Friendship功能提供好友间分享推文信息的机制更好的帮助用
#### v0.2(2022-11-06) - 北野 #### v0.2(2022-11-06) - 北野
* 添加初始文档内容 * 添加初始文档内容
#### v1.0(2023-01-04) - 北野
* 添加参考实现PR信息

@ -0,0 +1,43 @@
| 编号 | 作者 | 发表时间 | 变更时间 | 版本 | 状态 |
| ----- | ----- | ----- | ----- | ----- | ----- |
| 005| 北野 | 2022-11-21 | 2023-01-04 | v1.1 | 提议 |
### 引入go-mir优化后端架构设计
引入[github.com/alimy/mir/v3](https://github.com/alimy/mir)优化后端的架构设计,使得后端代码更具扩展型。
![](.assets/06-01.png)
### 需求
* 更方便添加后端功能项的实现;
* 优化代码结构,模块化、清晰化代码布局,使得更具扩展性;
* 兼容RESTful/gRPC 服务代码RESTful API是服务于Web/AdmingRPC API是提供给移动端(iOS/Android)的服务;
### 方案
依赖库:
* [go-mir](https://github.com/alimy/mir)
参考实现(PR):
* [引入go-mir重构paopao-ce的接入层与业务逻辑层 #196](https://github.com/rocboss/paopao-ce/pull/196)
### 疑问
1. 为什么引入go-mir
* [go-mir](https://github.com/alimy/mir)是一套提供类似gRPC服务开发体验的快速开发RESTful API后端开发脚手架巧妙的借用golang语法作为DSL描述RESTful API通过代码生成的方式自动生成相对应的API接口、HTTP服务器框架初始化代码等提供类似gRPC的开发体验对后端开发者非常友好;
* 引入go-mir的另一个主要目的是加速后端服务的开发更好的保证代码风格的一致性;
* 践行 [006-关于paopao-ce的结构设计](006-关于paopao-ce的结构设计.md);
1. 为什么要兼容RESTful/gRPC服务
* RESTful API是提供给Web端使用的包括paopao-ce web端以及后期的运维端admin gRPC API是提供给移动端(iOS/Android)使用的服务;
* RESTful API天然对web端浏览器友好而gRPC生态对后端、移动端天然友好可以根据google-protocol-buffers DSL定义服务API自动生成服务端、客户端代码非常利于开发特别是移动端开发省去了编写客户端网络数据服务相关的业务逻辑只需要专注于页面逻辑编写后端数据获取的网络数据访问逻辑直接调用自动生成的gRPC API客户端代码即可大大的减轻移动端开发的心智负担;
* 后端引入gRPC主要就是考虑到移动端(iOS/Android)开发的开发效率在减轻移动端开发网络数据获取业务逻辑的心智负担上gRPC生态与RESTful生态相比优势明显因此强力引入;
* 再一个就是[go-mir](https://github.com/alimy/mir) v3为RESTful服务的开发提供类似gRPC服务的开发体验也为后端兼容RESTful/gRPC服务创造了很好的条件只要代码结构组织清晰将会有很好的后端开发体验;
>*目前移动端 iOS/Android APP还在规划中这里后续的后端gRPC API服务也是为此做准备敬请期待*
### 更新记录
#### v0.0(2022-11-21) - 北野
* 初始文档
#### v1.0(2022-12-10) - 北野
* 添加内容
#### v1.1(2023-01-04) - 北野
* 添加参考实现PR信息

@ -1,17 +1,69 @@
| 编号 | 作者 | 发表时间 | 变更时间 | 版本 | 状态 | | 编号 | 作者 | 发表时间 | 变更时间 | 版本 | 状态 |
| ----- | ----- | ----- | ----- | ----- | ----- | | ----- | ----- | ----- | ----- | ----- | ----- |
| 006| 北野 | 2022-11-23 | 2022-11-23 | v0.0 | 提议 | | 006| 北野 | 2022-11-23 | 2022-01-01 | v1.0 | 提议 |
### 关于paopao-ce的结构设计 ### 关于paopao-ce的结构设计
本文档主要讨论paopao-ce目前的代码结构简要清晰的描述一个**API请求**从 **接受解析->逻辑处理->结果响应**的大概路径帮助开发人员快速了解paopao-ce代码基的基本面更好的融入paopao-ce的开发中做出PR贡献。
![](.assets/006-01.png) ![](.assets/006-01.png)
### 两种服务 - RESTful API服务 与 gRPC服务
paopao-ce提供RESTful API与gRPC两种类型子服务并且拥有**单实例多服务运行**的机制。RESTful API服务基于[gin](https://github.com/gin-gonic/gin)引擎实现,使用[go-mir](https://github.com/alimy/mir)脚手架辅助工具集实现RESTFul API从接口定义到代码自动生成的便捷开发体验。 gRPC服务使用[buf](https://github.com/bufbuild/buf)自动化辅助工具对gRPC服务从 `*.proto` DSL服务接口定义到接口代码自动生成的全流程管理。
### 结构说明
paopao-ce采用清晰的分层结构设计主要包括 **接入层、业务逻辑层、数据逻辑层、数据存储**。
* 接入层
RESTful API服务的接入层由 [gin](https://github.com/gin-gonic/gin)引擎 与 [go-mir](https://github.com/alimy/mir)生成的 **Binding/Render** 代码共同组成。当一个HTTP Request被http server接受后通过[gin](https://github.com/gin-gonic/gin)的路由机制,由相应的[go-mir](https://github.com/alimy/mir)生成的`Binding`将请求解析后传入 **业务逻辑层**中相对应的 子服务Servants 完成业务处理后获得结果,[go-mir](https://github.com/alimy/mir)生成的`Render`把结果渲染后生成对应的 HTTP Response发送出去以完成一个HTTP请求。
gRPC服务的接入层由其对应的gRPC服务器引擎组成当一个RPC请求过来后先把请求解码解析后传入 **业务逻辑层**中相对应的 子服务Servers 完成业务处理后获得结果,将处理结果编码后生成对应的 HTTP Response发送出去就完成了一个RPC请求的完整流程。
* 业务逻辑层
RESTful API服务的业务逻辑层是由[go-mir](https://github.com/alimy/mir)依据接口定义自动生成的**Servants服务接口**组成开发人员需要实现这些接口以提供相应的业务逻辑。gRPC也是一样的业务逻辑需要通过实现gRPC依据proto DSL定义接口自动生成的服务接口来提供相应业务处理服务。
* 数据逻辑层
paopao-ce将所有与数据存储相关的服务都统一定义成接口包括**SQL服务、缓存服务、OBS服务、Search服务** 等然后根据具体的部署环境选择适配的相应存储服务实现。比如OBS服务定义了统一的操作对象存储的服务接口然后提供阿里云、腾讯云、华为云、MinIO、S3、Localoss等的服务适配实现这样就可以根据不同的部署环境切换使用不同的对象存储服务实现。
* 数据存储
数据存储包括 SQL存储(MySQL/PostgreSQL/Sqlite3)、Cache、OBS、Search Engine(Zinc/Meilisearch)等paopao-ce本身不关心具体的数据存储是如何部署的一般是通过对应的标准方式连接部署实例以获取相应存储服务。
### paopao-ce代码目录的说明
```sh
tree -L 2
.
|-- auto
| |-- api
| `-- rpc
|-- internal
| |-- conf
| |-- core
| |-- dao
| |-- ims
| |-- migration
| |-- model
| |-- obs
| |-- servants
| `-- service
|-- main.go
|-- mirc
|-- proto
|-- release
`-- web
```
* 根目录的`mirc`包含RESTful API的[go-mir](https://github.com/alimy/mir)服务接口定义文件, `auto/api`目录包含[go-mir](https://github.com/alimy/mir)自动生成的服务接口代码;
* 目录`proto`包含gRPC的proto服务接口定义文件自动生成的服务接口代码包含在`auto/rpc`目录中;
* 业务逻辑层的代码都包含在`internal/servants`目录包括RESTful服务以及gRPC服务的业务逻辑处理代码都包含在这个目录中
* `internal/core`包含所有数据逻辑层的服务接口定义,相应的数据逻辑层服务接口实现代码都包含在`internal/dao`目录中;
* 一些大的功能模块统一放置于`internal`目录中,以降低代码目录深度;比如数据库迁移功能模块`migration`的代码包含在`internal/migration`目录、 消息推送功能模块`ims` -> `internal/ims`, 简单本地OBS功能`obs` -> `internal/obs` 等;
* `internal/service`目录包含paopao-ce所有子服务(`Web`、`Admin`、`Bot`、`SpaceX`、`Mobile` ...)的初始化逻辑代码;
* `internal/conf`目录包含全局配置相关的逻辑代码;
### 疑问 ### 疑问
1. 为什么要引入[go-mir](https://github.com/alimy/mir)? 1. 为什么要引入[go-mir](https://github.com/alimy/mir)?
TODO; **工欲善其事,必先利其器**。为了RESTFul API的后端开发体验可以媲美gRPC本人特意打造[go-mir](https://github.com/alimy/mir) v3版本来满足需求。[go-mir](https://github.com/alimy/mir)是一套使用golang自身语言生态实现的RESTFul API从接口定义到代码自动生成的脚手架辅助工具集便捷的实现快速后端开发体验颇有 *“程咬金的三板斧,简单抡着就完事”* 的韵味。而从[go-mir](https://github.com/alimy/mir)的官方文档参考也可以看出其生成的代码也确实就将一个HTTP的请求/响应简单分成 `请求绑定`->`业务逻辑`->`结果渲染`三个步骤去完成生成的代码结构简单清晰与gRPC的生成代码有点类似。
1. 为什么要兼容RESTful服务与gRPC服务 1. 为什么要兼容RESTful服务与gRPC服务
TODO RESTful服务与gRPC服务各自有擅长的场景在合适的场景使用最适合的技术去做相应的适配这是paopao-ce秉持的代码开发原则之一。
### 更新记录 ### 更新记录
#### v0.0(2022-11-23) - 北野 #### v0.0(2022-11-23) - 北野
* 初始文档, 先占个位置 * 初始文档, 先占个位置
#### v0.1(2022-12-23) - 北野
* 添加部分内容
#### v1.0(2023-01-01) - 北野
* 添加部分内容

@ -2,4 +2,5 @@
* [001-关于paopao-ce的设计定位](001-关于paopao-ce的设计定位.md "关于paopao-ce的设计定位") * [001-关于paopao-ce的设计定位](001-关于paopao-ce的设计定位.md "关于paopao-ce的设计定位")
* [002-关于Friendship功能项的设计](002-关于Friendship功能项的设计.md "关于Friendship功能项的设计") * [002-关于Friendship功能项的设计](002-关于Friendship功能项的设计.md "关于Friendship功能项的设计")
* [003-关于Followship功能项的设计](003-关于Followship功能项的设计.md "关于Followship功能项的设计") * [003-关于Followship功能项的设计](003-关于Followship功能项的设计.md "关于Followship功能项的设计")
* [005-引入go-mir优化后端架构设计](005-引入go-mir优化后端架构设计.md "引入go-mir优化后端架构设计")
* [006-关于paopao-ce的结构设计](006-关于paopao-ce的结构设计.md "关于paopao-ce的结构设计") * [006-关于paopao-ce的结构设计](006-关于paopao-ce的结构设计.md "关于paopao-ce的结构设计")

@ -11,8 +11,8 @@
* `Web` 开启Web服务(目前状态: WIP) * `Web` 开启Web服务(目前状态: WIP)
* [ ] 提按文档 * [ ] 提按文档
* [x] 服务初始化逻辑 * [x] 服务初始化逻辑
* [ ] 接口定义 * [x] 接口定义
* [ ] 业务逻辑实现 * [x] 业务逻辑实现
* `Admin` 开启Admin后台运维服务(目前状态: WIP) * `Admin` 开启Admin后台运维服务(目前状态: WIP)
* [ ] 提按文档 * [ ] 提按文档
* [x] 服务初始化逻辑 * [x] 服务初始化逻辑
@ -33,7 +33,16 @@
* [ ] 服务初始化逻辑 * [ ] 服务初始化逻辑
* [ ] 接口定义 * [ ] 接口定义
* [ ] 业务逻辑实现 * [ ] 业务逻辑实现
* `Deprecated:OldWeb` Deprecated(关闭)旧的Web服务(目前状态: WIP) * `Docs` 开启NativeOBS服务(目前状态: WIP)
* [ ] 提按文档
* [x] 服务初始化逻辑
* `Frontend:Web` 开启独立前端服务(目前状态: 内测)
* [ ] 提按文档
* [x] 服务初始化逻辑
* `Frontend:EmbedWeb` 开启内嵌于后端Web API服务中的前端服务(目前状态: 内测)
* [ ] 提按文档
* [x] 服务初始化逻辑
* `Deprecated:OldWeb` 开启旧的Web服务(目前状态: 内测)
* [ ] 提按文档 * [ ] 提按文档
* [x] 服务初始化逻辑 * [x] 服务初始化逻辑

@ -6,6 +6,7 @@ require (
github.com/Masterminds/semver/v3 v3.1.1 github.com/Masterminds/semver/v3 v3.1.1
github.com/afocus/captcha v0.0.0-20191010092841-4bd1f21c8868 github.com/afocus/captcha v0.0.0-20191010092841-4bd1f21c8868
github.com/alimy/cfg v0.3.0 github.com/alimy/cfg v0.3.0
github.com/alimy/mir/v3 v3.0.0
github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible
github.com/allegro/bigcache/v3 v3.0.2 github.com/allegro/bigcache/v3 v3.0.2
github.com/bytedance/sonic v1.5.0 github.com/bytedance/sonic v1.5.0
@ -30,6 +31,7 @@ require (
github.com/spf13/viper v1.14.0 github.com/spf13/viper v1.14.0
github.com/tencentyun/cos-go-sdk-v5 v0.7.35 github.com/tencentyun/cos-go-sdk-v5 v0.7.35
github.com/yinheli/mahonia v0.0.0-20131226213531-0eef680515cc github.com/yinheli/mahonia v0.0.0-20131226213531-0eef680515cc
google.golang.org/grpc v1.50.1
google.golang.org/protobuf v1.28.1 google.golang.org/protobuf v1.28.1
gopkg.in/natefinch/lumberjack.v2 v2.0.0 gopkg.in/natefinch/lumberjack.v2 v2.0.0
gopkg.in/resty.v1 v1.12.0 gopkg.in/resty.v1 v1.12.0
@ -116,6 +118,7 @@ require (
golang.org/x/text v0.4.0 // indirect golang.org/x/text v0.4.0 // indirect
golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect golang.org/x/time v0.0.0-20220609170525-579cf78fd858 // indirect
golang.org/x/tools v0.1.12 // indirect golang.org/x/tools v0.1.12 // indirect
google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e // indirect
gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect

@ -147,6 +147,8 @@ github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:C
github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY9UnI16Z+UJqRyk= github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY9UnI16Z+UJqRyk=
github.com/alimy/cfg v0.3.0 h1:9xgA0QWVCPSq9fFNRcYahVCAX22IL9ts2wrTQPfAStY= github.com/alimy/cfg v0.3.0 h1:9xgA0QWVCPSq9fFNRcYahVCAX22IL9ts2wrTQPfAStY=
github.com/alimy/cfg v0.3.0/go.mod h1:rOxbasTH2srl6StAjNF5Vyi8bfrdkl3fLGmOYtSw81c= github.com/alimy/cfg v0.3.0/go.mod h1:rOxbasTH2srl6StAjNF5Vyi8bfrdkl3fLGmOYtSw81c=
github.com/alimy/mir/v3 v3.0.0 h1:bUcT+SLs/BYHIuHzTCbYnxnEwbYDSCDJULU5a1YZDes=
github.com/alimy/mir/v3 v3.0.0/go.mod h1:ybhT2ijOiDn0lLwWzIY6vXdv+uzZrctS7VFfczcXBWU=
github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible h1:9gWa46nstkJ9miBReJcN8Gq34cBFbzSpQZVVT9N09TM= github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible h1:9gWa46nstkJ9miBReJcN8Gq34cBFbzSpQZVVT9N09TM=
github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8= github.com/aliyun/aliyun-oss-go-sdk v2.2.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
@ -2064,6 +2066,7 @@ google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ6
google.golang.org/genproto v0.0.0-20220111164026-67b88f271998/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220111164026-67b88f271998/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E=
google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e h1:S9GbmC1iCgvbLyAokVCwiO6tVIrU9Y7c5oMx1V/ki/Y= google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e h1:S9GbmC1iCgvbLyAokVCwiO6tVIrU9Y7c5oMx1V/ki/Y=
google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s=
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
@ -2098,6 +2101,7 @@ google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ5
google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY= google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY=
google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package conf package conf
import ( import (
@ -19,7 +23,15 @@ var (
MysqlSetting *MySQLSettingS MysqlSetting *MySQLSettingS
PostgresSetting *PostgresSettingS PostgresSetting *PostgresSettingS
Sqlite3Setting *Sqlite3SettingS Sqlite3Setting *Sqlite3SettingS
ServerSetting *ServerSettingS ServerSetting *HttpServerSettingS
WebServerSetting *HttpServerSettingS
AdminServerSetting *HttpServerSettingS
SpaceXServerSetting *HttpServerSettingS
BotServerSetting *HttpServerSettingS
LocalossServerSetting *HttpServerSettingS
FrontendWebSetting *HttpServerSettingS
DocsServerSetting *HttpServerSettingS
MobileServerSetting *GRPCServerSettingS
AppSetting *AppSettingS AppSetting *AppSettingS
CacheIndexSetting *CacheIndexSettingS CacheIndexSetting *CacheIndexSettingS
SimpleCacheIndexSetting *SimpleCacheIndexSettingS SimpleCacheIndexSetting *SimpleCacheIndexSettingS
@ -54,41 +66,47 @@ func setupSetting(suite []string, noDefault bool) error {
} }
objects := map[string]any{ objects := map[string]any{
"App": &AppSetting, "App": &AppSetting,
"Server": &ServerSetting, "Server": &ServerSetting,
"CacheIndex": &CacheIndexSetting, "WebServer": &WebServerSetting,
"SimpleCacheIndex": &SimpleCacheIndexSetting, "AdminServer": &AdminServerSetting,
"BigCacheIndex": &BigCacheIndexSetting, "SpaceXServer": &SpaceXServerSetting,
"Alipay": &AlipaySetting, "BotServer": &BotServerSetting,
"SmsJuhe": &SmsJuheSetting, "LocalossServer": &LocalossServerSetting,
"Logger": &loggerSetting, "FrontendWebServer": &FrontendWebSetting,
"LoggerFile": &loggerFileSetting, "DocsServer": &DocsServerSetting,
"LoggerZinc": &loggerZincSetting, "MobileServer": &MobileServerSetting,
"LoggerMeili": &loggerMeiliSetting, "CacheIndex": &CacheIndexSetting,
"Database": &DatabaseSetting, "SimpleCacheIndex": &SimpleCacheIndexSetting,
"MySQL": &MysqlSetting, "BigCacheIndex": &BigCacheIndexSetting,
"Postgres": &PostgresSetting, "Alipay": &AlipaySetting,
"Sqlite3": &Sqlite3Setting, "SmsJuhe": &SmsJuheSetting,
"TweetSearch": &TweetSearchSetting, "Logger": &loggerSetting,
"Zinc": &ZincSetting, "LoggerFile": &loggerFileSetting,
"Meili": &MeiliSetting, "LoggerZinc": &loggerZincSetting,
"Redis": &redisSetting, "LoggerMeili": &loggerMeiliSetting,
"JWT": &JWTSetting, "Database": &DatabaseSetting,
"ObjectStorage": &ObjectStorage, "MySQL": &MysqlSetting,
"AliOSS": &AliOSSSetting, "Postgres": &PostgresSetting,
"COS": &COSSetting, "Sqlite3": &Sqlite3Setting,
"HuaweiOBS": &HuaweiOBSSetting, "TweetSearch": &TweetSearchSetting,
"MinIO": &MinIOSetting, "Zinc": &ZincSetting,
"LocalOSS": &LocalOSSSetting, "Meili": &MeiliSetting,
"S3": &S3Setting, "Redis": &redisSetting,
"JWT": &JWTSetting,
"ObjectStorage": &ObjectStorage,
"AliOSS": &AliOSSSetting,
"COS": &COSSetting,
"HuaweiOBS": &HuaweiOBSSetting,
"MinIO": &MinIOSetting,
"LocalOSS": &LocalOSSSetting,
"S3": &S3Setting,
} }
if err = setting.Unmarshal(objects); err != nil { if err = setting.Unmarshal(objects); err != nil {
return err return err
} }
JWTSetting.Expire *= time.Second JWTSetting.Expire *= time.Second
ServerSetting.ReadTimeout *= time.Second
ServerSetting.WriteTimeout *= time.Second
SimpleCacheIndexSetting.CheckTickDuration *= time.Second SimpleCacheIndexSetting.CheckTickDuration *= time.Second
SimpleCacheIndexSetting.ExpireTickDuration *= time.Second SimpleCacheIndexSetting.ExpireTickDuration *= time.Second
BigCacheIndexSetting.ExpireInSecond *= time.Second BigCacheIndexSetting.ExpireInSecond *= time.Second
@ -134,3 +152,10 @@ func GetOssDomain() string {
} }
return uri + AliOSSSetting.Domain + "/" return uri + AliOSSSetting.Domain + "/"
} }
func RunMode() string {
if !cfg.If("Deprecated:OldWeb") {
return ServerSetting.RunMode
}
return AppSetting.RunMode
}

@ -1,4 +1,5 @@
App: # APP基础设置项 App: # APP基础设置项
RunMode: debug
AttachmentIncomeRate: 0.8 AttachmentIncomeRate: 0.8
MaxCommentCount: 10 MaxCommentCount: 10
DefaultContextTimeout: 60 DefaultContextTimeout: 60
@ -12,6 +13,44 @@ Server: # 服务设置
WriteTimeout: 60 WriteTimeout: 60
Features: Features:
Default: [] Default: []
WebServer: # Web服务
HttpIp: 0.0.0.0
HttpPort: 8010
ReadTimeout: 60
WriteTimeout: 60
AdminServer: # Admin后台运维服务
HttpIp: 0.0.0.0
HttpPort: 8014
ReadTimeout: 60
WriteTimeout: 60
SpaceXServer: # SpaceX服务
HttpIp: 0.0.0.0
HttpPort: 8012
ReadTimeout: 60
WriteTimeout: 60
BotServer: # Bot服务
HttpIp: 0.0.0.0
HttpPort: 8016
ReadTimeout: 60
WriteTimeout: 60
LocalossServer: # Localoss服务
HttpIp: 0.0.0.0
HttpPort: 8018
ReadTimeout: 60
WriteTimeout: 60
FrontendWebServer: # Web前端静态资源服务
HttpIp: 0.0.0.0
HttpPort: 8006
ReadTimeout: 60
WriteTimeout: 60
DocsServer: # 开发文档服务
HttpIp: 0.0.0.0
HttpPort: 8011
ReadTimeout: 60
WriteTimeout: 60
MobileServer: # 移动端grpc api服务
Host: 0.0.0.0
Port: 8020
SmsJuhe: SmsJuhe:
Gateway: https://v.juhe.cn/sms/send Gateway: https://v.juhe.cn/sms/send
Key: Key:

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package conf package conf
import ( import (

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
//go:build cgo //go:build cgo
// +build cgo // +build cgo

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
//go:build !cgo //go:build !cgo
// +build !cgo // +build !cgo

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package conf package conf
import ( import (

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package conf package conf
import ( import (

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package conf package conf
import ( import (

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package conf package conf
import ( import (
@ -45,7 +49,7 @@ type LoggerMeiliSettingS struct {
MinWorker int MinWorker int
} }
type ServerSettingS struct { type HttpServerSettingS struct {
RunMode string RunMode string
HttpIp string HttpIp string
HttpPort string HttpPort string
@ -53,7 +57,13 @@ type ServerSettingS struct {
WriteTimeout time.Duration WriteTimeout time.Duration
} }
type GRPCServerSettingS struct {
Host string
Port string
}
type AppSettingS struct { type AppSettingS struct {
RunMode string
MaxCommentCount int64 MaxCommentCount int64
AttachmentIncomeRate float64 AttachmentIncomeRate float64
DefaultContextTimeout time.Duration DefaultContextTimeout time.Duration
@ -260,6 +270,14 @@ func (s *Setting) featuresInfoFrom(k string) (map[string][]string, map[string]st
return suites, kv return suites, kv
} }
func (s *HttpServerSettingS) GetReadTimeout() time.Duration {
return s.ReadTimeout * time.Second
}
func (s *HttpServerSettingS) GetWriteTimeout() time.Duration {
return s.WriteTimeout * time.Second
}
func (s *MySQLSettingS) Dsn() string { func (s *MySQLSettingS) Dsn() string {
return fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=%s&parseTime=%t&loc=Local", return fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=%s&parseTime=%t&loc=Local",
s.UserName, s.UserName,

@ -1,7 +1,10 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package core package core
import ( import (
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/pkg/types" "github.com/rocboss/paopao-ce/pkg/types"
) )
@ -33,23 +36,17 @@ const (
ActCreateActivationCode ActCreateActivationCode
) )
type act uint8 type (
act uint8
type FriendFilter map[int64]types.Empty
type FriendSet map[string]types.Empty
type Action struct { FriendFilter map[int64]types.Empty
Act act FriendSet map[string]types.Empty
UserId int64
}
// AuthorizationManageService 授权管理服务 Action struct {
type AuthorizationManageService interface { Act act
IsAllow(user *model.User, action *Action) bool UserId int64
BeFriendFilter(userId int64) FriendFilter }
BeFriendIds(userId int64) ([]int64, error) )
MyFriendSet(userId int64) FriendSet
}
func (f FriendFilter) IsFriend(userId int64) bool { func (f FriendFilter) IsFriend(userId int64) bool {
_, yeah := f[userId] _, yeah := f[userId]
@ -57,7 +54,7 @@ func (f FriendFilter) IsFriend(userId int64) bool {
} }
// IsAllow default true if user is admin // IsAllow default true if user is admin
func (a act) IsAllow(user *model.User, userId int64, isFriend bool, isActivation bool) bool { func (a act) IsAllow(user *User, userId int64, isFriend bool, isActivation bool) bool {
if user.IsAdmin { if user.IsAdmin {
return true return true
} }
@ -116,3 +113,11 @@ func (a act) IsAllow(user *model.User, userId int64, isFriend bool, isActivation
return false return false
} }
// AuthorizationManageService 授权管理服务
type AuthorizationManageService interface {
IsAllow(user *User, action *Action) bool
BeFriendFilter(userId int64) FriendFilter
BeFriendIds(userId int64) ([]int64, error)
MyFriendSet(userId int64) FriendSet
}

@ -1,6 +1,12 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package core package core
import "github.com/rocboss/paopao-ce/internal/model" import (
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
)
const ( const (
IdxActNop IdxAct = iota + 1 IdxActNop IdxAct = iota + 1
@ -15,7 +21,7 @@ type IdxAct uint8
type IndexAction struct { type IndexAction struct {
Act IdxAct Act IdxAct
Post *model.Post Post *dbr.Post
} }
func (a IdxAct) String() string { func (a IdxAct) String() string {
@ -37,7 +43,7 @@ func (a IdxAct) String() string {
} }
} }
func NewIndexAction(act IdxAct, post *model.Post) *IndexAction { func NewIndexAction(act IdxAct, post *dbr.Post) *IndexAction {
return &IndexAction{ return &IndexAction{
Act: act, Act: act,
Post: post, Post: post,
@ -48,5 +54,5 @@ func NewIndexAction(act IdxAct, post *model.Post) *IndexAction {
type CacheIndexService interface { type CacheIndexService interface {
IndexPostsService IndexPostsService
SendAction(act IdxAct, post *model.Post) SendAction(act IdxAct, post *dbr.Post)
} }

@ -1,24 +1,36 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package core package core
import ( import (
"github.com/rocboss/paopao-ce/internal/model" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
)
type (
Comment = dbr.Comment
CommentFormated = dbr.CommentFormated
CommentReply = dbr.CommentReply
CommentContent = dbr.CommentContent
CommentReplyFormated = dbr.CommentReplyFormated
) )
// CommentService 评论检索服务 // CommentService 评论检索服务
type CommentService interface { type CommentService interface {
GetComments(conditions *model.ConditionsT, offset, limit int) ([]*model.Comment, error) GetComments(conditions *ConditionsT, offset, limit int) ([]*Comment, error)
GetCommentByID(id int64) (*model.Comment, error) GetCommentByID(id int64) (*Comment, error)
GetCommentCount(conditions *model.ConditionsT) (int64, error) GetCommentCount(conditions *ConditionsT) (int64, error)
GetCommentReplyByID(id int64) (*model.CommentReply, error) GetCommentReplyByID(id int64) (*CommentReply, error)
GetCommentContentsByIDs(ids []int64) ([]*model.CommentContent, error) GetCommentContentsByIDs(ids []int64) ([]*CommentContent, error)
GetCommentRepliesByID(ids []int64) ([]*model.CommentReplyFormated, error) GetCommentRepliesByID(ids []int64) ([]*CommentReplyFormated, error)
} }
// CommentManageService 评论管理服务 // CommentManageService 评论管理服务
type CommentManageService interface { type CommentManageService interface {
DeleteComment(comment *model.Comment) error DeleteComment(comment *Comment) error
CreateComment(comment *model.Comment) (*model.Comment, error) CreateComment(comment *Comment) (*Comment, error)
CreateCommentReply(reply *model.CommentReply) (*model.CommentReply, error) CreateCommentReply(reply *CommentReply) (*CommentReply, error)
DeleteCommentReply(reply *model.CommentReply) error DeleteCommentReply(reply *CommentReply) error
CreateCommentContent(content *model.CommentContent) (*model.CommentContent, error) CreateCommentContent(content *CommentContent) (*CommentContent, error)
} }

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package core package core
// DataService 数据服务集成 // DataService 数据服务集成

@ -1,15 +1,36 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package core package core
import ( import (
"github.com/rocboss/paopao-ce/internal/model" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
)
const (
MsgTypePost = dbr.MsgTypePost
MsgtypeComment = dbr.MsgtypeComment
MsgTypeReply = dbr.MsgTypeReply
MsgTypeWhisper = dbr.MsgTypeWhisper
MsgTypeRequestingFriend = dbr.MsgTypeRequestingFriend
MsgTypeSystem = dbr.MsgTypeSystem
MsgStatusUnread = dbr.MsgStatusUnread
MsgStatusReaded = dbr.MsgStatusReaded
)
type (
Message = dbr.Message
MessageFormated = dbr.MessageFormated
) )
// MessageService 消息服务 // MessageService 消息服务
type MessageService interface { type MessageService interface {
CreateMessage(msg *model.Message) (*model.Message, error) CreateMessage(msg *Message) (*Message, error)
GetUnreadCount(userID int64) (int64, error) GetUnreadCount(userID int64) (int64, error)
GetMessageByID(id int64) (*model.Message, error) GetMessageByID(id int64) (*Message, error)
ReadMessage(message *model.Message) error ReadMessage(message *Message) error
GetMessages(conditions *model.ConditionsT, offset, limit int) ([]*model.MessageFormated, error) GetMessages(conditions *ConditionsT, offset, limit int) ([]*MessageFormated, error)
GetMessageCount(conditions *model.ConditionsT) (int64, error) GetMessageCount(conditions *ConditionsT) (int64, error)
} }

@ -1,7 +1,11 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package core package core
import ( import (
"github.com/rocboss/paopao-ce/internal/model" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
) )
const ( const (
@ -9,28 +13,39 @@ const (
SearchTypeTag SearchType = "tag" SearchTypeTag SearchType = "tag"
) )
type SearchType string const (
PostVisitPublic = dbr.PostVisitPublic
PostVisitPrivate = dbr.PostVisitPrivate
PostVisitFriend = dbr.PostVisitFriend
PostVisitInvalid = dbr.PostVisitInvalid
)
type QueryReq struct { type (
Query string PostVisibleT = dbr.PostVisibleT
Visibility []model.PostVisibleT
Type SearchType
}
type QueryResp struct { SearchType string
Items []*model.PostFormated
Total int64
}
type TsDocItem struct { QueryReq struct {
Post *model.Post Query string
Content string Visibility []PostVisibleT
} Type SearchType
}
QueryResp struct {
Items []*PostFormated
Total int64
}
TsDocItem struct {
Post *Post
Content string
}
)
// TweetSearchService tweet search service interface // TweetSearchService tweet search service interface
type TweetSearchService interface { type TweetSearchService interface {
IndexName() string IndexName() string
AddDocuments(data []TsDocItem, primaryKey ...string) (bool, error) AddDocuments(data []TsDocItem, primaryKey ...string) (bool, error)
DeleteDocuments(identifiers []string) error DeleteDocuments(identifiers []string) error
Search(user *model.User, q *QueryReq, offset, limit int) (*QueryResp, error) Search(user *User, q *QueryReq, offset, limit int) (*QueryResp, error)
} }

@ -1,15 +1,23 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package core package core
import ( import (
"time" "time"
"github.com/rocboss/paopao-ce/internal/model" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
)
type (
Captcha = dbr.Captcha
) )
// SecurityService 安全相关服务 // SecurityService 安全相关服务
type SecurityService interface { type SecurityService interface {
GetLatestPhoneCaptcha(phone string) (*model.Captcha, error) GetLatestPhoneCaptcha(phone string) (*Captcha, error)
UsePhoneCaptcha(captcha *model.Captcha) error UsePhoneCaptcha(captcha *Captcha) error
SendPhoneCaptcha(phone string) error SendPhoneCaptcha(phone string) error
} }

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package core package core
import ( import (

@ -1,13 +1,22 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package core package core
import ( import (
"github.com/rocboss/paopao-ce/internal/model" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
)
type (
Tag = dbr.Tag
TagFormated = dbr.TagFormated
) )
// TopicService 话题服务 // TopicService 话题服务
type TopicService interface { type TopicService interface {
CreateTag(tag *model.Tag) (*model.Tag, error) CreateTag(tag *Tag) (*Tag, error)
DeleteTag(tag *model.Tag) error DeleteTag(tag *Tag) error
GetTags(conditions *model.ConditionsT, offset, limit int) ([]*model.Tag, error) GetTags(conditions *ConditionsT, offset, limit int) ([]*Tag, error)
GetTagsByKeyword(keyword string) ([]*model.Tag, error) GetTagsByKeyword(keyword string) ([]*Tag, error)
} }

@ -1,49 +1,83 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package core package core
import ( import (
"github.com/rocboss/paopao-ce/internal/model" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"github.com/rocboss/paopao-ce/internal/model/rest" )
const (
AttachmentTypeImage = dbr.AttachmentTypeImage
AttachmentTypeVideo = dbr.AttachmentTypeVideo
AttachmentTypeOther = dbr.AttachmentTypeOther
// 类型1标题2文字段落3图片地址4视频地址5语音地址6链接地址7附件资源
ContentTypeTitle = dbr.ContentTypeTitle
ContentTypeText = dbr.ContentTypeText
ContentTypeImage = dbr.ContentTypeImage
ContentTypeVideo = dbr.ContentTypeVideo
ContentTypeAudio = dbr.ContentTypeAudio
ContentTypeLink = dbr.ContentTypeLink
ContentTypeAttachment = dbr.ContentTypeAttachment
ContentTypeChargeAttachment = dbr.ContentTypeChargeAttachment
)
type (
PostStar = dbr.PostStar
PostCollection = dbr.PostCollection
PostAttachmentBill = dbr.PostAttachmentBill
PostContent = dbr.PostContent
Attachment = dbr.Attachment
AttachmentType = dbr.AttachmentType
PostContentT = dbr.PostContentT
IndexTweetList struct {
Tweets []*PostFormated
Total int64
}
) )
// TweetService 推文检索服务 // TweetService 推文检索服务
type TweetService interface { type TweetService interface {
GetPostByID(id int64) (*model.Post, error) GetPostByID(id int64) (*Post, error)
GetPosts(conditions *model.ConditionsT, offset, limit int) ([]*model.Post, error) GetPosts(conditions *ConditionsT, offset, limit int) ([]*Post, error)
GetPostCount(conditions *model.ConditionsT) (int64, error) GetPostCount(conditions *ConditionsT) (int64, error)
GetUserPostStar(postID, userID int64) (*model.PostStar, error) GetUserPostStar(postID, userID int64) (*PostStar, error)
GetUserPostStars(userID int64, offset, limit int) ([]*model.PostStar, error) GetUserPostStars(userID int64, offset, limit int) ([]*PostStar, error)
GetUserPostStarCount(userID int64) (int64, error) GetUserPostStarCount(userID int64) (int64, error)
GetUserPostCollection(postID, userID int64) (*model.PostCollection, error) GetUserPostCollection(postID, userID int64) (*PostCollection, error)
GetUserPostCollections(userID int64, offset, limit int) ([]*model.PostCollection, error) GetUserPostCollections(userID int64, offset, limit int) ([]*PostCollection, error)
GetUserPostCollectionCount(userID int64) (int64, error) GetUserPostCollectionCount(userID int64) (int64, error)
GetPostAttatchmentBill(postID, userID int64) (*model.PostAttachmentBill, error) GetPostAttatchmentBill(postID, userID int64) (*PostAttachmentBill, error)
GetPostContentsByIDs(ids []int64) ([]*model.PostContent, error) GetPostContentsByIDs(ids []int64) ([]*PostContent, error)
GetPostContentByID(id int64) (*model.PostContent, error) GetPostContentByID(id int64) (*PostContent, error)
} }
// TweetManageService 推文管理服务,包括创建/删除/更新推文 // TweetManageService 推文管理服务,包括创建/删除/更新推文
type TweetManageService interface { type TweetManageService interface {
CreateAttachment(attachment *model.Attachment) (*model.Attachment, error) CreateAttachment(attachment *Attachment) (*Attachment, error)
CreatePost(post *model.Post) (*model.Post, error) CreatePost(post *Post) (*Post, error)
DeletePost(post *model.Post) ([]string, error) DeletePost(post *Post) ([]string, error)
LockPost(post *model.Post) error LockPost(post *Post) error
StickPost(post *model.Post) error StickPost(post *Post) error
VisiblePost(post *model.Post, visibility model.PostVisibleT) error VisiblePost(post *Post, visibility PostVisibleT) error
UpdatePost(post *model.Post) error UpdatePost(post *Post) error
CreatePostStar(postID, userID int64) (*model.PostStar, error) CreatePostStar(postID, userID int64) (*PostStar, error)
DeletePostStar(p *model.PostStar) error DeletePostStar(p *PostStar) error
CreatePostCollection(postID, userID int64) (*model.PostCollection, error) CreatePostCollection(postID, userID int64) (*PostCollection, error)
DeletePostCollection(p *model.PostCollection) error DeletePostCollection(p *PostCollection) error
CreatePostContent(content *model.PostContent) (*model.PostContent, error) CreatePostContent(content *PostContent) (*PostContent, error)
} }
// TweetHelpService 推文辅助服务 // TweetHelpService 推文辅助服务
type TweetHelpService interface { type TweetHelpService interface {
RevampPosts(posts []*model.PostFormated) ([]*model.PostFormated, error) RevampPosts(posts []*PostFormated) ([]*PostFormated, error)
MergePosts(posts []*model.Post) ([]*model.PostFormated, error) MergePosts(posts []*Post) ([]*PostFormated, error)
} }
// IndexPostsService 广场首页推文列表服务 // IndexPostsService 广场首页推文列表服务
type IndexPostsService interface { type IndexPostsService interface {
IndexPosts(user *model.User, offset int, limit int) (*rest.IndexTweetsResp, error) IndexPosts(user *User, offset int, limit int) (*IndexTweetList, error)
} }

@ -0,0 +1,24 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package core
import (
"github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
)
const (
UserStatusNormal = dbr.UserStatusNormal
UserStatusClosed = dbr.UserStatusClosed
)
type (
User = dbr.User
Post = dbr.Post
ConditionsT = dbr.ConditionsT
PostFormated = dbr.PostFormated
UserFormated = dbr.UserFormated
PostContentFormated = dbr.PostContentFormated
Model = dbr.Model
)

@ -1,19 +1,33 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package core package core
import ( type (
"github.com/rocboss/paopao-ce/internal/model" ContactItem struct {
"github.com/rocboss/paopao-ce/internal/model/rest" UserId int64 `json:"user_id"`
UserName string `json:"username"`
Nickname string `json:"nickname"`
Avatar string `json:"avatar"`
Phone string `json:"phone"`
}
ContactList struct {
Contacts []ContactItem `json:"contacts"`
Total int64 `json:"total"`
}
) )
// UserManageService 用户管理服务 // UserManageService 用户管理服务
type UserManageService interface { type UserManageService interface {
GetUserByID(id int64) (*model.User, error) GetUserByID(id int64) (*User, error)
GetUserByUsername(username string) (*model.User, error) GetUserByUsername(username string) (*User, error)
GetUserByPhone(phone string) (*model.User, error) GetUserByPhone(phone string) (*User, error)
GetUsersByIDs(ids []int64) ([]*model.User, error) GetUsersByIDs(ids []int64) ([]*User, error)
GetUsersByKeyword(keyword string) ([]*model.User, error) GetUsersByKeyword(keyword string) ([]*User, error)
CreateUser(user *model.User) (*model.User, error) CreateUser(user *User) (*User, error)
UpdateUser(user *model.User) error UpdateUser(user *User) error
} }
// ContactManageService 联系人管理服务 // ContactManageService 联系人管理服务
@ -22,6 +36,6 @@ type ContactManageService interface {
AddFriend(userId int64, friendId int64) error AddFriend(userId int64, friendId int64) error
RejectFriend(userId int64, friendId int64) error RejectFriend(userId int64, friendId int64) error
DeleteFriend(userId int64, friendId int64) error DeleteFriend(userId int64, friendId int64) error
GetContacts(userId int64, offset int, limit int) (*rest.ContactsResp, error) GetContacts(userId int64, offset int, limit int) (*ContactList, error)
IsFriend(userID int64, friendID int64) bool IsFriend(userID int64, friendID int64) bool
} }

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package core package core
import ( import (

@ -1,15 +1,24 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package core package core
import ( import (
"github.com/rocboss/paopao-ce/internal/model" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
)
type (
WalletStatement = dbr.WalletStatement
WalletRecharge = dbr.WalletRecharge
) )
// WalletService wallet service interface // WalletService wallet service interface
type WalletService interface { type WalletService interface {
GetUserWalletBills(userID int64, offset, limit int) ([]*model.WalletStatement, error) GetUserWalletBills(userID int64, offset, limit int) ([]*WalletStatement, error)
GetUserWalletBillCount(userID int64) (int64, error) GetUserWalletBillCount(userID int64) (int64, error)
GetRechargeByID(id int64) (*model.WalletRecharge, error) GetRechargeByID(id int64) (*WalletRecharge, error)
CreateRecharge(userId, amount int64) (*model.WalletRecharge, error) CreateRecharge(userId, amount int64) (*WalletRecharge, error)
HandleRechargeSuccess(recharge *model.WalletRecharge, tradeNo string) error HandleRechargeSuccess(recharge *WalletRecharge, tradeNo string) error
HandlePostAttachmentBought(post *model.Post, user *model.User) error HandlePostAttachmentBought(post *Post, user *User) error
} }

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package cache package cache
import ( import (
@ -11,8 +15,6 @@ import (
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"github.com/allegro/bigcache/v3" "github.com/allegro/bigcache/v3"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/internal/model/rest"
"github.com/rocboss/paopao-ce/pkg/types" "github.com/rocboss/paopao-ce/pkg/types"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -24,7 +26,7 @@ var (
type postsEntry struct { type postsEntry struct {
key string key string
tweets *rest.IndexTweetsResp tweets *core.IndexTweetList
} }
type bigCacheIndexServant struct { type bigCacheIndexServant struct {
@ -38,7 +40,7 @@ type bigCacheIndexServant struct {
preventDuration time.Duration preventDuration time.Duration
} }
func (s *bigCacheIndexServant) IndexPosts(user *model.User, offset int, limit int) (*rest.IndexTweetsResp, error) { func (s *bigCacheIndexServant) IndexPosts(user *core.User, offset int, limit int) (*core.IndexTweetList, error) {
key := s.keyFrom(user, offset, limit) key := s.keyFrom(user, offset, limit)
posts, err := s.getPosts(key) posts, err := s.getPosts(key)
if err == nil { if err == nil {
@ -54,7 +56,7 @@ func (s *bigCacheIndexServant) IndexPosts(user *model.User, offset int, limit in
return posts, nil return posts, nil
} }
func (s *bigCacheIndexServant) getPosts(key string) (*rest.IndexTweetsResp, error) { func (s *bigCacheIndexServant) getPosts(key string) (*core.IndexTweetList, error) {
data, err := s.cache.Get(key) data, err := s.cache.Get(key)
if err != nil { if err != nil {
logrus.Debugf("bigCacheIndexServant.getPosts get posts by key: %s from cache err: %v", key, err) logrus.Debugf("bigCacheIndexServant.getPosts get posts by key: %s from cache err: %v", key, err)
@ -62,7 +64,7 @@ func (s *bigCacheIndexServant) getPosts(key string) (*rest.IndexTweetsResp, erro
} }
buf := bytes.NewBuffer(data) buf := bytes.NewBuffer(data)
dec := gob.NewDecoder(buf) dec := gob.NewDecoder(buf)
var resp rest.IndexTweetsResp var resp core.IndexTweetList
if err := dec.Decode(&resp); err != nil { if err := dec.Decode(&resp); err != nil {
logrus.Debugf("bigCacheIndexServant.getPosts get posts from cache in decode err: %v", err) logrus.Debugf("bigCacheIndexServant.getPosts get posts from cache in decode err: %v", err)
return nil, err return nil, err
@ -70,7 +72,7 @@ func (s *bigCacheIndexServant) getPosts(key string) (*rest.IndexTweetsResp, erro
return &resp, nil return &resp, nil
} }
func (s *bigCacheIndexServant) cachePosts(key string, tweets *rest.IndexTweetsResp) { func (s *bigCacheIndexServant) cachePosts(key string, tweets *core.IndexTweetList) {
entry := &postsEntry{key: key, tweets: tweets} entry := &postsEntry{key: key, tweets: tweets}
select { select {
case s.cachePostsCh <- entry: case s.cachePostsCh <- entry:
@ -96,7 +98,7 @@ func (s *bigCacheIndexServant) setPosts(entry *postsEntry) {
logrus.Debugf("bigCacheIndexServant.setPosts setPosts set cache by key: %s", entry.key) logrus.Debugf("bigCacheIndexServant.setPosts setPosts set cache by key: %s", entry.key)
} }
func (s *bigCacheIndexServant) keyFrom(user *model.User, offset int, limit int) string { func (s *bigCacheIndexServant) keyFrom(user *core.User, offset int, limit int) string {
var userId int64 = -1 var userId int64 = -1
if user != nil { if user != nil {
userId = user.ID userId = user.ID
@ -104,7 +106,7 @@ func (s *bigCacheIndexServant) keyFrom(user *model.User, offset int, limit int)
return fmt.Sprintf("index:%d:%d:%d", userId, offset, limit) return fmt.Sprintf("index:%d:%d:%d", userId, offset, limit)
} }
func (s *bigCacheIndexServant) SendAction(act core.IdxAct, post *model.Post) { func (s *bigCacheIndexServant) SendAction(act core.IdxAct, post *core.Post) {
action := core.NewIndexAction(act, post) action := core.NewIndexAction(act, post)
select { select {
case s.indexActionCh <- action: case s.indexActionCh <- action:
@ -134,7 +136,7 @@ func (s *bigCacheIndexServant) handleIndexAction(action *core.IndexAction) {
// 创建/删除 私密推文特殊处理 // 创建/删除 私密推文特殊处理
switch act { switch act {
case core.IdxActCreatePost, core.IdxActDeletePost: case core.IdxActCreatePost, core.IdxActDeletePost:
if post.Visibility == model.PostVisitPrivate { if post.Visibility == core.PostVisitPrivate {
s.deleteCacheByUserId(post.UserID, true) s.deleteCacheByUserId(post.UserID, true)
return return
} }

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package cache package cache
import ( import (

@ -1,10 +1,12 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package cache package cache
import ( import (
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/internal/model/rest"
) )
var ( var (
@ -16,11 +18,11 @@ type noneCacheIndexServant struct {
ips core.IndexPostsService ips core.IndexPostsService
} }
func (s *noneCacheIndexServant) IndexPosts(user *model.User, offset int, limit int) (*rest.IndexTweetsResp, error) { func (s *noneCacheIndexServant) IndexPosts(user *core.User, offset int, limit int) (*core.IndexTweetList, error) {
return s.ips.IndexPosts(user, offset, limit) return s.ips.IndexPosts(user, offset, limit)
} }
func (s *noneCacheIndexServant) SendAction(_act core.IdxAct, _post *model.Post) { func (s *noneCacheIndexServant) SendAction(_act core.IdxAct, _post *core.Post) {
// empty // empty
} }

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package cache package cache
import ( import (
@ -6,8 +10,6 @@ import (
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/internal/model/rest"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -20,21 +22,21 @@ type simpleCacheIndexServant struct {
ips core.IndexPostsService ips core.IndexPostsService
indexActionCh chan core.IdxAct indexActionCh chan core.IdxAct
indexPosts *rest.IndexTweetsResp indexPosts *core.IndexTweetList
atomicIndex atomic.Value atomicIndex atomic.Value
maxIndexSize int maxIndexSize int
checkTick *time.Ticker checkTick *time.Ticker
expireIndexTick *time.Ticker expireIndexTick *time.Ticker
} }
func (s *simpleCacheIndexServant) IndexPosts(user *model.User, offset int, limit int) (*rest.IndexTweetsResp, error) { func (s *simpleCacheIndexServant) IndexPosts(user *core.User, offset int, limit int) (*core.IndexTweetList, error) {
cacheResp := s.atomicIndex.Load().(*rest.IndexTweetsResp) cacheResp := s.atomicIndex.Load().(*core.IndexTweetList)
end := offset + limit end := offset + limit
if cacheResp != nil { if cacheResp != nil {
size := len(cacheResp.Tweets) size := len(cacheResp.Tweets)
logrus.Debugf("simpleCacheIndexServant.IndexPosts get index posts from cache posts: %d offset:%d limit:%d start:%d, end:%d", size, offset, limit, offset, end) logrus.Debugf("simpleCacheIndexServant.IndexPosts get index posts from cache posts: %d offset:%d limit:%d start:%d, end:%d", size, offset, limit, offset, end)
if size >= end { if size >= end {
return &rest.IndexTweetsResp{ return &core.IndexTweetList{
Tweets: cacheResp.Tweets[offset:end], Tweets: cacheResp.Tweets[offset:end],
Total: cacheResp.Total, Total: cacheResp.Total,
}, nil }, nil
@ -45,7 +47,7 @@ func (s *simpleCacheIndexServant) IndexPosts(user *model.User, offset int, limit
return s.ips.IndexPosts(user, offset, limit) return s.ips.IndexPosts(user, offset, limit)
} }
func (s *simpleCacheIndexServant) SendAction(act core.IdxAct, _post *model.Post) { func (s *simpleCacheIndexServant) SendAction(act core.IdxAct, _post *core.Post) {
select { select {
case s.indexActionCh <- act: case s.indexActionCh <- act:
logrus.Debugf("simpleCacheIndexServant.SendAction send indexAction by chan: %s", act) logrus.Debugf("simpleCacheIndexServant.SendAction send indexAction by chan: %s", act)

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package dao package dao
import ( import (

@ -1,8 +1,12 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package jinzhu package jinzhu
import ( import (
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"github.com/rocboss/paopao-ce/pkg/types" "github.com/rocboss/paopao-ce/pkg/types"
"gorm.io/gorm" "gorm.io/gorm"
) )
@ -21,7 +25,7 @@ func newAuthorizationManageService(db *gorm.DB) core.AuthorizationManageService
} }
} }
func (s *authorizationManageServant) IsAllow(user *model.User, action *core.Action) bool { func (s *authorizationManageServant) IsAllow(user *core.User, action *core.Action) bool {
// user is activation if had bind phone // user is activation if had bind phone
isActivation := (len(user.Phone) != 0) isActivation := (len(user.Phone) != 0)
isFriend := s.isFriend(user.ID, action.UserId) isFriend := s.isFriend(user.ID, action.UserId)
@ -30,7 +34,7 @@ func (s *authorizationManageServant) IsAllow(user *model.User, action *core.Acti
} }
func (s *authorizationManageServant) MyFriendSet(userId int64) core.FriendSet { func (s *authorizationManageServant) MyFriendSet(userId int64) core.FriendSet {
ids, err := (&model.Contact{UserId: userId}).MyFriendIds(s.db) ids, err := (&dbr.Contact{UserId: userId}).MyFriendIds(s.db)
if err != nil { if err != nil {
return core.FriendSet{} return core.FriendSet{}
} }
@ -43,7 +47,7 @@ func (s *authorizationManageServant) MyFriendSet(userId int64) core.FriendSet {
} }
func (s *authorizationManageServant) BeFriendFilter(userId int64) core.FriendFilter { func (s *authorizationManageServant) BeFriendFilter(userId int64) core.FriendFilter {
ids, err := (&model.Contact{FriendId: userId}).BeFriendIds(s.db) ids, err := (&dbr.Contact{FriendId: userId}).BeFriendIds(s.db)
if err != nil { if err != nil {
return core.FriendFilter{} return core.FriendFilter{}
} }
@ -56,12 +60,12 @@ func (s *authorizationManageServant) BeFriendFilter(userId int64) core.FriendFil
} }
func (s *authorizationManageServant) BeFriendIds(userId int64) ([]int64, error) { func (s *authorizationManageServant) BeFriendIds(userId int64) ([]int64, error) {
return (&model.Contact{FriendId: userId}).BeFriendIds(s.db) return (&dbr.Contact{FriendId: userId}).BeFriendIds(s.db)
} }
func (s *authorizationManageServant) isFriend(userId int64, friendId int64) bool { func (s *authorizationManageServant) isFriend(userId int64, friendId int64) bool {
contact, err := (&model.Contact{UserId: friendId, FriendId: userId}).GetByUserFriend(s.db) contact, err := (&dbr.Contact{UserId: friendId, FriendId: userId}).GetByUserFriend(s.db)
if err == nil || contact.Status == model.ContactStatusAgree { if err == nil || contact.Status == dbr.ContactStatusAgree {
return true return true
} }
return false return false

@ -1,8 +1,12 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package jinzhu package jinzhu
import ( import (
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"gorm.io/gorm" "gorm.io/gorm"
) )
@ -31,42 +35,42 @@ func newCommentManageService(db *gorm.DB) core.CommentManageService {
} }
} }
func (s *commentServant) GetComments(conditions *model.ConditionsT, offset, limit int) ([]*model.Comment, error) { func (s *commentServant) GetComments(conditions *core.ConditionsT, offset, limit int) ([]*core.Comment, error) {
return (&model.Comment{}).List(s.db, conditions, offset, limit) return (&dbr.Comment{}).List(s.db, conditions, offset, limit)
} }
func (s *commentServant) GetCommentByID(id int64) (*model.Comment, error) { func (s *commentServant) GetCommentByID(id int64) (*core.Comment, error) {
comment := &model.Comment{ comment := &dbr.Comment{
Model: &model.Model{ Model: &dbr.Model{
ID: id, ID: id,
}, },
} }
return comment.Get(s.db) return comment.Get(s.db)
} }
func (s *commentServant) GetCommentReplyByID(id int64) (*model.CommentReply, error) { func (s *commentServant) GetCommentReplyByID(id int64) (*core.CommentReply, error) {
reply := &model.CommentReply{ reply := &dbr.CommentReply{
Model: &model.Model{ Model: &dbr.Model{
ID: id, ID: id,
}, },
} }
return reply.Get(s.db) return reply.Get(s.db)
} }
func (s *commentServant) GetCommentCount(conditions *model.ConditionsT) (int64, error) { func (s *commentServant) GetCommentCount(conditions *core.ConditionsT) (int64, error) {
return (&model.Comment{}).Count(s.db, conditions) return (&dbr.Comment{}).Count(s.db, conditions)
} }
func (s *commentServant) GetCommentContentsByIDs(ids []int64) ([]*model.CommentContent, error) { func (s *commentServant) GetCommentContentsByIDs(ids []int64) ([]*core.CommentContent, error) {
commentContent := &model.CommentContent{} commentContent := &dbr.CommentContent{}
return commentContent.List(s.db, &model.ConditionsT{ return commentContent.List(s.db, &dbr.ConditionsT{
"comment_id IN ?": ids, "comment_id IN ?": ids,
}, 0, 0) }, 0, 0)
} }
func (s *commentServant) GetCommentRepliesByID(ids []int64) ([]*model.CommentReplyFormated, error) { func (s *commentServant) GetCommentRepliesByID(ids []int64) ([]*core.CommentReplyFormated, error) {
CommentReply := &model.CommentReply{} CommentReply := &dbr.CommentReply{}
replies, err := CommentReply.List(s.db, &model.ConditionsT{ replies, err := CommentReply.List(s.db, &dbr.ConditionsT{
"comment_id IN ?": ids, "comment_id IN ?": ids,
}, 0, 0) }, 0, 0)
@ -83,7 +87,7 @@ func (s *commentServant) GetCommentRepliesByID(ids []int64) ([]*model.CommentRep
if err != nil { if err != nil {
return nil, err return nil, err
} }
repliesFormated := []*model.CommentReplyFormated{} repliesFormated := []*core.CommentReplyFormated{}
for _, reply := range replies { for _, reply := range replies {
replyFormated := reply.Format() replyFormated := reply.Format()
for _, user := range users { for _, user := range users {
@ -101,22 +105,22 @@ func (s *commentServant) GetCommentRepliesByID(ids []int64) ([]*model.CommentRep
return repliesFormated, nil return repliesFormated, nil
} }
func (s *commentManageServant) DeleteComment(comment *model.Comment) error { func (s *commentManageServant) DeleteComment(comment *core.Comment) error {
return comment.Delete(s.db) return comment.Delete(s.db)
} }
func (s *commentManageServant) CreateComment(comment *model.Comment) (*model.Comment, error) { func (s *commentManageServant) CreateComment(comment *core.Comment) (*core.Comment, error) {
return comment.Create(s.db) return comment.Create(s.db)
} }
func (s *commentManageServant) CreateCommentReply(reply *model.CommentReply) (*model.CommentReply, error) { func (s *commentManageServant) CreateCommentReply(reply *core.CommentReply) (*core.CommentReply, error) {
return reply.Create(s.db) return reply.Create(s.db)
} }
func (s *commentManageServant) DeleteCommentReply(reply *model.CommentReply) error { func (s *commentManageServant) DeleteCommentReply(reply *core.CommentReply) error {
return reply.Delete(s.db) return reply.Delete(s.db)
} }
func (s *commentManageServant) CreateCommentContent(content *model.CommentContent) (*model.CommentContent, error) { func (s *commentManageServant) CreateCommentContent(content *core.CommentContent) (*core.CommentContent, error) {
return content.Create(s.db) return content.Create(s.db)
} }

@ -1,11 +1,14 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package jinzhu package jinzhu
import ( import (
"time" "time"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"github.com/rocboss/paopao-ce/internal/model/rest"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"gorm.io/gorm" "gorm.io/gorm"
) )
@ -24,14 +27,14 @@ func newContactManageService(db *gorm.DB) core.ContactManageService {
} }
} }
func (s *contactManageServant) fetchOrNewContact(db *gorm.DB, userId int64, friendId int64, status int8) (*model.Contact, error) { func (s *contactManageServant) fetchOrNewContact(db *gorm.DB, userId int64, friendId int64, status int8) (*dbr.Contact, error) {
contact := &model.Contact{ contact := &dbr.Contact{
UserId: userId, UserId: userId,
FriendId: friendId, FriendId: friendId,
} }
contact, err := contact.FetchUser(db) contact, err := contact.FetchUser(db)
if err != nil { if err != nil {
contact = &model.Contact{ contact = &dbr.Contact{
UserId: userId, UserId: userId,
FriendId: friendId, FriendId: friendId,
Status: status, Status: status,
@ -54,17 +57,17 @@ func (s *contactManageServant) RequestingFriend(userId int64, friendId int64, gr
} }
}() }()
contact, e := s.fetchOrNewContact(db, userId, friendId, model.ContactStatusRequesting) contact, e := s.fetchOrNewContact(db, userId, friendId, dbr.ContactStatusRequesting)
if e != nil { if e != nil {
err = e err = e
return return
} }
// 如果已经好友,啥也不干 // 如果已经好友,啥也不干
if contact.Status == model.ContactStatusAgree { if contact.Status == dbr.ContactStatusAgree {
return nil return nil
} else if contact.Status == model.ContactStatusReject || contact.Status == model.ContactStatusDeleted { } else if contact.Status == dbr.ContactStatusReject || contact.Status == dbr.ContactStatusDeleted {
contact.Status = model.ContactStatusRequesting contact.Status = dbr.ContactStatusRequesting
contact.IsDel = 0 // remove deleted flag if needed contact.IsDel = 0 // remove deleted flag if needed
if err = contact.UpdateInUnscoped(db); err != nil { if err = contact.UpdateInUnscoped(db); err != nil {
logrus.Errorf("contactManageServant.RequestingFriend update exsit contact err:%s", err) logrus.Errorf("contactManageServant.RequestingFriend update exsit contact err:%s", err)
@ -72,13 +75,13 @@ func (s *contactManageServant) RequestingFriend(userId int64, friendId int64, gr
} }
} }
msg := &model.Message{ msg := &dbr.Message{
SenderUserID: userId, SenderUserID: userId,
ReceiverUserID: friendId, ReceiverUserID: friendId,
Type: model.MsgTypeRequestingFriend, Type: dbr.MsgTypeRequestingFriend,
Brief: "请求添加好友,并附言:", Brief: "请求添加好友,并附言:",
Content: greetings, Content: greetings,
ReplyID: int64(model.ContactStatusRequesting), ReplyID: int64(dbr.ContactStatusRequesting),
} }
if _, err = msg.Create(db); err != nil { if _, err = msg.Create(db); err != nil {
logrus.Errorf("contactManageServant.RequestingFriend create message err:%s", err) logrus.Errorf("contactManageServant.RequestingFriend create message err:%s", err)
@ -97,7 +100,7 @@ func (s *contactManageServant) AddFriend(userId int64, friendId int64) (err erro
} }
}() }()
contact := &model.Contact{ contact := &dbr.Contact{
UserId: friendId, UserId: friendId,
FriendId: userId, FriendId: userId,
} }
@ -105,23 +108,23 @@ func (s *contactManageServant) AddFriend(userId int64, friendId int64) (err erro
return return
} }
// 如果还不是请求好友,啥也不干 // 如果还不是请求好友,啥也不干
if contact.Status != model.ContactStatusRequesting { if contact.Status != dbr.ContactStatusRequesting {
logrus.Debugf("contactManageServant.AddFriend not reuesting status now so skip") logrus.Debugf("contactManageServant.AddFriend not reuesting status now so skip")
return nil return nil
} }
contact.Status = model.ContactStatusAgree contact.Status = dbr.ContactStatusAgree
if err = contact.Update(db); err != nil { if err = contact.Update(db); err != nil {
return err return err
} }
contact, err = s.fetchOrNewContact(db, userId, friendId, model.ContactStatusAgree) contact, err = s.fetchOrNewContact(db, userId, friendId, dbr.ContactStatusAgree)
if err != nil { if err != nil {
return return
} }
// 如果已经好友,啥也不干 // 如果已经好友,啥也不干
if contact.Status != model.ContactStatusAgree { if contact.Status != dbr.ContactStatusAgree {
contact.Status = model.ContactStatusAgree contact.Status = dbr.ContactStatusAgree
contact.IsDel = 0 // remove deleted flag contact.IsDel = 0 // remove deleted flag
if err = contact.UpdateInUnscoped(db); err != nil { if err = contact.UpdateInUnscoped(db); err != nil {
logrus.Errorf("contactManageServant.AddFriend update contact err:%s", err) logrus.Errorf("contactManageServant.AddFriend update contact err:%s", err)
@ -129,8 +132,8 @@ func (s *contactManageServant) AddFriend(userId int64, friendId int64) (err erro
} }
} }
args := []any{userId, friendId, friendId, userId, model.MsgTypeRequestingFriend, model.ContactStatusRequesting} args := []any{userId, friendId, friendId, userId, dbr.MsgTypeRequestingFriend, dbr.ContactStatusRequesting}
msgs, e := (&model.Message{}).FetchBy(db, model.Predicates{ msgs, e := (&dbr.Message{}).FetchBy(db, dbr.Predicates{
"((sender_user_id = ? AND receiver_user_id = ?) OR (sender_user_id = ? AND receiver_user_id = ?)) AND type = ? AND reply_id = ?": args, "((sender_user_id = ? AND receiver_user_id = ?) OR (sender_user_id = ? AND receiver_user_id = ?)) AND type = ? AND reply_id = ?": args,
}) })
if e != nil { if e != nil {
@ -138,7 +141,7 @@ func (s *contactManageServant) AddFriend(userId int64, friendId int64) (err erro
return return
} }
for _, msg := range msgs { for _, msg := range msgs {
msg.ReplyID = int64(model.ContactStatusAgree) msg.ReplyID = int64(dbr.ContactStatusAgree)
if err = msg.Update(db); err != nil { if err = msg.Update(db); err != nil {
return return
} }
@ -156,7 +159,7 @@ func (s *contactManageServant) RejectFriend(userId int64, friendId int64) (err e
} }
}() }()
contact := &model.Contact{ contact := &dbr.Contact{
UserId: friendId, UserId: friendId,
FriendId: userId, FriendId: userId,
} }
@ -164,16 +167,16 @@ func (s *contactManageServant) RejectFriend(userId int64, friendId int64) (err e
return return
} }
// 如果还不是请求好友,啥也不干 // 如果还不是请求好友,啥也不干
if contact.Status != model.ContactStatusRequesting { if contact.Status != dbr.ContactStatusRequesting {
return nil return nil
} }
contact.Status = model.ContactStatusReject contact.Status = dbr.ContactStatusReject
if err = contact.Update(db); err != nil { if err = contact.Update(db); err != nil {
return err return err
} }
args := []any{friendId, userId, model.MsgTypeRequestingFriend, model.ContactStatusRequesting} args := []any{friendId, userId, dbr.MsgTypeRequestingFriend, dbr.ContactStatusRequesting}
msgs, e := (&model.Message{}).FetchBy(db, model.Predicates{ msgs, e := (&dbr.Message{}).FetchBy(db, dbr.Predicates{
"sender_user_id = ? AND receiver_user_id = ? AND type = ? AND reply_id = ?": args, "sender_user_id = ? AND receiver_user_id = ? AND type = ? AND reply_id = ?": args,
}) })
if e != nil { if e != nil {
@ -181,7 +184,7 @@ func (s *contactManageServant) RejectFriend(userId int64, friendId int64) (err e
return return
} }
for _, msg := range msgs { for _, msg := range msgs {
msg.ReplyID = int64(model.ContactStatusReject) msg.ReplyID = int64(dbr.ContactStatusReject)
if err = msg.Update(db); err != nil { if err = msg.Update(db); err != nil {
return return
} }
@ -199,7 +202,7 @@ func (s *contactManageServant) DeleteFriend(userId int64, friendId int64) (err e
} }
}() }()
contact := &model.Contact{ contact := &dbr.Contact{
UserId: userId, UserId: userId,
FriendId: friendId, FriendId: friendId,
} }
@ -210,10 +213,10 @@ func (s *contactManageServant) DeleteFriend(userId int64, friendId int64) (err e
for _, contact := range contacts { for _, contact := range contacts {
// 如果还不是好友,啥也不干 // 如果还不是好友,啥也不干
if contact.Status != model.ContactStatusAgree { if contact.Status != dbr.ContactStatusAgree {
continue continue
} }
contact.Status = model.ContactStatusDeleted contact.Status = dbr.ContactStatusDeleted
contact.DeletedOn = time.Now().Unix() contact.DeletedOn = time.Now().Unix()
contact.IsDel = 1 contact.IsDel = 1
if err = contact.Update(db); err != nil { if err = contact.Update(db); err != nil {
@ -223,11 +226,11 @@ func (s *contactManageServant) DeleteFriend(userId int64, friendId int64) (err e
return nil return nil
} }
func (s *contactManageServant) GetContacts(userId int64, offset int, limit int) (*rest.ContactsResp, error) { func (s *contactManageServant) GetContacts(userId int64, offset int, limit int) (*core.ContactList, error) {
contact := &model.Contact{} contact := &dbr.Contact{}
condition := model.ConditionsT{ condition := dbr.ConditionsT{
"user_id": userId, "user_id": userId,
"status": model.ContactStatusAgree, "status": dbr.ContactStatusAgree,
} }
contacts, err := contact.List(s.db, condition, offset, limit) contacts, err := contact.List(s.db, condition, offset, limit)
if err != nil { if err != nil {
@ -237,13 +240,13 @@ func (s *contactManageServant) GetContacts(userId int64, offset int, limit int)
if err != nil { if err != nil {
return nil, err return nil, err
} }
resp := &rest.ContactsResp{ resp := &core.ContactList{
Contacts: make([]rest.ContactItem, 0, len(contacts)), Contacts: make([]core.ContactItem, 0, len(contacts)),
Total: total, Total: total,
} }
for _, c := range contacts { for _, c := range contacts {
if c.User != nil { if c.User != nil {
resp.Contacts = append(resp.Contacts, rest.ContactItem{ resp.Contacts = append(resp.Contacts, core.ContactItem{
UserId: c.FriendId, UserId: c.FriendId,
UserName: c.User.Username, UserName: c.User.Username,
Nickname: c.User.Nickname, Nickname: c.User.Nickname,
@ -256,12 +259,12 @@ func (s *contactManageServant) GetContacts(userId int64, offset int, limit int)
} }
func (s *contactManageServant) IsFriend(userId int64, friendId int64) bool { func (s *contactManageServant) IsFriend(userId int64, friendId int64) bool {
contact := &model.Contact{ contact := &dbr.Contact{
UserId: friendId, UserId: friendId,
FriendId: userId, FriendId: userId,
} }
contact, err := contact.GetByUserFriend(s.db) contact, err := contact.GetByUserFriend(s.db)
if err == nil && contact.Status == model.ContactStatusAgree { if err == nil && contact.Status == dbr.ContactStatusAgree {
return true return true
} }
return false return false

@ -1,13 +1,17 @@
package model // Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package dbr
import "gorm.io/gorm" import "gorm.io/gorm"
type AttachmentType int type AttachmentType int
const ( const (
ATTACHMENT_TYPE_IMAGE AttachmentType = iota + 1 AttachmentTypeImage AttachmentType = iota + 1
ATTACHMENT_TYPE_VIDEO AttachmentTypeVideo
ATTACHMENT_TYPE_OTHER AttachmentTypeOther
) )
type Attachment struct { type Attachment struct {

@ -1,4 +1,8 @@
package model // Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package dbr
import "gorm.io/gorm" import "gorm.io/gorm"

@ -1,4 +1,8 @@
package model // Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package dbr
import ( import (
"time" "time"

@ -1,4 +1,8 @@
package model // Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package dbr
import ( import (
"time" "time"
@ -47,7 +51,7 @@ func (c *CommentContent) Create(db *gorm.DB) (*CommentContent, error) {
} }
func (c *CommentContent) MediaContentsByCommentId(db *gorm.DB, commentIds []int64) (contents []string, err error) { func (c *CommentContent) MediaContentsByCommentId(db *gorm.DB, commentIds []int64) (contents []string, err error) {
err = db.Model(c).Where("comment_id IN ? AND type = ?", commentIds, CONTENT_TYPE_IMAGE).Select("content").Find(&contents).Error err = db.Model(c).Where("comment_id IN ? AND type = ?", commentIds, ContentTypeImage).Select("content").Find(&contents).Error
return return
} }

@ -1,4 +1,8 @@
package model // Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package dbr
import ( import (
"time" "time"

@ -1,4 +1,8 @@
package model // Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package dbr
import ( import (
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"

@ -1,4 +1,8 @@
package model // Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package dbr
import "gorm.io/gorm" import "gorm.io/gorm"

@ -0,0 +1,40 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package dbr
import (
"time"
"gorm.io/gorm"
"gorm.io/plugin/soft_delete"
)
// Model 公共Model
type Model struct {
ID int64 `gorm:"primary_key" json:"id"`
CreatedOn int64 `json:"created_on"`
ModifiedOn int64 `json:"modified_on"`
DeletedOn int64 `json:"deleted_on"`
IsDel soft_delete.DeletedAt `gorm:"softDelete:flag" json:"is_del"`
}
type ConditionsT map[string]any
type Predicates map[string][]any
func (m *Model) BeforeCreate(tx *gorm.DB) (err error) {
nowTime := time.Now().Unix()
tx.Statement.SetColumn("created_on", nowTime)
tx.Statement.SetColumn("modified_on", nowTime)
return
}
func (m *Model) BeforeUpdate(tx *gorm.DB) (err error) {
if !tx.Statement.Changed("modified_on") {
tx.Statement.SetColumn("modified_on", time.Now().Unix())
}
return
}

@ -1,4 +1,8 @@
package model // Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package dbr
import ( import (
"strings" "strings"

@ -1,4 +1,8 @@
package model // Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package dbr
import "gorm.io/gorm" import "gorm.io/gorm"

@ -1,4 +1,8 @@
package model // Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package dbr
import ( import (
"time" "time"

@ -1,4 +1,8 @@
package model // Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package dbr
import ( import (
"time" "time"
@ -7,27 +11,26 @@ import (
) )
// 类型1标题2文字段落3图片地址4视频地址5语音地址6链接地址7附件资源 // 类型1标题2文字段落3图片地址4视频地址5语音地址6链接地址7附件资源
type PostContentT int type PostContentT int
const ( const (
CONTENT_TYPE_TITLE PostContentT = iota + 1 ContentTypeTitle PostContentT = iota + 1
CONTENT_TYPE_TEXT ContentTypeText
CONTENT_TYPE_IMAGE ContentTypeImage
CONTENT_TYPE_VIDEO ContentTypeVideo
CONTENT_TYPE_AUDIO ContentTypeAudio
CONTENT_TYPE_LINK ContentTypeLink
CONTENT_TYPE_ATTACHMENT ContentTypeAttachment
CONTENT_TYPE_CHARGE_ATTACHMENT ContentTypeChargeAttachment
) )
var ( var (
mediaContentType = []PostContentT{ mediaContentType = []PostContentT{
CONTENT_TYPE_IMAGE, ContentTypeImage,
CONTENT_TYPE_VIDEO, ContentTypeVideo,
CONTENT_TYPE_AUDIO, ContentTypeAudio,
CONTENT_TYPE_ATTACHMENT, ContentTypeAttachment,
CONTENT_TYPE_CHARGE_ATTACHMENT, ContentTypeChargeAttachment,
} }
) )

@ -1,4 +1,8 @@
package model // Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package dbr
import ( import (
"time" "time"

@ -1,4 +1,8 @@
package model // Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package dbr
import ( import (
"time" "time"

@ -1,4 +1,8 @@
package model // Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package dbr
import "gorm.io/gorm" import "gorm.io/gorm"

@ -1,4 +1,8 @@
package model // Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package dbr
import "gorm.io/gorm" import "gorm.io/gorm"

@ -1,4 +1,8 @@
package model // Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package dbr
import "gorm.io/gorm" import "gorm.io/gorm"

@ -1,9 +1,12 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package jinzhu package jinzhu
import ( import (
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"github.com/rocboss/paopao-ce/internal/model/rest"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
"gorm.io/gorm" "gorm.io/gorm"
) )
@ -40,20 +43,20 @@ func newSimpleIndexPostsService(db *gorm.DB) core.IndexPostsService {
} }
// IndexPosts 根据userId查询广场推文列表简单做到不同用户的主页都是不同的 // IndexPosts 根据userId查询广场推文列表简单做到不同用户的主页都是不同的
func (s *indexPostsServant) IndexPosts(user *model.User, offset int, limit int) (*rest.IndexTweetsResp, error) { func (s *indexPostsServant) IndexPosts(user *core.User, offset int, limit int) (*core.IndexTweetList, error) {
predicates := model.Predicates{ predicates := dbr.Predicates{
"ORDER": []any{"is_top DESC, latest_replied_on DESC"}, "ORDER": []any{"is_top DESC, latest_replied_on DESC"},
} }
if user == nil { if user == nil {
predicates["visibility = ?"] = []any{model.PostVisitPublic} predicates["visibility = ?"] = []any{dbr.PostVisitPublic}
} else if !user.IsAdmin { } else if !user.IsAdmin {
friendIds, _ := s.ams.BeFriendIds(user.ID) friendIds, _ := s.ams.BeFriendIds(user.ID)
friendIds = append(friendIds, user.ID) friendIds = append(friendIds, user.ID)
args := []any{model.PostVisitPublic, model.PostVisitPrivate, user.ID, model.PostVisitFriend, friendIds} args := []any{dbr.PostVisitPublic, dbr.PostVisitPrivate, user.ID, dbr.PostVisitFriend, friendIds}
predicates["visibility = ? OR (visibility = ? AND user_id = ?) OR (visibility = ? AND user_id IN ?)"] = args predicates["visibility = ? OR (visibility = ? AND user_id = ?) OR (visibility = ? AND user_id IN ?)"] = args
} }
posts, err := (&model.Post{}).Fetch(s.db, predicates, offset, limit) posts, err := (&dbr.Post{}).Fetch(s.db, predicates, offset, limit)
if err != nil { if err != nil {
logrus.Debugf("gormIndexPostsServant.IndexPosts err: %v", err) logrus.Debugf("gormIndexPostsServant.IndexPosts err: %v", err)
return nil, err return nil, err
@ -63,25 +66,25 @@ func (s *indexPostsServant) IndexPosts(user *model.User, offset int, limit int)
return nil, err return nil, err
} }
total, err := (&model.Post{}).CountBy(s.db, predicates) total, err := (&dbr.Post{}).CountBy(s.db, predicates)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &rest.IndexTweetsResp{ return &core.IndexTweetList{
Tweets: formatPosts, Tweets: formatPosts,
Total: total, Total: total,
}, nil }, nil
} }
// simpleCacheIndexGetPosts simpleCacheIndex 专属获取广场推文列表函数 // simpleCacheIndexGetPosts simpleCacheIndex 专属获取广场推文列表函数
func (s *simpleIndexPostsServant) IndexPosts(_user *model.User, offset int, limit int) (*rest.IndexTweetsResp, error) { func (s *simpleIndexPostsServant) IndexPosts(_user *core.User, offset int, limit int) (*core.IndexTweetList, error) {
predicates := model.Predicates{ predicates := dbr.Predicates{
"visibility = ?": []any{model.PostVisitPublic}, "visibility = ?": []any{dbr.PostVisitPublic},
"ORDER": []any{"is_top DESC, latest_replied_on DESC"}, "ORDER": []any{"is_top DESC, latest_replied_on DESC"},
} }
posts, err := (&model.Post{}).Fetch(s.db, predicates, offset, limit) posts, err := (&dbr.Post{}).Fetch(s.db, predicates, offset, limit)
if err != nil { if err != nil {
logrus.Debugf("gormSimpleIndexPostsServant.IndexPosts err: %v", err) logrus.Debugf("gormSimpleIndexPostsServant.IndexPosts err: %v", err)
return nil, err return nil, err
@ -92,12 +95,12 @@ func (s *simpleIndexPostsServant) IndexPosts(_user *model.User, offset int, limi
return nil, err return nil, err
} }
total, err := (&model.Post{}).CountBy(s.db, predicates) total, err := (&dbr.Post{}).CountBy(s.db, predicates)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &rest.IndexTweetsResp{ return &core.IndexTweetList{
Tweets: formatPosts, Tweets: formatPosts,
Total: total, Total: total,
}, nil }, nil

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
// Core service implement base gorm+mysql/postgresql/sqlite3. // Core service implement base gorm+mysql/postgresql/sqlite3.
// Jinzhu is the primary developer of gorm so use his name as // Jinzhu is the primary developer of gorm so use his name as
// package name as a saluter. // package name as a saluter.

@ -1,8 +1,12 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package jinzhu package jinzhu
import ( import (
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"gorm.io/gorm" "gorm.io/gorm"
) )
@ -20,37 +24,37 @@ func newMessageService(db *gorm.DB) core.MessageService {
} }
} }
func (d *messageServant) CreateMessage(msg *model.Message) (*model.Message, error) { func (d *messageServant) CreateMessage(msg *core.Message) (*core.Message, error) {
return msg.Create(d.db) return msg.Create(d.db)
} }
func (d *messageServant) GetUnreadCount(userID int64) (int64, error) { func (d *messageServant) GetUnreadCount(userID int64) (int64, error) {
return (&model.Message{}).Count(d.db, &model.ConditionsT{ return (&dbr.Message{}).Count(d.db, &dbr.ConditionsT{
"receiver_user_id": userID, "receiver_user_id": userID,
"is_read": model.MsgStatusUnread, "is_read": dbr.MsgStatusUnread,
}) })
} }
func (d *messageServant) GetMessageByID(id int64) (*model.Message, error) { func (d *messageServant) GetMessageByID(id int64) (*core.Message, error) {
return (&model.Message{ return (&dbr.Message{
Model: &model.Model{ Model: &dbr.Model{
ID: id, ID: id,
}, },
}).Get(d.db) }).Get(d.db)
} }
func (d *messageServant) ReadMessage(message *model.Message) error { func (d *messageServant) ReadMessage(message *core.Message) error {
message.IsRead = 1 message.IsRead = 1
return message.Update(d.db) return message.Update(d.db)
} }
func (d *messageServant) GetMessages(conditions *model.ConditionsT, offset, limit int) ([]*model.MessageFormated, error) { func (d *messageServant) GetMessages(conditions *core.ConditionsT, offset, limit int) ([]*core.MessageFormated, error) {
messages, err := (&model.Message{}).List(d.db, conditions, offset, limit) messages, err := (&dbr.Message{}).List(d.db, conditions, offset, limit)
if err != nil { if err != nil {
return nil, err return nil, err
} }
mfs := []*model.MessageFormated{} mfs := []*dbr.MessageFormated{}
for _, message := range messages { for _, message := range messages {
mf := message.Format() mf := message.Format()
mfs = append(mfs, mf) mfs = append(mfs, mf)
@ -59,6 +63,6 @@ func (d *messageServant) GetMessages(conditions *model.ConditionsT, offset, limi
return mfs, nil return mfs, nil
} }
func (d *messageServant) GetMessageCount(conditions *model.ConditionsT) (int64, error) { func (d *messageServant) GetMessageCount(conditions *core.ConditionsT) (int64, error) {
return (&model.Message{}).Count(d.db, conditions) return (&dbr.Message{}).Count(d.db, conditions)
} }

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package jinzhu package jinzhu
import ( import (
@ -6,7 +10,7 @@ import (
"time" "time"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"gorm.io/gorm" "gorm.io/gorm"
) )
@ -27,14 +31,14 @@ func newSecurityService(db *gorm.DB, phoneVerify core.PhoneVerifyService) core.S
} }
// GetLatestPhoneCaptcha 获取最新短信验证码 // GetLatestPhoneCaptcha 获取最新短信验证码
func (s *securityServant) GetLatestPhoneCaptcha(phone string) (*model.Captcha, error) { func (s *securityServant) GetLatestPhoneCaptcha(phone string) (*core.Captcha, error) {
return (&model.Captcha{ return (&dbr.Captcha{
Phone: phone, Phone: phone,
}).Get(s.db) }).Get(s.db)
} }
// UsePhoneCaptcha 更新短信验证码 // UsePhoneCaptcha 更新短信验证码
func (s *securityServant) UsePhoneCaptcha(captcha *model.Captcha) error { func (s *securityServant) UsePhoneCaptcha(captcha *core.Captcha) error {
captcha.UseTimes++ captcha.UseTimes++
return captcha.Update(s.db) return captcha.Update(s.db)
} }
@ -51,7 +55,7 @@ func (s *securityServant) SendPhoneCaptcha(phone string) error {
} }
// 写入表 // 写入表
captchaModel := &model.Captcha{ captchaModel := &dbr.Captcha{
Phone: phone, Phone: phone,
Captcha: captcha, Captcha: captcha,
ExpiredOn: time.Now().Add(expire * time.Minute).Unix(), ExpiredOn: time.Now().Add(expire * time.Minute).Unix(),

@ -1,10 +1,14 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package jinzhu package jinzhu
import ( import (
"strings" "strings"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"gorm.io/gorm" "gorm.io/gorm"
) )
@ -22,28 +26,28 @@ func newTopicService(db *gorm.DB) core.TopicService {
} }
} }
func (s *topicServant) CreateTag(tag *model.Tag) (*model.Tag, error) { func (s *topicServant) CreateTag(tag *core.Tag) (*core.Tag, error) {
return createTag(s.db, tag) return createTag(s.db, tag)
} }
func (s *topicServant) DeleteTag(tag *model.Tag) error { func (s *topicServant) DeleteTag(tag *core.Tag) error {
return deleteTag(s.db, tag) return deleteTag(s.db, tag)
} }
func (s *topicServant) GetTags(conditions *model.ConditionsT, offset, limit int) ([]*model.Tag, error) { func (s *topicServant) GetTags(conditions *core.ConditionsT, offset, limit int) ([]*core.Tag, error) {
return (&model.Tag{}).List(s.db, conditions, offset, limit) return (&dbr.Tag{}).List(s.db, conditions, offset, limit)
} }
func (s *topicServant) GetTagsByKeyword(keyword string) ([]*model.Tag, error) { func (s *topicServant) GetTagsByKeyword(keyword string) ([]*core.Tag, error) {
tag := &model.Tag{} tag := &dbr.Tag{}
keyword = "%" + strings.Trim(keyword, " ") + "%" keyword = "%" + strings.Trim(keyword, " ") + "%"
if keyword == "%%" { if keyword == "%%" {
return tag.List(s.db, &model.ConditionsT{ return tag.List(s.db, &dbr.ConditionsT{
"ORDER": "quote_num DESC", "ORDER": "quote_num DESC",
}, 0, 6) }, 0, 6)
} else { } else {
return tag.List(s.db, &model.ConditionsT{ return tag.List(s.db, &dbr.ConditionsT{
"tag LIKE ?": keyword, "tag LIKE ?": keyword,
"ORDER": "quote_num DESC", "ORDER": "quote_num DESC",
}, 0, 6) }, 0, 6)

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package jinzhu package jinzhu
import ( import (
@ -5,7 +9,7 @@ import (
"time" "time"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"gorm.io/gorm" "gorm.io/gorm"
) )
@ -48,7 +52,7 @@ func newTweetHelpService(db *gorm.DB) core.TweetHelpService {
} }
// MergePosts post数据整合 // MergePosts post数据整合
func (s *tweetHelpServant) MergePosts(posts []*model.Post) ([]*model.PostFormated, error) { func (s *tweetHelpServant) MergePosts(posts []*core.Post) ([]*core.PostFormated, error) {
postIds := make([]int64, 0, len(posts)) postIds := make([]int64, 0, len(posts))
userIds := make([]int64, 0, len(posts)) userIds := make([]int64, 0, len(posts))
for _, post := range posts { for _, post := range posts {
@ -66,18 +70,18 @@ func (s *tweetHelpServant) MergePosts(posts []*model.Post) ([]*model.PostFormate
return nil, err return nil, err
} }
userMap := make(map[int64]*model.UserFormated, len(users)) userMap := make(map[int64]*dbr.UserFormated, len(users))
for _, user := range users { for _, user := range users {
userMap[user.ID] = user.Format() userMap[user.ID] = user.Format()
} }
contentMap := make(map[int64][]*model.PostContentFormated, len(postContents)) contentMap := make(map[int64][]*dbr.PostContentFormated, len(postContents))
for _, content := range postContents { for _, content := range postContents {
contentMap[content.PostID] = append(contentMap[content.PostID], content.Format()) contentMap[content.PostID] = append(contentMap[content.PostID], content.Format())
} }
// 数据整合 // 数据整合
postsFormated := make([]*model.PostFormated, 0, len(posts)) postsFormated := make([]*dbr.PostFormated, 0, len(posts))
for _, post := range posts { for _, post := range posts {
postFormated := post.Format() postFormated := post.Format()
postFormated.User = userMap[post.UserID] postFormated.User = userMap[post.UserID]
@ -88,7 +92,7 @@ func (s *tweetHelpServant) MergePosts(posts []*model.Post) ([]*model.PostFormate
} }
// RevampPosts post数据整形修复 // RevampPosts post数据整形修复
func (s *tweetHelpServant) RevampPosts(posts []*model.PostFormated) ([]*model.PostFormated, error) { func (s *tweetHelpServant) RevampPosts(posts []*core.PostFormated) ([]*core.PostFormated, error) {
postIds := make([]int64, 0, len(posts)) postIds := make([]int64, 0, len(posts))
userIds := make([]int64, 0, len(posts)) userIds := make([]int64, 0, len(posts))
for _, post := range posts { for _, post := range posts {
@ -106,12 +110,12 @@ func (s *tweetHelpServant) RevampPosts(posts []*model.PostFormated) ([]*model.Po
return nil, err return nil, err
} }
userMap := make(map[int64]*model.UserFormated, len(users)) userMap := make(map[int64]*dbr.UserFormated, len(users))
for _, user := range users { for _, user := range users {
userMap[user.ID] = user.Format() userMap[user.ID] = user.Format()
} }
contentMap := make(map[int64][]*model.PostContentFormated, len(postContents)) contentMap := make(map[int64][]*dbr.PostContentFormated, len(postContents))
for _, content := range postContents { for _, content := range postContents {
contentMap[content.PostID] = append(contentMap[content.PostID], content.Format()) contentMap[content.PostID] = append(contentMap[content.PostID], content.Format())
} }
@ -124,23 +128,23 @@ func (s *tweetHelpServant) RevampPosts(posts []*model.PostFormated) ([]*model.Po
return posts, nil return posts, nil
} }
func (s *tweetHelpServant) getPostContentsByIDs(ids []int64) ([]*model.PostContent, error) { func (s *tweetHelpServant) getPostContentsByIDs(ids []int64) ([]*dbr.PostContent, error) {
return (&model.PostContent{}).List(s.db, &model.ConditionsT{ return (&dbr.PostContent{}).List(s.db, &dbr.ConditionsT{
"post_id IN ?": ids, "post_id IN ?": ids,
"ORDER": "sort ASC", "ORDER": "sort ASC",
}, 0, 0) }, 0, 0)
} }
func (s *tweetHelpServant) getUsersByIDs(ids []int64) ([]*model.User, error) { func (s *tweetHelpServant) getUsersByIDs(ids []int64) ([]*dbr.User, error) {
user := &model.User{} user := &dbr.User{}
return user.List(s.db, &model.ConditionsT{ return user.List(s.db, &dbr.ConditionsT{
"id IN ?": ids, "id IN ?": ids,
}, 0, 0) }, 0, 0)
} }
func (s *tweetManageServant) CreatePostCollection(postID, userID int64) (*model.PostCollection, error) { func (s *tweetManageServant) CreatePostCollection(postID, userID int64) (*core.PostCollection, error) {
collection := &model.PostCollection{ collection := &dbr.PostCollection{
PostID: postID, PostID: postID,
UserID: userID, UserID: userID,
} }
@ -148,19 +152,19 @@ func (s *tweetManageServant) CreatePostCollection(postID, userID int64) (*model.
return collection.Create(s.db) return collection.Create(s.db)
} }
func (s *tweetManageServant) DeletePostCollection(p *model.PostCollection) error { func (s *tweetManageServant) DeletePostCollection(p *core.PostCollection) error {
return p.Delete(s.db) return p.Delete(s.db)
} }
func (s *tweetManageServant) CreatePostContent(content *model.PostContent) (*model.PostContent, error) { func (s *tweetManageServant) CreatePostContent(content *core.PostContent) (*core.PostContent, error) {
return content.Create(s.db) return content.Create(s.db)
} }
func (s *tweetManageServant) CreateAttachment(attachment *model.Attachment) (*model.Attachment, error) { func (s *tweetManageServant) CreateAttachment(attachment *core.Attachment) (*core.Attachment, error) {
return attachment.Create(s.db) return attachment.Create(s.db)
} }
func (s *tweetManageServant) CreatePost(post *model.Post) (*model.Post, error) { func (s *tweetManageServant) CreatePost(post *core.Post) (*core.Post, error) {
post.LatestRepliedOn = time.Now().Unix() post.LatestRepliedOn = time.Now().Unix()
p, err := post.Create(s.db) p, err := post.Create(s.db)
if err != nil { if err != nil {
@ -170,11 +174,11 @@ func (s *tweetManageServant) CreatePost(post *model.Post) (*model.Post, error) {
return p, nil return p, nil
} }
func (s *tweetManageServant) DeletePost(post *model.Post) ([]string, error) { func (s *tweetManageServant) DeletePost(post *core.Post) ([]string, error) {
var mediaContents []string var mediaContents []string
postId := post.ID postId := post.ID
postContent := &model.PostContent{} postContent := &dbr.PostContent{}
err := s.db.Transaction( err := s.db.Transaction(
func(tx *gorm.DB) error { func(tx *gorm.DB) error {
if contents, err := postContent.MediaContentsByPostId(tx, postId); err == nil { if contents, err := postContent.MediaContentsByPostId(tx, postId); err == nil {
@ -218,8 +222,8 @@ func (s *tweetManageServant) DeletePost(post *model.Post) ([]string, error) {
} }
func (s *tweetManageServant) deleteCommentByPostId(db *gorm.DB, postId int64) ([]string, error) { func (s *tweetManageServant) deleteCommentByPostId(db *gorm.DB, postId int64) ([]string, error) {
comment := &model.Comment{} comment := &dbr.Comment{}
commentContent := &model.CommentContent{} commentContent := &dbr.CommentContent{}
// 获取推文的所有评论id // 获取推文的所有评论id
commentIds, err := comment.CommentIdsByPostId(db, postId) commentIds, err := comment.CommentIdsByPostId(db, postId)
@ -244,19 +248,19 @@ func (s *tweetManageServant) deleteCommentByPostId(db *gorm.DB, postId int64) ([
} }
// 删评论的评论 // 删评论的评论
if err = (&model.CommentReply{}).DeleteByCommentIds(db, commentIds); err != nil { if err = (&dbr.CommentReply{}).DeleteByCommentIds(db, commentIds); err != nil {
return nil, err return nil, err
} }
return mediaContents, nil return mediaContents, nil
} }
func (s *tweetManageServant) LockPost(post *model.Post) error { func (s *tweetManageServant) LockPost(post *core.Post) error {
post.IsLock = 1 - post.IsLock post.IsLock = 1 - post.IsLock
return post.Update(s.db) return post.Update(s.db)
} }
func (s *tweetManageServant) StickPost(post *model.Post) error { func (s *tweetManageServant) StickPost(post *core.Post) error {
post.IsTop = 1 - post.IsTop post.IsTop = 1 - post.IsTop
if err := post.Update(s.db); err != nil { if err := post.Update(s.db); err != nil {
return err return err
@ -265,7 +269,7 @@ func (s *tweetManageServant) StickPost(post *model.Post) error {
return nil return nil
} }
func (s *tweetManageServant) VisiblePost(post *model.Post, visibility model.PostVisibleT) error { func (s *tweetManageServant) VisiblePost(post *core.Post, visibility core.PostVisibleT) error {
oldVisibility := post.Visibility oldVisibility := post.Visibility
post.Visibility = visibility post.Visibility = visibility
// TODO: 这个判断是否可以不要呢 // TODO: 这个判断是否可以不要呢
@ -273,7 +277,7 @@ func (s *tweetManageServant) VisiblePost(post *model.Post, visibility model.Post
return nil return nil
} }
// 私密推文 特殊处理 // 私密推文 特殊处理
if visibility == model.PostVisitPrivate { if visibility == dbr.PostVisitPrivate {
// 强制取消置顶 // 强制取消置顶
// TODO: 置顶推文用户是否有权设置成私密? 后续完善 // TODO: 置顶推文用户是否有权设置成私密? 后续完善
post.IsTop = 0 post.IsTop = 0
@ -288,14 +292,14 @@ func (s *tweetManageServant) VisiblePost(post *model.Post, visibility model.Post
// tag处理 // tag处理
tags := strings.Split(post.Tags, ",") tags := strings.Split(post.Tags, ",")
for _, t := range tags { for _, t := range tags {
tag := &model.Tag{ tag := &dbr.Tag{
Tag: t, Tag: t,
} }
// TODO: 暂时宽松不处理错误,这里或许可以有优化,后续完善 // TODO: 暂时宽松不处理错误,这里或许可以有优化,后续完善
if oldVisibility == model.PostVisitPrivate { if oldVisibility == dbr.PostVisitPrivate {
// 从私密转为非私密才需要重新创建tag // 从私密转为非私密才需要重新创建tag
createTag(db, tag) createTag(db, tag)
} else if visibility == model.PostVisitPrivate { } else if visibility == dbr.PostVisitPrivate {
// 从非私密转为私密才需要删除tag // 从非私密转为私密才需要删除tag
deleteTag(db, tag) deleteTag(db, tag)
} }
@ -305,7 +309,7 @@ func (s *tweetManageServant) VisiblePost(post *model.Post, visibility model.Post
return nil return nil
} }
func (s *tweetManageServant) UpdatePost(post *model.Post) error { func (s *tweetManageServant) UpdatePost(post *core.Post) error {
if err := post.Update(s.db); err != nil { if err := post.Update(s.db); err != nil {
return err return err
} }
@ -313,104 +317,104 @@ func (s *tweetManageServant) UpdatePost(post *model.Post) error {
return nil return nil
} }
func (s *tweetManageServant) CreatePostStar(postID, userID int64) (*model.PostStar, error) { func (s *tweetManageServant) CreatePostStar(postID, userID int64) (*core.PostStar, error) {
star := &model.PostStar{ star := &dbr.PostStar{
PostID: postID, PostID: postID,
UserID: userID, UserID: userID,
} }
return star.Create(s.db) return star.Create(s.db)
} }
func (s *tweetManageServant) DeletePostStar(p *model.PostStar) error { func (s *tweetManageServant) DeletePostStar(p *core.PostStar) error {
return p.Delete(s.db) return p.Delete(s.db)
} }
func (s *tweetServant) GetPostByID(id int64) (*model.Post, error) { func (s *tweetServant) GetPostByID(id int64) (*core.Post, error) {
post := &model.Post{ post := &dbr.Post{
Model: &model.Model{ Model: &dbr.Model{
ID: id, ID: id,
}, },
} }
return post.Get(s.db) return post.Get(s.db)
} }
func (s *tweetServant) GetPosts(conditions *model.ConditionsT, offset, limit int) ([]*model.Post, error) { func (s *tweetServant) GetPosts(conditions *core.ConditionsT, offset, limit int) ([]*core.Post, error) {
return (&model.Post{}).List(s.db, conditions, offset, limit) return (&dbr.Post{}).List(s.db, conditions, offset, limit)
} }
func (s *tweetServant) GetPostCount(conditions *model.ConditionsT) (int64, error) { func (s *tweetServant) GetPostCount(conditions *core.ConditionsT) (int64, error) {
return (&model.Post{}).Count(s.db, conditions) return (&dbr.Post{}).Count(s.db, conditions)
} }
func (s *tweetServant) GetUserPostStar(postID, userID int64) (*model.PostStar, error) { func (s *tweetServant) GetUserPostStar(postID, userID int64) (*core.PostStar, error) {
star := &model.PostStar{ star := &dbr.PostStar{
PostID: postID, PostID: postID,
UserID: userID, UserID: userID,
} }
return star.Get(s.db) return star.Get(s.db)
} }
func (s *tweetServant) GetUserPostStars(userID int64, offset, limit int) ([]*model.PostStar, error) { func (s *tweetServant) GetUserPostStars(userID int64, offset, limit int) ([]*core.PostStar, error) {
star := &model.PostStar{ star := &dbr.PostStar{
UserID: userID, UserID: userID,
} }
return star.List(s.db, &model.ConditionsT{ return star.List(s.db, &dbr.ConditionsT{
"ORDER": s.db.NamingStrategy.TableName("PostStar") + ".id DESC", "ORDER": s.db.NamingStrategy.TableName("PostStar") + ".id DESC",
}, offset, limit) }, offset, limit)
} }
func (s *tweetServant) GetUserPostStarCount(userID int64) (int64, error) { func (s *tweetServant) GetUserPostStarCount(userID int64) (int64, error) {
star := &model.PostStar{ star := &dbr.PostStar{
UserID: userID, UserID: userID,
} }
return star.Count(s.db, &model.ConditionsT{}) return star.Count(s.db, &dbr.ConditionsT{})
} }
func (s *tweetServant) GetUserPostCollection(postID, userID int64) (*model.PostCollection, error) { func (s *tweetServant) GetUserPostCollection(postID, userID int64) (*core.PostCollection, error) {
star := &model.PostCollection{ star := &dbr.PostCollection{
PostID: postID, PostID: postID,
UserID: userID, UserID: userID,
} }
return star.Get(s.db) return star.Get(s.db)
} }
func (s *tweetServant) GetUserPostCollections(userID int64, offset, limit int) ([]*model.PostCollection, error) { func (s *tweetServant) GetUserPostCollections(userID int64, offset, limit int) ([]*core.PostCollection, error) {
collection := &model.PostCollection{ collection := &dbr.PostCollection{
UserID: userID, UserID: userID,
} }
return collection.List(s.db, &model.ConditionsT{ return collection.List(s.db, &dbr.ConditionsT{
"ORDER": s.db.NamingStrategy.TableName("PostCollection") + ".id DESC", "ORDER": s.db.NamingStrategy.TableName("PostCollection") + ".id DESC",
}, offset, limit) }, offset, limit)
} }
func (s *tweetServant) GetUserPostCollectionCount(userID int64) (int64, error) { func (s *tweetServant) GetUserPostCollectionCount(userID int64) (int64, error) {
collection := &model.PostCollection{ collection := &dbr.PostCollection{
UserID: userID, UserID: userID,
} }
return collection.Count(s.db, &model.ConditionsT{}) return collection.Count(s.db, &dbr.ConditionsT{})
} }
func (s *tweetServant) GetUserWalletBills(userID int64, offset, limit int) ([]*model.WalletStatement, error) { func (s *tweetServant) GetUserWalletBills(userID int64, offset, limit int) ([]*core.WalletStatement, error) {
statement := &model.WalletStatement{ statement := &dbr.WalletStatement{
UserID: userID, UserID: userID,
} }
return statement.List(s.db, &model.ConditionsT{ return statement.List(s.db, &dbr.ConditionsT{
"ORDER": "id DESC", "ORDER": "id DESC",
}, offset, limit) }, offset, limit)
} }
func (s *tweetServant) GetUserWalletBillCount(userID int64) (int64, error) { func (s *tweetServant) GetUserWalletBillCount(userID int64) (int64, error) {
statement := &model.WalletStatement{ statement := &dbr.WalletStatement{
UserID: userID, UserID: userID,
} }
return statement.Count(s.db, &model.ConditionsT{}) return statement.Count(s.db, &dbr.ConditionsT{})
} }
func (s *tweetServant) GetPostAttatchmentBill(postID, userID int64) (*model.PostAttachmentBill, error) { func (s *tweetServant) GetPostAttatchmentBill(postID, userID int64) (*core.PostAttachmentBill, error) {
bill := &model.PostAttachmentBill{ bill := &dbr.PostAttachmentBill{
PostID: postID, PostID: postID,
UserID: userID, UserID: userID,
} }
@ -418,16 +422,16 @@ func (s *tweetServant) GetPostAttatchmentBill(postID, userID int64) (*model.Post
return bill.Get(s.db) return bill.Get(s.db)
} }
func (s *tweetServant) GetPostContentsByIDs(ids []int64) ([]*model.PostContent, error) { func (s *tweetServant) GetPostContentsByIDs(ids []int64) ([]*core.PostContent, error) {
return (&model.PostContent{}).List(s.db, &model.ConditionsT{ return (&dbr.PostContent{}).List(s.db, &dbr.ConditionsT{
"post_id IN ?": ids, "post_id IN ?": ids,
"ORDER": "sort ASC", "ORDER": "sort ASC",
}, 0, 0) }, 0, 0)
} }
func (s *tweetServant) GetPostContentByID(id int64) (*model.PostContent, error) { func (s *tweetServant) GetPostContentByID(id int64) (*core.PostContent, error) {
return (&model.PostContent{ return (&dbr.PostContent{
Model: &model.Model{ Model: &dbr.Model{
ID: id, ID: id,
}, },
}).Get(s.db) }).Get(s.db)

@ -1,10 +1,14 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package jinzhu package jinzhu
import ( import (
"strings" "strings"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"gorm.io/gorm" "gorm.io/gorm"
) )
@ -22,69 +26,69 @@ func newUserManageService(db *gorm.DB) core.UserManageService {
} }
} }
func (s *userManageServant) GetUserByID(id int64) (*model.User, error) { func (s *userManageServant) GetUserByID(id int64) (*core.User, error) {
user := &model.User{ user := &dbr.User{
Model: &model.Model{ Model: &dbr.Model{
ID: id, ID: id,
}, },
} }
return user.Get(s.db) return user.Get(s.db)
} }
func (s *userManageServant) GetUserByUsername(username string) (*model.User, error) { func (s *userManageServant) GetUserByUsername(username string) (*core.User, error) {
user := &model.User{ user := &dbr.User{
Username: username, Username: username,
} }
return user.Get(s.db) return user.Get(s.db)
} }
func (s *userManageServant) GetUserByPhone(phone string) (*model.User, error) { func (s *userManageServant) GetUserByPhone(phone string) (*core.User, error) {
user := &model.User{ user := &dbr.User{
Phone: phone, Phone: phone,
} }
return user.Get(s.db) return user.Get(s.db)
} }
func (s *userManageServant) GetUsersByIDs(ids []int64) ([]*model.User, error) { func (s *userManageServant) GetUsersByIDs(ids []int64) ([]*core.User, error) {
user := &model.User{} user := &dbr.User{}
return user.List(s.db, &model.ConditionsT{ return user.List(s.db, &dbr.ConditionsT{
"id IN ?": ids, "id IN ?": ids,
}, 0, 0) }, 0, 0)
} }
func (s *userManageServant) GetUsersByKeyword(keyword string) ([]*model.User, error) { func (s *userManageServant) GetUsersByKeyword(keyword string) ([]*core.User, error) {
user := &model.User{} user := &dbr.User{}
keyword = strings.Trim(keyword, " ") + "%" keyword = strings.Trim(keyword, " ") + "%"
if keyword == "%" { if keyword == "%" {
return user.List(s.db, &model.ConditionsT{ return user.List(s.db, &dbr.ConditionsT{
"ORDER": "id ASC", "ORDER": "id ASC",
}, 0, 6) }, 0, 6)
} else { } else {
return user.List(s.db, &model.ConditionsT{ return user.List(s.db, &dbr.ConditionsT{
"username LIKE ?": keyword, "username LIKE ?": keyword,
}, 0, 6) }, 0, 6)
} }
} }
func (s *userManageServant) GetTagsByKeyword(keyword string) ([]*model.Tag, error) { func (s *userManageServant) GetTagsByKeyword(keyword string) ([]*core.Tag, error) {
tag := &model.Tag{} tag := &dbr.Tag{}
keyword = "%" + strings.Trim(keyword, " ") + "%" keyword = "%" + strings.Trim(keyword, " ") + "%"
if keyword == "%%" { if keyword == "%%" {
return tag.List(s.db, &model.ConditionsT{ return tag.List(s.db, &dbr.ConditionsT{
"ORDER": "quote_num DESC", "ORDER": "quote_num DESC",
}, 0, 6) }, 0, 6)
} else { } else {
return tag.List(s.db, &model.ConditionsT{ return tag.List(s.db, &dbr.ConditionsT{
"tag LIKE ?": keyword, "tag LIKE ?": keyword,
"ORDER": "quote_num DESC", "ORDER": "quote_num DESC",
}, 0, 6) }, 0, 6)
} }
} }
func (s *userManageServant) CreateUser(user *model.User) (*model.User, error) { func (s *userManageServant) CreateUser(user *dbr.User) (*core.User, error) {
return user.Create(s.db) return user.Create(s.db)
} }
func (s *userManageServant) UpdateUser(user *model.User) error { func (s *userManageServant) UpdateUser(user *core.User) error {
return user.Update(s.db) return user.Update(s.db)
} }

@ -1,11 +1,15 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package jinzhu package jinzhu
import ( import (
"github.com/rocboss/paopao-ce/internal/model" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"gorm.io/gorm" "gorm.io/gorm"
) )
func createTag(db *gorm.DB, tag *model.Tag) (*model.Tag, error) { func createTag(db *gorm.DB, tag *dbr.Tag) (*dbr.Tag, error) {
t, err := tag.Get(db) t, err := tag.Get(db)
if err != nil { if err != nil {
tag.QuoteNum = 1 tag.QuoteNum = 1
@ -23,7 +27,7 @@ func createTag(db *gorm.DB, tag *model.Tag) (*model.Tag, error) {
return t, nil return t, nil
} }
func deleteTag(db *gorm.DB, tag *model.Tag) error { func deleteTag(db *gorm.DB, tag *dbr.Tag) error {
tag, err := tag.Get(db) tag, err := tag.Get(db)
if err != nil { if err != nil {
return err return err
@ -33,7 +37,7 @@ func deleteTag(db *gorm.DB, tag *model.Tag) error {
} }
func deleteTags(db *gorm.DB, tags []string) error { func deleteTags(db *gorm.DB, tags []string) error {
allTags, err := (&model.Tag{}).TagsFrom(db, tags) allTags, err := (&dbr.Tag{}).TagsFrom(db, tags)
if err != nil { if err != nil {
return err return err
} }
@ -51,9 +55,9 @@ func deleteTags(db *gorm.DB, tags []string) error {
} }
// 根据IDs获取用户列表 // 根据IDs获取用户列表
func getUsersByIDs(db *gorm.DB, ids []int64) ([]*model.User, error) { func getUsersByIDs(db *gorm.DB, ids []int64) ([]*dbr.User, error) {
user := &model.User{} user := &dbr.User{}
return user.List(db, &model.ConditionsT{ return user.List(db, &dbr.ConditionsT{
"id IN ?": ids, "id IN ?": ids,
}, 0, 0) }, 0, 0)
} }

@ -1,9 +1,13 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package jinzhu package jinzhu
import ( import (
"github.com/rocboss/paopao-ce/internal/conf" "github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model" "github.com/rocboss/paopao-ce/internal/dao/jinzhu/dbr"
"gorm.io/gorm" "gorm.io/gorm"
) )
@ -21,17 +25,17 @@ func newWalletService(db *gorm.DB) core.WalletService {
} }
} }
func (d *walletServant) GetRechargeByID(id int64) (*model.WalletRecharge, error) { func (d *walletServant) GetRechargeByID(id int64) (*core.WalletRecharge, error) {
recharge := &model.WalletRecharge{ recharge := &dbr.WalletRecharge{
Model: &model.Model{ Model: &dbr.Model{
ID: id, ID: id,
}, },
} }
return recharge.Get(d.db) return recharge.Get(d.db)
} }
func (d *walletServant) CreateRecharge(userId, amount int64) (*model.WalletRecharge, error) { func (d *walletServant) CreateRecharge(userId, amount int64) (*core.WalletRecharge, error) {
recharge := &model.WalletRecharge{ recharge := &dbr.WalletRecharge{
UserID: userId, UserID: userId,
Amount: amount, Amount: amount,
} }
@ -39,26 +43,26 @@ func (d *walletServant) CreateRecharge(userId, amount int64) (*model.WalletRecha
return recharge.Create(d.db) return recharge.Create(d.db)
} }
func (d *walletServant) GetUserWalletBills(userID int64, offset, limit int) ([]*model.WalletStatement, error) { func (d *walletServant) GetUserWalletBills(userID int64, offset, limit int) ([]*core.WalletStatement, error) {
statement := &model.WalletStatement{ statement := &dbr.WalletStatement{
UserID: userID, UserID: userID,
} }
return statement.List(d.db, &model.ConditionsT{ return statement.List(d.db, &dbr.ConditionsT{
"ORDER": "id DESC", "ORDER": "id DESC",
}, offset, limit) }, offset, limit)
} }
func (d *walletServant) GetUserWalletBillCount(userID int64) (int64, error) { func (d *walletServant) GetUserWalletBillCount(userID int64) (int64, error) {
statement := &model.WalletStatement{ statement := &dbr.WalletStatement{
UserID: userID, UserID: userID,
} }
return statement.Count(d.db, &model.ConditionsT{}) return statement.Count(d.db, &dbr.ConditionsT{})
} }
func (d *walletServant) HandleRechargeSuccess(recharge *model.WalletRecharge, tradeNo string) error { func (d *walletServant) HandleRechargeSuccess(recharge *core.WalletRecharge, tradeNo string) error {
user, _ := (&model.User{ user, _ := (&dbr.User{
Model: &model.Model{ Model: &dbr.Model{
ID: recharge.UserID, ID: recharge.UserID,
}, },
}).Get(d.db) }).Get(d.db)
@ -71,7 +75,7 @@ func (d *walletServant) HandleRechargeSuccess(recharge *model.WalletRecharge, tr
} }
// 新增账单 // 新增账单
if err := tx.Create(&model.WalletStatement{ if err := tx.Create(&dbr.WalletStatement{
UserID: user.ID, UserID: user.ID,
ChangeAmount: recharge.Amount, ChangeAmount: recharge.Amount,
BalanceSnapshot: user.Balance + recharge.Amount, BalanceSnapshot: user.Balance + recharge.Amount,
@ -93,7 +97,7 @@ func (d *walletServant) HandleRechargeSuccess(recharge *model.WalletRecharge, tr
}) })
} }
func (d *walletServant) HandlePostAttachmentBought(post *model.Post, user *model.User) error { func (d *walletServant) HandlePostAttachmentBought(post *core.Post, user *core.User) error {
return d.db.Transaction(func(tx *gorm.DB) error { return d.db.Transaction(func(tx *gorm.DB) error {
// 扣除金额 // 扣除金额
if err := tx.Model(user).Update("balance", gorm.Expr("balance - ?", post.AttachmentPrice)).Error; err != nil { if err := tx.Model(user).Update("balance", gorm.Expr("balance - ?", post.AttachmentPrice)).Error; err != nil {
@ -102,7 +106,7 @@ func (d *walletServant) HandlePostAttachmentBought(post *model.Post, user *model
} }
// 新增账单 // 新增账单
if err := tx.Create(&model.WalletStatement{ if err := tx.Create(&dbr.WalletStatement{
PostID: post.ID, PostID: post.ID,
UserID: user.ID, UserID: user.ID,
ChangeAmount: -post.AttachmentPrice, ChangeAmount: -post.AttachmentPrice,
@ -113,7 +117,7 @@ func (d *walletServant) HandlePostAttachmentBought(post *model.Post, user *model
} }
// 新增附件购买记录 // 新增附件购买记录
if err := tx.Create(&model.PostAttachmentBill{ if err := tx.Create(&dbr.PostAttachmentBill{
PostID: post.ID, PostID: post.ID,
UserID: user.ID, UserID: user.ID,
PaidAmount: post.AttachmentPrice, PaidAmount: post.AttachmentPrice,
@ -124,8 +128,8 @@ func (d *walletServant) HandlePostAttachmentBought(post *model.Post, user *model
// 对附件主新增账单 // 对附件主新增账单
income := int64(float64(post.AttachmentPrice) * conf.AppSetting.AttachmentIncomeRate) income := int64(float64(post.AttachmentPrice) * conf.AppSetting.AttachmentIncomeRate)
if income > 0 { if income > 0 {
master := &model.User{ master := &dbr.User{
Model: &model.Model{ Model: &dbr.Model{
ID: post.UserID, ID: post.UserID,
}, },
} }
@ -137,7 +141,7 @@ func (d *walletServant) HandlePostAttachmentBought(post *model.Post, user *model
} }
// 新增账单 // 新增账单
if err := tx.Create(&model.WalletStatement{ if err := tx.Create(&dbr.WalletStatement{
PostID: post.ID, PostID: post.ID,
UserID: master.ID, UserID: master.ID,
ChangeAmount: income, ChangeAmount: income,

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
// Core service implement base sqlx+mysql. All sub-service // Core service implement base sqlx+mysql. All sub-service
// will declare here and provide initial function. // will declare here and provide initial function.

@ -1,10 +1,13 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package search package search
import ( import (
"time" "time"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -43,7 +46,7 @@ func (s *bridgeTweetSearchServant) DeleteDocuments(identifiers []string) error {
return nil return nil
} }
func (s *bridgeTweetSearchServant) Search(user *model.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) { func (s *bridgeTweetSearchServant) Search(user *core.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) {
return s.ts.Search(user, q, offset, limit) return s.ts.Search(user, q, offset, limit)
} }

@ -1,8 +1,11 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package search package search
import ( import (
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/pkg/types" "github.com/rocboss/paopao-ce/pkg/types"
) )
@ -10,19 +13,19 @@ type tweetSearchFilter struct {
ams core.AuthorizationManageService ams core.AuthorizationManageService
} }
func (s *tweetSearchFilter) filterResp(user *model.User, resp *core.QueryResp) { func (s *tweetSearchFilter) filterResp(user *core.User, resp *core.QueryResp) {
// 管理员不过滤 // 管理员不过滤
if user != nil && user.IsAdmin { if user != nil && user.IsAdmin {
return return
} }
var item *model.PostFormated var item *core.PostFormated
items := resp.Items items := resp.Items
latestIndex := len(items) - 1 latestIndex := len(items) - 1
if user == nil { if user == nil {
for i := 0; i <= latestIndex; i++ { for i := 0; i <= latestIndex; i++ {
item = items[i] item = items[i]
if item.Visibility != model.PostVisitPublic { if item.Visibility != core.PostVisitPublic {
items[i] = items[latestIndex] items[i] = items[latestIndex]
items = items[:latestIndex] items = items[:latestIndex]
resp.Total-- resp.Total--
@ -36,8 +39,8 @@ func (s *tweetSearchFilter) filterResp(user *model.User, resp *core.QueryResp) {
friendFilter[user.ID] = types.Empty{} friendFilter[user.ID] = types.Empty{}
for i := 0; i <= latestIndex; i++ { for i := 0; i <= latestIndex; i++ {
item = items[i] item = items[i]
cutFriend = (item.Visibility == model.PostVisitFriend && !friendFilter.IsFriend(item.UserID)) cutFriend = (item.Visibility == core.PostVisitFriend && !friendFilter.IsFriend(item.UserID))
cutPrivate = (item.Visibility == model.PostVisitPrivate && user.ID != item.UserID) cutPrivate = (item.Visibility == core.PostVisitPrivate && user.ID != item.UserID)
if cutFriend || cutPrivate { if cutFriend || cutPrivate {
items[i] = items[latestIndex] items[i] = items[latestIndex]
items = items[:latestIndex] items = items[:latestIndex]

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package search package search
import ( import (
@ -7,7 +11,6 @@ import (
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"github.com/meilisearch/meilisearch-go" "github.com/meilisearch/meilisearch-go"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/pkg/json" "github.com/rocboss/paopao-ce/pkg/json"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -28,20 +31,20 @@ type meiliTweetSearchServant struct {
} }
type postInfo struct { type postInfo struct {
ID int64 `json:"id"` ID int64 `json:"id"`
UserID int64 `json:"user_id"` UserID int64 `json:"user_id"`
CommentCount int64 `json:"comment_count"` CommentCount int64 `json:"comment_count"`
CollectionCount int64 `json:"collection_count"` CollectionCount int64 `json:"collection_count"`
UpvoteCount int64 `json:"upvote_count"` UpvoteCount int64 `json:"upvote_count"`
Visibility model.PostVisibleT `json:"visibility"` Visibility core.PostVisibleT `json:"visibility"`
IsTop int `json:"is_top"` IsTop int `json:"is_top"`
IsEssence int `json:"is_essence"` IsEssence int `json:"is_essence"`
IsLock int `json:"is_lock"` IsLock int `json:"is_lock"`
LatestRepliedOn int64 `json:"latest_replied_on"` LatestRepliedOn int64 `json:"latest_replied_on"`
CreatedOn int64 `json:"created_on"` CreatedOn int64 `json:"created_on"`
ModifiedOn int64 `json:"modified_on"` ModifiedOn int64 `json:"modified_on"`
AttachmentPrice int64 `json:"attachment_price"` AttachmentPrice int64 `json:"attachment_price"`
IPLoc string `json:"ip_loc"` IPLoc string `json:"ip_loc"`
} }
func (s *meiliTweetSearchServant) Name() string { func (s *meiliTweetSearchServant) Name() string {
@ -78,7 +81,7 @@ func (s *meiliTweetSearchServant) DeleteDocuments(identifiers []string) error {
return nil return nil
} }
func (s *meiliTweetSearchServant) Search(user *model.User, q *core.QueryReq, offset, limit int) (resp *core.QueryResp, err error) { func (s *meiliTweetSearchServant) Search(user *core.User, q *core.QueryReq, offset, limit int) (resp *core.QueryResp, err error) {
if q.Type == core.SearchTypeDefault && q.Query != "" { if q.Type == core.SearchTypeDefault && q.Query != "" {
resp, err = s.queryByContent(user, q, offset, limit) resp, err = s.queryByContent(user, q, offset, limit)
} else if q.Type == core.SearchTypeTag && q.Query != "" { } else if q.Type == core.SearchTypeTag && q.Query != "" {
@ -96,7 +99,7 @@ func (s *meiliTweetSearchServant) Search(user *model.User, q *core.QueryReq, off
return return
} }
func (s *meiliTweetSearchServant) queryByContent(user *model.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) { func (s *meiliTweetSearchServant) queryByContent(user *core.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) {
request := &meilisearch.SearchRequest{ request := &meilisearch.SearchRequest{
Offset: int64(offset), Offset: int64(offset),
Limit: int64(limit), Limit: int64(limit),
@ -117,7 +120,7 @@ func (s *meiliTweetSearchServant) queryByContent(user *model.User, q *core.Query
return s.postsFrom(resp) return s.postsFrom(resp)
} }
func (s *meiliTweetSearchServant) queryByTag(user *model.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) { func (s *meiliTweetSearchServant) queryByTag(user *core.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) {
request := &meilisearch.SearchRequest{ request := &meilisearch.SearchRequest{
Offset: int64(offset), Offset: int64(offset),
Limit: int64(limit), Limit: int64(limit),
@ -141,7 +144,7 @@ func (s *meiliTweetSearchServant) queryByTag(user *model.User, q *core.QueryReq,
return s.postsFrom(resp) return s.postsFrom(resp)
} }
func (s *meiliTweetSearchServant) queryAny(user *model.User, offset, limit int) (*core.QueryResp, error) { func (s *meiliTweetSearchServant) queryAny(user *core.User, offset, limit int) (*core.QueryResp, error) {
request := &meilisearch.SearchRequest{ request := &meilisearch.SearchRequest{
Offset: int64(offset), Offset: int64(offset),
Limit: int64(limit), Limit: int64(limit),
@ -161,7 +164,7 @@ func (s *meiliTweetSearchServant) queryAny(user *model.User, offset, limit int)
return s.postsFrom(resp) return s.postsFrom(resp)
} }
func (s *meiliTweetSearchServant) filterList(user *model.User) string { func (s *meiliTweetSearchServant) filterList(user *core.User) string {
if user == nil { if user == nil {
return s.publicFilter return s.publicFilter
} }
@ -174,7 +177,7 @@ func (s *meiliTweetSearchServant) filterList(user *model.User) string {
} }
func (s *meiliTweetSearchServant) postsFrom(resp *meilisearch.SearchResponse) (*core.QueryResp, error) { func (s *meiliTweetSearchServant) postsFrom(resp *meilisearch.SearchResponse) (*core.QueryResp, error) {
posts := make([]*model.PostFormated, 0, len(resp.Hits)) posts := make([]*core.PostFormated, 0, len(resp.Hits))
for _, hit := range resp.Hits { for _, hit := range resp.Hits {
raw, err := json.Marshal(hit) raw, err := json.Marshal(hit)
if err != nil { if err != nil {
@ -184,7 +187,7 @@ func (s *meiliTweetSearchServant) postsFrom(resp *meilisearch.SearchResponse) (*
if err = json.Unmarshal(raw, p); err != nil { if err = json.Unmarshal(raw, p); err != nil {
return nil, err return nil, err
} }
posts = append(posts, &model.PostFormated{ posts = append(posts, &core.PostFormated{
ID: p.ID, ID: p.ID,
UserID: p.UserID, UserID: p.UserID,
CommentCount: p.CommentCount, CommentCount: p.CommentCount,

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package search package search
import ( import (
@ -6,7 +10,6 @@ import (
"github.com/meilisearch/meilisearch-go" "github.com/meilisearch/meilisearch-go"
"github.com/rocboss/paopao-ce/internal/conf" "github.com/rocboss/paopao-ce/internal/conf"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/pkg/zinc" "github.com/rocboss/paopao-ce/pkg/zinc"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -40,9 +43,9 @@ func NewMeiliTweetSearchService(ams core.AuthorizationManageService) (core.Tweet
}, },
client: client, client: client,
index: client.Index(s.Index), index: client.Index(s.Index),
publicFilter: fmt.Sprintf("visibility=%d", model.PostVisitPublic), publicFilter: fmt.Sprintf("visibility=%d", core.PostVisitPublic),
privateFilter: fmt.Sprintf("visibility=%d AND user_id=", model.PostVisitPrivate), privateFilter: fmt.Sprintf("visibility=%d AND user_id=", core.PostVisitPrivate),
friendFilter: fmt.Sprintf("visibility=%d", model.PostVisitFriend), friendFilter: fmt.Sprintf("visibility=%d", core.PostVisitFriend),
} }
return mts, mts return mts, mts
} }
@ -55,9 +58,9 @@ func NewZincTweetSearchService(ams core.AuthorizationManageService) (core.TweetS
}, },
indexName: s.Index, indexName: s.Index,
client: zinc.NewClient(s), client: zinc.NewClient(s),
publicFilter: fmt.Sprintf("visibility:%d", model.PostVisitPublic), publicFilter: fmt.Sprintf("visibility:%d", core.PostVisitPublic),
privateFilter: fmt.Sprintf("visibility:%d AND user_id:%%d", model.PostVisitPrivate), privateFilter: fmt.Sprintf("visibility:%d AND user_id:%%d", core.PostVisitPrivate),
friendFilter: fmt.Sprintf("visibility:%d", model.PostVisitFriend), friendFilter: fmt.Sprintf("visibility:%d", core.PostVisitFriend),
} }
zts.createIndex() zts.createIndex()

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package search package search
import ( import (
@ -5,7 +9,6 @@ import (
"github.com/Masterminds/semver/v3" "github.com/Masterminds/semver/v3"
"github.com/rocboss/paopao-ce/internal/core" "github.com/rocboss/paopao-ce/internal/core"
"github.com/rocboss/paopao-ce/internal/model"
"github.com/rocboss/paopao-ce/pkg/json" "github.com/rocboss/paopao-ce/pkg/json"
"github.com/rocboss/paopao-ce/pkg/zinc" "github.com/rocboss/paopao-ce/pkg/zinc"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@ -73,7 +76,7 @@ func (s *zincTweetSearchServant) DeleteDocuments(identifiers []string) error {
return nil return nil
} }
func (s *zincTweetSearchServant) Search(user *model.User, q *core.QueryReq, offset, limit int) (resp *core.QueryResp, err error) { func (s *zincTweetSearchServant) Search(user *core.User, q *core.QueryReq, offset, limit int) (resp *core.QueryResp, err error) {
if q.Type == core.SearchTypeDefault && q.Query != "" { if q.Type == core.SearchTypeDefault && q.Query != "" {
resp, err = s.queryByContent(user, q, offset, limit) resp, err = s.queryByContent(user, q, offset, limit)
} else if q.Type == core.SearchTypeTag && q.Query != "" { } else if q.Type == core.SearchTypeTag && q.Query != "" {
@ -91,7 +94,7 @@ func (s *zincTweetSearchServant) Search(user *model.User, q *core.QueryReq, offs
return return
} }
func (s *zincTweetSearchServant) queryByContent(user *model.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) { func (s *zincTweetSearchServant) queryByContent(user *core.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) {
resp, err := s.client.EsQuery(s.indexName, map[string]any{ resp, err := s.client.EsQuery(s.indexName, map[string]any{
"query": map[string]any{ "query": map[string]any{
"match_phrase": map[string]any{ "match_phrase": map[string]any{
@ -108,7 +111,7 @@ func (s *zincTweetSearchServant) queryByContent(user *model.User, q *core.QueryR
return s.postsFrom(resp) return s.postsFrom(resp)
} }
func (s *zincTweetSearchServant) queryByTag(user *model.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) { func (s *zincTweetSearchServant) queryByTag(user *core.User, q *core.QueryReq, offset, limit int) (*core.QueryResp, error) {
resp, err := s.client.ApiQuery(s.indexName, map[string]any{ resp, err := s.client.ApiQuery(s.indexName, map[string]any{
"search_type": "querystring", "search_type": "querystring",
"query": map[string]any{ "query": map[string]any{
@ -124,7 +127,7 @@ func (s *zincTweetSearchServant) queryByTag(user *model.User, q *core.QueryReq,
return s.postsFrom(resp) return s.postsFrom(resp)
} }
func (s *zincTweetSearchServant) queryAny(user *model.User, offset, limit int) (*core.QueryResp, error) { func (s *zincTweetSearchServant) queryAny(user *core.User, offset, limit int) (*core.QueryResp, error) {
queryMap := map[string]any{ queryMap := map[string]any{
"query": map[string]any{ "query": map[string]any{
"match_all": map[string]string{}, "match_all": map[string]string{},
@ -141,9 +144,9 @@ func (s *zincTweetSearchServant) queryAny(user *model.User, offset, limit int) (
} }
func (s *zincTweetSearchServant) postsFrom(resp *zinc.QueryResultT) (*core.QueryResp, error) { func (s *zincTweetSearchServant) postsFrom(resp *zinc.QueryResultT) (*core.QueryResp, error) {
posts := make([]*model.PostFormated, 0, len(resp.Hits.Hits)) posts := make([]*core.PostFormated, 0, len(resp.Hits.Hits))
for _, hit := range resp.Hits.Hits { for _, hit := range resp.Hits.Hits {
item := &model.PostFormated{} item := &core.PostFormated{}
raw, err := json.Marshal(hit.Source) raw, err := json.Marshal(hit.Source)
if err != nil { if err != nil {
return nil, err return nil, err

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package security package security
import ( import (

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
// Core service implement base sqlx+postgresql. All sub-service // Core service implement base sqlx+postgresql. All sub-service
// will declare here and provide initial function. // will declare here and provide initial function.

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package storage package storage
import ( import (

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package storage package storage
import ( import (

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package storage package storage
import ( import (

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package storage package storage
import ( import (

@ -1,3 +1,7 @@
// Copyright 2022 ROC. All rights reserved.
// Use of this source code is governed by a MIT style
// license that can be found in the LICENSE file.
package storage package storage
import ( import (

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save